]> git.lizzy.rs Git - rust.git/commitdiff
syntax: don't use TraitRef in QPath.
authorEduard Burtescu <edy.burt@gmail.com>
Fri, 30 Jan 2015 08:09:44 +0000 (10:09 +0200)
committerEduard Burtescu <edy.burt@gmail.com>
Tue, 24 Feb 2015 12:14:16 +0000 (14:14 +0200)
23 files changed:
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/dead.rs
src/librustc/middle/ty.rs
src/librustc_back/svh.rs
src/librustc_privacy/lib.rs
src/librustc_resolve/lib.rs
src/librustc_trans/save/mod.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/wf.rs
src/librustc_typeck/coherence/impls.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/mod.rs
src/libsyntax/ast.rs
src/libsyntax/ast_util.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/test/compile-fail/ufcs-qpath-missing-params.rs

index d344ee8c881c5ab4fa796f64f80f9ae2264ffcb2..81fb1c8e913f62ab4fa45d5d1dcfac6f2be76afa 100644 (file)
@@ -717,6 +717,11 @@ fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId) {
         visit::walk_path(self, p);
     }
 
+    fn visit_qpath(&mut self, p: &ast::QPath, id: ast::NodeId) {
+        run_lints!(self, check_qpath, p, id);
+        visit::walk_qpath(self, p);
+    }
+
     fn visit_attribute(&mut self, attr: &ast::Attribute) {
         run_lints!(self, check_attribute, attr);
     }
index 021827b0101c81f7dee8caf04ab20ca6bcc9cac5..1e2ddb7db0bfa768be3b33091b7f787312ff8853 100644 (file)
@@ -157,6 +157,7 @@ fn check_lifetime_def(&mut self, _: &Context, _: &ast::LifetimeDef) { }
     fn check_explicit_self(&mut self, _: &Context, _: &ast::ExplicitSelf) { }
     fn check_mac(&mut self, _: &Context, _: &ast::Mac) { }
     fn check_path(&mut self, _: &Context, _: &ast::Path, _: ast::NodeId) { }
+    fn check_qpath(&mut self, _: &Context, _: &ast::QPath, _: ast::NodeId) { }
     fn check_attribute(&mut self, _: &Context, _: &ast::Attribute) { }
 
     /// Called when entering a syntax node that can have lint attributes such
index e6f5c36a2f81254896258330fc8b1529502d5597..1a695baf7216bf69791a62625fb39d924ffda8d2 100644 (file)
@@ -1241,9 +1241,8 @@ fn add_to_index(item: &ast::Item, rbml_w: &Encoder,
             }
             rbml_w.end_tag();
         }
-        if let Some(ref ast_trait_ref) = *opt_trait {
-            let trait_ref = ty::node_id_to_trait_ref(
-                tcx, ast_trait_ref.ref_id);
+        if opt_trait.is_some() {
+            let trait_ref = ty::impl_id_to_trait_ref(tcx, item.id);
             encode_trait_ref(rbml_w, ecx, &*trait_ref, tag_item_trait_ref);
         }
         encode_path(rbml_w, path.clone());
index ff78deb8d12ea6ba945531b6c34f0762b38a2ee6..4f9b900a5f8765c6f32eb46025ff7e800f62a89b 100644 (file)
@@ -306,6 +306,11 @@ fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
         visit::walk_path(self, path);
     }
 
+    fn visit_qpath(&mut self, qpath: &ast::QPath, id: ast::NodeId) {
+        self.lookup_and_handle_definition(&id);
+        visit::walk_qpath(self, qpath);
+    }
+
     fn visit_item(&mut self, _: &ast::Item) {
         // Do not recurse into items. These items will be added to the
         // worklist and recursed into manually if necessary.
index 3d059e27c5207d4cf5f0f3dd30e8211323b75ddc..c4fe3f4df02188d201ef545b7edb0c5da8502af3 100644 (file)
@@ -709,7 +709,7 @@ pub struct ctxt<'tcx> {
 
     pub impl_trait_cache: RefCell<DefIdMap<Option<Rc<ty::TraitRef<'tcx>>>>>,
 
-    pub trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
+    pub impl_trait_refs: RefCell<NodeMap<Rc<TraitRef<'tcx>>>>,
     pub trait_defs: RefCell<DefIdMap<Rc<TraitDef<'tcx>>>>,
 
     /// Maps from the def-id of an item (trait/struct/enum/fn) to its
@@ -2449,7 +2449,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         region_maps: region_maps,
         node_types: RefCell::new(FnvHashMap()),
         item_substs: RefCell::new(NodeMap()),
-        trait_refs: RefCell::new(NodeMap()),
+        impl_trait_refs: RefCell::new(NodeMap()),
         trait_defs: RefCell::new(DefIdMap()),
         predicates: RefCell::new(DefIdMap()),
         object_cast_map: RefCell::new(NodeMap()),
@@ -4174,12 +4174,12 @@ pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>,
     }
 }
 
-pub fn node_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
+pub fn impl_id_to_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId)
                                   -> Rc<ty::TraitRef<'tcx>> {
-    match cx.trait_refs.borrow().get(&id) {
+    match cx.impl_trait_refs.borrow().get(&id) {
         Some(ty) => ty.clone(),
         None => cx.sess.bug(
-            &format!("node_id_to_trait_ref: no trait ref for node `{}`",
+            &format!("impl_id_to_trait_ref: no trait ref for impl `{}`",
                     cx.map.node_to_string(id)))
     }
 }
@@ -5116,25 +5116,19 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
     memoized(&cx.impl_trait_cache, id, |id: ast::DefId| {
         if id.krate == ast::LOCAL_CRATE {
             debug!("(impl_trait_ref) searching for trait impl {:?}", id);
-            match cx.map.find(id.node) {
-                Some(ast_map::NodeItem(item)) => {
-                    match item.node {
-                        ast::ItemImpl(_, _, _, ref opt_trait, _, _) => {
-                            match opt_trait {
-                                &Some(ref t) => {
-                                    let trait_ref = ty::node_id_to_trait_ref(cx, t.ref_id);
-                                    Some(trait_ref)
-                                }
-                                &None => None
-                            }
-                        }
+            if let Some(ast_map::NodeItem(item)) = cx.map.find(id.node) {
+                if let ast::ItemImpl(_, _, _, ref opt_trait, _, _) = item.node {
+                    opt_trait.as_ref().map(|_| {
+                        ty::impl_id_to_trait_ref(cx, id.node)
+                    })
+                } else {
+                    None
                         ast::ItemDefaultImpl(_, ref ast_trait_ref) => {
                             Some(ty::node_id_to_trait_ref(cx, ast_trait_ref.ref_id))
                         }
-                        _ => None
-                    }
                 }
-                _ => None
+            } else {
+                None
             }
         } else {
             csearch::get_impl_trait(cx, id)
index 2fc43ab26b58ef328699c5a295df5386f79f982f..af886ed25ab20a8b1b639ce9e1e23fee02fbc3ba 100644 (file)
@@ -194,6 +194,7 @@ enum SawAbiComponent<'a> {
         SawVariant,
         SawExplicitSelf,
         SawPath,
+        SawQPath,
         SawOptLifetimeRef,
         SawBlock,
         SawPat,
@@ -485,6 +486,10 @@ fn visit_path(&mut self, path: &Path, _: ast::NodeId) {
             SawPath.hash(self.st); visit::walk_path(self, path)
         }
 
+        fn visit_qpath(&mut self, qpath: &QPath, _: ast::NodeId) {
+            SawQPath.hash(self.st); visit::walk_qpath(self, qpath)
+        }
+
         fn visit_block(&mut self, b: &Block) {
             SawBlock.hash(self.st); visit::walk_block(self, b)
         }
index 838ba9c658cf1661fda1b7e3b4ac3c9949d8d848..1f8ae3fbbcbb47875c96d1a719475101cd90930f 100644 (file)
@@ -1021,6 +1021,11 @@ fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
         self.check_path(path.span, id, path.segments.last().unwrap().identifier);
         visit::walk_path(self, path);
     }
+
+    fn visit_qpath(&mut self, qpath: &ast::QPath, id: ast::NodeId) {
+        self.check_path(qpath.trait_path.span, id, qpath.item_path.identifier);
+        visit::walk_qpath(self, qpath);
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
index 55ad52762e0c6b750be63e95dce017c0e432c65e..1380e2367256dbdcf1c27808d304840db8ed60ea 100644 (file)
@@ -2875,8 +2875,7 @@ fn resolve_item(&mut self, item: &Item) {
                     this.resolve_type_parameters(&generics.ty_params);
                     this.resolve_where_clause(&generics.where_clause);
 
-                    this.resolve_type_parameter_bounds(item.id, bounds,
-                                                       TraitDerivation);
+                    this.resolve_type_parameter_bounds(bounds, TraitDerivation);
 
                     for trait_item in &(*trait_items) {
                         // Create a new rib for the trait_item-specific type
@@ -3141,8 +3140,7 @@ fn resolve_type_parameter(&mut self,
                               type_parameter: &TyParam) {
         self.check_if_primitive_type_name(type_parameter.ident.name, type_parameter.span);
         for bound in &*type_parameter.bounds {
-            self.resolve_type_parameter_bound(type_parameter.id, bound,
-                                              TraitBoundingTypeParameter);
+            self.resolve_type_parameter_bound(bound, TraitBoundingTypeParameter);
         }
         match type_parameter.default {
             Some(ref ty) => self.resolve_type(&**ty),
@@ -3151,41 +3149,33 @@ fn resolve_type_parameter(&mut self,
     }
 
     fn resolve_type_parameter_bounds(&mut self,
-                                     id: NodeId,
                                      type_parameter_bounds: &OwnedSlice<TyParamBound>,
                                      reference_type: TraitReferenceType) {
         for type_parameter_bound in &**type_parameter_bounds {
-            self.resolve_type_parameter_bound(id, type_parameter_bound,
-                                              reference_type);
+            self.resolve_type_parameter_bound(type_parameter_bound, reference_type);
         }
     }
 
     fn resolve_type_parameter_bound(&mut self,
-                                    id: NodeId,
                                     type_parameter_bound: &TyParamBound,
                                     reference_type: TraitReferenceType) {
         match *type_parameter_bound {
             TraitTyParamBound(ref tref, _) => {
-                self.resolve_poly_trait_reference(id, tref, reference_type)
+                self.resolve_trait_reference(tref.trait_ref.ref_id,
+                                             &tref.trait_ref.path,
+                                             reference_type)
             }
             RegionTyParamBound(..) => {}
         }
     }
 
-    fn resolve_poly_trait_reference(&mut self,
-                                    id: NodeId,
-                                    poly_trait_reference: &PolyTraitRef,
-                                    reference_type: TraitReferenceType) {
-        self.resolve_trait_reference(id, &poly_trait_reference.trait_ref, reference_type)
-    }
-
     fn resolve_trait_reference(&mut self,
                                id: NodeId,
-                               trait_reference: &TraitRef,
+                               trait_path: &Path,
                                reference_type: TraitReferenceType) {
-        match self.resolve_path(id, &trait_reference.path, TypeNS, true) {
+        match self.resolve_path(id, trait_path, TypeNS, true) {
             None => {
-                let path_str = self.path_names_to_string(&trait_reference.path);
+                let path_str = self.path_names_to_string(trait_path);
                 let usage_str = match reference_type {
                     TraitBoundingTypeParameter => "bound type parameter with",
                     TraitImplementation        => "implement",
@@ -3195,26 +3185,23 @@ fn resolve_trait_reference(&mut self,
                 };
 
                 let msg = format!("attempt to {} a nonexistent trait `{}`", usage_str, path_str);
-                self.resolve_error(trait_reference.path.span, &msg[..]);
+                self.resolve_error(trait_path.span, &msg[..]);
             }
             Some(def) => {
                 match def {
                     (DefTrait(_), _) => {
                         debug!("(resolving trait) found trait def: {:?}", def);
-                        self.record_def(trait_reference.ref_id, def);
+                        self.record_def(id, def);
                     }
                     (def, _) => {
-                        self.resolve_error(trait_reference.path.span,
-                                           &format!("`{}` is not a trait",
-                                                   self.path_names_to_string(
-                                                       &trait_reference.path)));
+                        self.resolve_error(trait_path.span,
+                            &format!("`{}` is not a trait",
+                                     self.path_names_to_string(trait_path)));
 
                         // If it's a typedef, give a note
                         if let DefTy(..) = def {
-                            self.session.span_note(
-                                trait_reference.path.span,
-                                &format!("`type` aliases cannot be used for traits")
-                                );
+                            self.session.span_note(trait_path.span,
+                                &format!("`type` aliases cannot be used for traits"));
                         }
                     }
                 }
@@ -3229,8 +3216,7 @@ fn resolve_where_clause(&mut self, where_clause: &ast::WhereClause) {
                     self.resolve_type(&*bound_pred.bounded_ty);
 
                     for bound in &*bound_pred.bounds {
-                        self.resolve_type_parameter_bound(bound_pred.bounded_ty.id, bound,
-                                                          TraitBoundingTypeParameter);
+                        self.resolve_type_parameter_bound(bound, TraitBoundingTypeParameter);
                     }
                 }
                 &ast::WherePredicate::RegionPredicate(_) => {}
@@ -3303,14 +3289,16 @@ fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T where
         result
     }
 
-    fn with_optional_trait_ref<T, F>(&mut self, id: NodeId,
+    fn with_optional_trait_ref<T, F>(&mut self,
                                      opt_trait_ref: &Option<TraitRef>,
                                      f: F) -> T where
         F: FnOnce(&mut Resolver) -> T,
     {
         let new_val = match *opt_trait_ref {
             Some(ref trait_ref) => {
-                self.resolve_trait_reference(id, trait_ref, TraitImplementation);
+                self.resolve_trait_reference(trait_ref.ref_id,
+                                             &trait_ref.path,
+                                             TraitImplementation);
 
                 match self.def_map.borrow().get(&trait_ref.ref_id) {
                     Some(def) => {
@@ -3345,7 +3333,7 @@ fn resolve_implementation(&mut self,
             this.resolve_where_clause(&generics.where_clause);
 
             // Resolve the trait reference, if necessary.
-            this.with_optional_trait_ref(id, opt_trait_reference, |this| {
+            this.with_optional_trait_ref(opt_trait_reference, |this| {
                 // Resolve the self type.
                 this.resolve_type(self_type);
 
@@ -3630,13 +3618,12 @@ fn resolve_type(&mut self, ty: &Ty) {
 
             TyObjectSum(ref ty, ref bound_vec) => {
                 self.resolve_type(&**ty);
-                self.resolve_type_parameter_bounds(ty.id, bound_vec,
-                                                       TraitBoundingTypeParameter);
+                self.resolve_type_parameter_bounds(bound_vec, TraitBoundingTypeParameter);
             }
 
             TyQPath(ref qpath) => {
                 self.resolve_type(&*qpath.self_type);
-                self.resolve_trait_reference(ty.id, &*qpath.trait_ref, TraitQPath);
+                self.resolve_trait_reference(ty.id, &qpath.trait_path, TraitQPath);
                 for ty in qpath.item_path.parameters.types() {
                     self.resolve_type(&**ty);
                 }
@@ -3646,10 +3633,7 @@ fn resolve_type(&mut self, ty: &Ty) {
             }
 
             TyPolyTraitRef(ref bounds) => {
-                self.resolve_type_parameter_bounds(
-                    ty.id,
-                    bounds,
-                    TraitObject);
+                self.resolve_type_parameter_bounds(bounds, TraitObject);
                 visit::walk_ty(self, ty);
             }
             _ => {
@@ -4439,8 +4423,12 @@ fn resolve_expr(&mut self, expr: &Expr) {
                     ExprPath(ref path) => path,
                     ExprQPath(ref qpath) => {
                         self.resolve_type(&*qpath.self_type);
-                        self.resolve_trait_reference(expr.id, &*qpath.trait_ref, TraitQPath);
-                        path_from_qpath = qpath.trait_ref.path.clone();
+
+                        // Just make sure the trait is valid, don't record a def.
+                        self.resolve_trait_reference(expr.id, &qpath.trait_path, TraitQPath);
+                        self.def_map.borrow_mut().remove(&expr.id);
+
+                        path_from_qpath = qpath.trait_path.clone();
                         path_from_qpath.segments.push(qpath.item_path.clone());
                         &path_from_qpath
                     }
index af891001ea00e0ce16528a290de795fab9d2eeac..c92886651289270786fa1e75b2ff5a4cef13555a 100644 (file)
@@ -1340,10 +1340,10 @@ fn visit_expr(&mut self, ex: &ast::Expr) {
                 visit::walk_path(self, path);
             }
             ast::ExprQPath(ref qpath) => {
-                let mut path = qpath.trait_ref.path.clone();
+                let mut path = qpath.trait_path.clone();
                 path.segments.push(qpath.item_path.clone());
                 self.process_path(ex.id, ex.span, &path, None);
-                visit::walk_qpath(self, ex.span, &**qpath);
+                visit::walk_qpath(self, &**qpath);
             }
             ast::ExprStruct(ref path, ref fields, ref base) =>
                 self.process_struct_lit(ex, path, fields, base),
index 16a2dbf26870a64f1a79ed9a963dd72118ee3ba9..3c4af12c1f994dc1f0396121833d64687aaed7dc 100644 (file)
@@ -574,9 +574,10 @@ pub fn instantiate_poly_trait_ref<'tcx>(
     // lifetimes. Oh well, not there yet.
     let shifted_rscope = ShiftedRscope::new(rscope);
 
-    let trait_ref =
-        instantiate_trait_ref(this, &shifted_rscope, &ast_trait_ref.trait_ref,
-                              self_ty, Some(&mut projections));
+    let trait_ref = instantiate_trait_ref(this, &shifted_rscope,
+                                          &ast_trait_ref.trait_ref.path,
+                                          ast_trait_ref.trait_ref.ref_id,
+                                          None, self_ty, Some(&mut projections));
 
     for projection in projections {
         poly_projections.push(ty::Binder(projection));
@@ -594,26 +595,29 @@ pub fn instantiate_poly_trait_ref<'tcx>(
 pub fn instantiate_trait_ref<'tcx>(
     this: &AstConv<'tcx>,
     rscope: &RegionScope,
-    ast_trait_ref: &ast::TraitRef,
+    path: &ast::Path,
+    path_id: ast::NodeId,
+    impl_id: Option<ast::NodeId>,
     self_ty: Option<Ty<'tcx>>,
     projections: Option<&mut Vec<ty::ProjectionPredicate<'tcx>>>)
     -> Rc<ty::TraitRef<'tcx>>
 {
-    match ::lookup_def_tcx(this.tcx(), ast_trait_ref.path.span, ast_trait_ref.ref_id) {
+    match ::lookup_def_tcx(this.tcx(), path.span, path_id) {
         def::DefTrait(trait_def_id) => {
             let trait_ref = ast_path_to_trait_ref(this,
                                                   rscope,
                                                   trait_def_id,
                                                   self_ty,
-                                                  &ast_trait_ref.path,
+                                                  path,
                                                   projections);
-            this.tcx().trait_refs.borrow_mut().insert(ast_trait_ref.ref_id, trait_ref.clone());
+            if let Some(id) = impl_id {
+                this.tcx().impl_trait_refs.borrow_mut().insert(id, trait_ref.clone());
+            }
             trait_ref
         }
         _ => {
-            span_fatal!(this.tcx().sess, ast_trait_ref.path.span, E0245,
-                "`{}` is not a trait",
-                        ast_trait_ref.path.user_string(this.tcx()));
+            span_fatal!(this.tcx().sess, path.span, E0245, "`{}` is not a trait",
+                        path.user_string(this.tcx()));
         }
     }
 }
@@ -1056,7 +1060,9 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
 
     let trait_ref = instantiate_trait_ref(this,
                                           rscope,
-                                          &*qpath.trait_ref,
+                                          &qpath.trait_path,
+                                          ast_ty.id,
+                                          None,
                                           Some(self_type),
                                           None);
 
index 0430954ad7e2f9612e9482636956ca01b4bb5cb2..b6003071f8c725c218b81bcfec8c198259f8e953 100644 (file)
@@ -3611,13 +3611,10 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
           constrain_path_type_parameters(fcx, expr);
       }
       ast::ExprQPath(ref qpath) => {
-          // Require explicit type params for the trait.
           let self_ty = fcx.to_ty(&*qpath.self_type);
-          astconv::instantiate_trait_ref(fcx, fcx, &*qpath.trait_ref, Some(self_ty), None);
-
           let defn = lookup_def(fcx, expr.span, id);
           let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, expr.span, defn);
-          let mut path = qpath.trait_ref.path.clone();
+          let mut path = qpath.trait_path.clone();
           path.segments.push(qpath.item_path.clone());
           instantiate_path(fcx, &path, scheme, &predicates, Some(self_ty),
                            defn, expr.span, expr.id);
@@ -4829,7 +4826,8 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     // to add defaults. If the user provided *too many* types, that's
     // a problem.
     for &space in &ParamSpace::all() {
-        adjust_type_parameters(fcx, span, space, type_defs, &mut substs);
+        adjust_type_parameters(fcx, span, space, type_defs,
+                               opt_self_ty.is_some(), &mut substs);
         assert_eq!(substs.types.len(space), type_defs.len(space));
 
         adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
@@ -5007,6 +5005,7 @@ fn adjust_type_parameters<'a, 'tcx>(
         span: Span,
         space: ParamSpace,
         defs: &VecPerParamSpace<ty::TypeParameterDef<'tcx>>,
+        require_type_space: bool,
         substs: &mut Substs<'tcx>)
     {
         let provided_len = substs.types.len(space);
@@ -5029,9 +5028,8 @@ fn adjust_type_parameters<'a, 'tcx>(
 
         // Nothing specified at all: supply inference variables for
         // everything.
-        if provided_len == 0 {
-            substs.types.replace(space,
-                                 fcx.infcx().next_ty_vars(desired.len()));
+        if provided_len == 0 && !(require_type_space && space == subst::TypeSpace) {
+            substs.types.replace(space, fcx.infcx().next_ty_vars(desired.len()));
             return;
         }
 
index 399795c66567e3df49861e3ca14a9051d78161ca..e024526d0016f7756c18baa0e2036f2379b0a213 100644 (file)
@@ -81,8 +81,8 @@ fn check_item_well_formed(&mut self, item: &ast::Item) {
             ast::ItemImpl(_, ast::ImplPolarity::Positive, _, _, _, _) => {
                 self.check_impl(item);
             }
-            ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(ref tref), _, _) => {
-                let trait_ref = ty::node_id_to_trait_ref(ccx.tcx, tref.ref_id);
+            ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(_), _, _) => {
+                let trait_ref = ty::impl_id_to_trait_ref(ccx.tcx, item.id);
                 ty::populate_implementations_for_trait_if_necessary(ccx.tcx, trait_ref.def_id);
                 match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
                     Some(ty::BoundSend) | Some(ty::BoundSync) => {}
index e535b86a7bfd1e0cfa72c2cb8e74ed84fcc3e261..e89c96b36e1a23887e2b52631945d2a2c99985dd 100644 (file)
@@ -28,8 +28,8 @@ struct ImplsChecker<'cx, 'tcx:'cx> {
 impl<'cx, 'tcx,'v> visit::Visitor<'v> for ImplsChecker<'cx, 'tcx> {
     fn visit_item(&mut self, item: &'v ast::Item) {
         match item.node {
-            ast::ItemImpl(_, _, _, Some(ref opt_trait), _, _) => {
-                let trait_ref = ty::node_id_to_trait_ref(self.tcx, opt_trait.ref_id);
+            ast::ItemImpl(_, _, _, Some(_), _, _) => {
+                let trait_ref = ty::impl_id_to_trait_ref(self.tcx, item.id);
                 if let Some(_) = self.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
                     match trait_ref.self_ty().sty {
                         ty::ty_struct(..) | ty::ty_enum(..) => {}
index 7dac1eeb6f11723d95acf77184e164a6c7a24d8d..1913b55f1d8e69d03da3fc0b368345b055522ed5 100644 (file)
@@ -106,19 +106,9 @@ fn visit_item(&mut self, item: &Item) {
 
         //debug!("(checking coherence) item '{}'", token::get_ident(item.ident));
 
-        match item.node {
-            ItemImpl(_, _, _, ref opt_trait, _, _) => {
-                match opt_trait.clone() {
-                    Some(opt_trait) => {
-                        self.cc.check_implementation(item, &[opt_trait]);
-                    }
-                    None => self.cc.check_implementation(item, &[])
-                }
-            }
-            _ => {
-                // Nothing to do.
-            }
-        };
+        if let ItemImpl(_, _, _, ref opt_trait, _, _) = item.node {
+            self.cc.check_implementation(item, opt_trait.as_ref())
+        }
 
         visit::walk_item(self, item);
     }
@@ -155,9 +145,7 @@ fn check(&self, krate: &Crate) {
         self.check_implementations_of_copy();
     }
 
-    fn check_implementation(&self,
-                            item: &Item,
-                            associated_traits: &[TraitRef]) {
+    fn check_implementation(&self, item: &Item, opt_trait: Option<&TraitRef>) {
         let tcx = self.crate_context.tcx;
         let impl_did = local_def(item.id);
         let self_type = ty::lookup_item_type(tcx, impl_did);
@@ -167,9 +155,8 @@ fn check_implementation(&self,
 
         let impl_items = self.create_impl_from_item(item);
 
-        for associated_trait in associated_traits {
-            let trait_ref = ty::node_id_to_trait_ref(self.crate_context.tcx,
-                                                     associated_trait.ref_id);
+        if opt_trait.is_some() {
+            let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx, item.id);
             debug!("(checking implementation) adding impl for trait '{}', item '{}'",
                    trait_ref.repr(self.crate_context.tcx),
                    token::get_ident(item.ident));
@@ -191,7 +178,7 @@ fn check_implementation(&self,
             }
             Some(base_type_def_id) => {
                 // FIXME: Gather up default methods?
-                if associated_traits.len() == 0 {
+                if opt_trait.is_none() {
                     self.add_inherent_impl(base_type_def_id, impl_did);
                 }
             }
@@ -289,7 +276,7 @@ fn get_self_type_for_implementation(&self, impl_did: DefId)
     // Converts an implementation in the AST to a vector of items.
     fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
         match item.node {
-            ItemImpl(_, _, _, ref trait_refs, _, ref ast_items) => {
+            ItemImpl(_, _, _, ref opt_trait, _, ref ast_items) => {
                 let mut items: Vec<ImplOrTraitItemId> =
                         ast_items.iter()
                                  .map(|ast_item| {
@@ -304,13 +291,12 @@ fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
                             }
                         }).collect();
 
-                if let Some(ref trait_ref) = *trait_refs {
-                    let ty_trait_ref = ty::node_id_to_trait_ref(
-                        self.crate_context.tcx,
-                        trait_ref.ref_id);
+                if opt_trait.is_some() {
+                    let trait_ref = ty::impl_id_to_trait_ref(self.crate_context.tcx,
+                                                             item.id);
 
                     self.instantiate_default_methods(local_def(item.id),
-                                                     &*ty_trait_ref,
+                                                     &*trait_ref,
                                                      &mut items);
                 }
 
index 353e8e097a897d64e22c9e4e714bbc44835e806d..65c1d7adf48769f7b25d523d6ec799dd1869890a 100644 (file)
@@ -740,7 +740,9 @@ fn convert_item(ccx: &CollectCtxt, it: &ast::Item) {
             if let Some(ref trait_ref) = *opt_trait_ref {
                 astconv::instantiate_trait_ref(ccx,
                                                &ExplicitRscope,
-                                               trait_ref,
+                                               &trait_ref.path,
+                                               trait_ref.ref_id,
+                                               Some(it.id),
                                                Some(selfty),
                                                None);
             }
index d05aa4d20066bdaa4f45beb39c9b213f4046ee21..8e08c5278d004609a6ea0931d969766cec88aca7 100644 (file)
@@ -1629,7 +1629,7 @@ fn clean(&self, cx: &DocContext) -> Type {
         Type::QPath {
             name: self.item_path.identifier.clean(cx),
             self_type: box self.self_type.clean(cx),
-            trait_: box self.trait_ref.clean(cx)
+            trait_: box resolve_type(cx, self.trait_path.clean(cx), 0)
         }
     }
 }
index 7c83286f656b15392b9cf53298029cc863cc681f..5f9776425c3ff641f15a02d888669c390bf6b993 100644 (file)
@@ -782,11 +782,11 @@ pub enum Expr_ {
 ///
 ///     <Vec<T> as SomeTrait>::SomeAssociatedItem
 ///      ^~~~~     ^~~~~~~~~   ^~~~~~~~~~~~~~~~~~
-///      self_type  trait_name  item_path
+///      self_type  trait_path  item_path
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct QPath {
     pub self_type: P<Ty>,
-    pub trait_ref: P<TraitRef>,
+    pub trait_path: Path,
     pub item_path: PathSegment,
 }
 
@@ -1258,12 +1258,12 @@ pub enum Ty_ {
     ///
     /// Type parameters are stored in the Path itself
     TyPath(Path),
+    /// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
+    TyQPath(P<QPath>),
     /// Something like `A+B`. Note that `B` must always be a path.
     TyObjectSum(P<Ty>, TyParamBounds),
     /// A type like `for<'a> Foo<&'a Bar>`
     TyPolyTraitRef(TyParamBounds),
-    /// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType`
-    TyQPath(P<QPath>),
     /// No-op; kept solely so that we can pretty-print faithfully
     TyParen(P<Ty>),
     /// Unused for now
index 6ea37aaf72ce2971961c65be07ad3d3fd740be17..f207efc5b6c3410a2d4bca85d10c5b65a5517796 100644 (file)
@@ -561,13 +561,18 @@ fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
         visit::walk_trait_item(self, tm);
     }
 
-    fn visit_lifetime_ref(&mut self, lifetime: &'v Lifetime) {
+    fn visit_lifetime_ref(&mut self, lifetime: &Lifetime) {
         self.operation.visit_id(lifetime.id);
     }
 
-    fn visit_lifetime_def(&mut self, def: &'v LifetimeDef) {
+    fn visit_lifetime_def(&mut self, def: &LifetimeDef) {
         self.visit_lifetime_ref(&def.lifetime);
     }
+
+    fn visit_trait_ref(&mut self, trait_ref: &TraitRef) {
+        self.operation.visit_id(trait_ref.ref_id);
+        visit::walk_trait_ref(self, trait_ref);
+    }
 }
 
 pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &InlinedItem,
index ae4d2a80045982712e272c7035069041c5fd1eda..c0421fb6f1cf2050dfb551aca1e0c92c95d99375 100644 (file)
@@ -429,13 +429,13 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
             TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))),
             TyParen(ty) => TyParen(fld.fold_ty(ty)),
             TyPath(path) => TyPath(fld.fold_path(path)),
+            TyQPath(qpath) => {
+                TyQPath(fld.fold_qpath(qpath))
+            }
             TyObjectSum(ty, bounds) => {
                 TyObjectSum(fld.fold_ty(ty),
                             fld.fold_bounds(bounds))
             }
-            TyQPath(qpath) => {
-                TyQPath(fld.fold_qpath(qpath))
-            }
             TyFixedLengthVec(ty, e) => {
                 TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e))
             }
@@ -454,7 +454,7 @@ pub fn noop_fold_qpath<T: Folder>(qpath: P<QPath>, fld: &mut T) -> P<QPath> {
     qpath.map(|qpath| {
         QPath {
             self_type: fld.fold_ty(qpath.self_type),
-            trait_ref: qpath.trait_ref.map(|tr| fld.fold_trait_ref(tr)),
+            trait_path: fld.fold_path(qpath.trait_path),
             item_path: PathSegment {
                 identifier: fld.fold_ident(qpath.item_path.identifier),
                 parameters: fld.fold_path_parameters(qpath.item_path.parameters),
index bcef7238d7f21007035b7512234ee6d3ca6b5684..b2f597258558d18e8a26f5b7248f05d7be2af0e8 100644 (file)
@@ -1525,13 +1525,13 @@ pub fn parse_ty(&mut self) -> P<Ty> {
             // QUALIFIED PATH `<TYPE as TRAIT_REF>::item`
             let self_type = self.parse_ty_sum();
             self.expect_keyword(keywords::As);
-            let trait_ref = self.parse_trait_ref();
+            let trait_path = self.parse_path(LifetimeAndTypesWithoutColons);
             self.expect(&token::Gt);
             self.expect(&token::ModSep);
             let item_name = self.parse_ident();
             TyQPath(P(QPath {
                 self_type: self_type,
-                trait_ref: P(trait_ref),
+                trait_path: trait_path,
                 item_path: ast::PathSegment {
                     identifier: item_name,
                     parameters: ast::PathParameters::none()
@@ -2220,7 +2220,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                     // QUALIFIED PATH `<TYPE as TRAIT_REF>::item::<'a, T>`
                     let self_type = self.parse_ty_sum();
                     self.expect_keyword(keywords::As);
-                    let trait_ref = self.parse_trait_ref();
+                    let trait_path = self.parse_path(LifetimeAndTypesWithoutColons);
                     self.expect(&token::Gt);
                     self.expect(&token::ModSep);
                     let item_name = self.parse_ident();
@@ -2240,7 +2240,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                     let hi = self.span.hi;
                     return self.mk_expr(lo, hi, ExprQPath(P(QPath {
                         self_type: self_type,
-                        trait_ref: P(trait_ref),
+                        trait_path: trait_path,
                         item_path: ast::PathSegment {
                             identifier: item_name,
                             parameters: parameters
index 752d34a19c6e1760a64a8b60074d9904233579be..3cfb90a3e68182259ee8e09486aac5020af71ef7 100644 (file)
@@ -2047,7 +2047,7 @@ fn print_qpath(&mut self,
         try!(self.print_type(&*qpath.self_type));
         try!(space(&mut self.s));
         try!(self.word_space("as"));
-        try!(self.print_trait_ref(&*qpath.trait_ref));
+        try!(self.print_path(&qpath.trait_path, false));
         try!(word(&mut self.s, ">"));
         try!(word(&mut self.s, "::"));
         try!(self.print_ident(qpath.item_path.identifier));
index 4586495227d02d37833d98194405a7045d808ec2..4e90adea90c6211a4771446a3851a876cc589736 100644 (file)
@@ -125,8 +125,8 @@ fn visit_mac(&mut self, _mac: &'v Mac) {
     fn visit_path(&mut self, path: &'v Path, _id: ast::NodeId) {
         walk_path(self, path)
     }
-    fn visit_qpath(&mut self, qpath_span: Span, qpath: &'v QPath) {
-        walk_qpath(self, qpath_span, qpath)
+    fn visit_qpath(&mut self, qpath: &'v QPath, _id: ast::NodeId) {
+        walk_qpath(self, qpath)
     }
     fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
         walk_path_segment(self, path_span, path_segment)
@@ -402,13 +402,13 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
         TyPath(ref path) => {
             visitor.visit_path(path, typ.id);
         }
+        TyQPath(ref qpath) => {
+            visitor.visit_qpath(&**qpath, typ.id);
+        }
         TyObjectSum(ref ty, ref bounds) => {
             visitor.visit_ty(&**ty);
             walk_ty_param_bounds_helper(visitor, bounds);
         }
-        TyQPath(ref qpath) => {
-            visitor.visit_qpath(typ.span, &**qpath);
-        }
         TyFixedLengthVec(ref ty, ref expression) => {
             visitor.visit_ty(&**ty);
             visitor.visit_expr(&**expression)
@@ -436,12 +436,10 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
     }
 }
 
-pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V,
-                                      qpath_span: Span,
-                                      qpath: &'v QPath) {
+pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, qpath: &'v QPath) {
     visitor.visit_ty(&*qpath.self_type);
-    visitor.visit_trait_ref(&*qpath.trait_ref);
-    visitor.visit_path_segment(qpath_span, &qpath.item_path);
+    walk_path(visitor, &qpath.trait_path);
+    visitor.visit_path_segment(qpath.trait_path.span, &qpath.item_path);
 }
 
 pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
@@ -873,7 +871,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
             visitor.visit_path(path, expression.id)
         }
         ExprQPath(ref qpath) => {
-            visitor.visit_qpath(expression.span, &**qpath)
+            visitor.visit_qpath(&**qpath, expression.id)
         }
         ExprBreak(_) | ExprAgain(_) => {}
         ExprRet(ref optional_expression) => {
index f4e18265fd9901b528653a777f77ea31f6a55226..b3fe178dc455e83b0d8c40f7092b57cbee1090fd 100644 (file)
@@ -12,5 +12,5 @@
 
 fn main() {
     <String as IntoCow>::into_cow("foo".to_string());
-    //~^ ERROR wrong number of type arguments: expected 1, found 0
+    //~^ ERROR too few type parameters provided: expected 1 parameter(s)
 }