diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index e390620bcabe..6d2269b74a21 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 { 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, 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, 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, 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, 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 eb723830d383..c4b874f79301 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 7857bcad8135..a341b55333f4 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 ad5fa600bd81..7c6e537f0be2 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 3c4af12c1f99..8b5cb1f97466 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 3999e9cbe753..becbc27138b7 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() { }