diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 097416b4f280..e5aad4cdbd06 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1581,12 +1581,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { .unwrap(); } (None, None) => { + // `struct_tail` returns regions which haven't been mapped + // to nll vars yet so we do it here as `outlives_constraints` + // expects nll vars. + let src_lt = self.universal_regions.to_region_vid(src_lt); + let dst_lt = self.universal_regions.to_region_vid(dst_lt); + // The principalless (no non-auto traits) case: // You can only cast `dyn Send + 'long` to `dyn Send + 'short`. self.constraints.outlives_constraints.push( OutlivesConstraint { - sup: src_lt.as_var(), - sub: dst_lt.as_var(), + sup: src_lt, + sub: dst_lt, locations: location.to_locations(), span: location.to_locations().span(self.body), category: ConstraintCategory::Cast { diff --git a/tests/ui/cast/ptr-to-ptr-unsized-adt-tail-with-static-region.rs b/tests/ui/cast/ptr-to-ptr-unsized-adt-tail-with-static-region.rs new file mode 100644 index 000000000000..7319a670c881 --- /dev/null +++ b/tests/ui/cast/ptr-to-ptr-unsized-adt-tail-with-static-region.rs @@ -0,0 +1,15 @@ +//@ check-pass + +// During MIR typeck when casting `*mut dyn Sync + '?x` to +// `*mut Wrap` we compute the tail of `Wrap` as `dyn Sync + 'static`. +// +// This test ensures that we first convert the `'static` lifetime to +// the nll var `'?0` before introducing the region constraint `'?x: 'static`. + +struct Wrap(dyn Sync + 'static); + +fn cast(x: *mut (dyn Sync + 'static)) { + x as *mut Wrap; +} + +fn main() {}