about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs2
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-different-regions-misc.rs6
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-different-regions-misc.stderr35
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-ok.rs29
4 files changed, 65 insertions, 7 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 16e51e82f85..6b17879de26 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 d7c6c50d8be..18566acc07f 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 6069f4f3b55..6f590585c4a 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 <https://doc.rust-lang.org/nomicon/subtyping.html> 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 <https://doc.rust-lang.org/nomicon/subtyping.html> 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 <https://doc.rust-lang.org/nomicon/subtyping.html> 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 656c99c58dc..dbeee9d2944 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: ?Sized>(T);
+
+fn remove_auto_wrap<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut Wrapper<dyn Trait<'a>> {
+    x as _
+}
+
+fn cast_inherent_lt_wrap<'a, 'b>(
+    x: *mut (dyn Trait<'static> + 'a),
+) -> *mut Wrapper<dyn Trait<'static> + 'b> {
+    x as _
+}
+
+fn cast_away_higher_ranked_wrap<'a>(x: *mut dyn for<'b> Trait<'b>) -> *mut Wrapper<dyn Trait<'a>> {
+    x as _
+}
+
+fn unprincipled_wrap<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut Wrapper<dyn Sync + 'b> {
+    x as _
+}
+
 fn main() {}