]> git.lizzy.rs Git - rust.git/commitdiff
Give opaque types a better coherence error
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Wed, 21 Dec 2022 17:44:30 +0000 (17:44 +0000)
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Wed, 21 Dec 2022 17:44:30 +0000 (17:44 +0000)
compiler/rustc_hir_analysis/src/coherence/orphan.rs
src/test/ui/type-alias-impl-trait/coherence.stderr

index cc5114dba5efefbdb1283de86487177a701094e6..c6d4aeefc80e5e7883862065b6b6fe5fd63ba6d0 100644 (file)
@@ -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<A>` in `impl<A, B> for C<B> in D<A>`
                     err.span_label(self_ty_span, &msg);
index c923eb08ab312fa5d5cb112b834d1b0dee596624..00b0dbbb583fd8724034ebefb11323b9a1a29f7a 100644 (file)
@@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
 LL | impl<T> foreign_crate::ForeignTrait for AliasOfForeignType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------
    | |                                       |
-   | |                                       `AliasOfForeignType<T>` 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