Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6a64501

Browse files
do not materialise X in [X; 0] when X is unsizing a const
1 parent fce0e74 commit 6a64501

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

‎compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_middle::middle::region;
88
use rustc_middle::mir::interpret::Scalar;
99
use rustc_middle::mir::*;
1010
use rustc_middle::thir::*;
11+
use rustc_middle::ty::adjustment::PointerCoercion;
1112
use rustc_middle::ty::cast::{CastTy, mir_cast_kind};
1213
use rustc_middle::ty::util::IntTypeExt;
1314
use rustc_middle::ty::{self, Ty, UpvarArgs};
@@ -656,6 +657,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
656657
block.and(rvalue)
657658
}
658659

660+
/// Recursively inspect a THIR expression and probe through unsizing
661+
/// operations that can be const-folded today.
662+
fn check_constness(&self, mut ek: &'a ExprKind<'tcx>) -> bool {
663+
loop {
664+
match ek {
665+
&ExprKind::PointerCoercion {
666+
cast: PointerCoercion::Unsize,
667+
source: eid,
668+
is_from_as_cast: _,
669+
}
670+
| &ExprKind::Scope { region_scope: _, lint_level: _, value: eid } => {
671+
ek = &self.thir[eid].kind
672+
}
673+
_ => return matches!(Category::of(&ek), Some(Category::Constant)),
674+
}
675+
}
676+
}
677+
659678
fn build_zero_repeat(
660679
&mut self,
661680
mut block: BasicBlock,
@@ -666,7 +685,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
666685
let this = self;
667686
let value_expr = &this.thir[value];
668687
let elem_ty = value_expr.ty;
669-
if letSome(Category::Constant) = Category::of(&value_expr.kind) {
688+
if this.check_constness(&value_expr.kind) {
670689
// Repeating a const does nothing
671690
} else {
672691
// For a non-const, we may need to generate an appropriate `Drop`

‎tests/ui/coercion/issue-143671.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//@ run-pass
2+
3+
#![feature(unsize)]
4+
#![feature(coerce_unsized)]
5+
6+
use std::fmt::Display;
7+
use std::marker::Unsize;
8+
use std::ops::CoerceUnsized;
9+
10+
#[repr(transparent)]
11+
struct X<'a, T: ?Sized> {
12+
f: &'a T,
13+
}
14+
15+
impl<'a, T: ?Sized> Drop for X<'a, T> {
16+
fn drop(&mut self) {
17+
panic!()
18+
}
19+
}
20+
21+
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<X<'a, U>> for X<'a, T> where
22+
&'a T: CoerceUnsized<&'a U>
23+
{
24+
}
25+
26+
const Y: X<'static, i32> = X { f: &0 };
27+
28+
fn main() {
29+
let _: [X<'static, dyn Display>; 0] = [Y; 0];
30+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /