diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 231d7c2ef0225..e7930f0a1e3f6 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -12,6 +12,7 @@ use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; +use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ self, CoroutineArgsExt, InstanceKind, ScalarInt, Ty, TyCtxt, TypeVisitableExt, Upcast, Variance, }; @@ -56,7 +57,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { ty::Coroutine(..) => ExternAbi::Rust, // No need to do MIR validation on error bodies ty::Error(_) => return, - _ => span_bug!(body.span, "unexpected body ty: {body_ty:?}"), + _ => span_bug!(body.span, "unexpected body ty: {body_ty}"), }; ty::layout::fn_can_unwind(tcx, Some(def_id), body_abi) @@ -543,7 +544,13 @@ pub(super) fn validate_types<'tcx>( caller_body: &Body<'tcx>, ) -> Vec<(Location, String)> { let mut type_checker = TypeChecker { body, caller_body, tcx, typing_env, failures: Vec::new() }; - type_checker.visit_body(body); + // 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). + with_no_trimmed_paths!({ + type_checker.visit_body(body); + }); type_checker.failures } @@ -655,7 +662,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ProjectionElem::Index(index) => { let index_ty = self.body.local_decls[index].ty; if index_ty != self.tcx.types.usize { - self.fail(location, format!("bad index ({index_ty:?} != usize)")) + self.fail(location, format!("bad index ({index_ty} != usize)")) } } ProjectionElem::Deref @@ -664,10 +671,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let base_ty = place_ref.ty(&self.body.local_decls, self.tcx).ty; if base_ty.is_box() { - self.fail( - location, - format!("{base_ty:?} dereferenced after ElaborateBoxDerefs"), - ) + self.fail(location, format!("{base_ty} dereferenced after ElaborateBoxDerefs")) } } ProjectionElem::Field(f, ty) => { @@ -680,7 +684,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { this.fail( location, format!( - "Field projection `{place_ref:?}.{f:?}` specified type `{ty:?}`, but actual type is `{f_ty:?}`" + "Field projection `{place_ref:?}.{f:?}` specified type `{ty}`, but actual type is `{f_ty}`" ) ) } @@ -806,7 +810,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail( location, format!( - "Failed subtyping {ty:#?} and {:#?}", + "Failed subtyping {ty} and {}", place_ref.ty(&self.body.local_decls, self.tcx).ty ), ) @@ -826,7 +830,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail( location, format!( - "Cannot unwrap unsafe binder {binder_ty:?} into type {unwrapped_ty:?}" + "Cannot unwrap unsafe binder {binder_ty:?} into type {unwrapped_ty}" ), ); } @@ -841,7 +845,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if ty.is_union() || ty.is_enum() { self.fail( START_BLOCK.start_location(), - format!("invalid type {ty:?} in debuginfo for {:?}", debuginfo.name), + format!("invalid type {ty} in debuginfo for {:?}", debuginfo.name), ); } if projection.is_empty() { @@ -1064,15 +1068,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if !self.mir_assign_valid_types(a, b) { self.fail( location, - format!("Cannot {op:?} compare incompatible types {a:?} and {b:?}"), + format!("Cannot {op:?} compare incompatible types {a} and {b}"), ); } } else if a != b { self.fail( location, - format!( - "Cannot perform binary op {op:?} on unequal types {a:?} and {b:?}" - ), + format!("Cannot perform binary op {op:?} on unequal types {a} and {b}"), ); } } @@ -1081,7 +1083,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { Offset => { check_kinds!(a, "Cannot offset non-pointer type {:?}", ty::RawPtr(..)); if b != self.tcx.types.isize && b != self.tcx.types.usize { - self.fail(location, format!("Cannot offset by non-isize type {b:?}")); + self.fail(location, format!("Cannot offset by non-isize type {b}")); } } Eq | Lt | Le | Ne | Ge | Gt => { @@ -1313,7 +1315,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { { self.fail( location, - format!("Cannot transmute from non-`Sized` type {op_ty:?}"), + format!("Cannot transmute from non-`Sized` type {op_ty}"), ); } if !self @@ -1340,7 +1342,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } Rvalue::NullaryOp(NullOp::OffsetOf(indices), container) => { let fail_out_of_bounds = |this: &mut Self, location, field, ty| { - this.fail(location, format!("Out of bounds field {field:?} for {ty:?}")); + this.fail(location, format!("Out of bounds field {field:?} for {ty}")); }; let mut current_ty = *container; @@ -1374,7 +1376,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { _ => { self.fail( location, - format!("Cannot get offset ({variant:?}, {field:?}) from type {current_ty:?}"), + format!("Cannot get offset ({variant:?}, {field:?}) from type {current_ty}"), ); return; } @@ -1403,7 +1405,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if !self.mir_assign_valid_types(unwrapped_ty, binder_inner_ty) { self.fail( location, - format!("Cannot wrap {unwrapped_ty:?} into unsafe binder {binder_ty:?}"), + format!("Cannot wrap {unwrapped_ty} into unsafe binder {binder_ty:?}"), ); } } @@ -1489,24 +1491,27 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // since CopyNonOverlapping is parametrized by 1 type, // we only need to check that they are equal and not keep an extra parameter. if !self.mir_assign_valid_types(op_src_ty, op_dst_ty) { - self.fail(location, format!("bad arg ({op_src_ty:?} != {op_dst_ty:?})")); + self.fail(location, format!("bad arg ({op_src_ty} != {op_dst_ty})")); } let op_cnt_ty = count.ty(&self.body.local_decls, self.tcx); if op_cnt_ty != self.tcx.types.usize { - self.fail(location, format!("bad arg ({op_cnt_ty:?} != usize)")) + self.fail(location, format!("bad arg ({op_cnt_ty} != usize)")) } } StatementKind::SetDiscriminant { place, .. } => { if self.body.phase < MirPhase::Runtime(RuntimePhase::Initial) { self.fail(location, "`SetDiscriminant`is not allowed until deaggregation"); } - let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind(); - if !matches!(pty, ty::Adt(..) | ty::Coroutine(..) | ty::Alias(ty::Opaque, ..)) { + let pty = place.ty(&self.body.local_decls, self.tcx).ty; + if !matches!( + pty.kind(), + ty::Adt(..) | ty::Coroutine(..) | ty::Alias(ty::Opaque, ..) + ) { self.fail( location, format!( - "`SetDiscriminant` is only allowed on ADTs and coroutines, not {pty:?}" + "`SetDiscriminant` is only allowed on ADTs and coroutines, not {pty}" ), ); } @@ -1555,7 +1560,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { if ScalarInt::try_from_uint(value, size).is_none() { self.fail( location, - format!("the value {value:#x} is not a proper {switch_ty:?}"), + format!("the value {value:#x} is not a proper {switch_ty}"), ) } } diff --git a/tests/ui/mir/inline-causes-trimmed-paths.rs b/tests/ui/mir/inline-causes-trimmed-paths.rs new file mode 100644 index 0000000000000..d626ab4e1d9cd --- /dev/null +++ b/tests/ui/mir/inline-causes-trimmed-paths.rs @@ -0,0 +1,36 @@ +//@ build-pass +//@ compile-flags: -Zinline-mir + +trait Storage { + type Buffer: ?Sized; +} + +struct Array; +impl Storage for Array { + type Buffer = [(); N]; +} + +struct Slice; +impl Storage for Slice { + type Buffer = [()]; +} + +struct Wrap { + _b: S::Buffer, +} + +fn coerce(this: &Wrap>) -> &Wrap +where + Array: Storage, +{ + coerce_again(this) +} + +fn coerce_again(this: &Wrap>) -> &Wrap { + this +} + +fn main() { + let inner: Wrap> = Wrap { _b: [(); 1] }; + let _: &Wrap = coerce(&inner); +}