diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-08-06 20:23:39 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-06 20:23:39 +0200 |
| commit | 333c63b9fcf47ad8f8ea7c5e529258afaadc17a4 (patch) | |
| tree | 6f27d0578870eb4ff343a1d43d4a9680664a31ba | |
| parent | d3d9aae96076c78b9d1b557475ecad146cb588a0 (diff) | |
| parent | 3d5bd95558a0a6beb48531eea60994c694208b4a (diff) | |
| download | rust-333c63b9fcf47ad8f8ea7c5e529258afaadc17a4.tar.gz rust-333c63b9fcf47ad8f8ea7c5e529258afaadc17a4.zip | |
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.
4 files changed, 98 insertions, 14 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 9257be86471..33e8432596b 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3700,6 +3700,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; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index f18224c39ae..034a4918b50 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -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, diff --git a/tests/ui/associated-type-bounds/name-same-as-generic-type-issue-128249.rs b/tests/ui/associated-type-bounds/name-same-as-generic-type-issue-128249.rs new file mode 100644 index 00000000000..f5f8fa51e37 --- /dev/null +++ b/tests/ui/associated-type-bounds/name-same-as-generic-type-issue-128249.rs @@ -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() {} diff --git a/tests/ui/associated-type-bounds/name-same-as-generic-type-issue-128249.stderr b/tests/ui/associated-type-bounds/name-same-as-generic-type-issue-128249.stderr new file mode 100644 index 00000000000..06ab06003a1 --- /dev/null +++ b/tests/ui/associated-type-bounds/name-same-as-generic-type-issue-128249.stderr @@ -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`. |
