Skip to content

Commit d837ab4

Browse files
authored
Rollup merge of #139025 - compiler-errors:trim-validator-err, r=jieyouxu
Do not trim paths in MIR validator From my inline comment: ``` // The type checker formats a bunch of strings with type names in it, but these strings // are not always going to be encountered on the error path since the inliner also uses // the validator, and there are certain kinds of inlining (even for valid code) that // can cause validation errors (mostly around where clauses and rigid projections). ``` Fixes #138979 r? `@jieyouxu`
2 parents 5bd0fd6 + ed0a798 commit d837ab4

File tree

2 files changed

+67
-26
lines changed

2 files changed

+67
-26
lines changed

Diff for: compiler/rustc_mir_transform/src/validate.rs

+31-26
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_middle::mir::coverage::CoverageKind;
1212
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
1313
use rustc_middle::mir::*;
1414
use rustc_middle::ty::adjustment::PointerCoercion;
15+
use rustc_middle::ty::print::with_no_trimmed_paths;
1516
use rustc_middle::ty::{
1617
self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Upcast, Variance,
1718
};
@@ -56,7 +57,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator {
5657
ty::Coroutine(..) => ExternAbi::Rust,
5758
// No need to do MIR validation on error bodies
5859
ty::Error(_) => return,
59-
_ => span_bug!(body.span, "unexpected body ty: {body_ty:?}"),
60+
_ => span_bug!(body.span, "unexpected body ty: {body_ty}"),
6061
};
6162

6263
ty::layout::fn_can_unwind(tcx, Some(def_id), body_abi)
@@ -543,7 +544,13 @@ pub(super) fn validate_types<'tcx>(
543544
caller_body: &Body<'tcx>,
544545
) -> Vec<(Location, String)> {
545546
let mut type_checker = TypeChecker { body, caller_body, tcx, typing_env, failures: Vec::new() };
546-
type_checker.visit_body(body);
547+
// The type checker formats a bunch of strings with type names in it, but these strings
548+
// are not always going to be encountered on the error path since the inliner also uses
549+
// the validator, and there are certain kinds of inlining (even for valid code) that
550+
// can cause validation errors (mostly around where clauses and rigid projections).
551+
with_no_trimmed_paths!({
552+
type_checker.visit_body(body);
553+
});
547554
type_checker.failures
548555
}
549556

@@ -655,7 +662,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
655662
ProjectionElem::Index(index) => {
656663
let index_ty = self.body.local_decls[index].ty;
657664
if index_ty != self.tcx.types.usize {
658-
self.fail(location, format!("bad index ({index_ty:?} != usize)"))
665+
self.fail(location, format!("bad index ({index_ty} != usize)"))
659666
}
660667
}
661668
ProjectionElem::Deref
@@ -664,10 +671,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
664671
let base_ty = place_ref.ty(&self.body.local_decls, self.tcx).ty;
665672

666673
if base_ty.is_box() {
667-
self.fail(
668-
location,
669-
format!("{base_ty:?} dereferenced after ElaborateBoxDerefs"),
670-
)
674+
self.fail(location, format!("{base_ty} dereferenced after ElaborateBoxDerefs"))
671675
}
672676
}
673677
ProjectionElem::Field(f, ty) => {
@@ -680,7 +684,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
680684
this.fail(
681685
location,
682686
format!(
683-
"Field projection `{place_ref:?}.{f:?}` specified type `{ty:?}`, but actual type is `{f_ty:?}`"
687+
"Field projection `{place_ref:?}.{f:?}` specified type `{ty}`, but actual type is `{f_ty}`"
684688
)
685689
)
686690
}
@@ -806,7 +810,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
806810
self.fail(
807811
location,
808812
format!(
809-
"Failed subtyping {ty:#?} and {:#?}",
813+
"Failed subtyping {ty} and {}",
810814
place_ref.ty(&self.body.local_decls, self.tcx).ty
811815
),
812816
)
@@ -826,7 +830,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
826830
self.fail(
827831
location,
828832
format!(
829-
"Cannot unwrap unsafe binder {binder_ty:?} into type {unwrapped_ty:?}"
833+
"Cannot unwrap unsafe binder {binder_ty:?} into type {unwrapped_ty}"
830834
),
831835
);
832836
}
@@ -841,7 +845,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
841845
if ty.is_union() || ty.is_enum() {
842846
self.fail(
843847
START_BLOCK.start_location(),
844-
format!("invalid type {ty:?} in debuginfo for {:?}", debuginfo.name),
848+
format!("invalid type {ty} in debuginfo for {:?}", debuginfo.name),
845849
);
846850
}
847851
if projection.is_empty() {
@@ -1064,15 +1068,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
10641068
if !self.mir_assign_valid_types(a, b) {
10651069
self.fail(
10661070
location,
1067-
format!("Cannot {op:?} compare incompatible types {a:?} and {b:?}"),
1071+
format!("Cannot {op:?} compare incompatible types {a} and {b}"),
10681072
);
10691073
}
10701074
} else if a != b {
10711075
self.fail(
10721076
location,
1073-
format!(
1074-
"Cannot perform binary op {op:?} on unequal types {a:?} and {b:?}"
1075-
),
1077+
format!("Cannot perform binary op {op:?} on unequal types {a} and {b}"),
10761078
);
10771079
}
10781080
}
@@ -1081,7 +1083,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
10811083
Offset => {
10821084
check_kinds!(a, "Cannot offset non-pointer type {:?}", ty::RawPtr(..));
10831085
if b != self.tcx.types.isize && b != self.tcx.types.usize {
1084-
self.fail(location, format!("Cannot offset by non-isize type {b:?}"));
1086+
self.fail(location, format!("Cannot offset by non-isize type {b}"));
10851087
}
10861088
}
10871089
Eq | Lt | Le | Ne | Ge | Gt => {
@@ -1313,7 +1315,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
13131315
{
13141316
self.fail(
13151317
location,
1316-
format!("Cannot transmute from non-`Sized` type {op_ty:?}"),
1318+
format!("Cannot transmute from non-`Sized` type {op_ty}"),
13171319
);
13181320
}
13191321
if !self
@@ -1340,7 +1342,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
13401342
}
13411343
Rvalue::NullaryOp(NullOp::OffsetOf(indices), container) => {
13421344
let fail_out_of_bounds = |this: &mut Self, location, field, ty| {
1343-
this.fail(location, format!("Out of bounds field {field:?} for {ty:?}"));
1345+
this.fail(location, format!("Out of bounds field {field:?} for {ty}"));
13441346
};
13451347

13461348
let mut current_ty = *container;
@@ -1374,7 +1376,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
13741376
_ => {
13751377
self.fail(
13761378
location,
1377-
format!("Cannot get offset ({variant:?}, {field:?}) from type {current_ty:?}"),
1379+
format!("Cannot get offset ({variant:?}, {field:?}) from type {current_ty}"),
13781380
);
13791381
return;
13801382
}
@@ -1403,7 +1405,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
14031405
if !self.mir_assign_valid_types(unwrapped_ty, binder_inner_ty) {
14041406
self.fail(
14051407
location,
1406-
format!("Cannot wrap {unwrapped_ty:?} into unsafe binder {binder_ty:?}"),
1408+
format!("Cannot wrap {unwrapped_ty} into unsafe binder {binder_ty:?}"),
14071409
);
14081410
}
14091411
}
@@ -1489,24 +1491,27 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
14891491
// since CopyNonOverlapping is parametrized by 1 type,
14901492
// we only need to check that they are equal and not keep an extra parameter.
14911493
if !self.mir_assign_valid_types(op_src_ty, op_dst_ty) {
1492-
self.fail(location, format!("bad arg ({op_src_ty:?} != {op_dst_ty:?})"));
1494+
self.fail(location, format!("bad arg ({op_src_ty} != {op_dst_ty})"));
14931495
}
14941496

14951497
let op_cnt_ty = count.ty(&self.body.local_decls, self.tcx);
14961498
if op_cnt_ty != self.tcx.types.usize {
1497-
self.fail(location, format!("bad arg ({op_cnt_ty:?} != usize)"))
1499+
self.fail(location, format!("bad arg ({op_cnt_ty} != usize)"))
14981500
}
14991501
}
15001502
StatementKind::SetDiscriminant { place, .. } => {
15011503
if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) {
15021504
self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
15031505
}
1504-
let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind();
1505-
if !matches!(pty, ty::Adt(..) | ty::Coroutine(..) | ty::Alias(ty::Opaque, ..)) {
1506+
let pty = place.ty(&self.body.local_decls, self.tcx).ty;
1507+
if !matches!(
1508+
pty.kind(),
1509+
ty::Adt(..) | ty::Coroutine(..) | ty::Alias(ty::Opaque, ..)
1510+
) {
15061511
self.fail(
15071512
location,
15081513
format!(
1509-
"`SetDiscriminant` is only allowed on ADTs and coroutines, not {pty:?}"
1514+
"`SetDiscriminant` is only allowed on ADTs and coroutines, not {pty}"
15101515
),
15111516
);
15121517
}
@@ -1555,7 +1560,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
15551560
if ScalarInt::try_from_uint(value, size).is_none() {
15561561
self.fail(
15571562
location,
1558-
format!("the value {value:#x} is not a proper {switch_ty:?}"),
1563+
format!("the value {value:#x} is not a proper {switch_ty}"),
15591564
)
15601565
}
15611566
}

Diff for: tests/ui/mir/inline-causes-trimmed-paths.rs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//@ build-pass
2+
//@ compile-flags: -Zinline-mir
3+
4+
trait Storage {
5+
type Buffer: ?Sized;
6+
}
7+
8+
struct Array<const N: usize>;
9+
impl<const N: usize> Storage for Array<N> {
10+
type Buffer = [(); N];
11+
}
12+
13+
struct Slice;
14+
impl Storage for Slice {
15+
type Buffer = [()];
16+
}
17+
18+
struct Wrap<S: Storage> {
19+
_b: S::Buffer,
20+
}
21+
22+
fn coerce<const N: usize>(this: &Wrap<Array<N>>) -> &Wrap<Slice>
23+
where
24+
Array<N>: Storage,
25+
{
26+
coerce_again(this)
27+
}
28+
29+
fn coerce_again<const N: usize>(this: &Wrap<Array<N>>) -> &Wrap<Slice> {
30+
this
31+
}
32+
33+
fn main() {
34+
let inner: Wrap<Array<1>> = Wrap { _b: [(); 1] };
35+
let _: &Wrap<Slice> = coerce(&inner);
36+
}

0 commit comments

Comments
 (0)