Rollup merge of #128337 - bvanjoi:issue-121613, r=compiler-errors

skip assoc type during infer source visitor

Fixes #121613

Due to the generic arguments being lost during normalization, the associated type cannot retrieve the correct generics information, so this PR follows this [comment](https://github.com/rust-lang/rust/blob/master/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs#L937-L942) and skips `DefKind::AssocTy`

r? `@lcnr`
This commit is contained in:
Matthias Krüger 2024-07-29 17:46:44 +02:00 committed by GitHub
commit 5de94b67d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 120 additions and 56 deletions

View File

@ -934,13 +934,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
// which makes this somewhat difficult and prevents us from just
// using `self.path_inferred_arg_iter` here.
hir::ExprKind::Struct(&hir::QPath::Resolved(_self_ty, path), _, _)
// FIXME(TaKO8Ki): Ideally we should support this. For that
// we have to map back from the self type to the
// type alias though. That's difficult.
// FIXME(TaKO8Ki): Ideally we should support other kinds,
// such as `TyAlias` or `AssocTy`. For that we have to map
// back from the self type to the type alias though. That's difficult.
//
// See the `need_type_info/issue-103053.rs` test for
// a example.
if !matches!(path.res, Res::Def(DefKind::TyAlias, _)) => {
if matches!(path.res, Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)) => {
if let Some(ty) = self.opt_node_type(expr.hir_id)
&& let ty::Adt(_, args) = ty.kind()
{

View File

@ -1,28 +0,0 @@
//@ known-bug: #121613
fn main() {
// destructure through a qualified path
let <Foo as A>::Assoc { br } = StructStruct { br: 2 };
//~^ ERROR usage of qualified paths in this context is experimental
let _ = <Foo as A>::Assoc { br: 2 };
//~^ ERROR usage of qualified paths in this context is experimental
let <E>::V(..) = E::V(|a, b| a.cmp(b));
//~^ ERROR usage of qualified paths in this context is experimental
}
struct StructStruct {
br: i8,
}
struct Foo;
trait A {
type Assoc;
}
impl A for Foo {
type Assoc = StructStruct;
}
enum E {
V(u8)
}

View File

@ -1,24 +0,0 @@
//@ known-bug: #121613
fn main() {
let _ = <Foo as A>::Assoc { br: 2 };
let <E>::V(..) = E::V(|a, b| a.cmp(b));
}
struct StructStruct {
br: i8,
}
struct Foo;
trait A {
type Assoc;
}
impl A for Foo {
type Assoc = StructStruct;
}
enum E {
V(u8),
}

View File

@ -0,0 +1,24 @@
// issue#121613
#![feature(more_qualified_paths)]
struct S {}
struct Foo;
trait A {
type Assoc;
}
impl A for Foo {
type Assoc = S;
}
fn f() {}
fn main() {
<Foo as A>::Assoc {};
f(|a, b| a.cmp(b));
//~^ ERROR: type annotations needed
//~| ERROR: this function takes 0 arguments but 1 argument was supplied
}

View File

@ -0,0 +1,32 @@
error[E0282]: type annotations needed
--> $DIR/incompat-call-after-qualified-path-0.rs:21:6
|
LL | f(|a, b| a.cmp(b));
| ^ - type must be known at this point
|
help: consider giving this closure parameter an explicit type
|
LL | f(|a: /* Type */, b| a.cmp(b));
| ++++++++++++
error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/incompat-call-after-qualified-path-0.rs:21:3
|
LL | f(|a, b| a.cmp(b));
| ^ --------------- unexpected argument
|
note: function defined here
--> $DIR/incompat-call-after-qualified-path-0.rs:17:4
|
LL | fn f() {}
| ^
help: remove the extra argument
|
LL - f(|a, b| a.cmp(b));
LL + f();
|
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0061, E0282.
For more information about an error, try `rustc --explain E0061`.

View File

@ -0,0 +1,28 @@
// issue#121613
#![feature(more_qualified_paths)]
struct S<T> {
a: T
}
struct Foo;
trait A {
type Assoc<T>;
}
impl A for Foo {
type Assoc<T> = S<T>;
}
fn f() {}
fn main() {
<Foo as A>::Assoc::<i32> {
a: 1
};
f(|a, b| a.cmp(b));
//~^ ERROR: type annotations needed
//~| ERROR: this function takes 0 arguments but 1 argument was supplied
}

View File

@ -0,0 +1,32 @@
error[E0282]: type annotations needed
--> $DIR/incompat-call-after-qualified-path-1.rs:25:6
|
LL | f(|a, b| a.cmp(b));
| ^ - type must be known at this point
|
help: consider giving this closure parameter an explicit type
|
LL | f(|a: /* Type */, b| a.cmp(b));
| ++++++++++++
error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/incompat-call-after-qualified-path-1.rs:25:3
|
LL | f(|a, b| a.cmp(b));
| ^ --------------- unexpected argument
|
note: function defined here
--> $DIR/incompat-call-after-qualified-path-1.rs:19:4
|
LL | fn f() {}
| ^
help: remove the extra argument
|
LL - f(|a, b| a.cmp(b));
LL + f();
|
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0061, E0282.
For more information about an error, try `rustc --explain E0061`.