1
Fork 0

Give span to angle bracketed generic arguments

This commit is contained in:
Vadim Petrochenkov 2017-07-23 20:50:56 +03:00
parent ce3beb609f
commit 128f565dae
15 changed files with 166 additions and 58 deletions

View file

@ -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(),

View file

@ -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");
});
}
_ => {}
}

View file

@ -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];

View file

@ -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.

View file

@ -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
};

View file

@ -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,

View file

@ -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");
}

View file

@ -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| {

View file

@ -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
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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