From a9af75cdbc2f31fe0f68854d5b579616c4393839 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 21 Dec 2022 17:44:30 +0000 Subject: [PATCH] Give opaque types a better coherence error --- .../src/coherence/orphan.rs | 23 ++++++++++++------- .../ui/type-alias-impl-trait/coherence.stderr | 2 +- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index cc5114dba5efe..c6d4aeefc80e5 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -184,11 +184,19 @@ fn emit_orphan_check_error<'tcx>( ty::Adt(def, _) => tcx.mk_adt(*def, ty::List::empty()), _ => ty, }; - let this = "this".to_string(); - let (ty, postfix) = match &ty.kind() { - ty::Slice(_) => (this, " because slices are always foreign"), - ty::Array(..) => (this, " because arrays are always foreign"), - ty::Tuple(..) => (this, " because tuples are always foreign"), + let msg = |ty: &str, postfix: &str| { + format!("{ty} is not defined in the current crate{postfix}") + }; + let this = |name: &str| msg("this", &format!(" because {name} are always foreign")); + let msg = match &ty.kind() { + ty::Slice(_) => this("slices"), + ty::Array(..) => this("arrays"), + ty::Tuple(..) => this("tuples"), + ty::Alias(ty::Opaque, ..) => { + "type alias impl trait is treated as if it were foreign, \ + because its hidden type could be from a foreign crate" + .to_string() + } ty::RawPtr(ptr_ty) => { emit_newtype_suggestion_for_raw_ptr( full_impl_span, @@ -198,12 +206,11 @@ fn emit_orphan_check_error<'tcx>( &mut err, ); - (format!("`{}`", ty), " because raw pointers are always foreign") + msg(&format!("`{ty}`"), " because raw pointers are always foreign") } - _ => (format!("`{}`", ty), ""), + _ => msg(&format!("`{ty}`"), ""), }; - let msg = format!("{} is not defined in the current crate{}", ty, postfix); if is_target_ty { // Point at `D` in `impl for C in D` err.span_label(self_ty_span, &msg); diff --git a/src/test/ui/type-alias-impl-trait/coherence.stderr b/src/test/ui/type-alias-impl-trait/coherence.stderr index c923eb08ab312..00b0dbbb583fd 100644 --- a/src/test/ui/type-alias-impl-trait/coherence.stderr +++ b/src/test/ui/type-alias-impl-trait/coherence.stderr @@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar LL | impl foreign_crate::ForeignTrait for AliasOfForeignType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------- | | | - | | `AliasOfForeignType` is not defined in the current crate + | | type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate | impl doesn't use only types from inside the current crate | = note: define and implement a trait or new type instead