about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/metadata/decoder.rs42
-rw-r--r--src/librustc/middle/astencode.rs3
-rw-r--r--src/librustc/middle/def.rs4
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs8
-rw-r--r--src/librustc_typeck/astconv.rs5
-rw-r--r--src/test/compile-fail/associated-types-in-ambiguous-context.rs3
6 files changed, 38 insertions, 27 deletions
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index e390620bcab..6d2269b74a2 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -172,16 +172,13 @@ fn item_visibility(item: rbml::Doc) -> ast::Visibility {
     }
 }
 
-fn item_sort(item: rbml::Doc) -> char {
+fn item_sort(item: rbml::Doc) -> Option<char> {
     let mut ret = None;
     reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
         ret = Some(doc.as_str_slice().as_bytes()[0] as char);
         false
     });
-    match ret {
-        Some(r) => r,
-        None => panic!("No item_sort found")
-    }
+    ret
 }
 
 fn item_symbol(item: rbml::Doc) -> String {
@@ -344,7 +341,14 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
                 _ => panic!()
             }
         }
-        Type => DlDef(def::DefTy(did, false)),
+        Type => {
+            if item_sort(item) == Some('t') {
+                let trait_did = item_reqd_and_translated_parent_item(cnum, item);
+                DlDef(def::DefAssociatedTy(trait_did, did))
+            } else {
+                DlDef(def::DefTy(did, false))
+            }
+        }
         Mod => DlDef(def::DefMod(did)),
         ForeignMod => DlDef(def::DefForeignMod(did)),
         StructVariant => {
@@ -829,8 +833,10 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
                         tag_item_impl_item, |doc| {
         let def_id = item_def_id(doc, cdata);
         match item_sort(doc) {
-            'r' | 'p' => impl_items.push(ty::MethodTraitItemId(def_id)),
-            't' => impl_items.push(ty::TypeTraitItemId(def_id)),
+            Some('r') | Some('p') => {
+                impl_items.push(ty::MethodTraitItemId(def_id))
+            }
+            Some('t') => impl_items.push(ty::TypeTraitItemId(def_id)),
             _ => panic!("unknown impl item sort"),
         }
         true
@@ -854,14 +860,14 @@ pub fn get_trait_item_name_and_kind(intr: Rc<IdentInterner>,
     let doc = lookup_item(id, cdata.data());
     let name = item_name(&*intr, doc);
     match item_sort(doc) {
-        'r' | 'p' => {
+        Some('r') | Some('p') => {
             let explicit_self = get_explicit_self(doc);
             (name, def::TraitItemKind::from_explicit_self_category(explicit_self))
         }
-        't' => (name, def::TypeTraitItemKind),
+        Some('t') => (name, def::TypeTraitItemKind),
         c => {
             panic!("get_trait_item_name_and_kind(): unknown trait item kind \
-                   in metadata: `{}`", c)
+                   in metadata: `{:?}`", c)
         }
     }
 }
@@ -887,7 +893,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
     let vis = item_visibility(method_doc);
 
     match item_sort(method_doc) {
-        'r' | 'p' => {
+        Some('r') | Some('p') => {
             let generics = doc_generics(method_doc, tcx, cdata, tag_method_ty_generics);
             let predicates = doc_predicates(method_doc, tcx, cdata, tag_method_ty_generics);
             let fty = doc_method_fty(method_doc, tcx, cdata);
@@ -904,7 +910,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
                                                         container,
                                                         provided_source)))
         }
-        't' => {
+        Some('t') => {
             ty::TypeTraitItem(Rc::new(ty::AssociatedType {
                 name: name,
                 vis: vis,
@@ -924,8 +930,10 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
     reader::tagged_docs(item, tag_item_trait_item, |mth| {
         let def_id = item_def_id(mth, cdata);
         match item_sort(mth) {
-            'r' | 'p' => result.push(ty::MethodTraitItemId(def_id)),
-            't' => result.push(ty::TypeTraitItemId(def_id)),
+            Some('r') | Some('p') => {
+                result.push(ty::MethodTraitItemId(def_id));
+            }
+            Some('t') => result.push(ty::TypeTraitItemId(def_id)),
             _ => panic!("unknown trait item sort"),
         }
         true
@@ -954,7 +962,7 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
         let did = item_def_id(mth_id, cdata);
         let mth = lookup_item(did.node, data);
 
-        if item_sort(mth) == 'p' {
+        if item_sort(mth) == Some('p') {
             let trait_item = get_impl_or_trait_item(intr.clone(),
                                                     cdata,
                                                     did.node,
@@ -1558,7 +1566,7 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
     let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
     match maybe_find_item(id, items) {
         None => false,
-        Some(item) => item_sort(item) == 't',
+        Some(item) => item_sort(item) == Some('t'),
     }
 }
 
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index eb723830d38..c4b874f7930 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -442,7 +442,8 @@ impl tr for def::Def {
           },
           def::DefTrait(did) => def::DefTrait(did.tr(dcx)),
           def::DefTy(did, is_enum) => def::DefTy(did.tr(dcx), is_enum),
-          def::DefAssociatedTy(did) => def::DefAssociatedTy(did.tr(dcx)),
+          def::DefAssociatedTy(trait_did, did) =>
+              def::DefAssociatedTy(trait_did.tr(dcx), did.tr(dcx)),
           def::DefAssociatedPath(def::TyParamProvenance::FromSelf(did), ident) =>
               def::DefAssociatedPath(def::TyParamProvenance::FromSelf(did.tr(dcx)), ident),
           def::DefAssociatedPath(def::TyParamProvenance::FromParam(did), ident) =>
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index 7857bcad813..a341b55333f 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -32,7 +32,7 @@ pub enum Def {
     DefLocal(ast::NodeId),
     DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
     DefTy(ast::DefId, bool /* is_enum */),
-    DefAssociatedTy(ast::DefId),
+    DefAssociatedTy(ast::DefId /* trait */, ast::DefId),
     // A partially resolved path to an associated type `T::U` where `T` is a concrete
     // type (indicated by the DefId) which implements a trait which has an associated
     // type `U` (indicated by the Ident).
@@ -134,7 +134,7 @@ impl Def {
         match *self {
             DefFn(id, _) | DefStaticMethod(id, _) | DefMod(id) |
             DefForeignMod(id) | DefStatic(id, _) |
-            DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(id) |
+            DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(_, id) |
             DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
             DefMethod(id, _, _) | DefConst(id) |
             DefAssociatedPath(TyParamProvenance::FromSelf(id), _) |
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index ad5fa600bd8..7c6e537f0be 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -638,8 +638,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                     &new_parent,
                                     ForbidDuplicateTypesAndModules,
                                     typedef.span);
-                            let def = DefAssociatedTy(local_def(
-                                typedef.id));
+                            let def = DefAssociatedTy(local_def(item.id),
+                                                      local_def(typedef.id));
                             // NB: not IMPORTABLE
                             let modifiers = if typedef.vis == ast::Public {
                                 PUBLIC
@@ -716,8 +716,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                             (name, static_flag)
                         }
                         ast::TypeTraitItem(ref associated_type) => {
-                            let def = DefAssociatedTy(local_def(
-                                    associated_type.ty_param.id));
+                            let def = DefAssociatedTy(local_def(item.id),
+                                                      local_def(associated_type.ty_param.id));
 
                             let name_bindings =
                                 self.add_child(associated_type.ty_param.ident.name,
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 3c4af12c1f9..8b5cb1f9746 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1236,9 +1236,8 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
                     def::DefPrimTy(_) => {
                         panic!("DefPrimTy arm missed in previous ast_ty_to_prim_ty call");
                     }
-                    def::DefAssociatedTy(trait_type_id) => {
-                        let path_str = tcx.map.path_to_string(
-                            tcx.map.get_parent(trait_type_id.node));
+                    def::DefAssociatedTy(trait_id, _) => {
+                        let path_str = ty::item_path_str(tcx, trait_id);
                         span_err!(tcx.sess, ast_ty.span, E0223,
                                           "ambiguous associated \
                                                    type; specify the type \
diff --git a/src/test/compile-fail/associated-types-in-ambiguous-context.rs b/src/test/compile-fail/associated-types-in-ambiguous-context.rs
index 3999e9cbe75..becbc27138b 100644
--- a/src/test/compile-fail/associated-types-in-ambiguous-context.rs
+++ b/src/test/compile-fail/associated-types-in-ambiguous-context.rs
@@ -22,5 +22,8 @@ trait Grab {
     //~^ ERROR ambiguous associated type
 }
 
+type X = std::ops::Deref::Target;
+//~^ ERROR ambiguous associated type
+
 fn main() {
 }