Fix ICE when an associated type or const is wrongly marked as final

Co-authored-by: León Orell Valerian Liehr <me@fmease.dev>
This commit is contained in:
Makai
2026-02-22 23:42:15 +08:00
parent e0cb264b81
commit bde075b6f3
5 changed files with 52 additions and 39 deletions
+12 -3
View File
@@ -1088,9 +1088,18 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
}
};
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value, || {
hir::Defaultness::Default { has_value }
});
let defaultness = match i.kind.defaultness() {
// We do not yet support `final` on trait associated items other than functions.
// Even though we reject `final` on non-functions during AST validation, we still
// need to stop propagating it here because later compiler passes do not expect
// and cannot handle such items.
Defaultness::Final(..) if !matches!(i.kind, AssocItemKind::Fn(..)) => {
Defaultness::Implicit
}
defaultness => defaultness,
};
let (defaultness, _) = self
.lower_defaultness(defaultness, has_value, || hir::Defaultness::Default { has_value });
let item = hir::TraitItem {
owner_id: trait_item_def_id,
@@ -0,0 +1,12 @@
// This is a regression test for <https://github.com/rust-lang/rust/issues/152797>.
#![feature(final_associated_functions)]
#![feature(min_generic_const_args)]
#![expect(incomplete_features)]
trait Uwu {
final type Ovo;
//~^ error: `final` is only allowed on associated functions in traits
final type const QwQ: ();
//~^ error: `final` is only allowed on associated functions in traits
}
fn main() {}
@@ -0,0 +1,18 @@
error: `final` is only allowed on associated functions in traits
--> $DIR/final-on-assoc-type-const.rs:6:5
|
LL | final type Ovo;
| -----^^^^^^^^^^
| |
| `final` because of this
error: `final` is only allowed on associated functions in traits
--> $DIR/final-on-assoc-type-const.rs:8:5
|
LL | final type const QwQ: ();
| -----^^^^^^^^^^^^^^^^^^^^
| |
| `final` because of this
error: aborting due to 2 previous errors
-2
View File
@@ -38,11 +38,9 @@
final type Foo = ();
//~^ ERROR `final` is only allowed on associated functions in traits
//~^^ ERROR cannot override `Foo` because it already has a `final` definition in the trait
final const FOO: usize = 1;
//~^ ERROR `final` is only allowed on associated functions in traits
//~^^ ERROR cannot override `FOO` because it already has a `final` definition in the trait
}
+10 -34
View File
@@ -15,7 +15,7 @@ LL | final trait Trait {
= note: only associated functions in traits can be `final`
error: a static item cannot be `final`
--> $DIR/positions.rs:67:5
--> $DIR/positions.rs:65:5
|
LL | final static FOO_EXTERN: usize = 0;
| ^^^^^ `final` because of this
@@ -23,7 +23,7 @@ LL | final static FOO_EXTERN: usize = 0;
= note: only associated functions in traits can be `final`
error: an extern block cannot be `final`
--> $DIR/positions.rs:58:1
--> $DIR/positions.rs:56:1
|
LL | final unsafe extern "C" {
| ^^^^^ `final` because of this
@@ -87,7 +87,7 @@ LL | final type Foo = ();
| `final` because of this
error: `final` is only allowed on associated functions in traits
--> $DIR/positions.rs:43:5
--> $DIR/positions.rs:42:5
|
LL | final const FOO: usize = 1;
| -----^^^^^^^^^^^^^^^^^^^^^^
@@ -95,7 +95,7 @@ LL | final const FOO: usize = 1;
| `final` because of this
error: `final` is only allowed on associated functions in traits
--> $DIR/positions.rs:49:1
--> $DIR/positions.rs:47:1
|
LL | final fn foo() {}
| -----^^^^^^^^^
@@ -103,7 +103,7 @@ LL | final fn foo() {}
| `final` because of this
error: `final` is only allowed on associated functions in traits
--> $DIR/positions.rs:52:1
--> $DIR/positions.rs:50:1
|
LL | final type FooTy = ();
| -----^^^^^^^^^^^^^^^^^
@@ -111,7 +111,7 @@ LL | final type FooTy = ();
| `final` because of this
error: `final` is only allowed on associated functions in traits
--> $DIR/positions.rs:55:1
--> $DIR/positions.rs:53:1
|
LL | final const FOO: usize = 0;
| -----^^^^^^^^^^^^^^^^^^^^^^
@@ -119,7 +119,7 @@ LL | final const FOO: usize = 0;
| `final` because of this
error: `final` is only allowed on associated functions in traits
--> $DIR/positions.rs:61:5
--> $DIR/positions.rs:59:5
|
LL | final fn foo_extern();
| -----^^^^^^^^^^^^^^^^^
@@ -127,7 +127,7 @@ LL | final fn foo_extern();
| `final` because of this
error: `final` is only allowed on associated functions in traits
--> $DIR/positions.rs:64:5
--> $DIR/positions.rs:62:5
|
LL | final type FooExtern;
| -----^^^^^^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL | final type FooExtern;
| `final` because of this
error: incorrect `static` inside `extern` block
--> $DIR/positions.rs:67:18
--> $DIR/positions.rs:65:18
|
LL | final unsafe extern "C" {
| ----------------------- `extern` blocks define existing foreign statics and statics inside of them cannot have a body
@@ -159,29 +159,5 @@ note: `method` is marked final here
LL | final fn method() {}
| ^^^^^^^^^^^^^^^^^
error: cannot override `Foo` because it already has a `final` definition in the trait
--> $DIR/positions.rs:39:5
|
LL | final type Foo = ();
| ^^^^^^^^^^^^^^
|
note: `Foo` is marked final here
--> $DIR/positions.rs:16:5
|
LL | final type Foo = ();
| ^^^^^^^^^^^^^^
error: cannot override `FOO` because it already has a `final` definition in the trait
--> $DIR/positions.rs:43:5
|
LL | final const FOO: usize = 1;
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: `FOO` is marked final here
--> $DIR/positions.rs:19:5
|
LL | final const FOO: usize = 1;
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 21 previous errors
error: aborting due to 19 previous errors