about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-11-27 23:32:57 -0600
committerGitHub <noreply@github.com>2016-11-27 23:32:57 -0600
commit0b399e5e99a44cf44d3860d353a8b7619d466410 (patch)
tree05970fb630a5d97e49e9a6f4230c70696cff2a4c /src/libsyntax
parentc7ddb8946bf041d89ba109ec8dd754492de78606 (diff)
parent372c6df564616dd461b82def5d75428940ca04ae (diff)
downloadrust-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.rs8
-rw-r--r--src/libsyntax/test.rs7
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![ecx.ident_of("self"),
                                                     ecx.ident_of("test"),