Skip to content

Commit ebe69dc

Browse files
committed
Expand name resolution stub
1 parent e122eef commit ebe69dc

File tree

5 files changed

+439
-53
lines changed

5 files changed

+439
-53
lines changed

src/items/use-declarations.md

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ They may create bindings for:
116116
* [Built-in types]
117117
* [Attributes]
118118
* [Derive macros]
119+
* [Macros by example]
119120

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

392-
r[items.use.ambiguities]
393-
## Ambiguities
394-
395-
> [!NOTE]
396-
> This section is incomplete.
397-
398-
r[items.use.ambiguities.intro]
399-
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.
400-
401-
r[items.use.ambiguities.glob]
402-
Glob imports are allowed to import conflicting names in the same namespace as long as the name is not used.
403-
For example:
404-
405-
```rust
406-
mod foo {
407-
pub struct Qux;
408-
}
409-
410-
mod bar {
411-
pub struct Qux;
412-
}
413-
414-
use foo::*;
415-
use bar::*; //~ OK, no name conflict.
416-
417-
fn main() {
418-
// This would be an error, due to the ambiguity.
419-
//let x = Qux;
420-
}
421-
```
422-
423-
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:
424-
425-
```rust
426-
mod foo {
427-
pub struct Qux;
428-
}
429-
430-
mod bar {
431-
pub use super::foo::Qux;
432-
}
433-
434-
// These both import the same `Qux`. The visibility of `Qux`
435-
// is `pub` because that is the maximum visibility between
436-
// these two `use` declarations.
437-
pub use bar::*;
438-
use foo::*;
439-
440-
fn main() {
441-
let _: Qux = Qux;
442-
}
443-
```
393+
TODO mention ambiguities and link to name-res. Moved to name-res because
394+
ambiguities are fundamentally a product of the place of use, not the use
395+
declaration.
444396

445397
[`extern crate`]: extern-crates.md
446398
[`macro_rules`]: ../macros-by-example.md
@@ -460,3 +412,4 @@ fn main() {
460412
[tool attributes]: ../attributes.md#tool-attributes
461413
[type alias]: type-aliases.md
462414
[type namespace]: ../names/namespaces.md
415+
[macro.decl.scope.path.ambiguity]: ../macros-by-example.md#macro.decl.scope.path.ambiguity

src/macros-by-example.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,50 @@ fn foo() {
326326
// m!(); // Error: m is not in scope.
327327
```
328328

329+
* textual scope name bindings for macros may shadow path-based scope bindings
330+
to macros
331+
332+
```rust
333+
macro_rules! m {
334+
() => {
335+
println!("m");
336+
};
337+
}
338+
339+
#[macro_export]
340+
macro_rules! m2 {
341+
() => {
342+
println!("m2");
343+
};
344+
}
345+
346+
use crate::m2 as m;
347+
348+
m!(); // prints "m\n"
349+
```
350+
351+
r[macro.decl.scope.textual.ambiguity.moreexpandedvsouter]
352+
* it is an error for name bindings from macro expansions to shadow name bindings from outside of those expansions
353+
354+
```rust
355+
macro_rules! name {
356+
() => {}
357+
}
358+
359+
macro_rules! define_name {
360+
() => {
361+
macro_rules! name {
362+
() => {}
363+
}
364+
}
365+
}
366+
367+
fn foo() {
368+
define_name!();
369+
name!(); // ERROR `name` is ambiguous
370+
}
371+
```
372+
329373
<!-- template:attributes -->
330374
r[macro.decl.scope.macro_use]
331375
### The `macro_use` attribute
@@ -480,6 +524,49 @@ By default, macros only have [textual scope][macro.decl.scope.textual] and canno
480524
> # fn main() {}
481525
> ```
482526
527+
r[macro.decl.scope.path.reexport]
528+
529+
* macros can be re-exported to give them path-based scope from a module other than the crate root.
530+
* there's some visibility stuff here that may already be mentioned
531+
elsewhere. I'm pretty sure that w/o a #[macro_export] the macro being
532+
re-exported is implicitly pub(crate) and with one it is implicitly pub.
533+
The later is mentioned below, don't remember where I saw the former.
534+
535+
```
536+
mac::m!(); // OK: Path-based lookup finds m in the mac module.
537+
538+
mod mac {
539+
macro_rules! m {
540+
() => {};
541+
}
542+
pub(crate) use m;
543+
}
544+
```
545+
546+
r[macro.decl.scope.path.ambiguity]
547+
* path-based scope bindings for macros may not shadow textual scope bindings to macros
548+
* This is sort of an intersection between macros and imports, because at
549+
least in stable rust you can only get path-based macro resolutions from
550+
imports of mbe macros (and presumably from proc macro crates), but you
551+
can only get textual scope of macros from macro declarations
552+
* https://doc.rust-lang.org/nightly/reference/names/namespaces.html#r-names.namespaces.sub-namespaces.use-shadow
553+
554+
```rust
555+
#[macro_export]
556+
macro_rules! m2 {
557+
() => {}
558+
}
559+
560+
macro_rules! m {
561+
() => {}
562+
}
563+
564+
pub fn foo() {
565+
m!(); // ERROR `m` is ambiguous
566+
use crate::m2 as m;
567+
}
568+
```
569+
483570
r[macro.decl.scope.macro_export.export]
484571
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.
485572

0 commit comments

Comments
 (0)