10276: internal: parser cleanup r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
bors[bot] 2021-09-18 13:09:51 +00:00 committed by GitHub
commit 7729473dd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 555 additions and 759 deletions

View File

@ -34,8 +34,8 @@ mod items;
mod params;
mod paths;
mod patterns;
mod type_args;
mod type_params;
mod generic_args;
mod generic_params;
mod types;
use crate::{

View File

@ -486,7 +486,7 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
let m = lhs.precede(p);
p.bump_any();
name_ref(p);
type_args::opt_generic_arg_list(p, true);
generic_args::opt_generic_arg_list(p, true);
if p.at(T!['(']) {
arg_list(p);
}

View File

@ -23,38 +23,6 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser, colon_colon_required: bool) {
m.complete(p, GENERIC_ARG_LIST);
}
pub(super) fn const_arg(p: &mut Parser) {
let m = p.start();
// FIXME: duplicates the code below
match p.current() {
T!['{'] => {
expressions::block_expr(p);
m.complete(p, CONST_ARG);
}
k if k.is_literal() => {
expressions::literal(p);
m.complete(p, CONST_ARG);
}
T![true] | T![false] => {
expressions::literal(p);
m.complete(p, CONST_ARG);
}
T![-] => {
let lm = p.start();
p.bump(T![-]);
expressions::literal(p);
lm.complete(p, PREFIX_EXPR);
m.complete(p, CONST_ARG);
}
_ => {
let lm = p.start();
paths::use_path(p);
lm.complete(p, PATH_EXPR);
m.complete(p, CONST_ARG);
}
}
}
// test type_arg
// type A = B<'static, i32, 1, { 2 }, Item=u64, true, false>;
fn generic_arg(p: &mut Parser) {
@ -83,7 +51,7 @@ fn generic_arg(p: &mut Parser) {
path_ty.abandon(p);
m.complete(p, ASSOC_TYPE_ARG);
}
T![:] if p.nth(1) == T![:] => {
T![:] if p.at(T![::]) => {
// NameRef::, this is a path type
path_seg.complete(p, PATH_SEGMENT);
let qual = path.complete(p, PATH);
@ -94,7 +62,7 @@ fn generic_arg(p: &mut Parser) {
}
// NameRef<...>:
T![:] => {
type_params::bounds(p);
generic_params::bounds(p);
path_seg.abandon(p);
path.abandon(p);
@ -137,3 +105,35 @@ fn generic_arg(p: &mut Parser) {
}
}
}
pub(super) fn const_arg(p: &mut Parser) {
let m = p.start();
// FIXME: duplicates the code above
match p.current() {
T!['{'] => {
expressions::block_expr(p);
m.complete(p, CONST_ARG);
}
k if k.is_literal() => {
expressions::literal(p);
m.complete(p, CONST_ARG);
}
T![true] | T![false] => {
expressions::literal(p);
m.complete(p, CONST_ARG);
}
T![-] => {
let lm = p.start();
p.bump(T![-]);
expressions::literal(p);
lm.complete(p, PREFIX_EXPR);
m.complete(p, CONST_ARG);
}
_ => {
let lm = p.start();
paths::use_path(p);
lm.complete(p, PATH_EXPR);
m.complete(p, CONST_ARG);
}
}
}

View File

@ -1,34 +1,20 @@
use super::*;
pub(super) fn opt_generic_param_list(p: &mut Parser) {
if !p.at(T![<]) {
return;
if p.at(T![<]) {
generic_param_list(p);
}
generic_param_list(p);
}
// test generic_param_list
// fn f<T: Clone>() {}
fn generic_param_list(p: &mut Parser) {
assert!(p.at(T![<]));
let m = p.start();
p.bump(T![<]);
while !p.at(EOF) && !p.at(T![>]) {
let m = p.start();
// test generic_lifetime_type_attribute
// fn foo<#[derive(Lifetime)] 'a, #[derive(Type)] T>(_: &'a T) {
// }
attributes::outer_attrs(p);
match p.current() {
LIFETIME_IDENT => lifetime_param(p, m),
IDENT => type_param(p, m),
T![const] => const_param(p, m),
_ => {
m.abandon(p);
p.err_and_bump("expected type parameter")
}
}
generic_param(p);
if !p.at(T![>]) && !p.expect(T![,]) {
break;
}
@ -37,6 +23,24 @@ fn generic_param_list(p: &mut Parser) {
m.complete(p, GENERIC_PARAM_LIST);
}
fn generic_param(p: &mut Parser) {
let m = p.start();
// test generic_param_attribute
// fn foo<#[lt_attr] 'a, #[t_attr] T>() {}
attributes::outer_attrs(p);
match p.current() {
LIFETIME_IDENT => lifetime_param(p, m),
IDENT => type_param(p, m),
T![const] => const_param(p, m),
_ => {
m.abandon(p);
p.err_and_bump("expected type parameter")
}
}
}
// test lifetime_param
// fn f<'a: 'b>() {}
fn lifetime_param(p: &mut Parser, m: Marker) {
assert!(p.at(LIFETIME_IDENT));
lifetime(p);
@ -46,15 +50,17 @@ fn lifetime_param(p: &mut Parser, m: Marker) {
m.complete(p, LIFETIME_PARAM);
}
// test type_param
// fn f<T: Clone>() {}
fn type_param(p: &mut Parser, m: Marker) {
assert!(p.at(IDENT));
name(p);
if p.at(T![:]) {
bounds(p);
}
// test type_param_default
// struct S<T = i32>;
if p.at(T![=]) {
// test type_param_default
// struct S<T = i32>;
p.bump(T![=]);
types::type_(p)
}
@ -64,7 +70,6 @@ fn type_param(p: &mut Parser, m: Marker) {
// test const_param
// struct S<const N: u32>;
fn const_param(p: &mut Parser, m: Marker) {
assert!(p.at(T![const]));
p.bump(T![const]);
name(p);
if p.at(T![:]) {
@ -73,26 +78,18 @@ fn const_param(p: &mut Parser, m: Marker) {
p.error("missing type for const parameter");
}
// test const_param_defaults
// struct A<const N: i32 = -1>;
// struct B<const N: i32 = {}>;
// struct C<const N: i32 = some::CONST>;
if p.at(T![=]) {
// test const_param_defaults
// struct A<const N: i32 = -1>;
// struct B<const N: i32 = {}>;
// struct C<const N: i32 = some::CONST>;
p.bump(T![=]);
type_args::const_arg(p);
generic_args::const_arg(p);
}
m.complete(p, CONST_PARAM);
}
// test type_param_bounds
// struct S<T: 'a + ?Sized + (Copy)>;
pub(super) fn bounds(p: &mut Parser) {
assert!(p.at(T![:]));
p.bump(T![:]);
bounds_without_colon(p);
}
fn lifetime_bounds(p: &mut Parser) {
assert!(p.at(T![:]));
p.bump(T![:]);
@ -104,21 +101,28 @@ fn lifetime_bounds(p: &mut Parser) {
}
}
// test type_param_bounds
// struct S<T: 'a + ?Sized + (Copy)>;
pub(super) fn bounds(p: &mut Parser) {
assert!(p.at(T![:]));
p.bump(T![:]);
bounds_without_colon(p);
}
pub(super) fn bounds_without_colon(p: &mut Parser) {
let m = p.start();
bounds_without_colon_m(p, m);
}
pub(super) fn bounds_without_colon_m(p: &mut Parser, marker: Marker) -> CompletedMarker {
while type_bound(p) {
if !p.eat(T![+]) {
break;
}
}
marker.complete(p, TYPE_BOUND_LIST)
}
pub(super) fn bounds_without_colon(p: &mut Parser) {
let m = p.start();
bounds_without_colon_m(p, m);
}
fn type_bound(p: &mut Parser) -> bool {
let m = p.start();
let has_paren = p.eat(T!['(']);
@ -160,8 +164,9 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
let comma = p.eat(T![,]);
if is_where_clause_end(p) {
break;
match p.current() {
T!['{'] | T![;] | T![=] => break,
_ => (),
}
if !comma {
@ -170,20 +175,16 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
}
m.complete(p, WHERE_CLAUSE);
}
fn is_where_predicate(p: &mut Parser) -> bool {
match p.current() {
LIFETIME_IDENT => true,
T![impl] => false,
token => types::TYPE_FIRST.contains(token),
fn is_where_predicate(p: &mut Parser) -> bool {
match p.current() {
LIFETIME_IDENT => true,
T![impl] => false,
token => types::TYPE_FIRST.contains(token),
}
}
}
fn is_where_clause_end(p: &mut Parser) -> bool {
matches!(p.current(), T!['{'] | T![;] | T![=])
}
fn where_predicate(p: &mut Parser) {
let m = p.start();
match p.current() {
@ -199,12 +200,12 @@ fn where_predicate(p: &mut Parser) {
p.error("expected lifetime or type");
}
_ => {
// test where_pred_for
// fn for_trait<F>()
// where
// for<'a> F: Fn(&'a str)
// { }
if p.at(T![for]) {
// test where_pred_for
// fn for_trait<F>()
// where
// for<'a> F: Fn(&'a str)
// { }
types::for_binder(p);
}

View File

@ -19,7 +19,7 @@ use super::*;
// struct S;
pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
attributes::inner_attrs(p);
while !(stop_on_r_curly && p.at(T!['}']) || p.at(EOF)) {
while !p.at(EOF) && !(p.at(T!['}']) && stop_on_r_curly) {
item_or_macro(p, stop_on_r_curly)
}
}
@ -284,15 +284,15 @@ fn type_alias(p: &mut Parser, m: Marker) {
// test type_item_type_params
// type Result<T> = ();
type_params::opt_generic_param_list(p);
generic_params::opt_generic_param_list(p);
if p.at(T![:]) {
type_params::bounds(p);
generic_params::bounds(p);
}
// test type_item_where_clause
// type Foo where Foo: Copy = ();
type_params::opt_where_clause(p);
generic_params::opt_where_clause(p);
if p.eat(T![=]) {
types::type_(p);
}
@ -383,7 +383,7 @@ fn fn_(p: &mut Parser, m: Marker) {
name_r(p, ITEM_RECOVERY_SET);
// test function_type_params
// fn foo<T: Clone + Copy>(){}
type_params::opt_generic_param_list(p);
generic_params::opt_generic_param_list(p);
if p.at(T!['(']) {
params::param_list_fn_def(p);
@ -397,7 +397,7 @@ fn fn_(p: &mut Parser, m: Marker) {
// test function_where_clause
// fn foo<T>() where T: Copy {}
type_params::opt_where_clause(p);
generic_params::opt_where_clause(p);
if p.at(T![;]) {
// test fn_decl

View File

@ -17,10 +17,10 @@ pub(super) fn union(p: &mut Parser, m: Marker) {
fn struct_or_union(p: &mut Parser, m: Marker, is_struct: bool) {
name_r(p, ITEM_RECOVERY_SET);
type_params::opt_generic_param_list(p);
generic_params::opt_generic_param_list(p);
match p.current() {
T![where] => {
type_params::opt_where_clause(p);
generic_params::opt_where_clause(p);
match p.current() {
T![;] => p.bump(T![;]),
T!['{'] => record_field_list(p),
@ -42,7 +42,7 @@ fn struct_or_union(p: &mut Parser, m: Marker, is_struct: bool) {
tuple_field_list(p);
// test tuple_struct_where
// struct S<T>(T) where T: Clone;
type_params::opt_where_clause(p);
generic_params::opt_where_clause(p);
p.expect(T![;]);
}
_ => p.error(if is_struct { "expected `;`, `{`, or `(`" } else { "expected `{`" }),
@ -53,8 +53,8 @@ fn struct_or_union(p: &mut Parser, m: Marker, is_struct: bool) {
pub(super) fn enum_(p: &mut Parser, m: Marker) {
p.bump(T![enum]);
name_r(p, ITEM_RECOVERY_SET);
type_params::opt_generic_param_list(p);
type_params::opt_where_clause(p);
generic_params::opt_generic_param_list(p);
generic_params::opt_where_clause(p);
if p.at(T!['{']) {
variant_list(p);
} else {

View File

@ -8,17 +8,17 @@ pub(super) fn trait_(p: &mut Parser, m: Marker) {
// test trait_item_generic_params
// trait X<U: Debug + Display> {}
type_params::opt_generic_param_list(p);
generic_params::opt_generic_param_list(p);
if p.eat(T![=]) {
// test trait_alias
// trait Z<U> = T<U>;
type_params::bounds_without_colon(p);
generic_params::bounds_without_colon(p);
// test trait_alias_where_clause
// trait Z<U> = T<U> where U: Copy;
// trait Z<U> = where Self: T<U>;
type_params::opt_where_clause(p);
generic_params::opt_where_clause(p);
p.expect(T![;]);
m.complete(p, TRAIT);
return;
@ -27,12 +27,12 @@ pub(super) fn trait_(p: &mut Parser, m: Marker) {
if p.at(T![:]) {
// test trait_item_bounds
// trait T: Hash + Clone {}
type_params::bounds(p);
generic_params::bounds(p);
}
// test trait_item_where_clause
// trait T where Self: Copy {}
type_params::opt_where_clause(p);
generic_params::opt_where_clause(p);
if p.at(T!['{']) {
assoc_item_list(p);
@ -47,7 +47,7 @@ pub(super) fn trait_(p: &mut Parser, m: Marker) {
pub(super) fn impl_(p: &mut Parser, m: Marker) {
p.bump(T![impl]);
if p.at(T![<]) && not_a_qualified_path(p) {
type_params::opt_generic_param_list(p);
generic_params::opt_generic_param_list(p);
}
// test impl_item_const
@ -64,7 +64,7 @@ pub(super) fn impl_(p: &mut Parser, m: Marker) {
if p.eat(T![for]) {
impl_type(p);
}
type_params::opt_where_clause(p);
generic_params::opt_where_clause(p);
if p.at(T!['{']) {
assoc_item_list(p);
} else {

View File

@ -1,99 +1,60 @@
use super::*;
// test use_item
// use std::collections;
pub(super) fn use_(p: &mut Parser, m: Marker) {
assert!(p.at(T![use]));
p.bump(T![use]);
use_tree(p, true);
p.expect(T![;]);
m.complete(p, USE);
}
/// Parse a use 'tree', such as `some::path` in `use some::path;`
/// Note that this is called both by `use_item` and `use_tree_list`,
/// so handles both `some::path::{inner::path}` and `inner::path` in
/// `use some::path::{inner::path};`
// test use_tree
// use outer::tree::{inner::tree};
fn use_tree(p: &mut Parser, top_level: bool) {
let m = p.start();
match p.current() {
// Finish the use_tree for cases of e.g.
// `use some::path::{self, *};` or `use *;`
// This does not handle cases such as `use some::path::*`
// N.B. in Rust 2015 `use *;` imports all from crate root
// however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates')
// FIXME: Add this error (if not out of scope)
// test use_star
// test use_tree_star
// use *;
// use ::*;
// use some::path::{*};
// use some::path::{::*};
// use std::{*};
T![*] => p.bump(T![*]),
// test use_tree_abs_star
// use ::*;
// use std::{::*};
T![:] if p.at(T![::]) && p.nth(2) == T![*] => {
// Parse `use ::*;`, which imports all from the crate root in Rust 2015
// This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`)
// but still parses and errors later: ('crate root in paths can only be used in start position')
// FIXME: Add this error (if not out of scope)
// In Rust 2018, it is always invalid (see above)
p.bump(T![::]);
p.bump(T![*]);
}
// Open a use tree list
// Handles cases such as `use {some::path};` or `{inner::path}` in
// `use some::path::{{inner::path}, other::path}`
// test use_tree_list
// use {crate::path::from::root, or::path::from::crate_name}; // Rust 2018 (with a crate named `or`)
// use {path::from::root}; // Rust 2015
// use ::{some::arbitrary::path}; // Rust 2015
// use ::{{{root::export}}}; // Nonsensical but perfectly legal nesting
T!['{'] => {
use_tree_list(p);
}
T!['{'] => use_tree_list(p),
T![:] if p.at(T![::]) && p.nth(2) == T!['{'] => {
p.bump(T![::]);
use_tree_list(p);
}
// Parse a 'standard' path.
// Also handles aliases (e.g. `use something as something_else`)
// test use_path
// use ::crate_name; // Rust 2018 - All flavours
// use crate_name; // Rust 2018 - Anchored paths
// use item_in_scope_or_crate_name; // Rust 2018 - Uniform Paths
// test use_tree_path
// use ::std;
// use std::collections;
//
// use self::module::Item;
// use crate::Item;
// use self::some::Struct;
// use crate_name::some_item;
// use self::m;
// use super::m;
// use crate::m;
_ if paths::is_use_path_start(p) => {
paths::use_path(p);
match p.current() {
T![as] => {
// test use_alias
// use some::path as some_name;
// use some::{
// other::path as some_other_name,
// different::path as different_name,
// yet::another::path,
// running::out::of::synonyms::for_::different::*
// };
// use Trait as _;
opt_rename(p);
}
// test use_tree_alias
// use std as stdlib;
// use Trait as _;
T![as] => opt_rename(p),
T![:] if p.at(T![::]) => {
p.bump(T![::]);
match p.current() {
T![*] => {
p.bump(T![*]);
}
// test use_tree_list_after_path
// use crate::{Item};
// use self::{Item};
// test use_tree_path_star
// use std::*;
T![*] => p.bump(T![*]),
// test use_tree_path_use_tree
// use std::{collections};
T!['{'] => use_tree_list(p),
_ => {
// is this unreachable?
p.error("expected `{` or `*`");
}
_ => p.error("expected `{` or `*`"),
}
}
_ => (),
@ -115,6 +76,8 @@ fn use_tree(p: &mut Parser, top_level: bool) {
m.complete(p, USE_TREE);
}
// test use_tree_list
// use {a, b, c};
pub(crate) fn use_tree_list(p: &mut Parser) {
assert!(p.at(T!['{']));
let m = p.start();

View File

@ -117,9 +117,9 @@ fn opt_path_type_args(p: &mut Parser, mode: Mode) {
params::param_list_fn_trait(p);
opt_ret_type(p);
} else {
type_args::opt_generic_arg_list(p, false)
generic_args::opt_generic_arg_list(p, false)
}
}
Mode::Expr => type_args::opt_generic_arg_list(p, true),
Mode::Expr => generic_args::opt_generic_arg_list(p, true),
}
}

View File

@ -216,7 +216,7 @@ pub(super) fn for_binder(p: &mut Parser) {
assert!(p.at(T![for]));
p.bump(T![for]);
if p.at(T![<]) {
type_params::opt_generic_param_list(p);
generic_params::opt_generic_param_list(p);
} else {
p.error("expected `<`");
}
@ -254,7 +254,7 @@ fn impl_trait_type(p: &mut Parser) {
assert!(p.at(T![impl]));
let m = p.start();
p.bump(T![impl]);
type_params::bounds_without_colon(p);
generic_params::bounds_without_colon(p);
m.complete(p, IMPL_TRAIT_TYPE);
}
@ -264,7 +264,7 @@ fn dyn_trait_type(p: &mut Parser) {
assert!(p.at(T![dyn]));
let m = p.start();
p.bump(T![dyn]);
type_params::bounds_without_colon(p);
generic_params::bounds_without_colon(p);
m.complete(p, DYN_TRAIT_TYPE);
}
@ -339,7 +339,7 @@ fn opt_type_bounds_as_dyn_trait_type(p: &mut Parser, type_marker: CompletedMarke
p.eat(T![+]);
// Parse rest of the bounds into the TYPE_BOUND_LIST
let m = type_params::bounds_without_colon_m(p, m);
let m = generic_params::bounds_without_colon_m(p, m);
// Finally precede everything with DYN_TRAIT_TYPE
m.precede(p).complete(p, DYN_TRAIT_TYPE);

View File

@ -1,137 +1,29 @@
SOURCE_FILE@0..248
USE@0..58
SOURCE_FILE@0..15
USE@0..14
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..57
USE_TREE_LIST@4..57
USE_TREE@4..13
USE_TREE_LIST@4..13
L_CURLY@4..5 "{"
USE_TREE@5..28
PATH@5..28
PATH@5..22
PATH@5..16
PATH@5..10
PATH_SEGMENT@5..10
NAME_REF@5..10
CRATE_KW@5..10 "crate"
COLON2@10..12 "::"
PATH_SEGMENT@12..16
NAME_REF@12..16
IDENT@12..16 "path"
COLON2@16..18 "::"
PATH_SEGMENT@18..22
NAME_REF@18..22
IDENT@18..22 "from"
COLON2@22..24 "::"
PATH_SEGMENT@24..28
NAME_REF@24..28
IDENT@24..28 "root"
COMMA@28..29 ","
WHITESPACE@29..30 " "
USE_TREE@30..56
PATH@30..56
PATH@30..44
PATH@30..38
PATH@30..32
PATH_SEGMENT@30..32
NAME_REF@30..32
IDENT@30..32 "or"
COLON2@32..34 "::"
PATH_SEGMENT@34..38
NAME_REF@34..38
IDENT@34..38 "path"
COLON2@38..40 "::"
PATH_SEGMENT@40..44
NAME_REF@40..44
IDENT@40..44 "from"
COLON2@44..46 "::"
PATH_SEGMENT@46..56
NAME_REF@46..56
IDENT@46..56 "crate_name"
R_CURLY@56..57 "}"
SEMICOLON@57..58 ";"
WHITESPACE@58..59 " "
USE@59..121
COMMENT@59..97 "// Rust 2018 (with a ..."
WHITESPACE@97..98 "\n"
USE_KW@98..101 "use"
WHITESPACE@101..102 " "
USE_TREE@102..120
USE_TREE_LIST@102..120
L_CURLY@102..103 "{"
USE_TREE@103..119
PATH@103..119
PATH@103..113
PATH@103..107
PATH_SEGMENT@103..107
NAME_REF@103..107
IDENT@103..107 "path"
COLON2@107..109 "::"
PATH_SEGMENT@109..113
NAME_REF@109..113
IDENT@109..113 "from"
COLON2@113..115 "::"
PATH_SEGMENT@115..119
NAME_REF@115..119
IDENT@115..119 "root"
R_CURLY@119..120 "}"
SEMICOLON@120..121 ";"
WHITESPACE@121..122 " "
USE@122..165
COMMENT@122..134 "// Rust 2015"
WHITESPACE@134..135 "\n"
USE_KW@135..138 "use"
WHITESPACE@138..139 " "
USE_TREE@139..164
COLON2@139..141 "::"
USE_TREE_LIST@141..164
L_CURLY@141..142 "{"
USE_TREE@142..163
PATH@142..163
PATH@142..157
PATH@142..146
PATH_SEGMENT@142..146
NAME_REF@142..146
IDENT@142..146 "some"
COLON2@146..148 "::"
PATH_SEGMENT@148..157
NAME_REF@148..157
IDENT@148..157 "arbitrary"
COLON2@157..159 "::"
PATH_SEGMENT@159..163
NAME_REF@159..163
IDENT@159..163 "path"
R_CURLY@163..164 "}"
SEMICOLON@164..165 ";"
WHITESPACE@165..166 " "
USE@166..204
COMMENT@166..178 "// Rust 2015"
WHITESPACE@178..179 "\n"
USE_KW@179..182 "use"
WHITESPACE@182..183 " "
USE_TREE@183..203
COLON2@183..185 "::"
USE_TREE_LIST@185..203
L_CURLY@185..186 "{"
USE_TREE@186..202
USE_TREE_LIST@186..202
L_CURLY@186..187 "{"
USE_TREE@187..201
USE_TREE_LIST@187..201
L_CURLY@187..188 "{"
USE_TREE@188..200
PATH@188..200
PATH@188..192
PATH_SEGMENT@188..192
NAME_REF@188..192
IDENT@188..192 "root"
COLON2@192..194 "::"
PATH_SEGMENT@194..200
NAME_REF@194..200
IDENT@194..200 "export"
R_CURLY@200..201 "}"
R_CURLY@201..202 "}"
R_CURLY@202..203 "}"
SEMICOLON@203..204 ";"
WHITESPACE@204..205 " "
COMMENT@205..247 "// Nonsensical but pe ..."
WHITESPACE@247..248 "\n"
USE_TREE@5..6
PATH@5..6
PATH_SEGMENT@5..6
NAME_REF@5..6
IDENT@5..6 "a"
COMMA@6..7 ","
WHITESPACE@7..8 " "
USE_TREE@8..9
PATH@8..9
PATH_SEGMENT@8..9
NAME_REF@8..9
IDENT@8..9 "b"
COMMA@9..10 ","
WHITESPACE@10..11 " "
USE_TREE@11..12
PATH@11..12
PATH_SEGMENT@11..12
NAME_REF@11..12
IDENT@11..12 "c"
R_CURLY@12..13 "}"
SEMICOLON@13..14 ";"
WHITESPACE@14..15 "\n"

View File

@ -1,4 +1 @@
use {crate::path::from::root, or::path::from::crate_name}; // Rust 2018 (with a crate named `or`)
use {path::from::root}; // Rust 2015
use ::{some::arbitrary::path}; // Rust 2015
use ::{{{root::export}}}; // Nonsensical but perfectly legal nesting
use {a, b, c};

View File

@ -1,59 +0,0 @@
SOURCE_FILE@0..60
USE@0..6
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..5
STAR@4..5 "*"
SEMICOLON@5..6 ";"
WHITESPACE@6..7 "\n"
USE@7..15
USE_KW@7..10 "use"
WHITESPACE@10..11 " "
USE_TREE@11..14
COLON2@11..13 "::"
STAR@13..14 "*"
SEMICOLON@14..15 ";"
WHITESPACE@15..16 "\n"
USE@16..36
USE_KW@16..19 "use"
WHITESPACE@19..20 " "
USE_TREE@20..35
PATH@20..30
PATH@20..24
PATH_SEGMENT@20..24
NAME_REF@20..24
IDENT@20..24 "some"
COLON2@24..26 "::"
PATH_SEGMENT@26..30
NAME_REF@26..30
IDENT@26..30 "path"
COLON2@30..32 "::"
USE_TREE_LIST@32..35
L_CURLY@32..33 "{"
USE_TREE@33..34
STAR@33..34 "*"
R_CURLY@34..35 "}"
SEMICOLON@35..36 ";"
WHITESPACE@36..37 "\n"
USE@37..59
USE_KW@37..40 "use"
WHITESPACE@40..41 " "
USE_TREE@41..58
PATH@41..51
PATH@41..45
PATH_SEGMENT@41..45
NAME_REF@41..45
IDENT@41..45 "some"
COLON2@45..47 "::"
PATH_SEGMENT@47..51
NAME_REF@47..51
IDENT@47..51 "path"
COLON2@51..53 "::"
USE_TREE_LIST@53..58
L_CURLY@53..54 "{"
USE_TREE@54..57
COLON2@54..56 "::"
STAR@56..57 "*"
R_CURLY@57..58 "}"
SEMICOLON@58..59 ";"
WHITESPACE@59..60 "\n"

View File

@ -1,4 +0,0 @@
use *;
use ::*;
use some::path::{*};
use some::path::{::*};

View File

@ -1,138 +0,0 @@
SOURCE_FILE@0..198
USE@0..28
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..27
PATH@4..14
PATH@4..8
PATH_SEGMENT@4..8
NAME_REF@4..8
IDENT@4..8 "some"
COLON2@8..10 "::"
PATH_SEGMENT@10..14
NAME_REF@10..14
IDENT@10..14 "path"
WHITESPACE@14..15 " "
RENAME@15..27
AS_KW@15..17 "as"
WHITESPACE@17..18 " "
NAME@18..27
IDENT@18..27 "some_name"
SEMICOLON@27..28 ";"
WHITESPACE@28..29 "\n"
USE@29..181
USE_KW@29..32 "use"
WHITESPACE@32..33 " "
USE_TREE@33..180
PATH@33..37
PATH_SEGMENT@33..37
NAME_REF@33..37
IDENT@33..37 "some"
COLON2@37..39 "::"
USE_TREE_LIST@39..180
L_CURLY@39..40 "{"
WHITESPACE@40..42 "\n "
USE_TREE@42..72
PATH@42..53
PATH@42..47
PATH_SEGMENT@42..47
NAME_REF@42..47
IDENT@42..47 "other"
COLON2@47..49 "::"
PATH_SEGMENT@49..53
NAME_REF@49..53
IDENT@49..53 "path"
WHITESPACE@53..54 " "
RENAME@54..72
AS_KW@54..56 "as"
WHITESPACE@56..57 " "
NAME@57..72
IDENT@57..72 "some_other_name"
COMMA@72..73 ","
WHITESPACE@73..75 "\n "
USE_TREE@75..108
PATH@75..90
PATH@75..84
PATH_SEGMENT@75..84
NAME_REF@75..84
IDENT@75..84 "different"
COLON2@84..86 "::"
PATH_SEGMENT@86..90
NAME_REF@86..90
IDENT@86..90 "path"
WHITESPACE@90..91 " "
RENAME@91..108
AS_KW@91..93 "as"
WHITESPACE@93..94 " "
NAME@94..108
IDENT@94..108 "different_name"
COMMA@108..109 ","
WHITESPACE@109..111 "\n "
USE_TREE@111..129
PATH@111..129
PATH@111..123
PATH@111..114
PATH_SEGMENT@111..114
NAME_REF@111..114
IDENT@111..114 "yet"
COLON2@114..116 "::"
PATH_SEGMENT@116..123
NAME_REF@116..123
IDENT@116..123 "another"
COLON2@123..125 "::"
PATH_SEGMENT@125..129
NAME_REF@125..129
IDENT@125..129 "path"
COMMA@129..130 ","
WHITESPACE@130..132 "\n "
USE_TREE@132..178
PATH@132..175
PATH@132..164
PATH@132..158
PATH@132..148
PATH@132..144
PATH@132..139
PATH_SEGMENT@132..139
NAME_REF@132..139
IDENT@132..139 "running"
COLON2@139..141 "::"
PATH_SEGMENT@141..144
NAME_REF@141..144
IDENT@141..144 "out"
COLON2@144..146 "::"
PATH_SEGMENT@146..148
NAME_REF@146..148
IDENT@146..148 "of"
COLON2@148..150 "::"
PATH_SEGMENT@150..158
NAME_REF@150..158
IDENT@150..158 "synonyms"
COLON2@158..160 "::"
PATH_SEGMENT@160..164
NAME_REF@160..164
IDENT@160..164 "for_"
COLON2@164..166 "::"
PATH_SEGMENT@166..175
NAME_REF@166..175
IDENT@166..175 "different"
COLON2@175..177 "::"
STAR@177..178 "*"
WHITESPACE@178..179 "\n"
R_CURLY@179..180 "}"
SEMICOLON@180..181 ";"
WHITESPACE@181..182 "\n"
USE@182..197
USE_KW@182..185 "use"
WHITESPACE@185..186 " "
USE_TREE@186..196
PATH@186..191
PATH_SEGMENT@186..191
NAME_REF@186..191
IDENT@186..191 "Trait"
WHITESPACE@191..192 " "
RENAME@192..196
AS_KW@192..194 "as"
WHITESPACE@194..195 " "
UNDERSCORE@195..196 "_"
SEMICOLON@196..197 ";"
WHITESPACE@197..198 "\n"

View File

@ -1,8 +0,0 @@
use some::path as some_name;
use some::{
other::path as some_other_name,
different::path as different_name,
yet::another::path,
running::out::of::synonyms::for_::different::*
};
use Trait as _;

View File

@ -1,39 +0,0 @@
SOURCE_FILE@0..37
USE@0..18
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..17
PATH@4..9
PATH_SEGMENT@4..9
NAME_REF@4..9
CRATE_KW@4..9 "crate"
COLON2@9..11 "::"
USE_TREE_LIST@11..17
L_CURLY@11..12 "{"
USE_TREE@12..16
PATH@12..16
PATH_SEGMENT@12..16
NAME_REF@12..16
IDENT@12..16 "Item"
R_CURLY@16..17 "}"
SEMICOLON@17..18 ";"
WHITESPACE@18..19 "\n"
USE@19..36
USE_KW@19..22 "use"
WHITESPACE@22..23 " "
USE_TREE@23..35
PATH@23..27
PATH_SEGMENT@23..27
NAME_REF@23..27
SELF_KW@23..27 "self"
COLON2@27..29 "::"
USE_TREE_LIST@29..35
L_CURLY@29..30 "{"
USE_TREE@30..34
PATH@30..34
PATH_SEGMENT@30..34
NAME_REF@30..34
IDENT@30..34 "Item"
R_CURLY@34..35 "}"
SEMICOLON@35..36 ";"
WHITESPACE@36..37 "\n"

View File

@ -1,2 +0,0 @@
use crate::{Item};
use self::{Item};

View File

@ -1,108 +0,0 @@
SOURCE_FILE@0..247
USE@0..17
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..16
PATH@4..16
PATH_SEGMENT@4..16
COLON2@4..6 "::"
NAME_REF@6..16
IDENT@6..16 "crate_name"
SEMICOLON@16..17 ";"
WHITESPACE@17..18 " "
USE@18..61
COMMENT@18..45 "// Rust 2018 - All fl ..."
WHITESPACE@45..46 "\n"
USE_KW@46..49 "use"
WHITESPACE@49..50 " "
USE_TREE@50..60
PATH@50..60
PATH_SEGMENT@50..60
NAME_REF@50..60
IDENT@50..60 "crate_name"
SEMICOLON@60..61 ";"
WHITESPACE@61..62 " "
USE@62..124
COMMENT@62..91 "// Rust 2018 - Anchor ..."
WHITESPACE@91..92 "\n"
USE_KW@92..95 "use"
WHITESPACE@95..96 " "
USE_TREE@96..123
PATH@96..123
PATH_SEGMENT@96..123
NAME_REF@96..123
IDENT@96..123 "item_in_scope_or_crat ..."
SEMICOLON@123..124 ";"
WHITESPACE@124..125 " "
COMMENT@125..153 "// Rust 2018 - Unifor ..."
WHITESPACE@153..155 "\n\n"
USE@155..178
USE_KW@155..158 "use"
WHITESPACE@158..159 " "
USE_TREE@159..177
PATH@159..177
PATH@159..171
PATH@159..163
PATH_SEGMENT@159..163
NAME_REF@159..163
SELF_KW@159..163 "self"
COLON2@163..165 "::"
PATH_SEGMENT@165..171
NAME_REF@165..171
IDENT@165..171 "module"
COLON2@171..173 "::"
PATH_SEGMENT@173..177
NAME_REF@173..177
IDENT@173..177 "Item"
SEMICOLON@177..178 ";"
WHITESPACE@178..179 "\n"
USE@179..195
USE_KW@179..182 "use"
WHITESPACE@182..183 " "
USE_TREE@183..194
PATH@183..194
PATH@183..188
PATH_SEGMENT@183..188
NAME_REF@183..188
CRATE_KW@183..188 "crate"
COLON2@188..190 "::"
PATH_SEGMENT@190..194
NAME_REF@190..194
IDENT@190..194 "Item"
SEMICOLON@194..195 ";"
WHITESPACE@195..196 "\n"
USE@196..219
USE_KW@196..199 "use"
WHITESPACE@199..200 " "
USE_TREE@200..218
PATH@200..218
PATH@200..210
PATH@200..204
PATH_SEGMENT@200..204
NAME_REF@200..204
SELF_KW@200..204 "self"
COLON2@204..206 "::"
PATH_SEGMENT@206..210
NAME_REF@206..210
IDENT@206..210 "some"
COLON2@210..212 "::"
PATH_SEGMENT@212..218
NAME_REF@212..218
IDENT@212..218 "Struct"
SEMICOLON@218..219 ";"
WHITESPACE@219..220 "\n"
USE@220..246
USE_KW@220..223 "use"
WHITESPACE@223..224 " "
USE_TREE@224..245
PATH@224..245
PATH@224..234
PATH_SEGMENT@224..234
NAME_REF@224..234
IDENT@224..234 "crate_name"
COLON2@234..236 "::"
PATH_SEGMENT@236..245
NAME_REF@236..245
IDENT@236..245 "some_item"
SEMICOLON@245..246 ";"
WHITESPACE@246..247 "\n"

View File

@ -1,8 +0,0 @@
use ::crate_name; // Rust 2018 - All flavours
use crate_name; // Rust 2018 - Anchored paths
use item_in_scope_or_crate_name; // Rust 2018 - Uniform Paths
use self::module::Item;
use crate::Item;
use self::some::Struct;
use crate_name::some_item;

View File

@ -1,69 +0,0 @@
SOURCE_FILE@0..64
FN@0..63
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..6
IDENT@3..6 "foo"
GENERIC_PARAM_LIST@6..49
L_ANGLE@6..7 "<"
LIFETIME_PARAM@7..29
ATTR@7..26
POUND@7..8 "#"
L_BRACK@8..9 "["
META@9..25
PATH@9..15
PATH_SEGMENT@9..15
NAME_REF@9..15
IDENT@9..15 "derive"
TOKEN_TREE@15..25
L_PAREN@15..16 "("
IDENT@16..24 "Lifetime"
R_PAREN@24..25 ")"
R_BRACK@25..26 "]"
WHITESPACE@26..27 " "
LIFETIME@27..29
LIFETIME_IDENT@27..29 "'a"
COMMA@29..30 ","
WHITESPACE@30..31 " "
TYPE_PARAM@31..48
ATTR@31..46
POUND@31..32 "#"
L_BRACK@32..33 "["
META@33..45
PATH@33..39
PATH_SEGMENT@33..39
NAME_REF@33..39
IDENT@33..39 "derive"
TOKEN_TREE@39..45
L_PAREN@39..40 "("
IDENT@40..44 "Type"
R_PAREN@44..45 ")"
R_BRACK@45..46 "]"
WHITESPACE@46..47 " "
NAME@47..48
IDENT@47..48 "T"
R_ANGLE@48..49 ">"
PARAM_LIST@49..59
L_PAREN@49..50 "("
PARAM@50..58
WILDCARD_PAT@50..51
UNDERSCORE@50..51 "_"
COLON@51..52 ":"
WHITESPACE@52..53 " "
REF_TYPE@53..58
AMP@53..54 "&"
LIFETIME@54..56
LIFETIME_IDENT@54..56 "'a"
WHITESPACE@56..57 " "
PATH_TYPE@57..58
PATH@57..58
PATH_SEGMENT@57..58
NAME_REF@57..58
IDENT@57..58 "T"
R_PAREN@58..59 ")"
WHITESPACE@59..60 " "
BLOCK_EXPR@60..63
L_CURLY@60..61 "{"
WHITESPACE@61..62 "\n"
R_CURLY@62..63 "}"
WHITESPACE@63..64 "\n"

View File

@ -1,2 +0,0 @@
fn foo<#[derive(Lifetime)] 'a, #[derive(Type)] T>(_: &'a T) {
}

View File

@ -0,0 +1,24 @@
SOURCE_FILE@0..21
USE@0..6
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..5
STAR@4..5 "*"
SEMICOLON@5..6 ";"
WHITESPACE@6..7 "\n"
USE@7..20
USE_KW@7..10 "use"
WHITESPACE@10..11 " "
USE_TREE@11..19
PATH@11..14
PATH_SEGMENT@11..14
NAME_REF@11..14
IDENT@11..14 "std"
COLON2@14..16 "::"
USE_TREE_LIST@16..19
L_CURLY@16..17 "{"
USE_TREE@17..18
STAR@17..18 "*"
R_CURLY@18..19 "}"
SEMICOLON@19..20 ";"
WHITESPACE@20..21 "\n"

View File

@ -0,0 +1,2 @@
use *;
use std::{*};

View File

@ -0,0 +1,32 @@
SOURCE_FILE@0..35
USE@0..18
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..17
PATH@4..7
PATH_SEGMENT@4..7
NAME_REF@4..7
IDENT@4..7 "std"
WHITESPACE@7..8 " "
RENAME@8..17
AS_KW@8..10 "as"
WHITESPACE@10..11 " "
NAME@11..17
IDENT@11..17 "stdlib"
SEMICOLON@17..18 ";"
WHITESPACE@18..19 "\n"
USE@19..34
USE_KW@19..22 "use"
WHITESPACE@22..23 " "
USE_TREE@23..33
PATH@23..28
PATH_SEGMENT@23..28
NAME_REF@23..28
IDENT@23..28 "Trait"
WHITESPACE@28..29 " "
RENAME@29..33
AS_KW@29..31 "as"
WHITESPACE@31..32 " "
UNDERSCORE@32..33 "_"
SEMICOLON@33..34 ";"
WHITESPACE@34..35 "\n"

View File

@ -0,0 +1,2 @@
use std as stdlib;
use Trait as _;

View File

@ -0,0 +1,30 @@
SOURCE_FILE@0..32
USE@0..31
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..30
PATH@4..15
PATH@4..9
PATH_SEGMENT@4..9
NAME_REF@4..9
IDENT@4..9 "outer"
COLON2@9..11 "::"
PATH_SEGMENT@11..15
NAME_REF@11..15
IDENT@11..15 "tree"
COLON2@15..17 "::"
USE_TREE_LIST@17..30
L_CURLY@17..18 "{"
USE_TREE@18..29
PATH@18..29
PATH@18..23
PATH_SEGMENT@18..23
NAME_REF@18..23
IDENT@18..23 "inner"
COLON2@23..25 "::"
PATH_SEGMENT@25..29
NAME_REF@25..29
IDENT@25..29 "tree"
R_CURLY@29..30 "}"
SEMICOLON@30..31 ";"
WHITESPACE@31..32 "\n"

View File

@ -0,0 +1 @@
use outer::tree::{inner::tree};

View File

@ -0,0 +1,72 @@
SOURCE_FILE@0..75
USE@0..10
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..9
PATH@4..9
PATH_SEGMENT@4..9
COLON2@4..6 "::"
NAME_REF@6..9
IDENT@6..9 "std"
SEMICOLON@9..10 ";"
WHITESPACE@10..11 "\n"
USE@11..32
USE_KW@11..14 "use"
WHITESPACE@14..15 " "
USE_TREE@15..31
PATH@15..31
PATH@15..18
PATH_SEGMENT@15..18
NAME_REF@15..18
IDENT@15..18 "std"
COLON2@18..20 "::"
PATH_SEGMENT@20..31
NAME_REF@20..31
IDENT@20..31 "collections"
SEMICOLON@31..32 ";"
WHITESPACE@32..34 "\n\n"
USE@34..46
USE_KW@34..37 "use"
WHITESPACE@37..38 " "
USE_TREE@38..45
PATH@38..45
PATH@38..42
PATH_SEGMENT@38..42
NAME_REF@38..42
SELF_KW@38..42 "self"
COLON2@42..44 "::"
PATH_SEGMENT@44..45
NAME_REF@44..45
IDENT@44..45 "m"
SEMICOLON@45..46 ";"
WHITESPACE@46..47 "\n"
USE@47..60
USE_KW@47..50 "use"
WHITESPACE@50..51 " "
USE_TREE@51..59
PATH@51..59
PATH@51..56
PATH_SEGMENT@51..56
NAME_REF@51..56
SUPER_KW@51..56 "super"
COLON2@56..58 "::"
PATH_SEGMENT@58..59
NAME_REF@58..59
IDENT@58..59 "m"
SEMICOLON@59..60 ";"
WHITESPACE@60..61 "\n"
USE@61..74
USE_KW@61..64 "use"
WHITESPACE@64..65 " "
USE_TREE@65..73
PATH@65..73
PATH@65..70
PATH_SEGMENT@65..70
NAME_REF@65..70
CRATE_KW@65..70 "crate"
COLON2@70..72 "::"
PATH_SEGMENT@72..73
NAME_REF@72..73
IDENT@72..73 "m"
SEMICOLON@73..74 ";"
WHITESPACE@74..75 "\n"

View File

@ -0,0 +1,6 @@
use ::std;
use std::collections;
use self::m;
use super::m;
use crate::m;

View File

@ -0,0 +1,20 @@
SOURCE_FILE@0..24
USE@0..23
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..22
PATH@4..7
PATH_SEGMENT@4..7
NAME_REF@4..7
IDENT@4..7 "std"
COLON2@7..9 "::"
USE_TREE_LIST@9..22
L_CURLY@9..10 "{"
USE_TREE@10..21
PATH@10..21
PATH_SEGMENT@10..21
NAME_REF@10..21
IDENT@10..21 "collections"
R_CURLY@21..22 "}"
SEMICOLON@22..23 ";"
WHITESPACE@23..24 "\n"

View File

@ -0,0 +1 @@
use std::{collections};

View File

@ -0,0 +1,26 @@
SOURCE_FILE@0..25
USE@0..8
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..7
COLON2@4..6 "::"
STAR@6..7 "*"
SEMICOLON@7..8 ";"
WHITESPACE@8..9 "\n"
USE@9..24
USE_KW@9..12 "use"
WHITESPACE@12..13 " "
USE_TREE@13..23
PATH@13..16
PATH_SEGMENT@13..16
NAME_REF@13..16
IDENT@13..16 "std"
COLON2@16..18 "::"
USE_TREE_LIST@18..23
L_CURLY@18..19 "{"
USE_TREE@19..22
COLON2@19..21 "::"
STAR@21..22 "*"
R_CURLY@22..23 "}"
SEMICOLON@23..24 ";"
WHITESPACE@24..25 "\n"

View File

@ -0,0 +1,2 @@
use ::*;
use std::{::*};

View File

@ -0,0 +1,13 @@
SOURCE_FILE@0..12
USE@0..11
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..10
PATH@4..7
PATH_SEGMENT@4..7
NAME_REF@4..7
IDENT@4..7 "std"
COLON2@7..9 "::"
STAR@9..10 "*"
SEMICOLON@10..11 ";"
WHITESPACE@11..12 "\n"

View File

@ -0,0 +1 @@
use std::*;

View File

@ -0,0 +1,45 @@
SOURCE_FILE@0..40
FN@0..39
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..6
IDENT@3..6 "foo"
GENERIC_PARAM_LIST@6..34
L_ANGLE@6..7 "<"
LIFETIME_PARAM@7..20
ATTR@7..17
POUND@7..8 "#"
L_BRACK@8..9 "["
META@9..16
PATH@9..16
PATH_SEGMENT@9..16
NAME_REF@9..16
IDENT@9..16 "lt_attr"
R_BRACK@16..17 "]"
WHITESPACE@17..18 " "
LIFETIME@18..20
LIFETIME_IDENT@18..20 "'a"
COMMA@20..21 ","
WHITESPACE@21..22 " "
TYPE_PARAM@22..33
ATTR@22..31
POUND@22..23 "#"
L_BRACK@23..24 "["
META@24..30
PATH@24..30
PATH_SEGMENT@24..30
NAME_REF@24..30
IDENT@24..30 "t_attr"
R_BRACK@30..31 "]"
WHITESPACE@31..32 " "
NAME@32..33
IDENT@32..33 "T"
R_ANGLE@33..34 ">"
PARAM_LIST@34..36
L_PAREN@34..35 "("
R_PAREN@35..36 ")"
WHITESPACE@36..37 " "
BLOCK_EXPR@37..39
L_CURLY@37..38 "{"
R_CURLY@38..39 "}"
WHITESPACE@39..40 "\n"

View File

@ -0,0 +1 @@
fn foo<#[lt_attr] 'a, #[t_attr] T>() {}

View File

@ -0,0 +1,16 @@
SOURCE_FILE@0..22
USE@0..21
USE_KW@0..3 "use"
WHITESPACE@3..4 " "
USE_TREE@4..20
PATH@4..20
PATH@4..7
PATH_SEGMENT@4..7
NAME_REF@4..7
IDENT@4..7 "std"
COLON2@7..9 "::"
PATH_SEGMENT@9..20
NAME_REF@9..20
IDENT@9..20 "collections"
SEMICOLON@20..21 ";"
WHITESPACE@21..22 "\n"

View File

@ -0,0 +1 @@
use std::collections;

View File

@ -0,0 +1,24 @@
SOURCE_FILE@0..18
FN@0..17
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..4
IDENT@3..4 "f"
GENERIC_PARAM_LIST@4..12
L_ANGLE@4..5 "<"
LIFETIME_PARAM@5..11
LIFETIME@5..7
LIFETIME_IDENT@5..7 "'a"
COLON@7..8 ":"
WHITESPACE@8..9 " "
LIFETIME@9..11
LIFETIME_IDENT@9..11 "'b"
R_ANGLE@11..12 ">"
PARAM_LIST@12..14
L_PAREN@12..13 "("
R_PAREN@13..14 ")"
WHITESPACE@14..15 " "
BLOCK_EXPR@15..17
L_CURLY@15..16 "{"
R_CURLY@16..17 "}"
WHITESPACE@17..18 "\n"

View File

@ -0,0 +1 @@
fn f<'a: 'b>() {}

View File

@ -0,0 +1,29 @@
SOURCE_FILE@0..20
FN@0..19
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..4
IDENT@3..4 "f"
GENERIC_PARAM_LIST@4..14
L_ANGLE@4..5 "<"
TYPE_PARAM@5..13
NAME@5..6
IDENT@5..6 "T"
COLON@6..7 ":"
WHITESPACE@7..8 " "
TYPE_BOUND_LIST@8..13
TYPE_BOUND@8..13
PATH_TYPE@8..13
PATH@8..13
PATH_SEGMENT@8..13
NAME_REF@8..13
IDENT@8..13 "Clone"
R_ANGLE@13..14 ">"
PARAM_LIST@14..16
L_PAREN@14..15 "("
R_PAREN@15..16 ")"
WHITESPACE@16..17 " "
BLOCK_EXPR@17..19
L_CURLY@17..18 "{"
R_CURLY@18..19 "}"
WHITESPACE@19..20 "\n"

View File

@ -0,0 +1 @@
fn f<T: Clone>() {}

View File

@ -0,0 +1,29 @@
SOURCE_FILE@0..20
FN@0..19
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..4
IDENT@3..4 "f"
GENERIC_PARAM_LIST@4..14
L_ANGLE@4..5 "<"
TYPE_PARAM@5..13
NAME@5..6
IDENT@5..6 "T"
COLON@6..7 ":"
WHITESPACE@7..8 " "
TYPE_BOUND_LIST@8..13
TYPE_BOUND@8..13
PATH_TYPE@8..13
PATH@8..13
PATH_SEGMENT@8..13
NAME_REF@8..13
IDENT@8..13 "Clone"
R_ANGLE@13..14 ">"
PARAM_LIST@14..16
L_PAREN@14..15 "("
R_PAREN@15..16 ")"
WHITESPACE@16..17 " "
BLOCK_EXPR@17..19
L_CURLY@17..18 "{"
R_CURLY@18..19 "}"
WHITESPACE@19..20 "\n"

View File

@ -0,0 +1 @@
fn f<T: Clone>() {}