Point to argument/return type instead of the whole function header
This commit is contained in:
parent
bae645451e
commit
12243ec415
@ -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) => {
|
(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.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()) {
|
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 \
|
this item must have the opaque type in its signature \
|
||||||
in order to be able to register hidden types");
|
in order to be able to register hidden types");
|
||||||
}
|
}
|
||||||
|
@ -19,15 +19,26 @@ struct OpaqueTypeCollector<'tcx> {
|
|||||||
|
|
||||||
/// Avoid infinite recursion due to recursive declarations.
|
/// Avoid infinite recursion due to recursive declarations.
|
||||||
seen: FxHashSet<LocalDefId>,
|
seen: FxHashSet<LocalDefId>,
|
||||||
|
|
||||||
|
span: Option<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> OpaqueTypeCollector<'tcx> {
|
impl<'tcx> OpaqueTypeCollector<'tcx> {
|
||||||
fn new(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
|
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 {
|
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>> {
|
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());
|
self.opaques.push(alias_ty.def_id.expect_local());
|
||||||
|
|
||||||
// Collect opaque types nested within the associated type bounds of this opaque type.
|
// Collect opaque types nested within the associated type bounds of this opaque type.
|
||||||
for (pred, _span) in self
|
for (pred, span) in self
|
||||||
.tcx
|
.tcx
|
||||||
.explicit_item_bounds(alias_ty.def_id)
|
.explicit_item_bounds(alias_ty.def_id)
|
||||||
.subst_iter_copied(self.tcx, alias_ty.substs)
|
.subst_iter_copied(self.tcx, alias_ty.substs)
|
||||||
{
|
{
|
||||||
trace!(?pred);
|
trace!(?pred);
|
||||||
pred.visit_with(self)?;
|
self.visit_spanned(span, pred);
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlFlow::Continue(())
|
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);
|
let mut collector = OpaqueTypeCollector::new(tcx, item);
|
||||||
match kind {
|
match kind {
|
||||||
DefKind::AssocFn | DefKind::Fn => {
|
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 => {
|
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!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
error: non-defining opaque type use in defining scope
|
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> {}
|
LL | fn a(&'a self) -> Self::B<'a> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ generic argument `'a` used twice
|
| ^^^^^^^^^^^ generic argument `'a` used twice
|
||||||
|
|
|
|
||||||
note: for this opaque type
|
note: for this opaque type
|
||||||
--> $DIR/issue-88595.rs:19:18
|
--> $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>`
|
= note: expected opaque type `<C as A<'a>>::B<'a>`
|
||||||
found unit type `()`
|
found unit type `()`
|
||||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
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> {}
|
LL | fn a(&'a self) -> Self::B<'a> {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -40,10 +40,10 @@ LL | fn method() -> Self::Ty;
|
|||||||
= note: expected signature `fn() -> <() as compare_method::Trait>::Ty`
|
= note: expected signature `fn() -> <() as compare_method::Trait>::Ty`
|
||||||
found signature `fn()`
|
found signature `fn()`
|
||||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
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() -> () {}
|
LL | fn method() -> () {}
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/in-assoc-type-unconstrained.rs:20:19
|
--> $DIR/in-assoc-type-unconstrained.rs:20:19
|
||||||
|
@ -12,10 +12,10 @@ LL | fn foo(&self) -> <Self as Foo<()>>::Bar {}
|
|||||||
= note: expected opaque type `<() as Foo<()>>::Bar`
|
= note: expected opaque type `<() as Foo<()>>::Bar`
|
||||||
found unit type `()`
|
found unit type `()`
|
||||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
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 {}
|
LL | fn foo(&self) -> <Self as Foo<()>>::Bar {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -21,10 +21,10 @@ LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
|
|||||||
= note: expected signature `fn(&a::Bar, &(a::Bar, i32)) -> _`
|
= note: expected signature `fn(&a::Bar, &(a::Bar, i32)) -> _`
|
||||||
found signature `fn(&a::Bar, &(a::Foo, 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
|
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 {
|
LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^
|
||||||
|
|
||||||
error: unconstrained opaque type
|
error: unconstrained opaque type
|
||||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
|
--> $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)) -> _`
|
= note: expected signature `fn(&b::Bar, &(b::Foo, i32)) -> _`
|
||||||
found signature `fn(&b::Bar, &(b::Bar, 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
|
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 {
|
LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
35
tests/ui/type-alias-impl-trait/higher_kinded_params3.rs
Normal file
35
tests/ui/type-alias-impl-trait/higher_kinded_params3.rs
Normal file
@ -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() {}
|
15
tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr
Normal file
15
tests/ui/type-alias-impl-trait/higher_kinded_params3.stderr
Normal file
@ -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`.
|
@ -12,10 +12,10 @@ LL | let x: Self::Foo = ();
|
|||||||
= note: expected opaque type `<() as Foo>::Foo`
|
= note: expected opaque type `<() as Foo>::Foo`
|
||||||
found unit type `()`
|
found unit type `()`
|
||||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
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() {
|
LL | fn bar() {
|
||||||
| ^^^^^^^^
|
| ^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -12,10 +12,10 @@ LL | let _: <Self as Foo<DefinesOpaque>>::Assoc = "";
|
|||||||
= note: expected opaque type `<() as Foo<DefinesOpaque>>::Assoc`
|
= note: expected opaque type `<() as Foo<DefinesOpaque>>::Assoc`
|
||||||
found reference `&'static str`
|
found reference `&'static str`
|
||||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
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 {
|
LL | fn test() -> <() as Foo<NoOpaques>>::Assoc {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -26,10 +26,10 @@ LL | fn dont_define_this(_private: Private) {}
|
|||||||
= note: expected signature `fn(Private)`
|
= note: expected signature `fn(Private)`
|
||||||
found signature `fn(MyPrivate)`
|
found signature `fn(MyPrivate)`
|
||||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
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) {}
|
LL | fn dont_define_this(_private: MyPrivate) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user