Skip to content

Commit 333c63b

Browse files
authored
Rollup merge of #128377 - veera-sivarajan:fix-128249, r=davidtwco
Fix ICE Caused by Incorrectly Delaying E0107 Fixes #128249 For the following code: ```rust trait Foo<T> {} impl Foo<T: Default> for u8 {} ``` #126054 added some logic to delay emitting E0107 as the names of associated type `T` in the impl header and generic parameter `T` in `trait Foo` match. But it failed to ensure whether such unexpected associated type bounds are coming from a impl block header. This caused an ICE as the compiler was delaying E0107 for code like: ```rust trait Trait<Type> { type Type; fn method(&self) -> impl Trait<Type: '_>; } ``` because it assumed the associated type bound `Type: '_` is for the generic parameter `Type` in `trait Trait` since the names are same. This PR adds a check to ensure that E0107 is delayed only in the context of impl block header.
2 parents d3d9aae + 3d5bd95 commit 333c63b

File tree

4 files changed

+98
-14
lines changed

4 files changed

+98
-14
lines changed

compiler/rustc_hir/src/hir.rs

+5
Original file line numberDiff line numberDiff line change
@@ -3700,6 +3700,11 @@ impl<'hir> OwnerNode<'hir> {
37003700
}
37013701
}
37023702

3703+
/// Check if node is an impl block.
3704+
pub fn is_impl_block(&self) -> bool {
3705+
matches!(self, OwnerNode::Item(Item { kind: ItemKind::Impl(_), .. }))
3706+
}
3707+
37033708
expect_methods_self! {
37043709
expect_item, &'hir Item<'hir>, OwnerNode::Item(n), n;
37053710
expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n;

compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs

+27-14
Original file line numberDiff line numberDiff line change
@@ -552,21 +552,34 @@ pub(crate) fn check_generic_arg_count(
552552
synth_provided,
553553
}
554554
} else {
555-
let num_missing_args = expected_max - provided;
555+
// Check if associated type bounds are incorrectly written in impl block header like:
556+
// ```
557+
// trait Foo<T> {}
558+
// impl Foo<T: Default> for u8 {}
559+
// ```
560+
let parent_is_impl_block = cx
561+
.tcx()
562+
.hir()
563+
.parent_owner_iter(seg.hir_id)
564+
.next()
565+
.is_some_and(|(_, owner_node)| owner_node.is_impl_block());
566+
if parent_is_impl_block {
567+
let constraint_names: Vec<_> =
568+
gen_args.constraints.iter().map(|b| b.ident.name).collect();
569+
let param_names: Vec<_> = gen_params
570+
.own_params
571+
.iter()
572+
.filter(|param| !has_self || param.index != 0) // Assumes `Self` will always be the first parameter
573+
.map(|param| param.name)
574+
.collect();
575+
if constraint_names == param_names {
576+
// We set this to true and delay emitting `WrongNumberOfGenericArgs`
577+
// to provide a succinct error for cases like issue #113073
578+
all_params_are_binded = true;
579+
};
580+
}
556581

557-
let constraint_names: Vec<_> =
558-
gen_args.constraints.iter().map(|b| b.ident.name).collect();
559-
let param_names: Vec<_> = gen_params
560-
.own_params
561-
.iter()
562-
.filter(|param| !has_self || param.index != 0) // Assumes `Self` will always be the first parameter
563-
.map(|param| param.name)
564-
.collect();
565-
if constraint_names == param_names {
566-
// We set this to true and delay emitting `WrongNumberOfGenericArgs`
567-
// to provide a succinct error for cases like issue #113073
568-
all_params_are_binded = true;
569-
};
582+
let num_missing_args = expected_max - provided;
570583

571584
GenericArgsInfo::MissingTypesOrConsts {
572585
num_missing_args,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
trait Trait<Type> {
2+
type Type;
3+
4+
fn one(&self, val: impl Trait<Type: Default>);
5+
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
6+
7+
fn two<T: Trait<Type: Default>>(&self) -> T;
8+
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
9+
10+
fn three<T>(&self) -> T where
11+
T: Trait<Type: Default>,;
12+
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
2+
--> $DIR/name-same-as-generic-type-issue-128249.rs:4:30
3+
|
4+
LL | fn one(&self, val: impl Trait<Type: Default>);
5+
| ^^^^^ expected 1 generic argument
6+
|
7+
note: trait defined here, with 1 generic parameter: `Type`
8+
--> $DIR/name-same-as-generic-type-issue-128249.rs:1:7
9+
|
10+
LL | trait Trait<Type> {
11+
| ^^^^^ ----
12+
help: add missing generic argument
13+
|
14+
LL | fn one(&self, val: impl Trait<Type, Type: Default>);
15+
| +++++
16+
17+
error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
18+
--> $DIR/name-same-as-generic-type-issue-128249.rs:7:15
19+
|
20+
LL | fn two<T: Trait<Type: Default>>(&self) -> T;
21+
| ^^^^^ expected 1 generic argument
22+
|
23+
note: trait defined here, with 1 generic parameter: `Type`
24+
--> $DIR/name-same-as-generic-type-issue-128249.rs:1:7
25+
|
26+
LL | trait Trait<Type> {
27+
| ^^^^^ ----
28+
help: add missing generic argument
29+
|
30+
LL | fn two<T: Trait<Type, Type: Default>>(&self) -> T;
31+
| +++++
32+
33+
error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
34+
--> $DIR/name-same-as-generic-type-issue-128249.rs:11:12
35+
|
36+
LL | T: Trait<Type: Default>,;
37+
| ^^^^^ expected 1 generic argument
38+
|
39+
note: trait defined here, with 1 generic parameter: `Type`
40+
--> $DIR/name-same-as-generic-type-issue-128249.rs:1:7
41+
|
42+
LL | trait Trait<Type> {
43+
| ^^^^^ ----
44+
help: add missing generic argument
45+
|
46+
LL | T: Trait<Type, Type: Default>,;
47+
| +++++
48+
49+
error: aborting due to 3 previous errors
50+
51+
For more information about this error, try `rustc --explain E0107`.

0 commit comments

Comments
 (0)