about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSeo Sanghyeon <sanxiyn@gmail.com>2015-06-12 01:44:42 +0900
committerSeo Sanghyeon <sanxiyn@gmail.com>2015-06-12 20:28:09 +0900
commit16d5c83d5fe19a89ad6740ca4f53750f997e2def (patch)
treeebde1aaefa2676d1ec73f691d70591d4e405c00e
parent0da58cc361577d63afdcb84945a9f011970301e3 (diff)
downloadrust-16d5c83d5fe19a89ad6740ca4f53750f997e2def.tar.gz
rust-16d5c83d5fe19a89ad6740ca4f53750f997e2def.zip
Use more precise span when checking type definitions
-rw-r--r--src/librustc_typeck/check/mod.rs3
-rw-r--r--src/librustc_typeck/check/wf.rs32
-rw-r--r--src/test/compile-fail/trait-bounds-on-structs-and-enums.rs12
3 files changed, 20 insertions, 27 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 601db229c41..c524c3024eb 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1626,10 +1626,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let t = ast_ty_to_ty(self, self, ast_t);
 
         let mut bounds_checker = wf::BoundsChecker::new(self,
-                                                        ast_t.span,
                                                         self.body_id,
                                                         None);
-        bounds_checker.check_ty(t);
+        bounds_checker.check_ty(t, ast_t.span);
 
         t
     }
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index 62790a1d0a8..c1d260815f6 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -23,7 +23,7 @@ use util::ppaux::{Repr, UserString};
 use std::collections::HashSet;
 use syntax::ast;
 use syntax::ast_util::local_def;
-use syntax::codemap::Span;
+use syntax::codemap::{DUMMY_SP, Span};
 use syntax::parse::token::{self, special_idents};
 use syntax::visit;
 use syntax::visit::Visitor;
@@ -162,15 +162,14 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         self.with_fcx(item, |this, fcx| {
             let variants = lookup_fields(fcx);
             let mut bounds_checker = BoundsChecker::new(fcx,
-                                                        item.span,
                                                         item.id,
                                                         Some(&mut this.cache));
             debug!("check_type_defn at bounds_checker.scope: {:?}", bounds_checker.scope);
 
-             for variant in &variants {
+            for variant in &variants {
                 for field in &variant.fields {
                     // Regions are checked below.
-                    bounds_checker.check_traits_in_ty(field.ty);
+                    bounds_checker.check_traits_in_ty(field.ty, field.span);
                 }
 
                 // For DST, all intermediate types must be sized.
@@ -199,7 +198,6 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
     {
         self.with_fcx(item, |this, fcx| {
             let mut bounds_checker = BoundsChecker::new(fcx,
-                                                        item.span,
                                                         item.id,
                                                         Some(&mut this.cache));
             debug!("check_item_type at bounds_checker.scope: {:?}", bounds_checker.scope);
@@ -209,7 +207,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
                                                       &fcx.inh.param_env.free_substs,
                                                       &type_scheme.ty);
 
-            bounds_checker.check_traits_in_ty(item_ty);
+            bounds_checker.check_traits_in_ty(item_ty, item.span);
         });
     }
 
@@ -218,7 +216,6 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
     {
         self.with_fcx(item, |this, fcx| {
             let mut bounds_checker = BoundsChecker::new(fcx,
-                                                        item.span,
                                                         item.id,
                                                         Some(&mut this.cache));
             debug!("check_impl at bounds_checker.scope: {:?}", bounds_checker.scope);
@@ -231,7 +228,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
                                                       &fcx.inh.param_env.free_substs,
                                                       &self_ty);
 
-            bounds_checker.check_traits_in_ty(self_ty);
+            bounds_checker.check_traits_in_ty(self_ty, item.span);
 
             // Similarly, obtain an "inside" reference to the trait
             // that the impl implements.
@@ -252,7 +249,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
             // trait reference. Instead, this is done at the impl site.
             // Arguably this is wrong and we should treat the trait-reference
             // the same way as we treat the self-type.
-            bounds_checker.check_trait_ref(&trait_ref);
+            bounds_checker.check_trait_ref(&trait_ref, item.span);
 
             let cause =
                 traits::ObligationCause::new(
@@ -483,11 +480,10 @@ pub struct BoundsChecker<'cx,'tcx:'cx> {
 
 impl<'cx,'tcx> BoundsChecker<'cx,'tcx> {
     pub fn new(fcx: &'cx FnCtxt<'cx,'tcx>,
-               span: Span,
                scope: ast::NodeId,
                cache: Option<&'cx mut HashSet<Ty<'tcx>>>)
                -> BoundsChecker<'cx,'tcx> {
-        BoundsChecker { fcx: fcx, span: span, scope: scope,
+        BoundsChecker { fcx: fcx, span: DUMMY_SP, scope: scope,
                         cache: cache, binding_count: 0 }
     }
 
@@ -500,30 +496,32 @@ impl<'cx,'tcx> BoundsChecker<'cx,'tcx> {
     ///
     /// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated
     /// to the point where impl `A : Trait<B>` is implemented).
-    pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
+    pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, span: Span) {
         let trait_predicates = ty::lookup_predicates(self.fcx.tcx(), trait_ref.def_id);
 
-        let bounds = self.fcx.instantiate_bounds(self.span,
+        let bounds = self.fcx.instantiate_bounds(span,
                                                  trait_ref.substs,
                                                  &trait_predicates);
 
         self.fcx.add_obligations_for_parameters(
             traits::ObligationCause::new(
-                self.span,
+                span,
                 self.fcx.body_id,
                 traits::ItemObligation(trait_ref.def_id)),
             &bounds);
 
         for &ty in &trait_ref.substs.types {
-            self.check_traits_in_ty(ty);
+            self.check_traits_in_ty(ty, span);
         }
     }
 
-    pub fn check_ty(&mut self, ty: Ty<'tcx>) {
+    pub fn check_ty(&mut self, ty: Ty<'tcx>, span: Span) {
+        self.span = span;
         ty.fold_with(self);
     }
 
-    fn check_traits_in_ty(&mut self, ty: Ty<'tcx>) {
+    fn check_traits_in_ty(&mut self, ty: Ty<'tcx>, span: Span) {
+        self.span = span;
         // When checking types outside of a type def'n, we ignore
         // region obligations. See discussion below in fold_ty().
         self.binding_count += 1;
diff --git a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
index c18c5b386e8..9a1e4ee2471 100644
--- a/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
+++ b/src/test/compile-fail/trait-bounds-on-structs-and-enums.rs
@@ -32,23 +32,19 @@ impl<T> Foo<T> {
 }
 
 struct Baz {
-//~^ ERROR not implemented
-    a: Foo<isize>,
+    a: Foo<isize>, //~ ERROR not implemented
 }
 
 enum Boo {
-//~^ ERROR not implemented
-    Quux(Bar<usize>),
+    Quux(Bar<usize>), //~ ERROR not implemented
 }
 
 struct Badness<U> {
-//~^ ERROR not implemented
-    b: Foo<U>,
+    b: Foo<U>, //~ ERROR not implemented
 }
 
 enum MoreBadness<V> {
-//~^ ERROR not implemented
-    EvenMoreBadness(Bar<V>),
+    EvenMoreBadness(Bar<V>), //~ ERROR not implemented
 }
 
 trait PolyTrait<T>