diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 16e51e82f85e0..6b17879de262d 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2437,7 +2437,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); - self.eq_types( + self.sub_types( src_obj, dst_obj, location.to_locations(), diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs index d7c6c50d8bebc..18566acc07fe4 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs @@ -15,6 +15,12 @@ fn change_lt_ba<'a, 'b: 'a>(x: *mut dyn Trait<'a>) -> *mut dyn Trait<'b> { x as _ //~ error: lifetime may not live long enough } +fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> { + x as _ //~ error: lifetime may not live long enough + //~^ error: mismatched types + //~| one type is more general than the other +} + trait Assocked { type Assoc: ?Sized; } diff --git a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr index 6069f4f3b5563..6f590585c4a46 100644 --- a/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr +++ b/tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr @@ -61,7 +61,29 @@ LL | x as _ = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5 + | +LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> { + | -- lifetime `'a` defined here +LL | x as _ + | ^^^^^^ cast requires that `'a` must outlive `'static` + | +help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound + | +LL | fn change_lt_hr<'a>(x: *mut dyn Trait<'a>) -> *mut dyn for<'b> Trait<'b> + 'a { + | ++++ + +error[E0308]: mismatched types + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:19:5 + | +LL | x as _ + | ^^^^^^ one type is more general than the other + | + = note: expected trait object `dyn for<'b> Trait<'b>` + found trait object `dyn Trait<'_>` + +error: lifetime may not live long enough + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5 | LL | fn change_assoc_0<'a, 'b>( | -- -- lifetime `'b` defined here @@ -77,7 +99,7 @@ LL | x as _ = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:25:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:31:5 | LL | fn change_assoc_0<'a, 'b>( | -- -- lifetime `'b` defined here @@ -97,7 +119,7 @@ help: `'b` and `'a` must be the same: replace one with the other = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5 | LL | fn change_assoc_1<'a, 'b>( | -- -- lifetime `'b` defined here @@ -113,7 +135,7 @@ LL | x as _ = help: see for more information about variance error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:32:5 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:38:5 | LL | fn change_assoc_1<'a, 'b>( | -- -- lifetime `'b` defined here @@ -133,12 +155,13 @@ help: `'b` and `'a` must be the same: replace one with the other = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: lifetime may not live long enough - --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:39:20 + --> $DIR/ptr-to-trait-obj-different-regions-misc.rs:45:20 | LL | fn extend_to_static<'a>(ptr: *const dyn Trait<'a>) { | -- lifetime `'a` defined here LL | require_static(ptr as _) | ^^^^^^^^ cast requires that `'a` must outlive `'static` -error: aborting due to 9 previous errors +error: aborting due to 11 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/cast/ptr-to-trait-obj-ok.rs b/tests/ui/cast/ptr-to-trait-obj-ok.rs index 656c99c58dc9a..dbeee9d29441e 100644 --- a/tests/ui/cast/ptr-to-trait-obj-ok.rs +++ b/tests/ui/cast/ptr-to-trait-obj-ok.rs @@ -10,8 +10,37 @@ fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trai x as _ } +fn cast_away_higher_ranked<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut dyn Trait<'a> { + x as _ +} + fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) { x as _ } +// If it is possible to coerce from the source to the target type modulo +// regions, then we skip the HIR checks for ptr-to-ptr casts and possibly +// insert an unsizing coercion into the MIR before the ptr-to-ptr cast. +// By wrapping the target type, we ensure that no coercion happens +// and also test the non-coercion cast behavior. +struct Wrapper(T); + +fn remove_auto_wrap<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut Wrapper> { + x as _ +} + +fn cast_inherent_lt_wrap<'a, 'b>( + x: *mut (dyn Trait<'static> + 'a), +) -> *mut Wrapper + 'b> { + x as _ +} + +fn cast_away_higher_ranked_wrap<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut Wrapper> { + x as _ +} + +fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper { + x as _ +} + fn main() {}