diff options
| author | bors <bors@rust-lang.org> | 2016-11-27 23:32:57 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-11-27 23:32:57 -0600 |
| commit | 0b399e5e99a44cf44d3860d353a8b7619d466410 (patch) | |
| tree | 05970fb630a5d97e49e9a6f4230c70696cff2a4c /src/libsyntax | |
| parent | c7ddb8946bf041d89ba109ec8dd754492de78606 (diff) | |
| parent | 372c6df564616dd461b82def5d75428940ca04ae (diff) | |
| download | rust-0b399e5e99a44cf44d3860d353a8b7619d466410.tar.gz rust-0b399e5e99a44cf44d3860d353a8b7619d466410.zip | |
Auto merge of #37676 - eddyb:lazy-7, r=nikomatsakis
[7/n] rustc: desugar UFCS in HIR and don't use DefMap for associated resolutions.
_This is part of a series ([prev](https://github.com/rust-lang/rust/pull/37412) | [next](https://github.com/rust-lang/rust/pull/37688)) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well.
If any motivation is unclear, please ask for additional PR description clarifications or code comments._
<hr>
Previously, a path like `T::Assoc::method`, while equivalent to `<<T>::Assoc>::method`, wasn't desugared in any way at the HIR level and everything inspecting it had to either deal with knowing only `T` (before typeck) or knowing only the definition of `method` (after typeck).
Such a path also had only one `NodeId` and associated resolution during typeck modified `DefMap`, in a way that would be hard for incremental recompilation to track, and inconvenient for partial type conversions from HIR to `Ty`, which are required to break faux-cycles in on-demand type collection.
The desugarings performed by this PR are as follows:
* `use a::{b,c};` is flattened to `use a as _; use a::b; use a::c;`
* as resolution is complete, `use a as _;` doesn't do anything, except get checked for stability
* `Vec::new` (an expression) becomes `Vec<..>::new<..>`, to distinguish it from `<Vec>::new<..>`
* the "infer all parameters" `<..>` form is internal and not even pretty-printed
* used when there are no type parameters at all, in an expression or pattern path segment
* `T::A::B` becomes `<<T>::A>::B` in a type, and `<<T<..>>::A<..>>::B<..>` in an expression/pattern
* one additional `hir::Ty` node is created for each prefix, starting with the fully-resolved type (`T`) and extending it with each segment (e.g. `<T>::A`)
* fully-resolved paths contain their `Def` in HIR, getting rid of the `DefMap` and absolving incremental recompilation of needing to manually look up nodes to handle that side information
Not keeping the `DefMap` around meant that associated resolutions had to be stored somewhere else:
* expressions and patterns use a new `NodeId -> Def` map in `ty::Tables`
* compatible with the future per-body (constant / `fn` / closure) `Tables`
* types are accessible via `Ty` and the usual per-item generics / predicates / type
* `rustdoc` and `save-analysis` are the only situations which insist on mapping syntactical types to semantical ones, or at least understand the resolution of associated types, therefore the type conversion cache, i.e. a `NodeId -> Ty` map, is exposed by typeck for this purpose
* stability had to be split into a pass that runs on HIR and checks the results of name resolution, and impromptu checks triggered by `typeck` for associated paths, methods, fields, etc.
* privacy using semantic types results in accurate reachability for `impl Trait`, which fixes #35870, and thorough introspection of associated types, which may allow relaxing private-in-public checking on bounds, while keeping the intended ban on projections with private type parameters
cc @petrochenkov
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/codemap.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 7 |
2 files changed, 10 insertions, 5 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 3cdfa718eab..12ce6428911 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -51,6 +51,8 @@ pub enum ExpnFormat { MacroAttribute(Name), /// e.g. `format!()` MacroBang(Name), + /// Desugaring done by the compiler during HIR lowering. + CompilerDesugaring(Name) } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] @@ -105,8 +107,9 @@ pub struct NameAndSpan { impl NameAndSpan { pub fn name(&self) -> Name { match self.format { - ExpnFormat::MacroAttribute(s) => s, - ExpnFormat::MacroBang(s) => s, + ExpnFormat::MacroAttribute(s) | + ExpnFormat::MacroBang(s) | + ExpnFormat::CompilerDesugaring(s) => s, } } } @@ -813,6 +816,7 @@ impl CodeMap { let (pre, post) = match ei.callee.format { MacroAttribute(..) => ("#[", "]"), MacroBang(..) => ("", "!"), + CompilerDesugaring(..) => ("desugaring of `", "`"), }; let macro_decl_name = format!("{}{}{}", pre, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 4de3baf7d14..fca89e265e4 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -307,7 +307,7 @@ fn generate_test_harness(sess: &ParseSess, /// The expanded code calls some unstable functions in the test crate. fn ignored_span(cx: &TestCtxt, sp: Span) -> Span { let info = ExpnInfo { - call_site: DUMMY_SP, + call_site: sp, callee: NameAndSpan { format: MacroAttribute(Symbol::intern("test")), span: None, @@ -460,6 +460,7 @@ mod __test { fn mk_std(cx: &TestCtxt) -> P<ast::Item> { let id_test = Ident::from_str("test"); + let sp = ignored_span(cx, DUMMY_SP); let (vi, vis, ident) = if cx.is_test_crate { (ast::ItemKind::Use( P(nospan(ast::ViewPathSimple(id_test, @@ -474,7 +475,7 @@ fn mk_std(cx: &TestCtxt) -> P<ast::Item> { node: vi, attrs: vec![], vis: vis, - span: DUMMY_SP + span: sp }) } @@ -598,7 +599,7 @@ fn mk_tests(cx: &TestCtxt) -> P<ast::Item> { // FIXME #15962: should be using quote_item, but that stringifies // __test_reexports, causing it to be reinterned, losing the // gensym information. - let sp = DUMMY_SP; + let sp = ignored_span(cx, DUMMY_SP); let ecx = &cx.ext_cx; let struct_type = ecx.ty_path(ecx.path(sp, vec