about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs3
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs36
-rw-r--r--tests/ui/generic-associated-types/issue-88595.stderr8
-rw-r--r--tests/ui/impl-trait/in-assoc-type-unconstrained.stderr4
-rw-r--r--tests/ui/impl-trait/in-assoc-type.stderr4
-rw-r--r--tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr8
-rw-r--r--tests/ui/type-alias-impl-trait/higher_kinded_params3.rs35
-rw-r--r--tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr15
-rw-r--r--tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/unnameable_type.stderr4
11 files changed, 100 insertions, 25 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index a723dc3f079..2a32f0b5047 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -260,7 +260,8 @@ impl<T> Trait<T> for X {
                     (ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if alias.def_id.is_local() && matches!(tcx.def_kind(body_owner_def_id), DefKind::AssocFn | DefKind::AssocConst) => {
                         if tcx.is_type_alias_impl_trait(alias.def_id) {
                             if !tcx.opaque_types_defined_by(body_owner_def_id.expect_local()).contains(&alias.def_id.expect_local()) {
-                                diag.span_note(tcx.def_span(body_owner_def_id), "\
+                                let sp = tcx.def_ident_span(body_owner_def_id).unwrap_or_else(|| tcx.def_span(body_owner_def_id));
+                                diag.span_note(sp, "\
                                     this item must have the opaque type in its signature \
                                     in order to be able to register hidden types");
                             }
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 7af5f847e8b..d97b74017ed 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -19,15 +19,26 @@ struct OpaqueTypeCollector<'tcx> {
 
     /// Avoid infinite recursion due to recursive declarations.
     seen: FxHashSet<LocalDefId>,
+
+    span: Option<Span>,
 }
 
 impl<'tcx> OpaqueTypeCollector<'tcx> {
     fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
-        Self { tcx, opaques: Vec::new(), item, seen: Default::default() }
+        Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None }
     }
 
     fn span(&self) -> Span {
-        self.tcx.def_span(self.item)
+        self.span.unwrap_or_else(|| {
+            self.tcx.def_ident_span(self.item).unwrap_or_else(|| self.tcx.def_span(self.item))
+        })
+    }
+
+    fn visit_spanned(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) {
+        let old = self.span;
+        self.span = Some(span);
+        value.visit_with(self);
+        self.span = old;
     }
 
     fn parent_trait_ref(&self) -> Option<ty::TraitRef<'tcx>> {
@@ -72,13 +83,13 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
                         self.opaques.push(alias_ty.def_id.expect_local());
 
                         // Collect opaque types nested within the associated type bounds of this opaque type.
-                        for (pred, _span) in self
+                        for (pred, span) in self
                             .tcx
                             .explicit_item_bounds(alias_ty.def_id)
                             .subst_iter_copied(self.tcx, alias_ty.substs)
                         {
                             trace!(?pred);
-                            pred.visit_with(self)?;
+                            self.visit_spanned(span, pred);
                         }
 
                         ControlFlow::Continue(())
@@ -163,10 +174,23 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
             let mut collector = OpaqueTypeCollector::new(tcx, item);
             match kind {
                 DefKind::AssocFn | DefKind::Fn => {
-                    tcx.fn_sig(item).subst_identity().visit_with(&mut collector);
+                    let ty_sig = tcx.fn_sig(item).subst_identity();
+                    let hir_sig = tcx.hir().get_by_def_id(item).fn_sig().unwrap();
+                    collector.visit_spanned(hir_sig.decl.output.span(), ty_sig.output());
+                    for (hir, ty) in hir_sig.decl.inputs.iter().zip(ty_sig.inputs().iter()) {
+                        collector.visit_spanned(hir.span, ty.map_bound(|x| *x));
+                    }
                 }
                 DefKind::AssocTy | DefKind::AssocConst => {
-                    tcx.type_of(item).subst_identity().visit_with(&mut collector);
+                    let span = match tcx.hir().get_by_def_id(item) {
+                        rustc_hir::Node::ImplItem(it) => match it.kind {
+                            rustc_hir::ImplItemKind::Const(ty, _) => ty.span,
+                            rustc_hir::ImplItemKind::Type(ty) => ty.span,
+                            other => span_bug!(tcx.def_span(item), "{other:#?}"),
+                        },
+                        other => span_bug!(tcx.def_span(item), "{other:#?}"),
+                    };
+                    collector.visit_spanned(span, tcx.type_of(item).subst_identity());
                 }
                 _ => unreachable!(),
             }
diff --git a/tests/ui/generic-associated-types/issue-88595.stderr b/tests/ui/generic-associated-types/issue-88595.stderr
index d6caed85459..b0f6864f6ec 100644
--- a/tests/ui/generic-associated-types/issue-88595.stderr
+++ b/tests/ui/generic-associated-types/issue-88595.stderr
@@ -1,8 +1,8 @@
 error: non-defining opaque type use in defining scope
-  --> $DIR/issue-88595.rs:21:5
+  --> $DIR/issue-88595.rs:21:23
    |
 LL |     fn a(&'a self) -> Self::B<'a> {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ generic argument `'a` used twice
+   |                       ^^^^^^^^^^^ generic argument `'a` used twice
    |
 note: for this opaque type
   --> $DIR/issue-88595.rs:19:18
@@ -24,10 +24,10 @@ LL |     fn a(&'a self) -> Self::B<'a> {}
    = note: expected opaque type `<C as A<'a>>::B<'a>`
                 found unit type `()`
 note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/issue-88595.rs:21:5
+  --> $DIR/issue-88595.rs:21:8
    |
 LL |     fn a(&'a self) -> Self::B<'a> {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
index 1097cd0f452..8e61a65abe4 100644
--- a/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
+++ b/tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
@@ -40,10 +40,10 @@ LL |         fn method() -> Self::Ty;
    = note: expected signature `fn() -> <() as compare_method::Trait>::Ty`
               found signature `fn()`
 note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/in-assoc-type-unconstrained.rs:22:9
+  --> $DIR/in-assoc-type-unconstrained.rs:22:12
    |
 LL |         fn method() -> () {}
-   |         ^^^^^^^^^^^^^^^^^
+   |            ^^^^^^
 
 error: unconstrained opaque type
   --> $DIR/in-assoc-type-unconstrained.rs:20:19
diff --git a/tests/ui/impl-trait/in-assoc-type.stderr b/tests/ui/impl-trait/in-assoc-type.stderr
index f0a272dc2d5..ab3f3a14410 100644
--- a/tests/ui/impl-trait/in-assoc-type.stderr
+++ b/tests/ui/impl-trait/in-assoc-type.stderr
@@ -12,10 +12,10 @@ LL |     fn foo(&self) -> <Self as Foo<()>>::Bar {}
    = note: expected opaque type `<() as Foo<()>>::Bar`
                 found unit type `()`
 note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/in-assoc-type.rs:17:5
+  --> $DIR/in-assoc-type.rs:17:8
    |
 LL |     fn foo(&self) -> <Self as Foo<()>>::Bar {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^
 
 error: aborting due to previous error
 
diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
index bbd60d4398b..3e1981f096c 100644
--- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
+++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr
@@ -21,10 +21,10 @@ LL |         fn eq(&self, _other: &(Foo, i32)) -> bool {
    = note: expected signature `fn(&a::Bar, &(a::Bar, i32)) -> _`
               found signature `fn(&a::Bar, &(a::Foo, i32)) -> _`
 note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:9
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
    |
 LL |         fn eq(&self, _other: &(Foo, i32)) -> bool {
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^
 
 error: unconstrained opaque type
   --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
@@ -49,10 +49,10 @@ LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
    = note: expected signature `fn(&b::Bar, &(b::Foo, i32)) -> _`
               found signature `fn(&b::Bar, &(b::Bar, i32)) -> _`
 note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:9
+  --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:12
    |
 LL |         fn eq(&self, _other: &(Bar, i32)) -> bool {
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs
new file mode 100644
index 00000000000..839a611cb71
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.rs
@@ -0,0 +1,35 @@
+//! This test checks that we can't actually have an opaque type behind
+//! a binder that references variables from that binder.
+
+// edition: 2021
+
+#![feature(type_alias_impl_trait)]
+
+trait B {
+    type C;
+}
+
+struct A;
+
+impl<'a> B for &'a A {
+    type C = Tait<'a>;
+}
+
+type Tait<'a> = impl std::fmt::Debug + 'a;
+
+struct Terminator;
+
+type Successors<'a> = impl std::fmt::Debug + 'a;
+
+impl Terminator {
+    fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> {
+        f = g;
+        //~^ ERROR: mismatched types
+    }
+}
+
+fn g(x: &()) -> &() {
+    x
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr
new file mode 100644
index 00000000000..aaba9ad5ca7
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/higher_kinded_params3.rs:26:9
+   |
+LL | type Tait<'a> = impl std::fmt::Debug + 'a;
+   |                 ------------------------- the expected opaque type
+...
+LL |         f = g;
+   |         ^^^^^ one type is more general than the other
+   |
+   = note: expected fn pointer `for<'x> fn(&'x ()) -> Tait<'x>`
+              found fn pointer `for<'a> fn(&'a ()) -> &'a ()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr
index 2beed73cb85..6ec5d13f812 100644
--- a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr
+++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr
@@ -12,10 +12,10 @@ LL |         let x: Self::Foo = ();
    = note: expected opaque type `<() as Foo>::Foo`
                 found unit type `()`
 note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/invalid_impl_trait_in_assoc_ty.rs:10:5
+  --> $DIR/invalid_impl_trait_in_assoc_ty.rs:10:8
    |
 LL |     fn bar() {
-   |     ^^^^^^^^
+   |        ^^^
 
 error: aborting due to previous error
 
diff --git a/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr b/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr
index d2d00749091..a621bb519cd 100644
--- a/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr
+++ b/tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr
@@ -12,10 +12,10 @@ LL |         let _: <Self as Foo<DefinesOpaque>>::Assoc = "";
    = note: expected opaque type `<() as Foo<DefinesOpaque>>::Assoc`
                 found reference `&'static str`
 note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/not-matching-trait-refs-isnt-defining.rs:16:5
+  --> $DIR/not-matching-trait-refs-isnt-defining.rs:16:8
    |
 LL |     fn test() -> <() as Foo<NoOpaques>>::Assoc {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^
 
 error: aborting due to previous error
 
diff --git a/tests/ui/type-alias-impl-trait/unnameable_type.stderr b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
index 24f5cc8c733..c609ace919e 100644
--- a/tests/ui/type-alias-impl-trait/unnameable_type.stderr
+++ b/tests/ui/type-alias-impl-trait/unnameable_type.stderr
@@ -26,10 +26,10 @@ LL |         fn dont_define_this(_private: Private) {}
    = note: expected signature `fn(Private)`
               found signature `fn(MyPrivate)`
 note: this item must have the opaque type in its signature in order to be able to register hidden types
-  --> $DIR/unnameable_type.rs:20:5
+  --> $DIR/unnameable_type.rs:20:8
    |
 LL |     fn dont_define_this(_private: MyPrivate) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors