about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2017-07-23 20:50:56 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2017-07-27 22:59:35 +0300
commit128f565daeced02b9d90e1d1a6c0988d25fc1701 (patch)
tree5a48feb11052715b0cc105e836cc95de7a7dfa5b /src
parentce3beb609f75fb690d6980c9e6a62c6efa6f3d97 (diff)
downloadrust-128f565daeced02b9d90e1d1a6c0988d25fc1701.tar.gz
rust-128f565daeced02b9d90e1d1a6c0988d25fc1701.zip
Give span to angle bracketed generic arguments
Diffstat (limited to 'src')
-rw-r--r--src/librustc/hir/lowering.rs2
-rw-r--r--src/librustc_passes/ast_validation.rs16
-rw-r--r--src/librustc_resolve/macros.rs7
-rw-r--r--src/libsyntax/ast.rs12
-rw-r--r--src/libsyntax/ext/build.rs21
-rw-r--r--src/libsyntax/fold.rs5
-rw-r--r--src/libsyntax/parse/parser.rs6
-rw-r--r--src/libsyntax_pos/lib.rs6
-rw-r--r--src/test/compile-fail/macro-with-seps-err-msg.rs20
-rw-r--r--src/test/ui/span/import-ty-params.rs (renamed from src/test/compile-fail/import-ty-params.rs)0
-rw-r--r--src/test/ui/span/import-ty-params.stderr14
-rw-r--r--src/test/ui/span/macro-ty-params.rs31
-rw-r--r--src/test/ui/span/macro-ty-params.stderr62
-rw-r--r--src/test/ui/span/visibility-ty-params.rs (renamed from src/test/compile-fail/privacy/restricted/ty-params.rs)0
-rw-r--r--src/test/ui/span/visibility-ty-params.stderr22
15 files changed, 166 insertions, 58 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 67dc069da41..3ae3671b593 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -865,7 +865,7 @@ impl<'a> LoweringContext<'a> {
                                             data: &AngleBracketedParameterData,
                                             param_mode: ParamMode)
                                             -> hir::AngleBracketedParameterData {
-        let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data;
+        let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings, .. } = data;
         hir::AngleBracketedParameterData {
             lifetimes: self.lower_lifetimes(lifetimes),
             types: types.iter().map(|ty| self.lower_ty(ty)).collect(),
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index e8331cc5397..38d8555334c 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -195,10 +195,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         match item.node {
             ItemKind::Use(ref view_path) => {
                 let path = view_path.node.path();
-                if path.segments.iter().any(|segment| segment.parameters.is_some()) {
-                    self.err_handler()
-                        .span_err(path.span, "generic arguments in import path");
-                }
+                path.segments.iter().find(|segment| segment.parameters.is_some()).map(|segment| {
+                    self.err_handler().span_err(segment.parameters.as_ref().unwrap().span(),
+                                                "generic arguments in import path");
+                });
             }
             ItemKind::Impl(.., Some(..), _, ref impl_items) => {
                 self.invalid_visibility(&item.vis, item.span, None);
@@ -297,10 +297,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     fn visit_vis(&mut self, vis: &'a Visibility) {
         match *vis {
             Visibility::Restricted { ref path, .. } => {
-                if path.segments.iter().any(|segment| segment.parameters.is_some()) {
-                    self.err_handler()
-                        .span_err(path.span, "generic arguments in visibility path");
-                }
+                path.segments.iter().find(|segment| segment.parameters.is_some()).map(|segment| {
+                    self.err_handler().span_err(segment.parameters.as_ref().unwrap().span(),
+                                                "generic arguments in visibility path");
+                });
             }
             _ => {}
         }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index c256b42f1bd..f8f9b27f148 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -386,9 +386,10 @@ impl<'a> Resolver<'a> {
     fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
                             -> Result<Def, Determinacy> {
         let ast::Path { ref segments, span } = *path;
-        if segments.iter().any(|segment| segment.parameters.is_some()) {
-            self.session.span_err(span, "generic arguments in macro path");
-        }
+        segments.iter().find(|segment| segment.parameters.is_some()).map(|segment| {
+            self.session.span_err(segment.parameters.as_ref().unwrap().span(),
+                                  "generic arguments in macro path");
+        });
 
         let path: Vec<_> = segments.iter().map(|seg| respan(seg.span, seg.identifier)).collect();
         let invocation = self.invocations[&scope];
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 544afc5d6f6..4fc73787353 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -153,14 +153,10 @@ pub enum PathParameters {
 }
 
 impl PathParameters {
-    pub fn span(&self, fallback: Span) -> Span {
+    pub fn span(&self) -> Span {
         match *self {
-            AngleBracketed(ref data) => {
-                data.lifetimes.get(0).map(|x| x.span).or_else(||
-                data.types.get(0).map(|x| x.span)).or_else(||
-                data.bindings.get(0).map(|x| x.span)).unwrap_or(fallback)
-            }
-            Parenthesized(ref data) => data.span
+            AngleBracketed(ref data) => data.span,
+            Parenthesized(ref data) => data.span,
         }
     }
 }
@@ -168,6 +164,8 @@ impl PathParameters {
 /// A path like `Foo<'a, T>`
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Default)]
 pub struct AngleBracketedParameterData {
+    /// Overall span
+    pub span: Span,
     /// The lifetime parameters for this path segment.
     pub lifetimes: Vec<Lifetime>,
     /// The type parameters for this path segment, if present.
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index af9143eadbc..e004f7354eb 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -312,7 +312,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new())
     }
     fn path_all(&self,
-                sp: Span,
+                span: Span,
                 global: bool,
                 mut idents: Vec<ast::Ident> ,
                 lifetimes: Vec<ast::Lifetime>,
@@ -322,24 +322,17 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let last_identifier = idents.pop().unwrap();
         let mut segments: Vec<ast::PathSegment> = Vec::new();
         if global {
-            segments.push(ast::PathSegment::crate_root(sp));
+            segments.push(ast::PathSegment::crate_root(span));
         }
 
-        segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, sp)));
+        segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, span)));
         let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
-            ast::AngleBracketedParameterData { lifetimes, types, bindings }.into()
+            ast::AngleBracketedParameterData { lifetimes, types, bindings, span }.into()
         } else {
             None
         };
-        segments.push(ast::PathSegment {
-            identifier: last_identifier,
-            span: sp,
-            parameters: parameters
-        });
-        ast::Path {
-            span: sp,
-            segments: segments,
-        }
+        segments.push(ast::PathSegment { identifier: last_identifier, span, parameters });
+        ast::Path { span, segments }
     }
 
     /// Constructs a qualified path.
@@ -366,7 +359,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
                  -> (ast::QSelf, ast::Path) {
         let mut path = trait_path;
         let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
-            ast::AngleBracketedParameterData { lifetimes, types, bindings }.into()
+            ast::AngleBracketedParameterData { lifetimes, types, bindings, span: ident.span }.into()
         } else {
             None
         };
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index eaec1eef172..8c616df858a 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -471,10 +471,11 @@ pub fn noop_fold_angle_bracketed_parameter_data<T: Folder>(data: AngleBracketedP
                                                            fld: &mut T)
                                                            -> AngleBracketedParameterData
 {
-    let AngleBracketedParameterData { lifetimes, types, bindings } = data;
+    let AngleBracketedParameterData { lifetimes, types, bindings, span } = data;
     AngleBracketedParameterData { lifetimes: fld.fold_lifetimes(lifetimes),
                                   types: types.move_map(|ty| fld.fold_ty(ty)),
-                                  bindings: bindings.move_map(|b| fld.fold_ty_binding(b)) }
+                                  bindings: bindings.move_map(|b| fld.fold_ty_binding(b)),
+                                  span: fld.new_span(span) }
 }
 
 pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedParameterData,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 833a10efa0b..d1591a219b3 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1808,8 +1808,8 @@ impl<'a> Parser<'a> {
                 // `<'a, T, A = U>`
                 let (lifetimes, types, bindings) = self.parse_generic_args()?;
                 self.expect_gt()?;
-                let _span = lo.to(self.prev_span);
-                AngleBracketedParameterData { lifetimes, types, bindings }.into()
+                let span = lo.to(self.prev_span);
+                AngleBracketedParameterData { lifetimes, types, bindings, span }.into()
             } else {
                 // `(T, U) -> R`
                 self.bump(); // `(`
@@ -2357,7 +2357,7 @@ impl<'a> Parser<'a> {
             _ => {
                 // Field access `expr.f`
                 if let Some(parameters) = segment.parameters {
-                    self.span_err(parameters.span(segment.span),
+                    self.span_err(parameters.span(),
                                   "field expressions may not have generic arguments");
                 }
 
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 820adc60999..3a701f91314 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -239,6 +239,12 @@ pub struct SpanLabel {
     pub label: Option<String>,
 }
 
+impl Default for Span {
+    fn default() -> Self {
+        DUMMY_SP
+    }
+}
+
 impl serialize::UseSpecializedEncodable for Span {
     fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_struct("Span", 2, |s| {
diff --git a/src/test/compile-fail/macro-with-seps-err-msg.rs b/src/test/compile-fail/macro-with-seps-err-msg.rs
index 8e0c451959d..0f123997ca1 100644
--- a/src/test/compile-fail/macro-with-seps-err-msg.rs
+++ b/src/test/compile-fail/macro-with-seps-err-msg.rs
@@ -10,28 +10,8 @@
 
 // gate-test-use_extern_macros
 
-macro_rules! m {
-    ($p1: path) => {
-        #[derive($p1)] struct U;
-    }
-}
-
 fn main() {
     globnar::brotz!(); //~ ERROR non-ident macro paths are experimental
     #[derive(foo::Bar)] struct T; //~ ERROR non-ident macro paths are experimental
     ::foo!(); //~ ERROR non-ident macro paths are experimental
-
-    foo::<T>!();
-    //~^ ERROR generic arguments in macro path
-    //~| ERROR generic arguments in macro path
-    //~| ERROR generic arguments in macro path
-    foo::<>!();
-    //~^ ERROR generic arguments in macro path
-    //~| ERROR generic arguments in macro path
-    //~| ERROR generic arguments in macro path
-    m!(MyTrait<>);
-    //~^ ERROR generic arguments in macro path
-    //~| ERROR generic arguments in macro path
-    //~| ERROR generic arguments in macro path
-    //~| ERROR generic arguments in macro path
 }
diff --git a/src/test/compile-fail/import-ty-params.rs b/src/test/ui/span/import-ty-params.rs
index d1e3d20f4ba..d1e3d20f4ba 100644
--- a/src/test/compile-fail/import-ty-params.rs
+++ b/src/test/ui/span/import-ty-params.rs
diff --git a/src/test/ui/span/import-ty-params.stderr b/src/test/ui/span/import-ty-params.stderr
new file mode 100644
index 00000000000..de959a14cc5
--- /dev/null
+++ b/src/test/ui/span/import-ty-params.stderr
@@ -0,0 +1,14 @@
+error: generic arguments in import path
+  --> $DIR/import-ty-params.rs:24:25
+   |
+24 |     import! { a::b::c::S<u8> } //~ ERROR generic arguments in import path
+   |                         ^^^^
+
+error: generic arguments in import path
+  --> $DIR/import-ty-params.rs:27:25
+   |
+27 |     import! { a::b::c::S<> } //~ ERROR generic arguments in import path
+   |                         ^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/span/macro-ty-params.rs b/src/test/ui/span/macro-ty-params.rs
new file mode 100644
index 00000000000..08a7518dff9
--- /dev/null
+++ b/src/test/ui/span/macro-ty-params.rs
@@ -0,0 +1,31 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+macro_rules! m {
+    ($p1: path) => {
+        #[derive($p1)] struct U;
+    }
+}
+
+fn main() {
+    foo::<T>!();
+    //~^ ERROR generic arguments in macro path
+    //~| ERROR generic arguments in macro path
+    //~| ERROR generic arguments in macro path
+    foo::<>!();
+    //~^ ERROR generic arguments in macro path
+    //~| ERROR generic arguments in macro path
+    //~| ERROR generic arguments in macro path
+    m!(MyTrait<>);
+    //~^ ERROR generic arguments in macro path
+    //~| ERROR generic arguments in macro path
+    //~| ERROR generic arguments in macro path
+    //~| ERROR generic arguments in macro path
+}
diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr
new file mode 100644
index 00000000000..ff3847ce1fa
--- /dev/null
+++ b/src/test/ui/span/macro-ty-params.stderr
@@ -0,0 +1,62 @@
+error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:18:8
+   |
+18 |     foo::<T>!();
+   |        ^^^^^
+
+error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:22:8
+   |
+22 |     foo::<>!();
+   |        ^^^^
+
+error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:26:15
+   |
+26 |     m!(MyTrait<>);
+   |               ^^
+
+error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:26:15
+   |
+26 |     m!(MyTrait<>);
+   |               ^^
+
+error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:26:15
+   |
+26 |     m!(MyTrait<>);
+   |               ^^
+
+error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:22:8
+   |
+22 |     foo::<>!();
+   |        ^^^^
+
+error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:18:8
+   |
+18 |     foo::<T>!();
+   |        ^^^^^
+
+error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:18:8
+   |
+18 |     foo::<T>!();
+   |        ^^^^^
+
+error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:22:8
+   |
+22 |     foo::<>!();
+   |        ^^^^
+
+error: generic arguments in macro path
+  --> $DIR/macro-ty-params.rs:26:15
+   |
+26 |     m!(MyTrait<>);
+   |               ^^
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/compile-fail/privacy/restricted/ty-params.rs b/src/test/ui/span/visibility-ty-params.rs
index 8d4817e80b9..8d4817e80b9 100644
--- a/src/test/compile-fail/privacy/restricted/ty-params.rs
+++ b/src/test/ui/span/visibility-ty-params.rs
diff --git a/src/test/ui/span/visibility-ty-params.stderr b/src/test/ui/span/visibility-ty-params.stderr
new file mode 100644
index 00000000000..0460b7ca025
--- /dev/null
+++ b/src/test/ui/span/visibility-ty-params.stderr
@@ -0,0 +1,22 @@
+error[E0577]: expected module, found struct `S`
+  --> $DIR/visibility-ty-params.rs:16:5
+   |
+16 | m!{ S<u8> } //~ ERROR generic arguments in visibility path
+   |     -^^^^
+   |     |
+   |     did you mean `m`?
+
+error: generic arguments in visibility path
+  --> $DIR/visibility-ty-params.rs:16:6
+   |
+16 | m!{ S<u8> } //~ ERROR generic arguments in visibility path
+   |      ^^^^
+
+error: generic arguments in visibility path
+  --> $DIR/visibility-ty-params.rs:20:10
+   |
+20 |     m!{ m<> } //~ ERROR generic arguments in visibility path
+   |          ^^
+
+error: aborting due to 3 previous errors
+