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
Some situations are an error when there is an ambiguity as to which macro definition, `use` declaration, or module an import or macro invocation's name refers to. This happens when there are two name candidates that do not resolve to the same entity where neither candidate is [permitted] to shadow the other.
151
-
152
-
TODO rewrite
150
+
There are certain situations during expansion-time resolution where there are multiple macro definitions, `use` declarations, or modules an import or macro invocation's name could refer to where the compiler cannot consistently determine which candidate should shadow the other. Shadowing cannot be permitted in these situations and the compiler instead emits ambiguity errors.
Names may not be resolved through ambiguous glob imports. Glob imports are allowed to import conflicting names in the same namespace as long as the name is not used. Names with conflicting candidates from ambiguous glob imports may still be shadowed by non-glob imports and used without producing an error. The errors occur at time of use, not time of import.
@@ -165,11 +163,13 @@ mod m2 {
165
163
pub struct Ambig;
166
164
}
167
165
166
+
// OK: This brings conficting names into scope and namespace
167
+
// but they have not been used yet.
168
168
use m1::*;
169
-
use m2::*; // OK: No name conflict.
169
+
use m2::*;
170
170
171
171
fn ambiguous_use() {
172
-
let x = Ambig; // ERROR: `Ambig` is ambiguous
172
+
let x = Ambig; // ERROR: `Ambig` is ambiguous.
173
173
}
174
174
```
175
175
@@ -199,38 +199,44 @@ mod m1 {
199
199
}
200
200
201
201
modm2 {
202
+
// This re-exports the same `Ambig` item through a second module.
202
203
pubusesuper::m1::Ambig;
203
204
}
204
205
205
-
// These both import the same `Ambig`. The visibility of `Ambig` is
206
-
// `pub` because that is the maximum visibility between these two `use`
207
-
// declarations.
208
-
pubusem2::*;
209
-
usem1::*;
206
+
// These both import the same `Ambig`.
207
+
//
208
+
// The visibility of `Ambig` is `pub` because that is the
209
+
// maximum visibility between these two `use` declarations.
210
+
modm3 {
211
+
pubusesuper::m1::*;
212
+
usesuper::m2::*;
213
+
}
210
214
211
215
fnmain() {
212
-
let_:Ambig=Ambig;
216
+
// `Ambig` can be used through the m3
217
+
// globs and still has `pub` visibility.
218
+
let_=m3::Ambig;
213
219
}
214
220
```
215
-
// TODO update example to rely upon visibilty for compilation success
Names may not be resolved through glob imports when there is another candidate available in an [outer scope].
223
+
Names in imports and macro invocations may not be resolved through glob imports when there is another candidate available in an [outer scope].
219
224
220
225
```rust,compile_fail,E0659
221
226
mod glob {
222
227
pub mod ambig {
223
-
// ^-- glob `ambig` candidate
224
228
pub struct Name;
225
229
}
226
230
}
227
231
232
+
// Outer `ambig` candidate.
228
233
pub mod ambig {
229
-
// ^-- outer `ambig` candidate
230
234
pub struct Name;
231
235
}
232
236
233
237
const _: () = {
238
+
// Cannot resolve `ambig` through this glob
239
+
// because of the outer `ambig` candidate above.
234
240
use glob::*;
235
241
use ambig::Name; // ERROR: `ambig` is ambiguous.
236
242
};
@@ -258,7 +264,7 @@ const _: () = {
258
264
```
259
265
260
266
> [!NOTE]
261
-
> These ambiguity errors are specific to imports, even though they are only observed when those imports are used. Having multiple candidates available for a given name during later stages of resolution is not considered an error. So long as none of the imports themselves are ambiguous, there will always be a single unambiguous closest resolution.
267
+
> These ambiguity errors are specific to expansion-time resolution. Having multiple candidates available for a given name during later stages of resolution is not considered an error. So long as none of the imports themselves are ambiguous, there will always be a single unambiguous closest resolution.
Name bindings from macro expansions may not shadow name bindings from outside of those expansions.
357
+
Names may not be resolved through ambiguous candidates inside of macro expansions. Candidates inside of macro expansions are ambiguous when they would shadow a candidate for the same name from outside of the first candidate's macro expansion and the invocation of the name being resolved is also from outside of the first candidate's macro expansion.
349
358
350
359
```rust,compile_fail,E0659
351
-
macro_rules! name {
360
+
macro_rules! define_ambig {
361
+
() => {
362
+
macro_rules! ambig {
363
+
() => {}
364
+
}
365
+
}
366
+
}
367
+
368
+
// Introduce outer candidate definition for `ambig` macro invocation.
369
+
macro_rules! ambig {
370
+
() => {}
371
+
}
372
+
373
+
// Introduce a second candidate definition for `ambig` inside of a macro
374
+
// expansion.
375
+
define_ambig!();
376
+
377
+
// The definition of `ambig` from the second invocation
378
+
// of `define_ambig` is the innermost canadidate.
379
+
//
380
+
// The definition of `ambig` from the first invocation of `define_ambig`
381
+
// is the second candidate.
382
+
//
383
+
// The compiler checks that the first candidate is inside of a macro
384
+
// expansion, that the second candidate is not from within the same
385
+
// macro expansion, and that the name being resolved is not from
386
+
// within the same macro expansion.
387
+
ambig!(); // ERROR: `ambig` is ambiguous.
388
+
```
389
+
390
+
The reverse is not considered ambiguous.
391
+
392
+
```rust
393
+
# macro_rules!define_ambig {
394
+
# () => {
395
+
# macro_rules!ambig {
396
+
# () => {}
397
+
# }
398
+
# }
399
+
# }
400
+
// Swap order of definitions.
401
+
define_ambig!();
402
+
macro_rules!ambig {
352
403
() => {}
353
404
}
405
+
// The innermost candidate is now less expanded so it may shadow more
406
+
// the macro expanded definition above it.
407
+
ambig!();
408
+
```
409
+
410
+
Nor is it ambiguous if the invocation being resolved is within the innermost candidate's expansion.
354
411
355
-
macro_rules! define_name {
412
+
```rust
413
+
macro_rules!ambig {
414
+
() => {}
415
+
}
416
+
417
+
macro_rules!define_and_invoke_ambig {
356
418
() => {
357
-
macro_rules! name {
419
+
// Define innermost candidate.
420
+
macro_rules!ambig {
358
421
() => {}
359
422
}
423
+
424
+
// Invocation of `ambig` is in the same expansion as the
425
+
// innermost candidate.
426
+
ambig!(); // OK
360
427
}
361
428
}
362
429
363
-
fn f() {
364
-
define_name!();
365
-
name!(); // ERROR: `name` is ambiguous.
430
+
define_and_invoke_ambig!();
431
+
```
432
+
433
+
It doesn't matter if both definitions come from invocations of the same macro, the outermost candidate is still considered "less expanded" because it is not within the expansion containing the innermost candidate's definition.
434
+
435
+
```rust,compile_fail,E0659
436
+
# macro_rules! define_ambig {
437
+
# () => {
438
+
# macro_rules! ambig {
439
+
# () => {}
440
+
# }
441
+
# }
442
+
# }
443
+
define_ambig!();
444
+
define_ambig!();
445
+
ambig!(); // ERROR: `ambig` is ambiguous.
446
+
```
447
+
448
+
This also applies to imports, so long as the innermost candidate for the invocation of name is from within a macro expansion.
0 commit comments