]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/collect.rs
Rollup merge of #27397 - Dangthrimble:master, r=steveklabnik
[rust.git] / src / librustc_typeck / collect.rs
index 8949edb027e952c289d5567ca5e9e65eb4bd5d4f..5b65f7808307292a8780dbe62ce2a599ceda149b 100644 (file)
@@ -91,7 +91,6 @@
 use syntax::ast_util::local_def;
 use syntax::codemap::Span;
 use syntax::parse::token::special_idents;
-use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::visit;
 
@@ -404,7 +403,11 @@ fn trait_defines_associated_type_named(&self,
         }
     }
 
-    fn ty_infer(&self, span: Span) -> Ty<'tcx> {
+        fn ty_infer(&self,
+                    _ty_param_def: Option<ty::TypeParameterDef<'tcx>>,
+                    _substs: Option<&mut Substs<'tcx>>,
+                    _space: Option<ParamSpace>,
+                    span: Span) -> Ty<'tcx> {
         span_err!(self.tcx().sess, span, E0121,
                   "the type placeholder `_` is not allowed within types on item signatures");
         self.tcx().types.err
@@ -747,17 +750,7 @@ fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
            rcvr_ty_generics,
            rcvr_ty_predicates);
 
-    let tcx = ccx.tcx;
-    let mut seen_methods = FnvHashSet();
-    for (sig, id, ident, vis, span) in methods {
-        if !seen_methods.insert(ident.name) {
-            let fn_desc = match sig.explicit_self.node {
-                ast::SelfStatic => "associated function",
-                _               => "method",
-            };
-            span_err!(tcx.sess, span, E0201, "duplicate {}", fn_desc);
-        }
-
+    for (sig, id, ident, vis, _span) in methods {
         convert_method(ccx,
                        container,
                        sig,
@@ -801,7 +794,7 @@ fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
 
 fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
     let tcx = ccx.tcx;
-    debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id);
+    debug!("convert: item {} with id {}", it.ident, it.id);
     match it.node {
         // These don't define types.
         ast::ItemExternCrate(_) | ast::ItemUse(_) |
@@ -846,6 +839,18 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
                                                 ty: selfty });
             tcx.predicates.borrow_mut().insert(local_def(it.id),
                                                ty_predicates.clone());
+            if let &Some(ref ast_trait_ref) = opt_trait_ref {
+                tcx.impl_trait_refs.borrow_mut().insert(
+                    local_def(it.id),
+                    Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
+                                                             &ExplicitRscope,
+                                                             ast_trait_ref,
+                                                             Some(selfty)))
+                        );
+            } else {
+                tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), None);
+            }
+
 
             // If there is a trait reference, treat the methods as always public.
             // This is to work around some incorrect behavior in privacy checking:
@@ -859,7 +864,30 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
             };
 
             // Convert all the associated consts.
+            // Also, check if there are any duplicate associated items
+            let mut seen_type_items = FnvHashSet();
+            let mut seen_value_items = FnvHashSet();
+
             for impl_item in impl_items {
+                let seen_items = match impl_item.node {
+                    ast::TypeImplItem(_) => &mut seen_type_items,
+                    _                    => &mut seen_value_items,
+                };
+                if !seen_items.insert(impl_item.ident.name) {
+                    let desc = match impl_item.node {
+                        ast::ConstImplItem(_, _) => "associated constant",
+                        ast::TypeImplItem(_) => "associated type",
+                        ast::MethodImplItem(ref sig, _) =>
+                            match sig.explicit_self.node {
+                                ast::SelfStatic => "associated function",
+                                _ => "method",
+                            },
+                        _ => "associated item",
+                    };
+
+                    span_err!(tcx.sess, impl_item.span, E0201, "duplicate {}", desc);
+                }
+
                 if let ast::ConstImplItem(ref ty, ref expr) = impl_item.node {
                     let ty = ccx.icx(&ty_predicates)
                                 .to_ty(&ExplicitRscope, &*ty);
@@ -922,18 +950,6 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) {
                 }
             }
 
-            if let &Some(ref ast_trait_ref) = opt_trait_ref {
-                tcx.impl_trait_refs.borrow_mut().insert(
-                    local_def(it.id),
-                    Some(astconv::instantiate_mono_trait_ref(&ccx.icx(&ty_predicates),
-                                                             &ExplicitRscope,
-                                                             ast_trait_ref,
-                                                             Some(selfty)))
-                        );
-            } else {
-                tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), None);
-            }
-
             enforce_impl_params_are_constrained(tcx,
                                                 generics,
                                                 local_def(it.id),
@@ -1069,7 +1085,7 @@ fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                 Some(prev_span) => {
                     span_err!(tcx.sess, f.span, E0124,
                               "field `{}` is already declared",
-                              token::get_name(result.name));
+                              result.name);
                     span_note!(tcx.sess, *prev_span, "previously declared here");
                     true
                 },
@@ -1630,11 +1646,14 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     // the node id for the Self type parameter.
     let param_id = trait_id;
 
+    let parent = ccx.tcx.map.get_parent(param_id);
+
     let def = ty::TypeParameterDef {
         space: SelfSpace,
         index: 0,
         name: special_idents::type_self.name,
         def_id: local_def(param_id),
+        default_def_id: local_def(parent),
         default: None,
         object_lifetime_default: ty::ObjectLifetimeDefault::BaseDefault,
     };
@@ -1903,11 +1922,14 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         compute_object_lifetime_default(ccx, param.id,
                                         &param.bounds, &ast_generics.where_clause);
 
+    let parent = tcx.map.get_parent(param.id);
+
     let def = ty::TypeParameterDef {
         space: space,
         index: index,
         name: param.ident.name,
         def_id: local_def(param.id),
+        default_def_id: local_def(parent),
         default: default,
         object_lifetime_default: object_lifetime_default,
     };