Give span to angle bracketed generic arguments
This commit is contained in:
parent
ce3beb609f
commit
128f565dae
15 changed files with 166 additions and 58 deletions
|
@ -865,7 +865,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
data: &AngleBracketedParameterData,
|
data: &AngleBracketedParameterData,
|
||||||
param_mode: ParamMode)
|
param_mode: ParamMode)
|
||||||
-> hir::AngleBracketedParameterData {
|
-> hir::AngleBracketedParameterData {
|
||||||
let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data;
|
let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings, .. } = data;
|
||||||
hir::AngleBracketedParameterData {
|
hir::AngleBracketedParameterData {
|
||||||
lifetimes: self.lower_lifetimes(lifetimes),
|
lifetimes: self.lower_lifetimes(lifetimes),
|
||||||
types: types.iter().map(|ty| self.lower_ty(ty)).collect(),
|
types: types.iter().map(|ty| self.lower_ty(ty)).collect(),
|
||||||
|
|
|
@ -195,10 +195,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
match item.node {
|
match item.node {
|
||||||
ItemKind::Use(ref view_path) => {
|
ItemKind::Use(ref view_path) => {
|
||||||
let path = view_path.node.path();
|
let path = view_path.node.path();
|
||||||
if path.segments.iter().any(|segment| segment.parameters.is_some()) {
|
path.segments.iter().find(|segment| segment.parameters.is_some()).map(|segment| {
|
||||||
self.err_handler()
|
self.err_handler().span_err(segment.parameters.as_ref().unwrap().span(),
|
||||||
.span_err(path.span, "generic arguments in import path");
|
"generic arguments in import path");
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
ItemKind::Impl(.., Some(..), _, ref impl_items) => {
|
ItemKind::Impl(.., Some(..), _, ref impl_items) => {
|
||||||
self.invalid_visibility(&item.vis, item.span, None);
|
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) {
|
fn visit_vis(&mut self, vis: &'a Visibility) {
|
||||||
match *vis {
|
match *vis {
|
||||||
Visibility::Restricted { ref path, .. } => {
|
Visibility::Restricted { ref path, .. } => {
|
||||||
if path.segments.iter().any(|segment| segment.parameters.is_some()) {
|
path.segments.iter().find(|segment| segment.parameters.is_some()).map(|segment| {
|
||||||
self.err_handler()
|
self.err_handler().span_err(segment.parameters.as_ref().unwrap().span(),
|
||||||
.span_err(path.span, "generic arguments in visibility path");
|
"generic arguments in visibility path");
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -386,9 +386,10 @@ impl<'a> Resolver<'a> {
|
||||||
fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
|
fn resolve_macro_to_def(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
|
||||||
-> Result<Def, Determinacy> {
|
-> Result<Def, Determinacy> {
|
||||||
let ast::Path { ref segments, span } = *path;
|
let ast::Path { ref segments, span } = *path;
|
||||||
if segments.iter().any(|segment| segment.parameters.is_some()) {
|
segments.iter().find(|segment| segment.parameters.is_some()).map(|segment| {
|
||||||
self.session.span_err(span, "generic arguments in macro path");
|
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 path: Vec<_> = segments.iter().map(|seg| respan(seg.span, seg.identifier)).collect();
|
||||||
let invocation = self.invocations[&scope];
|
let invocation = self.invocations[&scope];
|
||||||
|
|
|
@ -153,14 +153,10 @@ pub enum PathParameters {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PathParameters {
|
impl PathParameters {
|
||||||
pub fn span(&self, fallback: Span) -> Span {
|
pub fn span(&self) -> Span {
|
||||||
match *self {
|
match *self {
|
||||||
AngleBracketed(ref data) => {
|
AngleBracketed(ref data) => data.span,
|
||||||
data.lifetimes.get(0).map(|x| x.span).or_else(||
|
Parenthesized(ref data) => data.span,
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,6 +164,8 @@ impl PathParameters {
|
||||||
/// A path like `Foo<'a, T>`
|
/// A path like `Foo<'a, T>`
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Default)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Default)]
|
||||||
pub struct AngleBracketedParameterData {
|
pub struct AngleBracketedParameterData {
|
||||||
|
/// Overall span
|
||||||
|
pub span: Span,
|
||||||
/// The lifetime parameters for this path segment.
|
/// The lifetime parameters for this path segment.
|
||||||
pub lifetimes: Vec<Lifetime>,
|
pub lifetimes: Vec<Lifetime>,
|
||||||
/// The type parameters for this path segment, if present.
|
/// The type parameters for this path segment, if present.
|
||||||
|
|
|
@ -312,7 +312,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
self.path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new())
|
self.path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new())
|
||||||
}
|
}
|
||||||
fn path_all(&self,
|
fn path_all(&self,
|
||||||
sp: Span,
|
span: Span,
|
||||||
global: bool,
|
global: bool,
|
||||||
mut idents: Vec<ast::Ident> ,
|
mut idents: Vec<ast::Ident> ,
|
||||||
lifetimes: Vec<ast::Lifetime>,
|
lifetimes: Vec<ast::Lifetime>,
|
||||||
|
@ -322,24 +322,17 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
let last_identifier = idents.pop().unwrap();
|
let last_identifier = idents.pop().unwrap();
|
||||||
let mut segments: Vec<ast::PathSegment> = Vec::new();
|
let mut segments: Vec<ast::PathSegment> = Vec::new();
|
||||||
if global {
|
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() {
|
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 {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
segments.push(ast::PathSegment {
|
segments.push(ast::PathSegment { identifier: last_identifier, span, parameters });
|
||||||
identifier: last_identifier,
|
ast::Path { span, segments }
|
||||||
span: sp,
|
|
||||||
parameters: parameters
|
|
||||||
});
|
|
||||||
ast::Path {
|
|
||||||
span: sp,
|
|
||||||
segments: segments,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a qualified path.
|
/// Constructs a qualified path.
|
||||||
|
@ -366,7 +359,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
-> (ast::QSelf, ast::Path) {
|
-> (ast::QSelf, ast::Path) {
|
||||||
let mut path = trait_path;
|
let mut path = trait_path;
|
||||||
let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
|
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 {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
|
@ -471,10 +471,11 @@ pub fn noop_fold_angle_bracketed_parameter_data<T: Folder>(data: AngleBracketedP
|
||||||
fld: &mut T)
|
fld: &mut T)
|
||||||
-> AngleBracketedParameterData
|
-> AngleBracketedParameterData
|
||||||
{
|
{
|
||||||
let AngleBracketedParameterData { lifetimes, types, bindings } = data;
|
let AngleBracketedParameterData { lifetimes, types, bindings, span } = data;
|
||||||
AngleBracketedParameterData { lifetimes: fld.fold_lifetimes(lifetimes),
|
AngleBracketedParameterData { lifetimes: fld.fold_lifetimes(lifetimes),
|
||||||
types: types.move_map(|ty| fld.fold_ty(ty)),
|
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,
|
pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedParameterData,
|
||||||
|
|
|
@ -1808,8 +1808,8 @@ impl<'a> Parser<'a> {
|
||||||
// `<'a, T, A = U>`
|
// `<'a, T, A = U>`
|
||||||
let (lifetimes, types, bindings) = self.parse_generic_args()?;
|
let (lifetimes, types, bindings) = self.parse_generic_args()?;
|
||||||
self.expect_gt()?;
|
self.expect_gt()?;
|
||||||
let _span = lo.to(self.prev_span);
|
let span = lo.to(self.prev_span);
|
||||||
AngleBracketedParameterData { lifetimes, types, bindings }.into()
|
AngleBracketedParameterData { lifetimes, types, bindings, span }.into()
|
||||||
} else {
|
} else {
|
||||||
// `(T, U) -> R`
|
// `(T, U) -> R`
|
||||||
self.bump(); // `(`
|
self.bump(); // `(`
|
||||||
|
@ -2357,7 +2357,7 @@ impl<'a> Parser<'a> {
|
||||||
_ => {
|
_ => {
|
||||||
// Field access `expr.f`
|
// Field access `expr.f`
|
||||||
if let Some(parameters) = segment.parameters {
|
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");
|
"field expressions may not have generic arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,12 @@ pub struct SpanLabel {
|
||||||
pub label: Option<String>,
|
pub label: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Span {
|
||||||
|
fn default() -> Self {
|
||||||
|
DUMMY_SP
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl serialize::UseSpecializedEncodable for Span {
|
impl serialize::UseSpecializedEncodable for Span {
|
||||||
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
s.emit_struct("Span", 2, |s| {
|
s.emit_struct("Span", 2, |s| {
|
||||||
|
|
|
@ -10,28 +10,8 @@
|
||||||
|
|
||||||
// gate-test-use_extern_macros
|
// gate-test-use_extern_macros
|
||||||
|
|
||||||
macro_rules! m {
|
|
||||||
($p1: path) => {
|
|
||||||
#[derive($p1)] struct U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
globnar::brotz!(); //~ ERROR non-ident macro paths are experimental
|
globnar::brotz!(); //~ ERROR non-ident macro paths are experimental
|
||||||
#[derive(foo::Bar)] struct T; //~ 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!(); //~ 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
|
|
||||||
}
|
}
|
||||||
|
|
14
src/test/ui/span/import-ty-params.stderr
Normal file
14
src/test/ui/span/import-ty-params.stderr
Normal 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
|
||||||
|
|
31
src/test/ui/span/macro-ty-params.rs
Normal file
31
src/test/ui/span/macro-ty-params.rs
Normal 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
|
||||||
|
}
|
62
src/test/ui/span/macro-ty-params.stderr
Normal file
62
src/test/ui/span/macro-ty-params.stderr
Normal 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
|
||||||
|
|
22
src/test/ui/span/visibility-ty-params.stderr
Normal file
22
src/test/ui/span/visibility-ty-params.stderr
Normal 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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue