Skip to content

Commit 12243ec

Browse files
committed
Point to argument/return type instead of the whole function header
1 parent bae6454 commit 12243ec

11 files changed

+100
-25
lines changed

compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,8 @@ impl<T> Trait<T> for X {
260260
(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) => {
261261
if tcx.is_type_alias_impl_trait(alias.def_id) {
262262
if !tcx.opaque_types_defined_by(body_owner_def_id.expect_local()).contains(&alias.def_id.expect_local()) {
263-
diag.span_note(tcx.def_span(body_owner_def_id), "\
263+
let sp = tcx.def_ident_span(body_owner_def_id).unwrap_or_else(|| tcx.def_span(body_owner_def_id));
264+
diag.span_note(sp, "\
264265
this item must have the opaque type in its signature \
265266
in order to be able to register hidden types");
266267
}

compiler/rustc_ty_utils/src/opaque_types.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,26 @@ struct OpaqueTypeCollector<'tcx> {
1919

2020
/// Avoid infinite recursion due to recursive declarations.
2121
seen: FxHashSet<LocalDefId>,
22+
23+
span: Option<Span>,
2224
}
2325

2426
impl<'tcx> OpaqueTypeCollector<'tcx> {
2527
fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
26-
Self { tcx, opaques: Vec::new(), item, seen: Default::default() }
28+
Self { tcx, opaques: Vec::new(), item, seen: Default::default(), span: None }
2729
}
2830

2931
fn span(&self) -> Span {
30-
self.tcx.def_span(self.item)
32+
self.span.unwrap_or_else(|| {
33+
self.tcx.def_ident_span(self.item).unwrap_or_else(|| self.tcx.def_span(self.item))
34+
})
35+
}
36+
37+
fn visit_spanned(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) {
38+
let old = self.span;
39+
self.span = Some(span);
40+
value.visit_with(self);
41+
self.span = old;
3142
}
3243

3344
fn parent_trait_ref(&self) -> Option<ty::TraitRef<'tcx>> {
@@ -72,13 +83,13 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
7283
self.opaques.push(alias_ty.def_id.expect_local());
7384

7485
// Collect opaque types nested within the associated type bounds of this opaque type.
75-
for (pred, _span) in self
86+
for (pred, span) in self
7687
.tcx
7788
.explicit_item_bounds(alias_ty.def_id)
7889
.subst_iter_copied(self.tcx, alias_ty.substs)
7990
{
8091
trace!(?pred);
81-
pred.visit_with(self)?;
92+
self.visit_spanned(span, pred);
8293
}
8394

8495
ControlFlow::Continue(())
@@ -163,10 +174,23 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
163174
let mut collector = OpaqueTypeCollector::new(tcx, item);
164175
match kind {
165176
DefKind::AssocFn | DefKind::Fn => {
166-
tcx.fn_sig(item).subst_identity().visit_with(&mut collector);
177+
let ty_sig = tcx.fn_sig(item).subst_identity();
178+
let hir_sig = tcx.hir().get_by_def_id(item).fn_sig().unwrap();
179+
collector.visit_spanned(hir_sig.decl.output.span(), ty_sig.output());
180+
for (hir, ty) in hir_sig.decl.inputs.iter().zip(ty_sig.inputs().iter()) {
181+
collector.visit_spanned(hir.span, ty.map_bound(|x| *x));
182+
}
167183
}
168184
DefKind::AssocTy | DefKind::AssocConst => {
169-
tcx.type_of(item).subst_identity().visit_with(&mut collector);
185+
let span = match tcx.hir().get_by_def_id(item) {
186+
rustc_hir::Node::ImplItem(it) => match it.kind {
187+
rustc_hir::ImplItemKind::Const(ty, _) => ty.span,
188+
rustc_hir::ImplItemKind::Type(ty) => ty.span,
189+
other => span_bug!(tcx.def_span(item), "{other:#?}"),
190+
},
191+
other => span_bug!(tcx.def_span(item), "{other:#?}"),
192+
};
193+
collector.visit_spanned(span, tcx.type_of(item).subst_identity());
170194
}
171195
_ => unreachable!(),
172196
}

tests/ui/generic-associated-types/issue-88595.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error: non-defining opaque type use in defining scope
2-
--> $DIR/issue-88595.rs:21:5
2+
--> $DIR/issue-88595.rs:21:23
33
|
44
LL | fn a(&'a self) -> Self::B<'a> {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ generic argument `'a` used twice
5+
| ^^^^^^^^^^^ generic argument `'a` used twice
66
|
77
note: for this opaque type
88
--> $DIR/issue-88595.rs:19:18
@@ -24,10 +24,10 @@ LL | fn a(&'a self) -> Self::B<'a> {}
2424
= note: expected opaque type `<C as A<'a>>::B<'a>`
2525
found unit type `()`
2626
note: this item must have the opaque type in its signature in order to be able to register hidden types
27-
--> $DIR/issue-88595.rs:21:5
27+
--> $DIR/issue-88595.rs:21:8
2828
|
2929
LL | fn a(&'a self) -> Self::B<'a> {}
30-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30+
| ^
3131

3232
error: aborting due to 2 previous errors
3333

tests/ui/impl-trait/in-assoc-type-unconstrained.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ LL | fn method() -> Self::Ty;
4040
= note: expected signature `fn() -> <() as compare_method::Trait>::Ty`
4141
found signature `fn()`
4242
note: this item must have the opaque type in its signature in order to be able to register hidden types
43-
--> $DIR/in-assoc-type-unconstrained.rs:22:9
43+
--> $DIR/in-assoc-type-unconstrained.rs:22:12
4444
|
4545
LL | fn method() -> () {}
46-
| ^^^^^^^^^^^^^^^^^
46+
| ^^^^^^
4747

4848
error: unconstrained opaque type
4949
--> $DIR/in-assoc-type-unconstrained.rs:20:19

tests/ui/impl-trait/in-assoc-type.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ LL | fn foo(&self) -> <Self as Foo<()>>::Bar {}
1212
= note: expected opaque type `<() as Foo<()>>::Bar`
1313
found unit type `()`
1414
note: this item must have the opaque type in its signature in order to be able to register hidden types
15-
--> $DIR/in-assoc-type.rs:17:5
15+
--> $DIR/in-assoc-type.rs:17:8
1616
|
1717
LL | fn foo(&self) -> <Self as Foo<()>>::Bar {}
18-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
| ^^^
1919

2020
error: aborting due to previous error
2121

tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
2121
= note: expected signature `fn(&a::Bar, &(a::Bar, i32)) -> _`
2222
found signature `fn(&a::Bar, &(a::Foo, i32)) -> _`
2323
note: this item must have the opaque type in its signature in order to be able to register hidden types
24-
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:9
24+
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
2525
|
2626
LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
27-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27+
| ^^
2828

2929
error: unconstrained opaque type
3030
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
@@ -49,10 +49,10 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
4949
= note: expected signature `fn(&b::Bar, &(b::Foo, i32)) -> _`
5050
found signature `fn(&b::Bar, &(b::Bar, i32)) -> _`
5151
note: this item must have the opaque type in its signature in order to be able to register hidden types
52-
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:9
52+
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:12
5353
|
5454
LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
55-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
55+
| ^^
5656

5757
error: aborting due to 4 previous errors
5858

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//! This test checks that we can't actually have an opaque type behind
2+
//! a binder that references variables from that binder.
3+
4+
// edition: 2021
5+
6+
#![feature(type_alias_impl_trait)]
7+
8+
trait B {
9+
type C;
10+
}
11+
12+
struct A;
13+
14+
impl<'a> B for &'a A {
15+
type C = Tait<'a>;
16+
}
17+
18+
type Tait<'a> = impl std::fmt::Debug + 'a;
19+
20+
struct Terminator;
21+
22+
type Successors<'a> = impl std::fmt::Debug + 'a;
23+
24+
impl Terminator {
25+
fn successors(&self, mut f: for<'x> fn(&'x ()) -> <&'x A as B>::C) -> Successors<'_> {
26+
f = g;
27+
//~^ ERROR: mismatched types
28+
}
29+
}
30+
31+
fn g(x: &()) -> &() {
32+
x
33+
}
34+
35+
fn main() {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/higher_kinded_params3.rs:26:9
3+
|
4+
LL | type Tait<'a> = impl std::fmt::Debug + 'a;
5+
| ------------------------- the expected opaque type
6+
...
7+
LL | f = g;
8+
| ^^^^^ one type is more general than the other
9+
|
10+
= note: expected fn pointer `for<'x> fn(&'x ()) -> Tait<'x>`
11+
found fn pointer `for<'a> fn(&'a ()) -> &'a ()`
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0308`.

tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ LL | let x: Self::Foo = ();
1212
= note: expected opaque type `<() as Foo>::Foo`
1313
found unit type `()`
1414
note: this item must have the opaque type in its signature in order to be able to register hidden types
15-
--> $DIR/invalid_impl_trait_in_assoc_ty.rs:10:5
15+
--> $DIR/invalid_impl_trait_in_assoc_ty.rs:10:8
1616
|
1717
LL | fn bar() {
18-
| ^^^^^^^^
18+
| ^^^
1919

2020
error: aborting due to previous error
2121

tests/ui/type-alias-impl-trait/not-matching-trait-refs-isnt-defining.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ LL | let _: <Self as Foo<DefinesOpaque>>::Assoc = "";
1212
= note: expected opaque type `<() as Foo<DefinesOpaque>>::Assoc`
1313
found reference `&'static str`
1414
note: this item must have the opaque type in its signature in order to be able to register hidden types
15-
--> $DIR/not-matching-trait-refs-isnt-defining.rs:16:5
15+
--> $DIR/not-matching-trait-refs-isnt-defining.rs:16:8
1616
|
1717
LL | fn test() -> <() as Foo<NoOpaques>>::Assoc {
18-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
| ^^^^
1919

2020
error: aborting due to previous error
2121

tests/ui/type-alias-impl-trait/unnameable_type.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ LL | fn dont_define_this(_private: Private) {}
2626
= note: expected signature `fn(Private)`
2727
found signature `fn(MyPrivate)`
2828
note: this item must have the opaque type in its signature in order to be able to register hidden types
29-
--> $DIR/unnameable_type.rs:20:5
29+
--> $DIR/unnameable_type.rs:20:8
3030
|
3131
LL | fn dont_define_this(_private: MyPrivate) {}
32-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32+
| ^^^^^^^^^^^^^^^^
3333

3434
error: aborting due to 2 previous errors
3535

0 commit comments

Comments
 (0)