-
Notifications
You must be signed in to change notification settings - Fork 12.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #51457 - petrochenkov:hygnoparent, r=<try>
hygiene: Eliminate expansion hierarchy in favor of call-site hierarchy "Expansion hierarchy" and "call-site hierarchy" are two slightly different ways to nest macro invocations and answer the question "who is the parent" for a given invocation. For example, here both hierarchies coincide ```rust macro inner() { ... } macro outer() { inner!() } outer!(); // expansions: root -> outer -> inner // call-sites: root -> outer -> inner ``` but here they are different ```rust macro inner() { ... } macro outer($stuff: stuff) { $stuff } // expansions: root -> outer -> inner (`inner` is expanded as a part of `outer`'s output) // call-sites: root -> outer; root -> inner outer!(inner!()) ``` All our talk about hygiene was in terms of "def-site" and "call-site" name resolution so far and the "expansion hierarchy" is an internal detail, but it was actually used in few places in the way affecting resolution results. For example, in the attached test case the structure `S` itself was previously resolved succesfully, but resolution of its field `field` failed due to use of "expansion hierarchy". This PR eliminates expansion hierarchy from hygiene algorithm and uses call-site hierarchy instead. This is also a nice simplification of the model. Instead of growing in *three* dimensions in similar but subtly different ways (def-site, call-site, expansion) hygiene hierarchies now grow in *two* dimensions in similar but subtly different ways (def-site, call-site).
- Loading branch information
Showing
11 changed files
with
77 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
src/test/ui/hygiene/call-site-parent-vs-expansion-parent.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// compile-pass | ||
|
||
#![feature(decl_macro)] | ||
|
||
macro_rules! define_field { | ||
() => { | ||
struct S { field: u8 } | ||
}; | ||
($field: ident) => { | ||
struct Z { $field: u8 } | ||
}; | ||
} | ||
|
||
mod modern { | ||
macro use_field($define_field1: item, $define_field2: item) { | ||
$define_field1 | ||
$define_field2 | ||
|
||
// OK, both struct name `S` and field `name` resolve to definitions | ||
// produced by `define_field` and living in the "root" context | ||
// that is in scope at `use_field`'s def-site. | ||
fn f() { S { field: 0 }; } | ||
fn g() { Z { field: 0 }; } | ||
} | ||
|
||
use_field!(define_field!{}, define_field!{ field }); | ||
} | ||
|
||
mod legacy { | ||
macro_rules! use_field {($define_field1: item, $define_field2: item) => { | ||
$define_field1 | ||
$define_field2 | ||
|
||
// OK, everything is at the same call-site. | ||
fn f() { S { field: 0 }; } | ||
fn g() { Z { field: 0 }; } | ||
}} | ||
|
||
use_field!(define_field!{}, define_field!{ field }); | ||
} | ||
|
||
fn main() {} |