-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Rust 'const iter' results in 'for'-errors #27639
Comments
For loops are expanded roughly like this: {
let result = match ::std::iter::IntoIterator::into_iter(<head>) {
mut iter => {
[opt_ident]: loop {
match ::std::iter::Iterator::next(&mut iter) {
::std::option::Option::Some(<pat>) => <body>,
::std::option::Option::None => break
}
}
}
};
result
} The use of the identifier "iter" in the expansion is somehow conflicting with the constant; a bug in the expansion code, I guess. |
I think macro expansion isn't hygienic with respect to identifiers in patterns when the identifier is also a const in the containing context (playpen): macro_rules! foo {
($ex:expr) => {
match $ex {
Some(ouch) => println!("{}", ouch),
None => println!("none")
}
}
}
pub fn main() {
const ouch: i32 = 123;
foo!(Some(567));
}
This is only an issue with consts; changing the |
Ah, that's probably because you can't use values of let bindings in patterns to begin with. |
It's likely because hygiene doesn't apply to item names and the names of constants are the only case where you can use a item as a pattern. The |
So is this not a bug? |
This is very much a bug. |
Instead of `ast::Ident`, bindings, paths and labels in HIR now keep a new structure called `hir::Ident` containing mtwt-renamed `name` and the original not-renamed `unhygienic_name`. `name` is supposed to be used by default, `unhygienic_name` is rarely used. This is not ideal, but better than the status quo for two reasons: - MTWT tables can be cleared immediately after lowering to HIR - This is less bug-prone, because it is impossible now to forget applying `mtwt::resolve` to a name. It is still possible to use `name` instead of `unhygienic_name` by mistake, but `unhygienic_name`s are used only in few very special circumstances, so it shouldn't be a problem. Besides name resolution `unhygienic_name` is used in some lints and debuginfo. `unhygienic_name` can be very well approximated by "reverse renaming" `token::intern(name.as_str())` or even plain string `name.as_str()`, except that it would break gensyms like `iter` in desugared `for` loops. This approximation is likely good enough for lints and debuginfo, but not for name resolution, unfortunately (see #27639), so `unhygienic_name` has to be kept. cc #29782 r? @nrc
having the following code
produces the following error:
Somehow defining the const 'iter' doesn't let rust build the iterator needed by the for-loop. I know, that renaming the const fixes this issue, but can someone explain this behavior to be, please?
Kind Regards,
BH16
The text was updated successfully, but these errors were encountered: