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
Copy file name to clipboardExpand all lines: src/macros-by-example.md
+42-5
Original file line number
Diff line number
Diff line change
@@ -416,11 +416,46 @@ by other crates, either by path or by `#[macro_use]` as described above.
416
416
r[macro.decl.hygiene]
417
417
418
418
r[macro.decl.hygiene.intro]
419
-
By default, all identifiers referred to in a macro are expanded as-is, and are
420
-
looked up at the macro's invocation site. This can lead to issues if a macro
421
-
refers to an item or macro which isn't in scope at the invocation site. To
422
-
alleviate this, the `$crate` metavariable can be used at the start of a path to
423
-
force lookup to occur inside the crate defining the macro.
419
+
Macros by example have _mixed-site hygiene_. This means that [loop labels], [block labels], and local variables are looked up at the macro definition site while other symbols are looked up at the macro invocation site. For example:
420
+
421
+
```rust
422
+
letx=1;
423
+
fnfunc() {
424
+
unreachable!("this is never called")
425
+
}
426
+
427
+
macro_rules!check {
428
+
() => {
429
+
assert_eq!(x, 1); // Uses `x` from the definition site.
430
+
func(); // Uses `func` from the invocation site.
431
+
};
432
+
}
433
+
434
+
{
435
+
letx=2;
436
+
fnfunc() { /* does not panic */ }
437
+
check!();
438
+
}
439
+
```
440
+
441
+
Labels and local variables defined in macro expansion are not shared between invocations, so this code doesn’t compile:
442
+
443
+
```rust,compile_fail,E0425
444
+
macro_rules! m {
445
+
(define) => {
446
+
let x = 1;
447
+
};
448
+
(refer) => {
449
+
dbg!(x);
450
+
};
451
+
}
452
+
453
+
m!(define);
454
+
m!(refer);
455
+
```
456
+
457
+
r[macro.decl.hygiene.crate]
458
+
A special case is the `$crate` metavariable. It refers to the crate defining the macro, and can be used at the start of the path to look up items or macros which are not in scope at the invocation site.
424
459
425
460
<!-- ignore: requires external crates -->
426
461
```rust,ignore
@@ -565,6 +600,7 @@ expansions, taking separators into account. This means:
0 commit comments