Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ICE Caused by Incorrectly Delaying E0107 #128377

Merged
merged 2 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3689,6 +3689,11 @@ impl<'hir> OwnerNode<'hir> {
}
}

/// Check if node is an impl block.
pub fn is_impl_block(&self) -> bool {
matches!(self, OwnerNode::Item(Item { kind: ItemKind::Impl(_), .. }))
}

expect_methods_self! {
expect_item, &'hir Item<'hir>, OwnerNode::Item(n), n;
expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n;
Expand Down
41 changes: 27 additions & 14 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,21 +552,34 @@ pub(crate) fn check_generic_arg_count(
synth_provided,
}
} else {
let num_missing_args = expected_max - provided;
// Check if associated type bounds are incorrectly written in impl block header like:
// ```
// trait Foo<T> {}
// impl Foo<T: Default> for u8 {}
// ```
let parent_is_impl_block = cx
.tcx()
.hir()
.parent_owner_iter(seg.hir_id)
.next()
.is_some_and(|(_, owner_node)| owner_node.is_impl_block());
if parent_is_impl_block {
let constraint_names: Vec<_> =
gen_args.constraints.iter().map(|b| b.ident.name).collect();
let param_names: Vec<_> = gen_params
.own_params
.iter()
.filter(|param| !has_self || param.index != 0) // Assumes `Self` will always be the first parameter
.map(|param| param.name)
.collect();
if constraint_names == param_names {
// We set this to true and delay emitting `WrongNumberOfGenericArgs`
// to provide a succinct error for cases like issue #113073
all_params_are_binded = true;
};
}

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

GenericArgsInfo::MissingTypesOrConsts {
num_missing_args,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
trait Trait<Type> {
type Type;

fn one(&self, val: impl Trait<Type: Default>);
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied

fn two<T: Trait<Type: Default>>(&self) -> T;
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied

fn three<T>(&self) -> T where
T: Trait<Type: Default>,;
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/name-same-as-generic-type-issue-128249.rs:4:30
|
LL | fn one(&self, val: impl Trait<Type: Default>);
| ^^^^^ expected 1 generic argument
|
note: trait defined here, with 1 generic parameter: `Type`
--> $DIR/name-same-as-generic-type-issue-128249.rs:1:7
|
LL | trait Trait<Type> {
| ^^^^^ ----
help: add missing generic argument
|
LL | fn one(&self, val: impl Trait<Type, Type: Default>);
| +++++

error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/name-same-as-generic-type-issue-128249.rs:7:15
|
LL | fn two<T: Trait<Type: Default>>(&self) -> T;
| ^^^^^ expected 1 generic argument
|
note: trait defined here, with 1 generic parameter: `Type`
--> $DIR/name-same-as-generic-type-issue-128249.rs:1:7
|
LL | trait Trait<Type> {
| ^^^^^ ----
help: add missing generic argument
|
LL | fn two<T: Trait<Type, Type: Default>>(&self) -> T;
| +++++

error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/name-same-as-generic-type-issue-128249.rs:11:12
|
LL | T: Trait<Type: Default>,;
| ^^^^^ expected 1 generic argument
|
note: trait defined here, with 1 generic parameter: `Type`
--> $DIR/name-same-as-generic-type-issue-128249.rs:1:7
|
LL | trait Trait<Type> {
| ^^^^^ ----
help: add missing generic argument
|
LL | T: Trait<Type, Type: Default>,;
| +++++

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0107`.
Loading