Fix name resolution in lexical scopes
Currently, `resolve_item_in_lexical_scope` does not check the "ribs" (type parameters and local variables). This can allow items that should be shadowed by type parameters to be named.
For example,
```rust
struct T { i: i32 }
fn f<T>() {
let t = T { i: 0 }; // This use of `T` resolves to the struct, not the type parameter
}
mod Foo {
pub fn f() {}
}
fn g<Foo>() {
Foo::f(); // This use of `Foo` resolves to the module, not the type parameter
}
```
This PR changes `resolve_item_in_lexical_scope` so that it fails when the item is shadowed by a rib (fixes#32120).
This is a [breaking-change], but it looks unlikely to cause breakage in practice.
r? @nikomatsakis
Forbid glob-importing from a type alias
This PR forbids glob-importing from a type alias or trait (fixes#30560):
```rust
type Alias = ();
use Alias::*; // This is currently allowed but shouldn't be
```
This is a [breaking-change]. Since the disallowed glob imports don't actually import anything, any breakage can be fixed by removing the offending glob import.
r? @alexcrichton
Fix a regression in import resolution
This fixes#32089 (caused by #31726) by deducing that name resolution has failed (as opposed to being determinate) in more cases.
r? @nikomatsakis
This PR privacy checks paths as they are resolved instead of in `librustc_privacy` (fixes#12334 and fixes#31779). This removes the need for the `LastPrivate` system introduced in PR #9735, the limitations of which cause #31779.
This PR also reports privacy violations in paths to intra- and inter-crate items the same way -- it always reports the first inaccessible segment of the path.
Since it fixes#31779, this is a [breaking-change]. For example, the following code would break:
```rust
mod foo {
pub use foo::bar::S;
mod bar { // `bar` should be private to `foo`
pub struct S;
}
}
impl foo::S {
fn f() {}
}
fn main() {
foo::bar::S::f(); // This is now a privacy error
}
```
r? @alexcrichton
This fixes a bug (#31845) introduced in #31105 in which lexical scopes contain items from all anonymous module ancestors, even if the path to the anonymous module includes a normal module:
```rust
fn f() {
fn g() {}
mod foo {
fn h() {
g(); // This erroneously resolves on nightly
}
}
}
```
This is a [breaking-change] on nightly but not on stable or beta.
r? @nikomatsakis
The standard library doesn't depend on rustc_bitflags, so move it to explicit
dependencies on all other crates. Additionally, the arena/fmt_macros deps could
be dropped from libsyntax.
The standard library doesn't depend on rustc_bitflags, so move it to explicit
dependencies on all other crates. Additionally, the arena/fmt_macros deps could
be dropped from libsyntax.
Now that #31461 is merged, a failing resolution can never become indeterminate or succeed, so we no longer have to keep trying to resolve failing import directives.
r? @nrc
This commit adds functionality that allows the name resolution pass
to search for entities (traits/types/enums/structs) by name, in
order to show recommendations along with the errors.
For now, only E0405 and E0412 have suggestions attached, as per the
request in bug #21221, but it's likely other errors can also benefit
from the ability to generate suggestions.
This commit adds functionality that allows the name resolution pass
to search for entities (traits/types/enums/structs) by name, in
order to show recommendations along with the errors.
For now, only E0405 and E0412 have suggestions attached, as per the
request in bug #21221, but it's likely other errors can also benefit
from the ability to generate suggestions.
This PR fixes two unrelated diagnostics bugs in resolve.
First, it reports privacy errors for an import only after the import resolution is determined, fixing #31402.
Second, it expands the per-module map from block ids to anonymous modules so that it also maps module declarations ids to modules, and it uses this map to in `with_scope` to fix#31644.
r? @nrc
r? @brson
cc @alexcrichton
I still need to add error code explanation test with this, but I can't figure out a way to generate the `.md` files in order to test example source codes.
Will fix#27328.
Refactor away resolve_name_in_module in resolve_imports.rs
Rewrite and improve the core name resolution procedure in NameResolution::result and Module::resolve_name
Refactor the duplicate checking code into NameResolution::try_define
This PR refactors away `Module`'s `external_module_children` and instead puts `extern crate` declarations in `children` like other items, simplifying duplicate checking and name resolution.
This PR also allows values to share a name with extern crates, which are only defined in the type namespace. Other than that, it is a pure refactoring.
r? @nrc
This fixes an ICE introduced by #31065 that occurs when a path cannot be resolved because of a certain class of unresolved import (`Indeterminate` imports).
For example, this currently causes an ICE:
```rust
mod foo { pub use self::*; }
fn main() { foo::f() }
```
r? @nrc
We no longer require `use` and `extern crate` items to precede other items in modules thanks to [RFC #385](https://github.com/rust-lang/rfcs/pull/385), but we still require `use` and `extern crate` items to precede statements in blocks (other items can appear anywhere in a block).
I think that this is a needless distinction between imports and other items that contradicts the intent of the RFC.
This commit removes the `-D warnings` flag being passed through the makefiles to
all crates to instead be a crate attribute. We want these attributes always
applied for all our standard builds, and this is more amenable to Cargo-based
builds as well.
Note that all `deny(warnings)` attributes are gated with a `cfg(stage0)`
attribute currently to match the same semantics we have today
This fixes#23880, a scoping bug in which items in a block are shadowed by local variables and type parameters that are in scope.
After this PR, an item in a block will shadow any local variables or type parameters above the item in the scope hierarchy. Items in a block will continue to be shadowed by local variables in the same block (even if the item is defined after the local variable).
This is a [breaking-change]. For example, the following code breaks:
```rust
fn foo() {
let mut f = 1;
{
fn f() {}
f += 1; // This will resolve to the function instead of the local variable
}
}
This fixes a bug in which items in a block are shadowed by local variables and type parameters that are in scope.
It is a [breaking-change]. For example, the following code breaks:
```rust
fn foo() {
let mut f = 1;
{
fn f() {}
f += 1; // This will now resolve to the function instead of the local variable
}
}
```
Any breakage can be fixed by renaming the item that is no longer shadowed.
This PR adds some minor error correction to the parser - if there is a missing ident, we recover and carry on. It also makes compilation more robust so that non-fatal errors (which is still most of them, unfortunately) in parsing do not cause us to abort compilation. The effect is that a program with a missing or incorrect ident can get all the way to type checking.
This commit removes the `-D warnings` flag being passed through the makefiles to
all crates to instead be a crate attribute. We want these attributes always
applied for all our standard builds, and this is more amenable to Cargo-based
builds as well.
Note that all `deny(warnings)` attributes are gated with a `cfg(stage0)`
attribute currently to match the same semantics we have today
I tried to add an inline `span_suggestion()` to the error as well, but since generics don't have their own span it becomes too fragile/complicated to work.
r? @steveklabnik
fixes#19477
Fix a bug allowing an item and an external crate to collide so long as the external crate is declared after the item. For example,
```rust
mod core { pub fn f() {} } // This would be an error if it followed the `extern crate`
extern crate core; // This declaration is shadowed by the preceding module
fn main() { core::f(); }
```
This is a [breaking-change], but it looks unlikely to cause breakage in practice, and any breakage can be fixed by removing colliding `extern crate` declarations, which are shadowed and hence unused.
Add note when item accessed from module via `m.i` rather than `m::i`.
(I tried to make this somewhat future-proofed, in that the `UnresolvedNameContext` could be expanded in the future with other cases besides paths that are known to be modules.)
This supersedes PR #30356 ; since I'm responsible for a bunch of new code here, someone else should review it. :)
This fixes a bug in which unused imports can get wrongly marked as used when checking for unused qualifications in `resolve_path` (issue #30078), and it removes unused imports that were previously undetected because of the bug.
We can now handle name resolution errors and get past type checking (if we're a bit lucky). This is the first step towards doing code completion for partial programs (we need error recovery in the parser and early access to save-analysis).
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 https://github.com/rust-lang/rust/issues/27639), so `unhygienic_name` has to be kept.
cc https://github.com/rust-lang/rust/issues/29782
r? @nrc
Fixes https://github.com/rust-lang/rust/issues/28692
Fixes https://github.com/rust-lang/rust/issues/28992
Fixes some other similar issues (see the tests)
[breaking-change], needs crater run (cc @brson or @alexcrichton )
The pattern with parens `UnitVariant(..)` for unit variants seems to be popular in rustc (see the second commit), but mostly used by one person (@nikomatsakis), according to git blame. If it causes breakage on crates.io I'll add an exceptional case for it.
Fixes#13677
This does the same sort of suggestion for misspelt macros that we already do for misspelt identifiers.
Example. Compiling this program:
```rust
macro_rules! foo {
($e:expr) => ( $e )
}
fn main() {
fob!("hello!");
}
```
gives the following error message:
```
/Users/mcp/temp/test.rs:7:5: 7:8 error: macro undefined: 'fob!'
/Users/mcp/temp/test.rs:7 fob!("hello!");
^~~
/Users/mcp/temp/test.rs:7:5: 7:8 help: did you mean `foo`?
/Users/mcp/temp/test.rs:7 fob!("hello!");
```
I had to move the levenshtein distance function into libsyntax for this. Maybe this should live somewhere else (some utility crate?), but I couldn't find a crate to put it in that is imported by libsyntax and the other rustc crates.
Replace `TypeNsDef` and `ValueNsDef` with a more general type `NsDef`.
Define a newtype `NameBinding` for `Rc<RefCell<Option<NsDef>>>` and refactor `NameBindings` to be a `NameBinding` for each namespace.
Replace uses of `NameBindings` with `NameBinding` where only one binding is being used (in `NamespaceResult`, `Target,` etc).
Refactor away `resolve_definition_of_name_in_module` and `NameDefinition`, fixing issue #4952.
[breaking change]
I'm not sure if those renames are ok. [TokenType::Tt* to TokenType::*](https://github.com/rust-lang/rust/pull/29582) was obvious, but for all those Item-enums it's less obvious to me what the right way forward is due to the underscore.
The command-line error message for E0432 does mention the possibility of missing the `extern crate` declaration, but the detailed error message for it doesn't.
Fixes#29517.
Change build_reduced_graph.rs so the fields def and module of NsDef are never both Some unless the NsDef represents a duplicate definition (see issue 26421).
Define a newtype `NameBinding` for `Rc<RefCell<Option<NsDef>>>` and refactor `NameBindings` to be a `NameBinding` for each namespace.
Replace uses of `NameBindings` with `NameBinding` where only one binding is being used (in `NamespaceResult`, `Target,` etc).
Refactor away `resolve_definition_of_name_in_module` and `NameDefinition`.
The command-line error message for E0432 does mention the possibility of
missing the `extern crate` declaration, but the detailed error message
for it doesn't.
Fixes#29517.
`resolve_identifier` used to mark a variable as an upvar when used within a closure. However, the function is also used for the "unnecessary qualification" lint, which would mark paths whose last component had the same name as a local as upvars.
Fixes#29522
r? @eddyb
This commit stabilizes and deprecates library APIs whose FCP has closed in the
last cycle, specifically:
Stabilized APIs:
* `fs::canonicalize`
* `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists,
is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait.
* `Formatter::fill`
* `Formatter::width`
* `Formatter::precision`
* `Formatter::sign_plus`
* `Formatter::sign_minus`
* `Formatter::alternate`
* `Formatter::sign_aware_zero_pad`
* `string::ParseError`
* `Utf8Error::valid_up_to`
* `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}`
* `<[T]>::split_{first,last}{,_mut}`
* `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated
but will be once 1.5 is released.
* `str::{R,}MatchIndices`
* `str::{r,}match_indices`
* `char::from_u32_unchecked`
* `VecDeque::insert`
* `VecDeque::shrink_to_fit`
* `VecDeque::as_slices`
* `VecDeque::as_mut_slices`
* `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`)
* `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`)
* `Vec::resize`
* `str::slice_mut_unchecked`
* `FileTypeExt`
* `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}`
* `BinaryHeap::from` - `from_vec` deprecated in favor of this
* `BinaryHeap::into_vec` - plus a `Into` impl
* `BinaryHeap::into_sorted_vec`
Deprecated APIs
* `slice::ref_slice`
* `slice::mut_ref_slice`
* `iter::{range_inclusive, RangeInclusive}`
* `std::dynamic_lib`
Closes#27706Closes#27725
cc #27726 (align not stabilized yet)
Closes#27734Closes#27737Closes#27742Closes#27743Closes#27772Closes#27774Closes#27777Closes#27781
cc #27788 (a few remaining methods though)
Closes#27790Closes#27793Closes#27796Closes#27810
cc #28147 (not all parts stabilized)
Currently it is possible to do the following:
- define a module named `Foo` and then a unit or tuple struct also named `Foo`
- define any struct named `Foo` and then a module named `Foo`
This commit introduces a warning for both of these cases.
paths, and construct paths for all definitions. Also, stop rewriting
DefIds for closures, and instead just load the closure data from
the original def-id, which may be in another crate.
Make sure Name, SyntaxContext and Ident are passed by value
Make sure Idents don't serve as keys (or parts of keys) in maps, Ident comparison is not well defined
Since enums are namespaced now, should we also remove the `Fk` prefixes from `FnKind` and remove the reexport? (The reexport must be removed because otherwise it clashes with glob imports containing `ItemFn`). IMO writing `FnKind::Method` is much clearer than `FkMethod`.
In order to test the validity of identifiers, exposing the name resolution module is necessary. Other changes mostly comprise of exposing modules publicly like parts of save-analysis, so they can be called appropriately.
As noted in my previous PR #27439 , the import resolution algorithm has two cases where it bails out:
- The algorithm will delay an import if the module containing the target of the import still has unresolved glob imports
- The algorithm will delay a glob import of the target module still has unresolved imports
This PR alters the behaviour to only bail out when the above described unresolved imports are `pub`, as non-pub imports don't affect the result anyway.
It is still possible to fail the algorithm with examples like
```rust
pub mod a {
pub use b::*;
}
pub mod b {
pub use a::*;
}
```
but such configurations cannot be resolved in any meaningful way, as these are cyclic imports.
Closes#4865
(This is a second try at #26242. This time I think things should be ok.)
The current algorithm handling import resolutions works sequentially, handling imports in the order they appear in the source file, and blocking/bailing on the first one generating an error/being unresolved.
This can lead to situations where the order of the `use` statements can make the difference between "this code compiles" and "this code fails on an unresolved import" (see #18083 for example). This is especially true when considering glob imports.
This PR changes the behaviour of the algorithm to instead try to resolve all imports in a module. If one fails, it is recorded and the next one is tried (instead of directly giving up). Also, all errors generated are stored (and not reported directly).
The main loop of the algorithms guaranties that the algorithm will always finish: if a round of resolution does not resolve anything new, we are stuck and give up. At this point, the new version of the algorithm will display all errors generated by the last round of resolve. This way we are sure to not silence relevant errors or help messages, but also to not give up too early.
**As a consequence, the import resolution becomes independent of the order in which the `use` statements are written in the source files.** I personally don't see any situations where this could be a problem, but this might need some thought.
I passed `rpass` and `cfail` tests on my computer, and now am compiling a full stage2 compiler to ensure the crates reporting errors in my previous attempts still build correctly. I guess once I have checked it, this will need a crater run?
Fixes#18083.
r? @alexcrichton , cc @nrc @brson
Most errors generated by resolve might be caused by
not-yet-resolved glob imports. This changes the behavior of the
resolve imports algorithms to not fail prematurally on first
error, but instead buffer intermediate errors and report them
only when stuck.
Fixes#18083
This is a resubmission of my previous git failure - apologies. Just fixing up a wording error that was discovered in E0253 after the r.
r? @Manishearth
This commit shards the all-encompassing `core`, `std_misc`, `collections`, and `alloc` features into finer-grained components that are much more easily opted into and tracked. This reflects the effort to push forward current unstable APIs to either stabilization or removal. Keeping track of unstable features on a much more fine-grained basis will enable the library subteam to quickly analyze a feature and help prioritize internally about what APIs should be stabilized.
A few assorted APIs were deprecated along the way, but otherwise this change is just changing the feature name associated with each API. Soon we will have a dashboard for keeping track of all the unstable APIs in the standard library, and I'll also start making issues for each unstable API after performing a first-pass for stabilization.
Currently in the E0252 message, traits and modules are all called types (as in "a type named `Foo` has already been imported", even when `Foo` was a trait or module). This commit changes that to additionally detect when the import in question is a trait or module and report it accordingly.
Fixes#25396.
Currently in the E0252 message, traits and modules are all called types
(as in "a type named `Foo` has already been imported", even when `Foo` was
a trait or module). This commit changes that to additionally detect when
the import in question is a trait or module and report it accordingly.
Fixes#25396.
Previously, it said "import `Foo` conflicts with existing submodule" even
when it was a type alias, enum, or trait. The message now says the conflict
is with "type in this module" in the case of the first two, and "trait in
this module" for the last one.
Fixes#24081.
- add feature gate
- add basic tests
- adjust parser to eliminate conflict between `const fn` and associated
constants
- allow `const fn` in traits/trait-impls, but forbid later in type check
- correct some merge conflicts
This fixes#24922 and #25017, and reduces the number of error messages that talk about "methods" when associated constants rather than methods are involved.
I will admit that I haven't thought very carefully about the error messages. My goal has been to make more of the messages technically correct in all situations, and to avoid ICEs. But in some cases we could probably talk specifically about "methods" rather than "items".
Add diagnostic message for E0317, E0154, E0259 and E0260; part of #24407.
About E0317, I was unsure if I should add an example of what could be wrong, such as `struct i64`, `enum char { A, B }` or `type isize = i64`. I decided against it, since the diagnostic message looks clear enough to me.
What do you think?
It is currently broken to use syntax such as `<T as Foo>::U::static_method()` where `<T as Foo>::U` is an associated type. I was able to fix this and simplify the parser a bit at the same time.
This also fixes the corresponding issue with associated types (#22139), but that's somewhat irrelevant because #22519 is still open, so this syntax still causes an error in type checking.
Similarly, although this fix applies to associated consts, #25046 forbids associated constants from using type parameters or `Self`, while #19559 means that associated types have to always have one of those two. Therefore, I think that you can't use an associated const from an associated type anyway.