You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Missing variables/fields give confusing error when name is the same as a built-in attribute like start or path #86290
This is because there is a builtin attribute #[start] that can be applied to a function to make it the entry point, which is what it resolves start to, since you have no variable shadowing it.
error[E0425]: cannot find value `bar` in this scope
--> src/lib.rs:8:13
|
8 | bar,
| ^^^ a field by this name exists in `Self`
For more information about this error, try `rustc --explain E0425`.
error: could not compile `playground` due to previous error
It seems to me that there is little point in saying “a field by this name exists”, since we're in a struct initializer — if there wasn't such a field, we'd be getting a different error. Or perhaps it would be helpful to say “a field by this name exists in Self, but there is no variable by this name to initialize it with; try writing bar: something_else_here”.
changed the title [-]Confusing error when populating a struct with a field called 'start' without an explicit value and a variable called start is not defined[/-][+]Missing variables/fields give confusing error when name is the same as a built-in attribute like `start` or `path`[/+]on Jun 20, 2026
The logic of the diagnostic is that if we cannot find a name in its expected namespace, then we try to find it in the 2 remaining namespaces.
We could also get something like "expected value, found enum E" or "expected value, found macro format" here.
Why are built-in attributes specifically problematic in this case? How are they different from the cases above?
I don't think we should change any logic here to special-case built-in attributes.
Maybe only tweak the wording to make it clear that we are searching for the same name in different namespaces.
@petrochenkov and I concluded that this is worth discussing a bit more broadly:
A possible wording for cross-namespace cases:
expected value, but a built-in attribute with the same name exists in another namespace
expected value, but an enum with the same name exists in another namespace
expected type, but a constant with the same name exists in another namespace
Same-namespace diagnostics, error codes, labels, suggestions, and resolution order would stay unchanged. The diagnostic branch would be selected when res.ns() differs from source.namespace().
I guess that part of the pause with respect to attributes is that it feels completely reasonable to accidentally use a type name, but since the attribute syntax requires so much extra wrapping, the attribute namespace feels totally unrelated. I would expect it to still say something along the lines of "name not defined (as a variable)" even if it mentions it found the attribute.
@clarfonthey Yeah, that distinction makes sense. The missing variable should stay front and center, and the attribute should only show up as extra context. Something like:
no value named path is defined in this scope
note: a built-in attribute named path exists in another namespace
Then we can use the same shape for the other cross-namespace cases. Is that closer to what you had in mind?
@clarfonthey Got it. Then the cross-namespace lookup should be purely additive: keep the ordinary missing-name diagnostic and all of its suggestions, and only add a note about the name found in another namespace.
Activity
mbartlett21 commentedon Jun 15, 2021
This is because there is a builtin attribute
#[start]that can be applied to a function to make it the entry point, which is what it resolvesstartto, since you have no variable shadowing it.jjl commentedon Jun 17, 2021
Ahh, gotcha. I don't think it's helpful to note that it found an attribute of that name, or at least it confused me.
kpreid commentedon Jul 23, 2022
If the field name does not happen to be an attribute, the note is less confusing but still unhelpful:
It seems to me that there is little point in saying “a field by this name exists”, since we're in a struct initializer — if there wasn't such a field, we'd be getting a different error. Or perhaps it would be helpful to say “a field by this name exists in
Self, but there is no variable by this name to initialize it with; try writingbar: something_else_here”.AnthonyMikh commentedon Aug 14, 2022
Hit it today with a code that can be minified to this:
Giving
In my case it was even more confusing because I was rearranging my code and I actually had a variable named
path, just in a nested scope.Interestingly enough, Rust prior to version 1.38.0 gives a more sensible error. For example, Rust 1.37.0 gives the following:
clarfonthey commentedon Jun 20, 2026
Want to call out that this is still happening in 2026: #158168 (comment)
[-]Confusing error when populating a struct with a field called 'start' without an explicit value and a variable called start is not defined[/-][+]Missing variables/fields give confusing error when name is the same as a built-in attribute like `start` or `path`[/+]TorinAsakura commentedon Jul 14, 2026
@rustbot claim
petrochenkov commentedon Jul 15, 2026
The logic of the diagnostic is that if we cannot find a name in its expected namespace, then we try to find it in the 2 remaining namespaces.
We could also get something like "expected value, found enum
E" or "expected value, found macroformat" here.Why are built-in attributes specifically problematic in this case? How are they different from the cases above?
I don't think we should change any logic here to special-case built-in attributes.
Maybe only tweak the wording to make it clear that we are searching for the same name in different namespaces.
TorinAsakura commentedon Jul 16, 2026
@petrochenkov and I concluded that this is worth discussing a bit more broadly:
A possible wording for cross-namespace cases:
Same-namespace diagnostics, error codes, labels, suggestions, and resolution order would stay unchanged. The diagnostic branch would be selected when res.ns() differs from source.namespace().
Does this wording look reasonable?
clarfonthey commentedon Jul 16, 2026
I guess that part of the pause with respect to attributes is that it feels completely reasonable to accidentally use a type name, but since the attribute syntax requires so much extra wrapping, the attribute namespace feels totally unrelated. I would expect it to still say something along the lines of "name not defined (as a variable)" even if it mentions it found the attribute.
TorinAsakura commentedon Jul 16, 2026
@clarfonthey Yeah, that distinction makes sense. The missing variable should stay front and center, and the attribute should only show up as extra context. Something like:
Then we can use the same shape for the other cross-namespace cases. Is that closer to what you had in mind?
clarfonthey commentedon Jul 16, 2026
Yes, except there should also be the usual "did you forget to define it?" caveat and the presence in another namespace shouldn't remove it.
TorinAsakura commentedon Jul 16, 2026
@clarfonthey Got it. Then the cross-namespace lookup should be purely additive: keep the ordinary missing-name diagnostic and all of its suggestions, and only add a note about the name found in another namespace.
Rollup merge of rust-lang#159307 - TorinAsakura:fix/builtin-attribute…
Unrolled build for #159307
Rollup merge of #159307 - TorinAsakura:fix/builtin-attribute-value-di…