Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 4 additions & 52 deletions src/items/use-declarations.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ They may create bindings for:
* [Built-in types]
* [Attributes]
* [Derive macros]
* [Macros by example]

r[items.use.path.disallowed]
They cannot import [associated items], [generic parameters], [local variables], paths with [`Self`], or [tool attributes]. More restrictions are described below.
Expand Down Expand Up @@ -389,58 +390,9 @@ r[items.use.restrictions.variant]
use TypeAlias::MyVariant; //~ ERROR
```

r[items.use.ambiguities]
## Ambiguities

> [!NOTE]
> This section is incomplete.

r[items.use.ambiguities.intro]
Some situations are an error when there is an ambiguity as to which name a `use` declaration refers. This happens when there are two name candidates that do not resolve to the same entity.

r[items.use.ambiguities.glob]
Glob imports are allowed to import conflicting names in the same namespace as long as the name is not used.
For example:

```rust
mod foo {
pub struct Qux;
}

mod bar {
pub struct Qux;
}

use foo::*;
use bar::*; //~ OK, no name conflict.

fn main() {
// This would be an error, due to the ambiguity.
//let x = Qux;
}
```

Multiple glob imports are allowed to import the same name, and that name is allowed to be used, if the imports are of the same item (following re-exports). The visibility of the name is the maximum visibility of the imports. For example:

```rust
mod foo {
pub struct Qux;
}

mod bar {
pub use super::foo::Qux;
}

// These both import the same `Qux`. The visibility of `Qux`
// is `pub` because that is the maximum visibility between
// these two `use` declarations.
pub use bar::*;
use foo::*;

fn main() {
let _: Qux = Qux;
}
```
TODO mention ambiguities and link to name-res. Moved to name-res because
ambiguities are fundamentally a product of the place of use, not the use
declaration.

[`extern crate`]: extern-crates.md
[`macro_rules`]: ../macros-by-example.md
Expand Down
41 changes: 41 additions & 0 deletions src/macros-by-example.md
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: come back and add a section mentioning the macro-related ambiguity errors and linking to the name-res chapter

Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,28 @@ fn foo() {
// m!(); // Error: m is not in scope.
```

* textual scope name bindings for macros may shadow path-based scope bindings
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this get a rule?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems so, yes.

to macros

```rust
macro_rules! m {
() => {
println!("m");
};
}

#[macro_export]
macro_rules! m2 {
() => {
println!("m2");
};
}

use crate::m2 as m;

m!(); // prints "m\n"
```

<!-- template:attributes -->
r[macro.decl.scope.macro_use]
### The `macro_use` attribute
Expand Down Expand Up @@ -480,6 +502,25 @@ By default, macros only have [textual scope][macro.decl.scope.textual] and canno
> # fn main() {}
> ```

r[macro.decl.scope.path.reexport]

* macros can be re-exported to give them path-based scope from a module other than the crate root.
* there's some visibility stuff here that may already be mentioned
elsewhere. I'm pretty sure that w/o a #[macro_export] the macro being
re-exported is implicitly pub(crate) and with one it is implicitly pub.
The later is mentioned below, don't remember where I saw the former.

```
mac::m!(); // OK: Path-based lookup finds m in the mac module.

mod mac {
macro_rules! m {
() => {};
}
pub(crate) use m;
}
```

r[macro.decl.scope.macro_export.export]
The `macro_export` attribute causes a macro to be exported from the crate root so that it can be referred to in other crates by path.

Expand Down
Loading
Loading