Skip to content

Commit

Permalink
Give span to angle bracketed generic arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Jul 27, 2017
1 parent ce3beb6 commit 128f565
Show file tree
Hide file tree
Showing 15 changed files with 166 additions and 58 deletions.
2 changes: 1 addition & 1 deletion src/librustc/hir/lowering.rs
Expand Up @@ -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(),
Expand Down
16 changes: 8 additions & 8 deletions src/librustc_passes/ast_validation.rs
Expand Up @@ -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);
Expand Down Expand Up @@ -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");
});
}
_ => {}
}
Expand Down
7 changes: 4 additions & 3 deletions src/librustc_resolve/macros.rs
Expand Up @@ -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];
Expand Down
12 changes: 5 additions & 7 deletions src/libsyntax/ast.rs
Expand Up @@ -153,21 +153,19 @@ 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,
}
}
}

/// 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.
Expand Down
21 changes: 7 additions & 14 deletions src/libsyntax/ext/build.rs
Expand Up @@ -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>,
Expand All @@ -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.
Expand All @@ -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
};
Expand Down
5 changes: 3 additions & 2 deletions src/libsyntax/fold.rs
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/parse/parser.rs
Expand Up @@ -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(); // `(`
Expand Down Expand Up @@ -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");
}

Expand Down
6 changes: 6 additions & 0 deletions src/libsyntax_pos/lib.rs
Expand Up @@ -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| {
Expand Down
20 changes: 0 additions & 20 deletions src/test/compile-fail/macro-with-seps-err-msg.rs
Expand Up @@ -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
}
File renamed without changes.
14 changes: 14 additions & 0 deletions 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

31 changes: 31 additions & 0 deletions 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
}
62 changes: 62 additions & 0 deletions 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

File renamed without changes.
22 changes: 22 additions & 0 deletions 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

0 comments on commit 128f565

Please sign in to comment.