From 0de7568e417ae001a45ae0a85b8bc2067a5f9c46 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Apr 2022 21:07:46 -0700 Subject: [PATCH] Mention traits being upcasted, types being coerced --- compiler/rustc_typeck/src/check/coercion.rs | 19 ++++++++++++------- .../feature-gate-trait_upcasting.stderr | 3 ++- src/test/ui/issues/issue-11515.stderr | 3 ++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs index 57d3079935415..9790a42102837 100644 --- a/compiler/rustc_typeck/src/check/coercion.rs +++ b/compiler/rustc_typeck/src/check/coercion.rs @@ -615,7 +615,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { )]; let mut has_unsized_tuple_coercion = false; - let mut has_trait_upcasting_coercion = false; + let mut has_trait_upcasting_coercion = None; // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where @@ -635,7 +635,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { && data_a.principal_def_id() != data_b.principal_def_id() { debug!("coerce_unsized: found trait upcasting coercion"); - has_trait_upcasting_coercion = true; + has_trait_upcasting_coercion = Some((self_ty, unsize_ty)); } if let ty::Tuple(..) = unsize_ty.kind() { debug!("coerce_unsized: found unsized tuple coercion"); @@ -706,14 +706,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { .emit(); } - if has_trait_upcasting_coercion && !self.tcx().features().trait_upcasting { - feature_err( + if let Some((sub, sup)) = has_trait_upcasting_coercion + && !self.tcx().features().trait_upcasting + { + // Renders better when we erase regions, since they're not really the point here. + let (sub, sup) = self.tcx.erase_regions((sub, sup)); + let mut err = feature_err( &self.tcx.sess.parse_sess, sym::trait_upcasting, self.cause.span, - "trait upcasting coercion is experimental", - ) - .emit(); + &format!("cannot cast `{sub}` to `{sup}`, trait upcasting coercion is experimental"), + ); + err.note(&format!("required when coercing `{source}` into `{target}`")); + err.emit(); } Ok(coercion) diff --git a/src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr b/src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr index bc13a5d7d7b46..93afa78459d3d 100644 --- a/src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr +++ b/src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr @@ -1,4 +1,4 @@ -error[E0658]: trait upcasting coercion is experimental +error[E0658]: cannot cast `dyn Bar` to `dyn Foo`, trait upcasting coercion is experimental --> $DIR/feature-gate-trait_upcasting.rs:11:25 | LL | let foo: &dyn Foo = bar; @@ -6,6 +6,7 @@ LL | let foo: &dyn Foo = bar; | = note: see issue #65991 for more information = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable + = note: required when coercing `&dyn Bar` into `&dyn Foo` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-11515.stderr b/src/test/ui/issues/issue-11515.stderr index a70e7c416bc0f..17bfae2a4e46b 100644 --- a/src/test/ui/issues/issue-11515.stderr +++ b/src/test/ui/issues/issue-11515.stderr @@ -1,4 +1,4 @@ -error[E0658]: trait upcasting coercion is experimental +error[E0658]: cannot cast `dyn Fn()` to `dyn FnMut()`, trait upcasting coercion is experimental --> $DIR/issue-11515.rs:9:33 | LL | let test = box Test { func: closure }; @@ -6,6 +6,7 @@ LL | let test = box Test { func: closure }; | = note: see issue #65991 for more information = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable + = note: required when coercing `Box<(dyn Fn() + 'static)>` into `Box<(dyn FnMut() + 'static)>` error: aborting due to previous error