-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix anon const def-creation when macros are involved
Ever since #125915, some `ast::AnonConst`s turn into `hir::ConstArgKind::Path`s, which don't have associated `DefId`s. To deal with the fact that we don't have resolution information in `DefCollector`, we decided to implement a process where if the anon const *appeared* to be trivial (i.e., `N` or `{ N }`), we would avoid creating a def for it in `DefCollector`. If later, in AST lowering, we realized it turned out to be a unit struct literal, or we were lowering it to something that didn't use `hir::ConstArg`, we'd create its def there. However, let's say we have a macro `m!()` that expands to a reference to a free constant `FOO`. If we use `m!()` in the body of an anon const (e.g., `Foo<{ m!() }>`), then in def collection, it appears to be a nontrivial anon const and we create a def. But the macro expands to something that looks like a trivial const arg, but is not, so in AST lowering we "fix" the mistake we assumed def collection made and create a def for it. This causes a duplicate definition ICE. The long-term fix for this is to delay the creation of defs for all expression-like nodes until AST lowering (see #128844 for an incomplete attempt at this). This would avoid issues like this one that are caused by hacky workarounds. However, doing this uncovers a pre-existing bug with opaque types that is quite involved to fix (see #129023). In the meantime, this PR fixes the bug by delaying def creation for anon consts whose bodies are macro invocations until after we expand the macro and know what is inside it. This is accomplished by adding information to create the anon const's def to the data in `Resolver.invocation_parents`.
- Loading branch information
Showing
10 changed files
with
224 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
21 changes: 21 additions & 0 deletions
21
tests/ui/const-generics/early/trivial-const-arg-macro-nested.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//@ check-pass | ||
|
||
// This is a regression test for #128016. | ||
|
||
macro_rules! len_inner { | ||
() => { | ||
BAR | ||
}; | ||
} | ||
|
||
macro_rules! len { | ||
() => { | ||
len_inner!() | ||
}; | ||
} | ||
|
||
const BAR: usize = 0; | ||
|
||
fn main() { | ||
let val: [bool; len!()] = []; | ||
} |
13 changes: 13 additions & 0 deletions
13
tests/ui/const-generics/early/trivial-const-arg-macro-param.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
//@ check-pass | ||
|
||
macro_rules! len { | ||
($x:ident) => { | ||
$x | ||
}; | ||
} | ||
|
||
fn bar<const N: usize>() { | ||
let val: [bool; len!(N)] = [true; N]; | ||
} | ||
|
||
fn main() {} |
13 changes: 13 additions & 0 deletions
13
tests/ui/const-generics/early/trivial-const-arg-macro-res-error.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// This is a regression test for #128016. | ||
|
||
macro_rules! len { | ||
() => { | ||
target | ||
//~^ ERROR cannot find value `target` | ||
}; | ||
} | ||
|
||
fn main() { | ||
let val: [str; len!()] = []; | ||
//~^ ERROR the size for values | ||
} |
24 changes: 24 additions & 0 deletions
24
tests/ui/const-generics/early/trivial-const-arg-macro-res-error.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
error[E0425]: cannot find value `target` in this scope | ||
--> $DIR/trivial-const-arg-macro-res-error.rs:5:9 | ||
| | ||
LL | target | ||
| ^^^^^^ not found in this scope | ||
... | ||
LL | let val: [str; len!()] = []; | ||
| ------ in this macro invocation | ||
| | ||
= note: this error originates in the macro `len` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
||
error[E0277]: the size for values of type `str` cannot be known at compilation time | ||
--> $DIR/trivial-const-arg-macro-res-error.rs:11:14 | ||
| | ||
LL | let val: [str; len!()] = []; | ||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time | ||
| | ||
= help: the trait `Sized` is not implemented for `str` | ||
= note: slice and array elements must have `Sized` type | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
Some errors have detailed explanations: E0277, E0425. | ||
For more information about an error, try `rustc --explain E0277`. |
Oops, something went wrong.