Skip to content

Commit ce3beb6

Browse files
committed
Discern between Path and Path<> in AST
1 parent da77a1a commit ce3beb6

File tree

7 files changed

+50
-32
lines changed

7 files changed

+50
-32
lines changed

src/librustc_passes/ast_validation.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
197197
let path = view_path.node.path();
198198
if path.segments.iter().any(|segment| segment.parameters.is_some()) {
199199
self.err_handler()
200-
.span_err(path.span, "type or lifetime parameters in import path");
200+
.span_err(path.span, "generic arguments in import path");
201201
}
202202
}
203203
ItemKind::Impl(.., Some(..), _, ref impl_items) => {
@@ -297,9 +297,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
297297
fn visit_vis(&mut self, vis: &'a Visibility) {
298298
match *vis {
299299
Visibility::Restricted { ref path, .. } => {
300-
if !path.segments.iter().all(|segment| segment.parameters.is_none()) {
300+
if path.segments.iter().any(|segment| segment.parameters.is_some()) {
301301
self.err_handler()
302-
.span_err(path.span, "type or lifetime parameters in visibility path");
302+
.span_err(path.span, "generic arguments in visibility path");
303303
}
304304
}
305305
_ => {}

src/librustc_resolve/macros.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -387,11 +387,7 @@ impl<'a> Resolver<'a> {
387387
-> Result<Def, Determinacy> {
388388
let ast::Path { ref segments, span } = *path;
389389
if segments.iter().any(|segment| segment.parameters.is_some()) {
390-
let kind =
391-
if segments.last().unwrap().parameters.is_some() { "macro" } else { "module" };
392-
let msg = format!("type parameters are not allowed on {}s", kind);
393-
self.session.span_err(path.span, &msg);
394-
return Err(Determinacy::Determined);
390+
self.session.span_err(span, "generic arguments in macro path");
395391
}
396392

397393
let path: Vec<_> = segments.iter().map(|seg| respan(seg.span, seg.identifier)).collect();

src/libsyntax/ast.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,11 @@ pub struct PathSegment {
120120
pub span: Span,
121121

122122
/// Type/lifetime parameters attached to this path. They come in
123-
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
124-
/// this is more than just simple syntactic sugar; the use of
125-
/// parens affects the region binding rules, so we preserve the
126-
/// distinction.
127-
/// The `Option<P<..>>` wrapper is purely a size optimization;
128-
/// `None` is used to represent both `Path` and `Path<>`.
123+
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`.
124+
/// `None` means that no parameter list is supplied (`Path`),
125+
/// `Some` means that parameter list is supplied (`Path<X, Y>`)
126+
/// but it can be empty (`Path<>`).
127+
/// `P` is used as a size optimization for the common case with no parameters.
129128
pub parameters: Option<P<PathParameters>>,
130129
}
131130

@@ -181,8 +180,7 @@ pub struct AngleBracketedParameterData {
181180

182181
impl Into<Option<P<PathParameters>>> for AngleBracketedParameterData {
183182
fn into(self) -> Option<P<PathParameters>> {
184-
let empty = self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty();
185-
if empty { None } else { Some(P(PathParameters::AngleBracketed(self))) }
183+
Some(P(PathParameters::AngleBracketed(self)))
186184
}
187185
}
188186

src/libsyntax/ext/build.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -326,14 +326,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
326326
}
327327

328328
segments.extend(idents.into_iter().map(|i| ast::PathSegment::from_ident(i, sp)));
329-
let parameters = if lifetimes.is_empty() && types.is_empty() && bindings.is_empty() {
330-
None
329+
let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
330+
ast::AngleBracketedParameterData { lifetimes, types, bindings }.into()
331331
} else {
332-
Some(P(ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData {
333-
lifetimes: lifetimes,
334-
types: types,
335-
bindings: bindings,
336-
})))
332+
None
337333
};
338334
segments.push(ast::PathSegment {
339335
identifier: last_identifier,
@@ -369,15 +365,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
369365
bindings: Vec<ast::TypeBinding>)
370366
-> (ast::QSelf, ast::Path) {
371367
let mut path = trait_path;
372-
let parameters = ast::AngleBracketedParameterData {
373-
lifetimes: lifetimes,
374-
types: types,
375-
bindings: bindings,
368+
let parameters = if !lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty() {
369+
ast::AngleBracketedParameterData { lifetimes, types, bindings }.into()
370+
} else {
371+
None
376372
};
377373
path.segments.push(ast::PathSegment {
378374
identifier: ident.node,
379375
span: ident.span,
380-
parameters: Some(P(ast::PathParameters::AngleBracketed(parameters))),
376+
parameters: parameters,
381377
});
382378

383379
(ast::QSelf {

src/test/compile-fail/import-ty-params.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ macro_rules! import {
2020
($p: path) => (use $p;);
2121
}
2222

23-
import! { a::b::c::S<u8> } //~ERROR type or lifetime parameters in import path
23+
fn f1() {
24+
import! { a::b::c::S<u8> } //~ ERROR generic arguments in import path
25+
}
26+
fn f2() {
27+
import! { a::b::c::S<> } //~ ERROR generic arguments in import path
28+
}
2429

2530
fn main() {}

src/test/compile-fail/macro-with-seps-err-msg.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,28 @@
1010

1111
// gate-test-use_extern_macros
1212

13+
macro_rules! m {
14+
($p1: path) => {
15+
#[derive($p1)] struct U;
16+
}
17+
}
18+
1319
fn main() {
1420
globnar::brotz!(); //~ ERROR non-ident macro paths are experimental
15-
::foo!(); //~ ERROR non-ident macro paths are experimental
16-
foo::<T>!(); //~ ERROR type parameters are not allowed on macros
1721
#[derive(foo::Bar)] struct T; //~ ERROR non-ident macro paths are experimental
22+
::foo!(); //~ ERROR non-ident macro paths are experimental
23+
24+
foo::<T>!();
25+
//~^ ERROR generic arguments in macro path
26+
//~| ERROR generic arguments in macro path
27+
//~| ERROR generic arguments in macro path
28+
foo::<>!();
29+
//~^ ERROR generic arguments in macro path
30+
//~| ERROR generic arguments in macro path
31+
//~| ERROR generic arguments in macro path
32+
m!(MyTrait<>);
33+
//~^ ERROR generic arguments in macro path
34+
//~| ERROR generic arguments in macro path
35+
//~| ERROR generic arguments in macro path
36+
//~| ERROR generic arguments in macro path
1837
}

src/test/compile-fail/privacy/restricted/ty-params.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ macro_rules! m {
1313
}
1414

1515
struct S<T>(T);
16-
m!{ S<u8> } //~ ERROR type or lifetime parameters in visibility path
16+
m!{ S<u8> } //~ ERROR generic arguments in visibility path
1717
//~^ ERROR expected module, found struct `S`
1818

19+
mod m {
20+
m!{ m<> } //~ ERROR generic arguments in visibility path
21+
}
22+
1923
fn main() {}

0 commit comments

Comments
 (0)