Rollup merge of #103621 - fee1-dead-contrib:iat-fix-use, r=cjgillot

Correctly resolve Inherent Associated Types

I don't know if this is the best way to do this, but at least it is one way.
This commit is contained in:
Dylan DPC 2022-11-05 11:31:28 +05:30 committed by GitHub
commit 3450aa38d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 67 additions and 73 deletions

View File

@ -1910,6 +1910,20 @@ pub fn associated_path_to_ty(
} }
} }
} }
// see if we can satisfy using an inherent associated type
for impl_ in tcx.inherent_impls(adt_def.did()) {
let assoc_ty = tcx.associated_items(impl_).find_by_name_and_kind(
tcx,
assoc_ident,
ty::AssocKind::Type,
*impl_,
);
if let Some(assoc_ty) = assoc_ty {
let ty = tcx.type_of(assoc_ty.def_id);
return Ok((ty, DefKind::AssocTy, assoc_ty.def_id));
}
}
} }
// Find the type of the associated item, and the trait where the associated // Find the type of the associated item, and the trait where the associated

View File

@ -1381,7 +1381,8 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
ty::Projection(proj) => Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id), ty::Projection(proj) => Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id),
// Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s. // Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
ty::Error(_) => return Type::Infer, ty::Error(_) => return Type::Infer,
_ => bug!("clean: expected associated type, found `{:?}`", ty), // Otherwise, this is an inherent associated type.
_ => return clean_middle_ty(ty, cx, None),
}; };
let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx); let trait_ = clean_path(&hir::Path { span, res, segments: &[] }, cx);
register_res(cx, trait_.res); register_res(cx, trait_.res);

View File

@ -1,3 +1,4 @@
// check-pass
// This test ensures that rustdoc does not panic on inherented associated types // This test ensures that rustdoc does not panic on inherented associated types
// that are referred to without fully-qualified syntax. // that are referred to without fully-qualified syntax.
@ -9,8 +10,4 @@
impl Struct { impl Struct {
pub type AssocTy = usize; pub type AssocTy = usize;
pub const AssocConst: Self::AssocTy = 42; pub const AssocConst: Self::AssocTy = 42;
//~^ ERROR ambiguous associated type
//~| HELP use fully-qualified syntax
//~| ERROR ambiguous associated type
//~| HELP use fully-qualified syntax
} }

View File

@ -1,15 +0,0 @@
error[E0223]: ambiguous associated type
--> $DIR/ambiguous-inherent-assoc-ty.rs:11:27
|
LL | pub const AssocConst: Self::AssocTy = 42;
| ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy`
error[E0223]: ambiguous associated type
--> $DIR/ambiguous-inherent-assoc-ty.rs:11:27
|
LL | pub const AssocConst: Self::AssocTy = 42;
| ^^^^^^^^^^^^^ help: use fully-qualified syntax: `<Struct as Trait>::AssocTy`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0223`.

View File

@ -1,20 +0,0 @@
// Test that inherent associated types work with
// inherent_associated_types feature gate.
#![feature(inherent_associated_types)]
#![allow(incomplete_features)]
struct Foo;
impl Foo {
type Bar = isize;
}
impl Foo {
type Baz; //~ ERROR associated type in `impl` without body
}
fn main() {
let x : Foo::Bar; //~ERROR ambiguous associated type
x = 0isize;
}

View File

@ -1,17 +0,0 @@
error: associated type in `impl` without body
--> $DIR/assoc-inherent.rs:14:5
|
LL | type Baz;
| ^^^^^^^^-
| |
| help: provide a definition for the type: `= <type>;`
error[E0223]: ambiguous associated type
--> $DIR/assoc-inherent.rs:18:13
|
LL | let x : Foo::Bar;
| ^^^^^^^^ help: use fully-qualified syntax: `<Foo as Trait>::Bar`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0223`.

View File

@ -0,0 +1,10 @@
#![feature(inherent_associated_types)]
#![allow(incomplete_features)]
struct Foo;
impl Foo {
type Baz; //~ ERROR associated type in `impl` without body
}
fn main() {}

View File

@ -0,0 +1,10 @@
error: associated type in `impl` without body
--> $DIR/assoc-inherent-no-body.rs:7:5
|
LL | type Baz;
| ^^^^^^^^-
| |
| help: provide a definition for the type: `= <type>;`
error: aborting due to previous error

View File

@ -0,0 +1,14 @@
// check-pass
#![feature(inherent_associated_types)]
#![allow(incomplete_features)]
struct Foo;
impl Foo {
type Bar = isize;
}
fn main() {
let x: Foo::Bar;
x = 0isize;
}

View File

@ -1,19 +1,3 @@
error: `Self` is not valid in the self type of an impl block
--> $DIR/resolve-self-in-impl.rs:14:13
|
LL | impl Tr for Self {}
| ^^^^
|
= note: replace `Self` with a different type
error: `Self` is not valid in the self type of an impl block
--> $DIR/resolve-self-in-impl.rs:15:15
|
LL | impl Tr for S<Self> {}
| ^^^^
|
= note: replace `Self` with a different type
error: `Self` is not valid in the self type of an impl block error: `Self` is not valid in the self type of an impl block
--> $DIR/resolve-self-in-impl.rs:16:6 --> $DIR/resolve-self-in-impl.rs:16:6
| |
@ -38,6 +22,22 @@ LL | impl (Self, Self) {}
| |
= note: replace `Self` with a different type = note: replace `Self` with a different type
error: `Self` is not valid in the self type of an impl block
--> $DIR/resolve-self-in-impl.rs:14:13
|
LL | impl Tr for Self {}
| ^^^^
|
= note: replace `Self` with a different type
error: `Self` is not valid in the self type of an impl block
--> $DIR/resolve-self-in-impl.rs:15:15
|
LL | impl Tr for S<Self> {}
| ^^^^
|
= note: replace `Self` with a different type
error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>` error[E0391]: cycle detected when computing trait implemented by `<impl at $DIR/resolve-self-in-impl.rs:19:1: 19:23>`
--> $DIR/resolve-self-in-impl.rs:19:1 --> $DIR/resolve-self-in-impl.rs:19:1
| |