From 467e200cd5c032489b9bc87284f2a8fbfb922fc3 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 25 Nov 2024 18:17:23 +0100 Subject: [PATCH 1/4] add tests --- ...=> const_arg_trivial_macro_expansion-1.rs} | 287 +++++++++++++++--- ...onst_arg_trivial_macro_expansion-3-pass.rs | 46 +++ .../const_arg_trivial_macro_expansion-4.rs | 18 ++ ...const_arg_trivial_macro_expansion-4.stderr | 37 +++ 4 files changed, 352 insertions(+), 36 deletions(-) rename tests/ui/const-generics/early/{const_arg_trivial_macro_expansion.rs => const_arg_trivial_macro_expansion-1.rs} (56%) create mode 100644 tests/ui/const-generics/early/const_arg_trivial_macro_expansion-3-pass.rs create mode 100644 tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.rs create mode 100644 tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-1.rs similarity index 56% rename from tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs rename to tests/ui/const-generics/early/const_arg_trivial_macro_expansion-1.rs index 2fdd703ab6f32..5ea445520f1a5 100644 --- a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion.rs +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-1.rs @@ -85,6 +85,14 @@ macro_rules! braced_braced_expr { () => {{ braced_expr!() }}; } +macro_rules! closure { + () => { |()| () }; +} + +macro_rules! empty { + () => {}; +} + #[rustfmt::skip] mod array_paren_call { // Arrays where the expanded result is a `Res::Err` @@ -128,6 +136,14 @@ mod array_paren_call { fn array_33() -> [(); braced_expr!()] { loop {} } fn array_34() -> [(); { unbraced_expr!() }] { loop {} } fn array_35() -> [(); { braced_expr!() }] { loop {} } + + // Arrays whose expanded form contains a nested definition + fn array_36() -> [(); closure!()] { loop {} } + fn array_37() -> [(); { closure!() }] { loop {} } + + // Arrays whose macro expansion is empty + fn array_38() -> [(); empty!()] { loop {} } + fn array_39() -> [(); { empty!() }] { loop {} } } #[rustfmt::skip] @@ -173,6 +189,14 @@ mod array_brace_call { fn array_33() -> [(); braced_expr!{}] { loop {} } fn array_34() -> [(); { unbraced_expr!{} }] { loop {} } fn array_35() -> [(); { braced_expr!{} }] { loop {} } + + // Arrays whose expanded form contains a nested definition + fn array_36() -> [(); closure!{}] { loop {} } + fn array_37() -> [(); { closure!{} }] { loop {} } + + // Arrays whose macro expansion is empty + fn array_38() -> [(); empty!{}] { loop {} } + fn array_39() -> [(); { empty!{} }] { loop {} } } #[rustfmt::skip] @@ -218,6 +242,14 @@ mod array_square_call { fn array_33() -> [(); braced_expr![]] { loop {} } fn array_34() -> [(); { unbraced_expr![] }] { loop {} } fn array_35() -> [(); { braced_expr![] }] { loop {} } + + // Arrays whose expanded form contains a nested definition + fn array_36() -> [(); closure![]] { loop {} } + fn array_37() -> [(); { closure![] }] { loop {} } + + // Arrays whose macro expansion is empty + fn array_38() -> [(); empty![]] { loop {} } + fn array_39() -> [(); { empty![] }] { loop {} } } struct Foo; @@ -255,18 +287,26 @@ mod adt_paren_call { fn adt_23() -> Foo<{ braced_ident!() }> { loop {} } // An ADT where the expanded result is a complex expr - fn array_24() -> Foo { loop {} } - fn array_25() -> Foo { loop {} } - fn array_26() -> Foo { loop {} } - fn array_27() -> Foo { loop {} } - fn array_28() -> Foo<{ unbraced_unbraced_expr!() }> { loop {} } - fn array_29() -> Foo<{ braced_unbraced_expr!() }> { loop {} } - fn array_30() -> Foo<{ unbraced_braced_expr!() }> { loop {} } - fn array_31() -> Foo<{ braced_braced_expr!() }> { loop {} } - fn array_32() -> Foo { loop {} } - fn array_33() -> Foo { loop {} } - fn array_34() -> Foo<{ unbraced_expr!() }> { loop {} } - fn array_35() -> Foo<{ braced_expr!() }> { loop {} } + fn adt_24() -> Foo { loop {} } + fn adt_25() -> Foo { loop {} } + fn adt_26() -> Foo { loop {} } + fn adt_27() -> Foo { loop {} } + fn adt_28() -> Foo<{ unbraced_unbraced_expr!() }> { loop {} } + fn adt_29() -> Foo<{ braced_unbraced_expr!() }> { loop {} } + fn adt_30() -> Foo<{ unbraced_braced_expr!() }> { loop {} } + fn adt_31() -> Foo<{ braced_braced_expr!() }> { loop {} } + fn adt_32() -> Foo { loop {} } + fn adt_33() -> Foo { loop {} } + fn adt_34() -> Foo<{ unbraced_expr!() }> { loop {} } + fn adt_35() -> Foo<{ braced_expr!() }> { loop {} } + + // An ADT whose expanded form contains a nested definition + fn adt_36() -> Foo { loop {} } + fn adt_37() -> Foo<{ closure!() }> { loop {} } + + // An ADT whose macro expansion is empty + fn adt_38() -> Foo { loop {} } + fn adt_39() -> Foo<{ empty!() }> { loop {} } } #[rustfmt::skip] @@ -302,18 +342,26 @@ mod adt_brace_call { fn adt_23() -> Foo<{ braced_ident!{} }> { loop {} } // An ADT where the expanded result is a complex expr - fn array_24() -> Foo { loop {} } - fn array_25() -> Foo { loop {} } - fn array_26() -> Foo { loop {} } - fn array_27() -> Foo { loop {} } - fn array_28() -> Foo<{ unbraced_unbraced_expr!{} }> { loop {} } - fn array_29() -> Foo<{ braced_unbraced_expr!{} }> { loop {} } - fn array_30() -> Foo<{ unbraced_braced_expr!{} }> { loop {} } - fn array_31() -> Foo<{ braced_braced_expr!{} }> { loop {} } - fn array_32() -> Foo { loop {} } - fn array_33() -> Foo { loop {} } - fn array_34() -> Foo<{ unbraced_expr!{} }> { loop {} } - fn array_35() -> Foo<{ braced_expr!{} }> { loop {} } + fn adt_24() -> Foo { loop {} } + fn adt_25() -> Foo { loop {} } + fn adt_26() -> Foo { loop {} } + fn adt_27() -> Foo { loop {} } + fn adt_28() -> Foo<{ unbraced_unbraced_expr!{} }> { loop {} } + fn adt_29() -> Foo<{ braced_unbraced_expr!{} }> { loop {} } + fn adt_30() -> Foo<{ unbraced_braced_expr!{} }> { loop {} } + fn adt_31() -> Foo<{ braced_braced_expr!{} }> { loop {} } + fn adt_32() -> Foo { loop {} } + fn adt_33() -> Foo { loop {} } + fn adt_34() -> Foo<{ unbraced_expr!{} }> { loop {} } + fn adt_35() -> Foo<{ braced_expr!{} }> { loop {} } + + // An ADT whose expanded form contains a nested definition + fn adt_36() -> Foo { loop {} } + fn adt_37() -> Foo<{ closure!{} }> { loop {} } + + // An ADT whose macro expansion is empty + fn adt_38() -> Foo { loop {} } + fn adt_39() -> Foo<{ empty!{} }> { loop {} } } #[rustfmt::skip] @@ -349,18 +397,185 @@ mod adt_square_call { fn adt_23() -> Foo<{ braced_ident![] }> { loop {} } // An ADT where the expanded result is a complex expr - fn array_24() -> Foo { loop {} } - fn array_25() -> Foo { loop {} } - fn array_26() -> Foo { loop {} } - fn array_27() -> Foo { loop {} } - fn array_28() -> Foo<{ unbraced_unbraced_expr![] }> { loop {} } - fn array_29() -> Foo<{ braced_unbraced_expr![] }> { loop {} } - fn array_30() -> Foo<{ unbraced_braced_expr![] }> { loop {} } - fn array_31() -> Foo<{ braced_braced_expr![] }> { loop {} } - fn array_32() -> Foo { loop {} } - fn array_33() -> Foo { loop {} } - fn array_34() -> Foo<{ unbraced_expr![] }> { loop {} } - fn array_35() -> Foo<{ braced_expr![] }> { loop {} } + fn adt_24() -> Foo { loop {} } + fn adt_25() -> Foo { loop {} } + fn adt_26() -> Foo { loop {} } + fn adt_27() -> Foo { loop {} } + fn adt_28() -> Foo<{ unbraced_unbraced_expr![] }> { loop {} } + fn adt_29() -> Foo<{ braced_unbraced_expr![] }> { loop {} } + fn adt_30() -> Foo<{ unbraced_braced_expr![] }> { loop {} } + fn adt_31() -> Foo<{ braced_braced_expr![] }> { loop {} } + fn adt_32() -> Foo { loop {} } + fn adt_33() -> Foo { loop {} } + fn adt_34() -> Foo<{ unbraced_expr![] }> { loop {} } + fn adt_35() -> Foo<{ braced_expr![] }> { loop {} } + + // An ADT whose expanded form contains a nested definition + fn adt_36() -> Foo { loop {} } + fn adt_37() -> Foo<{ closure![] }> { loop {} } + + // An ADT whose macro expansion is empty + fn adt_38() -> Foo { loop {} } + fn adt_39() -> Foo<{ empty![] }> { loop {} } +} + +#[rustfmt::skip] +mod repeat_paren_call { + // A repeat expr where the expanded result is a `Res::Err` + fn repeat_0() { [(); unbraced_unbraced_ident!()]; } + fn repeat_1() { [(); braced_unbraced_ident!()]; } + fn repeat_2() { [(); unbraced_braced_ident!()]; } + fn repeat_3() { [(); braced_braced_ident!()]; } + fn repeat_4() { [(); { unbraced_unbraced_ident!() }]; } + fn repeat_5() { [(); { braced_unbraced_ident!() }]; } + fn repeat_6() { [(); { unbraced_braced_ident!() }]; } + fn repeat_7() { [(); { braced_braced_ident!() }]; } + fn repeat_8() { [(); unbraced_ident!()]; } + fn repeat_9() { [(); braced_ident!()]; } + fn repeat_10() { [(); { unbraced_ident!() }]; } + fn repeat_11() { [(); { braced_ident!() }]; } + + // A repeat expr where the expanded result is a `Res::ConstParam` + fn repeat_12() { [(); unbraced_unbraced_ident!()]; } + fn repeat_13() { [(); braced_unbraced_ident!()]; } + fn repeat_14() { [(); unbraced_braced_ident!()]; } + fn repeat_15() { [(); braced_braced_ident!()]; } + fn repeat_16() { [(); { unbraced_unbraced_ident!() }]; } + fn repeat_17() { [(); { braced_unbraced_ident!() }]; } + fn repeat_18() { [(); { unbraced_braced_ident!() }]; } + fn repeat_19() { [(); { braced_braced_ident!() }]; } + fn repeat_20() { [(); unbraced_ident!()]; } + fn repeat_21() { [(); braced_ident!()]; } + fn repeat_22() { [(); { unbraced_ident!() }]; } + fn repeat_23() { [(); { braced_ident!() }]; } + + // A repeat expr where the expanded result is a complex expr + fn repeat_24() { [(); unbraced_unbraced_expr!()]; } + fn repeat_25() { [(); braced_unbraced_expr!()]; } + fn repeat_26() { [(); unbraced_braced_expr!()]; } + fn repeat_27() { [(); braced_braced_expr!()]; } + fn repeat_28() { [(); { unbraced_unbraced_expr!() }]; } + fn repeat_29() { [(); { braced_unbraced_expr!() }]; } + fn repeat_30() { [(); { unbraced_braced_expr!() }]; } + fn repeat_31() { [(); { braced_braced_expr!() }]; } + fn repeat_32() { [(); unbraced_expr!()]; } + fn repeat_33() { [(); braced_expr!()]; } + fn repeat_34() { [(); { unbraced_expr!() }]; } + fn repeat_35() { [(); { braced_expr!() }]; } + + // A repeat expr whose expanded form contains a nested definition + fn repeat_36() { [(); closure!()] } + fn repeat_37() { [(); { closure!() }] } + + // A repeat expr whose macro expansion is empty + fn repeat_38() { [(); empty!()] } + fn repeat_39() { [(); { empty!() }] } +} + +#[rustfmt::skip] +mod repeat_brace_call { + // A repeat expr where the expanded result is a `Res::Err` + fn repeat_0() { [(); unbraced_unbraced_ident!{}]; } + fn repeat_1() { [(); braced_unbraced_ident!{}]; } + fn repeat_2() { [(); unbraced_braced_ident!{}]; } + fn repeat_3() { [(); braced_braced_ident!{}]; } + fn repeat_4() { [(); { unbraced_unbraced_ident!{} }]; } + fn repeat_5() { [(); { braced_unbraced_ident!{} }]; } + fn repeat_6() { [(); { unbraced_braced_ident!{} }]; } + fn repeat_7() { [(); { braced_braced_ident!{} }]; } + fn repeat_8() { [(); unbraced_ident!{}]; } + fn repeat_9() { [(); braced_ident!{}]; } + fn repeat_10() { [(); { unbraced_ident!{} }]; } + fn repeat_11() { [(); { braced_ident!{} }]; } + + // A repeat expr where the expanded result is a `Res::ConstParam` + fn repeat_12() { [(); unbraced_unbraced_ident!{}]; } + fn repeat_13() { [(); braced_unbraced_ident!{}]; } + fn repeat_14() { [(); unbraced_braced_ident!{}]; } + fn repeat_15() { [(); braced_braced_ident!{}]; } + fn repeat_16() { [(); { unbraced_unbraced_ident!{} }]; } + fn repeat_17() { [(); { braced_unbraced_ident!{} }]; } + fn repeat_18() { [(); { unbraced_braced_ident!{} }]; } + fn repeat_19() { [(); { braced_braced_ident!{} }]; } + fn repeat_20() { [(); unbraced_ident!{}]; } + fn repeat_21() { [(); braced_ident!{}]; } + fn repeat_22() { [(); { unbraced_ident!{} }]; } + fn repeat_23() { [(); { braced_ident!{} }]; } + + // A repeat expr where the expanded result is a complex expr + fn repeat_24() { [(); unbraced_unbraced_expr!{}]; } + fn repeat_25() { [(); braced_unbraced_expr!{}]; } + fn repeat_26() { [(); unbraced_braced_expr!{}]; } + fn repeat_27() { [(); braced_braced_expr!{}]; } + fn repeat_28() { [(); { unbraced_unbraced_expr!{} }]; } + fn repeat_29() { [(); { braced_unbraced_expr!{} }]; } + fn repeat_30() { [(); { unbraced_braced_expr!{} }]; } + fn repeat_31() { [(); { braced_braced_expr!{} }]; } + fn repeat_32() { [(); unbraced_expr!{}]; } + fn repeat_33() { [(); braced_expr!{}]; } + fn repeat_34() { [(); { unbraced_expr!{} }]; } + fn repeat_35() { [(); { braced_expr!{} }]; } + + // A repeat expr whose expanded form contains a nested definition + fn repeat_36() { [(); closure!{}] } + fn repeat_37() { [(); { closure!{} }] } + + // A repeat expr whose macro expansion is empty + fn repeat_38() { [(); empty!{}] } + fn repeat_39() { [(); { empty!{} }] } +} + +#[rustfmt::skip] +mod repeat_square_call { + // A repeat expr where the expanded result is a `Res::Err` + fn repeat_0() { [(); unbraced_unbraced_ident![]]; } + fn repeat_1() { [(); braced_unbraced_ident![]]; } + fn repeat_2() { [(); unbraced_braced_ident![]]; } + fn repeat_3() { [(); braced_braced_ident![]]; } + fn repeat_4() { [(); { unbraced_unbraced_ident![] }]; } + fn repeat_5() { [(); { braced_unbraced_ident![] }]; } + fn repeat_6() { [(); { unbraced_braced_ident![] }]; } + fn repeat_7() { [(); { braced_braced_ident![] }]; } + fn repeat_8() { [(); unbraced_ident![]]; } + fn repeat_9() { [(); braced_ident![]]; } + fn repeat_10() { [(); { unbraced_ident![] }]; } + fn repeat_11() { [(); { braced_ident![] }]; } + + // A repeat expr where the expanded result is a `Res::ConstParam` + fn repeat_12() { [(); unbraced_unbraced_ident![]]; } + fn repeat_13() { [(); braced_unbraced_ident![]]; } + fn repeat_14() { [(); unbraced_braced_ident![]]; } + fn repeat_15() { [(); braced_braced_ident![]]; } + fn repeat_16() { [(); { unbraced_unbraced_ident![] }]; } + fn repeat_17() { [(); { braced_unbraced_ident![] }]; } + fn repeat_18() { [(); { unbraced_braced_ident![] }]; } + fn repeat_19() { [(); { braced_braced_ident![] }]; } + fn repeat_20() { [(); unbraced_ident![]]; } + fn repeat_21() { [(); braced_ident![]]; } + fn repeat_22() { [(); { unbraced_ident![] }]; } + fn repeat_23() { [(); { braced_ident![] }]; } + + // A repeat expr where the expanded result is a complex expr + fn repeat_24() { [(); unbraced_unbraced_expr![]]; } + fn repeat_25() { [(); braced_unbraced_expr![]]; } + fn repeat_26() { [(); unbraced_braced_expr![]]; } + fn repeat_27() { [(); braced_braced_expr![]]; } + fn repeat_28() { [(); { unbraced_unbraced_expr![] }]; } + fn repeat_29() { [(); { braced_unbraced_expr![] }]; } + fn repeat_30() { [(); { unbraced_braced_expr![] }]; } + fn repeat_31() { [(); { braced_braced_expr![] }]; } + fn repeat_32() { [(); unbraced_expr![]]; } + fn repeat_33() { [(); braced_expr![]]; } + fn repeat_34() { [(); { unbraced_expr![] }]; } + fn repeat_35() { [(); { braced_expr![] }]; } + + // A repeat expr whose expanded form contains a nested definition + fn repeat_36() { [(); closure![]] } + fn repeat_37() { [(); { closure![] }] } + + // A repeat expr whose macro expansion is empty + fn repeat_38() { [(); empty![]] } + fn repeat_39() { [(); { empty![] }] } } fn main() {} diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-3-pass.rs b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-3-pass.rs new file mode 100644 index 0000000000000..fb6190324c6cf --- /dev/null +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-3-pass.rs @@ -0,0 +1,46 @@ +// Additional checks for macro expansion in const args + +//@ check-pass + +macro_rules! closure { + () => { |()| () }; +} + +macro_rules! indir_semi { + ($nested:ident) => { $nested!(); }; +} + +macro_rules! indir { + ($nested:ident) => { $nested!() }; +} + +macro_rules! empty { + () => {}; +} + +macro_rules! arg { + () => { N }; +} + +struct Adt; + +fn array1() -> [(); { closure!(); 0 }] { loop {} } +fn array2() -> [(); { indir!(closure); 0}] { loop {} } +fn array3() -> [(); { indir_semi!{ closure } 0 }] { loop {} } +fn array4() -> [(); { indir!{ empty } arg!{} }] { loop {} } +fn array5() -> [(); { empty!{} arg!() }] { loop {} } +fn array6() -> [(); { empty!{} N }] { loop {} } +fn array7() -> [(); { arg!{} empty!{} }] { loop {} } +fn array8() -> [(); { empty!{} arg!{} empty!{} }] { loop {} } + +fn adt1() -> Adt<{ closure!(); 0 }> { loop {} } +fn adt2() -> Adt<{ indir!(closure); 0}> { loop {} } +fn adt3() -> Adt<{ indir_semi!{ closure } 0 }> { loop {} } +fn adt4() -> Adt<{ indir!{ empty } arg!{} }> { loop {} } +fn adt5() -> Adt<{ empty!{} arg!() }> { loop {} } +fn adt6() -> Adt<{ empty!{} N }> { loop {} } +fn adt7() -> Adt<{ arg!{} empty!{} }> { loop {} } +fn adt8() -> Adt<{ empty!{} arg!{} empty!{} }> { loop {} } + + +fn main() {} diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.rs b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.rs new file mode 100644 index 0000000000000..3353d6cf2da3d --- /dev/null +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.rs @@ -0,0 +1,18 @@ +macro_rules! empty { + () => {}; +} + +macro_rules! arg { + () => { + N + //~^ ERROR generic parameters may not be used in const operations + //~| ERROR generic parameters may not be used in const operations + }; +} + +struct Foo; +fn foo() -> Foo<{ arg!{} arg!{} }> { loop {} } +fn bar() -> [(); { empty!{}; N }] { loop {} } +//~^ ERROR generic parameters may not be used in const operations + +fn main() {} diff --git a/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr new file mode 100644 index 0000000000000..4722968b20346 --- /dev/null +++ b/tests/ui/const-generics/early/const_arg_trivial_macro_expansion-4.stderr @@ -0,0 +1,37 @@ +error: generic parameters may not be used in const operations + --> $DIR/const_arg_trivial_macro_expansion-4.rs:7:9 + | +LL | N + | ^ cannot perform const operation using `N` +... +LL | fn foo() -> Foo<{ arg!{} arg!{} }> { loop {} } + | ------ in this macro invocation + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = note: this error originates in the macro `arg` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: generic parameters may not be used in const operations + --> $DIR/const_arg_trivial_macro_expansion-4.rs:7:9 + | +LL | N + | ^ cannot perform const operation using `N` +... +LL | fn foo() -> Foo<{ arg!{} arg!{} }> { loop {} } + | ------ in this macro invocation + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + = note: this error originates in the macro `arg` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: generic parameters may not be used in const operations + --> $DIR/const_arg_trivial_macro_expansion-4.rs:15:46 + | +LL | fn bar() -> [(); { empty!{}; N }] { loop {} } + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: aborting due to 3 previous errors + From 94131bd0a8e125d6d32034aadf010d9250f83867 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 25 Nov 2024 18:42:10 +0100 Subject: [PATCH 2/4] always create `DefId`s when lowering anon-consts --- compiler/rustc_ast/src/ast.rs | 7 +- compiler/rustc_ast_lowering/src/asm.rs | 17 +- compiler/rustc_ast_lowering/src/expr.rs | 8 +- compiler/rustc_ast_lowering/src/lib.rs | 19 +-- compiler/rustc_metadata/src/rmeta/encoder.rs | 14 ++ compiler/rustc_resolve/src/def_collector.rs | 158 +++---------------- compiler/rustc_resolve/src/late.rs | 4 +- compiler/rustc_resolve/src/lib.rs | 13 -- tests/ui/consts/issue-36163.stderr | 6 +- 9 files changed, 61 insertions(+), 185 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index ecb6ef5a2a646..56b20e0ad8938 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1184,14 +1184,15 @@ pub struct Expr { } impl Expr { - /// Is this expr either `N`, or `{ N }`. + /// Could this expr be either `N`, or `{ N }`, where `N` is a const parameter. /// /// If this is not the case, name resolution does not resolve `N` when using /// `min_const_generics` as more complex expressions are not supported. /// /// Does not ensure that the path resolves to a const param, the caller should check this. - pub fn is_potential_trivial_const_arg(&self, strip_identity_block: bool) -> bool { - let this = if strip_identity_block { self.maybe_unwrap_block() } else { self }; + /// This also does not consider macros, so it's only correct after macro-expansion. + pub fn is_potential_trivial_const_arg(&self) -> bool { + let this = self.maybe_unwrap_block(); if let ExprKind::Path(None, path) = &this.kind && path.is_potential_trivial_const_arg() diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index ff803e509973a..cc0171d74a41c 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -224,16 +224,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Wrap the expression in an AnonConst. let parent_def_id = self.current_def_id_parent; let node_id = self.next_node_id(); - // HACK(min_generic_const_args): see lower_anon_const - if !expr.is_potential_trivial_const_arg(true) { - self.create_def( - parent_def_id, - node_id, - kw::Empty, - DefKind::AnonConst, - *op_sp, - ); - } + self.create_def( + parent_def_id, + node_id, + kw::Empty, + DefKind::AnonConst, + *op_sp, + ); let anon_const = AnonConst { id: node_id, value: P(expr) }; hir::InlineAsmOperand::SymFn { anon_const: self.lower_anon_const_to_anon_const(&anon_const), diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 3af29838b72c4..dafed4f906aac 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -454,13 +454,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if legacy_args_idx.contains(&idx) { let parent_def_id = self.current_def_id_parent; let node_id = self.next_node_id(); - - // HACK(min_generic_const_args): see lower_anon_const - if !arg.is_potential_trivial_const_arg(true) { - // Add a definition for the in-band const def. - self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span); - } - + self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span); let mut visitor = WillCreateDefIdsVisitor {}; let const_value = if let ControlFlow::Break(span) = visitor.visit_expr(&arg) { AstP(Expr { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index dae816663e00e..ea2e77fb9ddbd 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2159,7 +2159,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { None, ); - return ConstArg { hir_id: self.next_id(), kind: hir::ConstArgKind::Path(qpath) }; + return ConstArg { + hir_id: self.lower_node_id(anon.id), + kind: hir::ConstArgKind::Path(qpath), + }; } let lowered_anon = self.lower_anon_const_to_anon_const(anon); @@ -2169,20 +2172,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// See [`hir::ConstArg`] for when to use this function vs /// [`Self::lower_anon_const_to_const_arg`]. fn lower_anon_const_to_anon_const(&mut self, c: &AnonConst) -> &'hir hir::AnonConst { - if c.value.is_potential_trivial_const_arg(true) { - // HACK(min_generic_const_args): see DefCollector::visit_anon_const - // Over there, we guess if this is a bare param and only create a def if - // we think it's not. However we may can guess wrong (see there for example) - // in which case we have to create the def here. - self.create_def( - self.current_def_id_parent, - c.id, - kw::Empty, - DefKind::AnonConst, - c.value.span, - ); - } - self.arena.alloc(self.with_new_scopes(c.value.span, |this| { let def_id = this.local_def_id(c.id); let hir_id = this.lower_node_id(c.id); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index dd149af52052e..068a5d31a8e12 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1383,6 +1383,20 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def_id = local_id.to_def_id(); let def_kind = tcx.def_kind(local_id); self.tables.def_kind.set_some(def_id.index, def_kind); + + // The `DefCollector` will sometimes create unnecessary `DefId`s + // for trivial const arguments which are directly lowered to + // `ConstArgKind::Path`. We never actually access this `DefId` + // anywhere so we don't need to encode it for other crates. + if def_kind == DefKind::AnonConst + && matches!( + tcx.hir_node_by_def_id(local_id), + hir::Node::ConstArg(hir::ConstArg { kind: hir::ConstArgKind::Path(..), .. }) + ) + { + continue; + } + if should_encode_span(def_kind) { let def_span = tcx.def_span(local_id); record!(self.tables.def_span[def_id] <- def_span); diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 7536869e2fe25..6649284258121 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -12,23 +12,16 @@ use rustc_span::hygiene::LocalExpnId; use rustc_span::symbol::{Symbol, kw, sym}; use tracing::debug; -use crate::{ImplTraitContext, InvocationParent, PendingAnonConstInfo, Resolver}; +use crate::{ImplTraitContext, InvocationParent, Resolver}; pub(crate) fn collect_definitions( resolver: &mut Resolver<'_, '_>, fragment: &AstFragment, expansion: LocalExpnId, ) { - let InvocationParent { parent_def, pending_anon_const_info, impl_trait_context, in_attr } = + let InvocationParent { parent_def, impl_trait_context, in_attr } = resolver.invocation_parents[&expansion]; - let mut visitor = DefCollector { - resolver, - parent_def, - pending_anon_const_info, - expansion, - impl_trait_context, - in_attr, - }; + let mut visitor = DefCollector { resolver, parent_def, expansion, impl_trait_context, in_attr }; fragment.visit_with(&mut visitor); } @@ -36,13 +29,6 @@ pub(crate) fn collect_definitions( struct DefCollector<'a, 'ra, 'tcx> { resolver: &'a mut Resolver<'ra, 'tcx>, parent_def: LocalDefId, - /// If we have an anon const that consists of a macro invocation, e.g. `Foo<{ m!() }>`, - /// we need to wait until we know what the macro expands to before we create the def for - /// the anon const. That's because we lower some anon consts into `hir::ConstArgKind::Path`, - /// which don't have defs. - /// - /// See `Self::visit_anon_const()`. - pending_anon_const_info: Option, impl_trait_context: ImplTraitContext, in_attr: bool, expansion: LocalExpnId, @@ -110,61 +96,13 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { fn visit_macro_invoc(&mut self, id: NodeId) { let id = id.placeholder_to_expn_id(); - let pending_anon_const_info = self.pending_anon_const_info.take(); let old_parent = self.resolver.invocation_parents.insert(id, InvocationParent { parent_def: self.parent_def, - pending_anon_const_info, impl_trait_context: self.impl_trait_context, in_attr: self.in_attr, }); assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation"); } - - /// Determines whether the const argument `AnonConst` is a simple macro call, optionally - /// surrounded with braces. - /// - /// If this const argument *is* a trivial macro call then the id for the macro call is - /// returned along with the information required to build the anon const's def if - /// the macro call expands to a non-trivial expression. - fn is_const_arg_trivial_macro_expansion( - &self, - anon_const: &'a AnonConst, - ) -> Option<(PendingAnonConstInfo, NodeId)> { - anon_const.value.optionally_braced_mac_call(false).map(|(block_was_stripped, id)| { - ( - PendingAnonConstInfo { - id: anon_const.id, - span: anon_const.value.span, - block_was_stripped, - }, - id, - ) - }) - } - - /// Determines whether the expression `const_arg_sub_expr` is a simple macro call, sometimes - /// surrounded with braces if a set of braces has not already been entered. This is required - /// as `{ N }` is treated as equivalent to a bare parameter `N` whereas `{{ N }}` is treated as - /// a real block expression and is lowered to an anonymous constant which is not allowed to use - /// generic parameters. - /// - /// If this expression is a trivial macro call then the id for the macro call is - /// returned along with the information required to build the anon const's def if - /// the macro call expands to a non-trivial expression. - fn is_const_arg_sub_expr_trivial_macro_expansion( - &self, - const_arg_sub_expr: &'a Expr, - ) -> Option<(PendingAnonConstInfo, NodeId)> { - let pending_anon = self.pending_anon_const_info.unwrap_or_else(|| - panic!("Checking expr is trivial macro call without having entered anon const: `{const_arg_sub_expr:?}`"), - ); - - const_arg_sub_expr.optionally_braced_mac_call(pending_anon.block_was_stripped).map( - |(block_was_stripped, id)| { - (PendingAnonConstInfo { block_was_stripped, ..pending_anon }, id) - }, - ) - } } impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { @@ -376,78 +314,34 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } fn visit_anon_const(&mut self, constant: &'a AnonConst) { - // HACK(min_generic_const_args): don't create defs for anon consts if we think they will - // later be turned into ConstArgKind::Path's. because this is before resolve is done, we - // may accidentally identify a construction of a unit struct as a param and not create a - // def. we'll then create a def later in ast lowering in this case. the parent of nested - // items will be messed up, but that's ok because there can't be any if we're just looking - // for bare idents. - - if let Some((pending_anon, macro_invoc)) = - self.is_const_arg_trivial_macro_expansion(constant) - { - self.pending_anon_const_info = Some(pending_anon); - return self.visit_macro_invoc(macro_invoc); - } else if constant.value.is_potential_trivial_const_arg(true) { - return visit::walk_anon_const(self, constant); - } - - let def = self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span); - self.with_parent(def, |this| visit::walk_anon_const(this, constant)); + let parent = + self.create_def(constant.id, kw::Empty, DefKind::AnonConst, constant.value.span); + self.with_parent(parent, |this| visit::walk_anon_const(this, constant)); } fn visit_expr(&mut self, expr: &'a Expr) { - // If we're visiting the expression of a const argument that was a macro call then - // check if it is *still* unknown whether it is a trivial const arg or not. If so - // recurse into the macro call and delay creating the anon const def until expansion. - if self.pending_anon_const_info.is_some() - && let Some((pending_anon, macro_invoc)) = - self.is_const_arg_sub_expr_trivial_macro_expansion(expr) - { - self.pending_anon_const_info = Some(pending_anon); - return self.visit_macro_invoc(macro_invoc); - } - - // See self.pending_anon_const_info for explanation - let parent_def = self - .pending_anon_const_info - .take() - // If we already stripped away a set of braces then do not do it again when determining - // if the macro expanded to a trivial const arg. This arises in cases such as: - // `Foo<{ bar!() }>` where `bar!()` expands to `{ N }`. This should not be considered a - // trivial const argument even though `{ N }` by itself *is*. - .filter(|pending_anon| { - !expr.is_potential_trivial_const_arg(!pending_anon.block_was_stripped) - }) - .map(|pending_anon| { - self.create_def(pending_anon.id, kw::Empty, DefKind::AnonConst, pending_anon.span) - }) - .unwrap_or(self.parent_def); - - self.with_parent(parent_def, |this| { - let parent_def = match expr.kind { - ExprKind::MacCall(..) => return this.visit_macro_invoc(expr.id), - ExprKind::Closure(..) | ExprKind::Gen(..) => { - this.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span) - } - ExprKind::ConstBlock(ref constant) => { - for attr in &expr.attrs { - visit::walk_attribute(this, attr); - } - let def = this.create_def( - constant.id, - kw::Empty, - DefKind::InlineConst, - constant.value.span, - ); - this.with_parent(def, |this| visit::walk_anon_const(this, constant)); - return; + let parent_def = match expr.kind { + ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id), + ExprKind::Closure(..) | ExprKind::Gen(..) => { + self.create_def(expr.id, kw::Empty, DefKind::Closure, expr.span) + } + ExprKind::ConstBlock(ref constant) => { + for attr in &expr.attrs { + visit::walk_attribute(self, attr); } - _ => this.parent_def, - }; + let def = self.create_def( + constant.id, + kw::Empty, + DefKind::InlineConst, + constant.value.span, + ); + self.with_parent(def, |this| visit::walk_anon_const(this, constant)); + return; + } + _ => self.parent_def, + }; - this.with_parent(parent_def, |this| visit::walk_expr(this, expr)) - }) + self.with_parent(parent_def, |this| visit::walk_expr(this, expr)) } fn visit_ty(&mut self, ty: &'a Ty) { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 60815ffdb1b9e..fc92dc8b4ed71 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4521,7 +4521,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ); self.resolve_anon_const_manual( - constant.value.is_potential_trivial_const_arg(true), + constant.value.is_potential_trivial_const_arg(), anon_const_kind, |this| this.resolve_expr(&constant.value, None), ) @@ -4685,7 +4685,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // that is how they will be later lowered to HIR. if const_args.contains(&idx) { self.resolve_anon_const_manual( - argument.is_potential_trivial_const_arg(true), + argument.is_potential_trivial_const_arg(), AnonConstKind::ConstArg(IsRepeatExpr::No), |this| this.resolve_expr(argument, None), ); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index e382295b8f6d8..094871ad26876 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -174,7 +174,6 @@ impl<'ra> ParentScope<'ra> { #[derive(Copy, Debug, Clone)] struct InvocationParent { parent_def: LocalDefId, - pending_anon_const_info: Option, impl_trait_context: ImplTraitContext, in_attr: bool, } @@ -182,23 +181,11 @@ struct InvocationParent { impl InvocationParent { const ROOT: Self = Self { parent_def: CRATE_DEF_ID, - pending_anon_const_info: None, impl_trait_context: ImplTraitContext::Existential, in_attr: false, }; } -#[derive(Copy, Debug, Clone)] -struct PendingAnonConstInfo { - // A const arg is only a "trivial" const arg if it has at *most* one set of braces - // around the argument. We track whether we have stripped an outter brace so that - // if a macro expands to a braced expression *and* the macro was itself inside of - // some braces then we can consider it to be a non-trivial const argument. - block_was_stripped: bool, - id: NodeId, - span: Span, -} - #[derive(Copy, Debug, Clone)] enum ImplTraitContext { Existential, diff --git a/tests/ui/consts/issue-36163.stderr b/tests/ui/consts/issue-36163.stderr index 52d3e003f0ac9..8a7a0981f4154 100644 --- a/tests/ui/consts/issue-36163.stderr +++ b/tests/ui/consts/issue-36163.stderr @@ -1,10 +1,10 @@ -error[E0391]: cycle detected when simplifying constant for the type system `Foo::{constant#0}` +error[E0391]: cycle detected when simplifying constant for the type system `Foo::B::{constant#0}` --> $DIR/issue-36163.rs:4:9 | LL | B = A, | ^ | -note: ...which requires const-evaluating + checking `Foo::{constant#0}`... +note: ...which requires const-evaluating + checking `Foo::B::{constant#0}`... --> $DIR/issue-36163.rs:4:9 | LL | B = A, @@ -19,7 +19,7 @@ note: ...which requires const-evaluating + checking `A`... | LL | const A: isize = Foo::B as isize; | ^^^^^^^^^^^^^^^ - = note: ...which again requires simplifying constant for the type system `Foo::{constant#0}`, completing the cycle + = note: ...which again requires simplifying constant for the type system `Foo::B::{constant#0}`, completing the cycle note: cycle used when checking that `Foo` is well-formed --> $DIR/issue-36163.rs:3:1 | From 23ba2d11944a2eb538dca4583ff2465ca8da37a3 Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 25 Nov 2024 18:43:34 +0100 Subject: [PATCH 3/4] ast_lowering: rm separate `def_id_parent` no longer necessary as we now always create a ` DefId` for anon-consts --- compiler/rustc_ast_lowering/src/asm.rs | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 102 +++++++++++------------- compiler/rustc_ast_lowering/src/lib.rs | 54 ++++--------- 3 files changed, 62 insertions(+), 96 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index cc0171d74a41c..17bcff774b843 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -222,7 +222,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; // Wrap the expression in an AnonConst. - let parent_def_id = self.current_def_id_parent; + let parent_def_id = self.current_hir_id_owner.def_id; let node_id = self.next_node_id(); self.create_def( parent_def_id, diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index dafed4f906aac..3032042ff9fee 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -109,9 +109,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ConstBlock { def_id, hir_id: this.lower_node_id(c.id), - body: this.with_def_id_parent(def_id, |this| { - this.lower_const_body(c.value.span, Some(&c.value)) - }), + body: this.lower_const_body(c.value.span, Some(&c.value)), } }); hir::ExprKind::ConstBlock(c) @@ -452,7 +450,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut generic_args = ThinVec::new(); for (idx, arg) in args.iter().cloned().enumerate() { if legacy_args_idx.contains(&idx) { - let parent_def_id = self.current_def_id_parent; + let parent_def_id = self.current_hir_id_owner.def_id; let node_id = self.next_node_id(); self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span); let mut visitor = WillCreateDefIdsVisitor {}; @@ -753,19 +751,17 @@ impl<'hir> LoweringContext<'_, 'hir> { lifetime_elision_allowed: false, }); - let body = self.with_def_id_parent(closure_def_id, move |this| { - this.lower_body(move |this| { - this.coroutine_kind = Some(coroutine_kind); + let body = self.lower_body(move |this| { + this.coroutine_kind = Some(coroutine_kind); - let old_ctx = this.task_context; - if task_context.is_some() { - this.task_context = task_context; - } - let res = body(this); - this.task_context = old_ctx; + let old_ctx = this.task_context; + if task_context.is_some() { + this.task_context = task_context; + } + let res = body(this); + this.task_context = old_ctx; - (params, res) - }) + (params, res) }); // `static |<_task_context?>| -> { }`: @@ -1050,26 +1046,24 @@ impl<'hir> LoweringContext<'_, 'hir> { let (binder_clause, generic_params) = self.lower_closure_binder(binder); let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| { - this.with_def_id_parent(closure_def_id, move |this| { - let mut coroutine_kind = if this - .attrs - .get(&closure_hir_id.local_id) - .is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine))) - { - Some(hir::CoroutineKind::Coroutine(Movability::Movable)) - } else { - None - }; - let body_id = this.lower_fn_body(decl, |this| { - this.coroutine_kind = coroutine_kind; - let e = this.lower_expr_mut(body); - coroutine_kind = this.coroutine_kind; - e - }); - let coroutine_option = - this.closure_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability); - (body_id, coroutine_option) - }) + let mut coroutine_kind = if this + .attrs + .get(&closure_hir_id.local_id) + .is_some_and(|attrs| attrs.iter().any(|attr| attr.has_name(sym::coroutine))) + { + Some(hir::CoroutineKind::Coroutine(Movability::Movable)) + } else { + None + }; + let body_id = this.lower_fn_body(decl, |this| { + this.coroutine_kind = coroutine_kind; + let e = this.lower_expr_mut(body); + coroutine_kind = this.coroutine_kind; + e + }); + let coroutine_option = + this.closure_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability); + (body_id, coroutine_option) }); let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params); @@ -1159,28 +1153,26 @@ impl<'hir> LoweringContext<'_, 'hir> { ); let body = self.with_new_scopes(fn_decl_span, |this| { - this.with_def_id_parent(closure_def_id, |this| { - let inner_decl = - FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) }; - - // Transform `async |x: u8| -> X { ... }` into - // `|x: u8| || -> X { ... }`. - let body_id = this.lower_body(|this| { - let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments( - &inner_decl, - |this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)), - fn_decl_span, - body.span, - coroutine_kind, - hir::CoroutineSource::Closure, - ); + let inner_decl = + FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) }; + + // Transform `async |x: u8| -> X { ... }` into + // `|x: u8| || -> X { ... }`. + let body_id = this.lower_body(|this| { + let (parameters, expr) = this.lower_coroutine_body_with_moved_arguments( + &inner_decl, + |this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)), + fn_decl_span, + body.span, + coroutine_kind, + hir::CoroutineSource::Closure, + ); - this.maybe_forward_track_caller(body.span, closure_hir_id, expr.hir_id); + this.maybe_forward_track_caller(body.span, closure_hir_id, expr.hir_id); - (parameters, expr) - }); - body_id - }) + (parameters, expr) + }); + body_id }); let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index ea2e77fb9ddbd..96546239f4c27 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -117,18 +117,6 @@ struct LoweringContext<'a, 'hir> { is_in_dyn_type: bool, current_hir_id_owner: hir::OwnerId, - /// Why do we need this in addition to [`Self::current_hir_id_owner`]? - /// - /// Currently (as of June 2024), anonymous constants are not HIR owners; however, - /// they do get their own DefIds. Some of these DefIds have to be created during - /// AST lowering, rather than def collection, because we can't tell until after - /// name resolution whether an anonymous constant will end up instead being a - /// [`hir::ConstArgKind::Path`]. However, to compute which generics are - /// available to an anonymous constant nested inside another, we need to make - /// sure that the parent is recorded as the parent anon const, not the enclosing - /// item. So we need to track parent defs differently from HIR owners, since they - /// will be finer-grained in the case of anon consts. - current_def_id_parent: LocalDefId, item_local_id_counter: hir::ItemLocalId, trait_map: ItemLocalMap>, @@ -161,7 +149,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { attrs: SortedMap::default(), children: Vec::default(), current_hir_id_owner: hir::CRATE_OWNER_ID, - current_def_id_parent: CRATE_DEF_ID, item_local_id_counter: hir::ItemLocalId::ZERO, ident_and_label_to_local_id: Default::default(), #[cfg(debug_assertions)] @@ -565,7 +552,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { debug_assert_eq!(_old, None); } - let item = self.with_def_id_parent(def_id, f); + let item = f(self); debug_assert_eq!(def_id, item.def_id().def_id); // `f` should have consumed all the elements in these vectors when constructing `item`. debug_assert!(self.impl_trait_defs.is_empty()); @@ -590,13 +577,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.children.push((def_id, hir::MaybeOwner::Owner(info))); } - fn with_def_id_parent(&mut self, parent: LocalDefId, f: impl FnOnce(&mut Self) -> T) -> T { - let current_def_id_parent = std::mem::replace(&mut self.current_def_id_parent, parent); - let result = f(self); - self.current_def_id_parent = current_def_id_parent; - result - } - fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> { let attrs = std::mem::take(&mut self.attrs); let mut bodies = std::mem::take(&mut self.bodies); @@ -773,7 +753,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { LifetimeRes::Fresh { param, kind, .. } => { // Late resolution delegates to us the creation of the `LocalDefId`. let _def_id = self.create_def( - self.current_hir_id_owner.def_id, // FIXME: should this use self.current_def_id_parent? + self.current_hir_id_owner.def_id, param, kw::UnderscoreLifetime, DefKind::LifetimeParam, @@ -1466,17 +1446,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id); debug!(?opaque_ty_def_id, ?opaque_ty_hir_id); - let opaque_ty_def = self.with_def_id_parent(opaque_ty_def_id, |this| { - let bounds = lower_item_bounds(this); - let opaque_ty_def = hir::OpaqueTy { - hir_id: opaque_ty_hir_id, - def_id: opaque_ty_def_id, - bounds, - origin, - span: this.lower_span(opaque_ty_span), - }; - this.arena.alloc(opaque_ty_def) - }); + let bounds = lower_item_bounds(self); + let opaque_ty_def = hir::OpaqueTy { + hir_id: opaque_ty_hir_id, + def_id: opaque_ty_def_id, + bounds, + origin, + span: self.lower_span(opaque_ty_span), + }; + let opaque_ty_def = self.arena.alloc(opaque_ty_def); hir::TyKind::OpaqueDef(opaque_ty_def) } @@ -2084,7 +2062,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { // Construct an AnonConst where the expr is the "ty"'s path. - let parent_def_id = self.current_def_id_parent; + let parent_def_id = self.current_hir_id_owner.def_id; let node_id = self.next_node_id(); let span = self.lower_span(span); @@ -2108,9 +2086,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.arena.alloc(hir::AnonConst { def_id, hir_id, - body: this.with_def_id_parent(def_id, |this| { - this.lower_const_body(path_expr.span, Some(&path_expr)) - }), + body: this.lower_const_body(path_expr.span, Some(&path_expr)), span, }) }); @@ -2178,9 +2154,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::AnonConst { def_id, hir_id, - body: this.with_def_id_parent(def_id, |this| { - this.lower_const_body(c.value.span, Some(&c.value)) - }), + body: this.lower_const_body(c.value.span, Some(&c.value)), span: this.lower_span(c.value.span), } })) From d401a078e7839745c8e7d172527111134ad206dd Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 25 Nov 2024 18:50:20 +0100 Subject: [PATCH 4/4] update comment --- compiler/rustc_hir/src/def.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 3276f516a52a1..0b7ffc4af4590 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -109,7 +109,16 @@ pub enum DefKind { Use, /// An `extern` block. ForeignMod, - /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]` + /// Anonymous constant, e.g. the `1 + 2` in `[u8; 1 + 2]`. + /// + /// Not all anon-consts are actually still relevant in the HIR. We lower + /// trivial const-arguments directly to `hir::ConstArgKind::Path`, at which + /// point the definition for the anon-const ends up unused and incomplete. + /// + /// We do not provide any a `Span` for the definition and pretty much all other + /// queries also ICE when using this `DefId`. Given that the `DefId` of such + /// constants should only be reachable by iterating all definitions of a + /// given crate, you should not have to worry about this. AnonConst, /// An inline constant, e.g. `const { 1 + 2 }` InlineConst,