diff options
| author | bors <bors@rust-lang.org> | 2014-11-07 00:02:18 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-11-07 00:02:18 +0000 |
| commit | 45cbdec4174778bf915f17561ef971c068a7fcbc (patch) | |
| tree | 9516c60b7323f1233858665501a5029c9c3f90f0 /src/libsyntax | |
| parent | 8ed288edb27fc83b15a549af69c82b5bb4f8ac1e (diff) | |
| parent | d27039d701a3c6e97f19e41436d06ed42c0f5f8a (diff) | |
| download | rust-45cbdec4174778bf915f17561ef971c068a7fcbc.tar.gz rust-45cbdec4174778bf915f17561ef971c068a7fcbc.zip | |
auto merge of #18719 : alexcrichton/rust/rollup, r=alexcrichton
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 113 | ||||
| -rw-r--r-- | src/libsyntax/ast_map/mod.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/diagnostics/plugin.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/ext/concat_idents.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/format.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/mtwt.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 73 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 266 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 112 | ||||
| -rw-r--r-- | src/libsyntax/std_inject.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/util/interner.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 35 |
18 files changed, 400 insertions, 290 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 078e393eb28..6a354fa20e1 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -171,7 +171,7 @@ pub struct Path { /// module (like paths in an import). pub global: bool, /// The segments in the path: the things separated by `::`. - pub segments: Vec<PathSegment> , + pub segments: Vec<PathSegment>, } /// A segment of a path: an identifier, an optional lifetime, and a set of @@ -180,12 +180,107 @@ pub struct Path { pub struct PathSegment { /// The identifier portion of this path segment. pub identifier: Ident, + + /// Type/lifetime parameters attached to this path. They come in + /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that + /// this is more than just simple syntactic sugar; the use of + /// parens affects the region binding rules, so we preserve the + /// distinction. + pub parameters: PathParameters, +} + +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +pub enum PathParameters { + AngleBracketedParameters(AngleBracketedParameterData), + ParenthesizedParameters(ParenthesizedParameterData), +} + +impl PathParameters { + pub fn none() -> PathParameters { + AngleBracketedParameters(AngleBracketedParameterData { + lifetimes: Vec::new(), + types: OwnedSlice::empty(), + }) + } + + pub fn is_empty(&self) -> bool { + match *self { + AngleBracketedParameters(ref data) => data.is_empty(), + + // Even if the user supplied no types, something like + // `X()` is equivalent to `X<(),()>`. + ParenthesizedParameters(..) => false, + } + } + + pub fn has_lifetimes(&self) -> bool { + match *self { + AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(), + ParenthesizedParameters(_) => false, + } + } + + pub fn has_types(&self) -> bool { + match *self { + AngleBracketedParameters(ref data) => !data.types.is_empty(), + ParenthesizedParameters(..) => true, + } + } + + pub fn types(&self) -> Vec<&P<Ty>> { + /*! + * Returns the types that the user wrote. Note that these do not + * necessarily map to the type parameters in the parenthesized case. + */ + match *self { + AngleBracketedParameters(ref data) => { + data.types.iter().collect() + } + ParenthesizedParameters(ref data) => { + data.inputs.iter() + .chain(data.output.iter()) + .collect() + } + } + } + + pub fn lifetimes(&self) -> Vec<&Lifetime> { + match *self { + AngleBracketedParameters(ref data) => { + data.lifetimes.iter().collect() + } + ParenthesizedParameters(_) => { + Vec::new() + } + } + } +} + +/// A path like `Foo<'a, T>` +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +pub struct AngleBracketedParameterData { /// The lifetime parameters for this path segment. pub lifetimes: Vec<Lifetime>, /// The type parameters for this path segment, if present. pub types: OwnedSlice<P<Ty>>, } +impl AngleBracketedParameterData { + fn is_empty(&self) -> bool { + self.lifetimes.is_empty() && self.types.is_empty() + } +} + +/// A path like `Foo(A,B) -> C` +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +pub struct ParenthesizedParameterData { + /// `(A,B)` + pub inputs: Vec<P<Ty>>, + + /// `C` + pub output: Option<P<Ty>>, +} + pub type CrateNum = u32; pub type NodeId = u32; @@ -213,21 +308,12 @@ pub const DUMMY_NODE_ID: NodeId = -1; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum TyParamBound { TraitTyParamBound(TraitRef), - UnboxedFnTyParamBound(P<UnboxedFnBound>), RegionTyParamBound(Lifetime) } pub type TyParamBounds = OwnedSlice<TyParamBound>; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] -pub struct UnboxedFnBound { - pub path: Path, - pub decl: P<FnDecl>, - pub lifetimes: Vec<LifetimeDef>, - pub ref_id: NodeId, -} - -#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct TyParam { pub ident: Ident, pub id: NodeId, @@ -995,12 +1081,6 @@ pub struct BareFnTy { } #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] -pub struct UnboxedFnTy { - pub kind: UnboxedClosureKind, - pub decl: P<FnDecl>, -} - -#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum Ty_ { TyNil, TyBot, /* bottom type */ @@ -1012,7 +1092,6 @@ pub enum Ty_ { TyClosure(P<ClosureTy>), TyProc(P<ClosureTy>), TyBareFn(P<BareFnTy>), - TyUnboxedFn(P<UnboxedFnTy>), TyTup(Vec<P<Ty>> ), TyPath(Path, Option<TyParamBounds>, NodeId), // for #7264; see above /// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType` diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index f049b964ff3..3adb062864e 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -848,9 +848,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { TyBareFn(ref fd) => { self.visit_fn_decl(&*fd.decl); } - TyUnboxedFn(ref fd) => { - self.visit_fn_decl(&*fd.decl); - } _ => {} } visit::walk_ty(self, ty); diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 3aa60236d70..2e3a15bfd4b 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -171,8 +171,10 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path { segments: vec!( ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: Vec::new(), + types: OwnedSlice::empty(), + }) } ), } @@ -681,11 +683,11 @@ pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> boo false } else { for (idx,seg) in a.iter().enumerate() { - if (seg.identifier.name != b[idx].identifier.name) + if seg.identifier.name != b[idx].identifier.name // FIXME #7743: ident -> name problems in lifetime comparison? - || (seg.lifetimes != b[idx].lifetimes) // can types contain idents? - || (seg.types != b[idx].types) { + || seg.parameters != b[idx].parameters + { return false; } } @@ -747,12 +749,10 @@ impl PostExpansionMethod for Method { mod test { use ast::*; use super::*; - use owned_slice::OwnedSlice; fn ident_to_segment(id : &Ident) -> PathSegment { - PathSegment {identifier:id.clone(), - lifetimes: Vec::new(), - types: OwnedSlice::empty()} + PathSegment {identifier: id.clone(), + parameters: PathParameters::none()} } #[test] fn idents_name_eq_test() { diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index d9d549f6841..d077fbd7bf0 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -63,7 +63,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, () }); with_used_diagnostics(|diagnostics| { - match diagnostics.swap(code.name, span) { + match diagnostics.insert(code.name, span) { Some(previous_span) => { ecx.span_warn(span, format!( "diagnostic code {} already used", token::get_ident(code).get() @@ -93,7 +93,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, _ => unreachable!() }; with_registered_diagnostics(|diagnostics| { - if !diagnostics.insert(code.name, description) { + if diagnostics.insert(code.name, description).is_some() { ecx.span_err(span, format!( "diagnostic code {} already registered", token::get_ident(*code).get() ).as_slice()); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 152b89b86e7..5401da8cd05 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -768,7 +768,7 @@ impl SyntaxEnv { pub fn find(&self, k: &Name) -> Option<Rc<SyntaxExtension>> { for frame in self.chain.iter().rev() { - match frame.map.find(k) { + match frame.map.get(k) { Some(v) => return Some(v.clone()), None => {} } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index dc4eaf7d7ad..5921d630b89 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -313,14 +313,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> { .map(|ident| { ast::PathSegment { identifier: ident, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } }).collect(); segments.push(ast::PathSegment { identifier: last_identifier, - lifetimes: lifetimes, - types: OwnedSlice::from_vec(types), + parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: lifetimes, + types: OwnedSlice::from_vec(types), + }) }); ast::Path { span: sp, diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index e5e93a7d8b3..aa18b1be31a 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -12,7 +12,6 @@ use ast; use codemap::Span; use ext::base::*; use ext::base; -use owned_slice::OwnedSlice; use parse::token; use parse::token::{str_to_ident}; use ptr::P; @@ -52,8 +51,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree] segments: vec!( ast::PathSegment { identifier: res, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ) } diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 486ce910e2b..a28f24e7663 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -252,7 +252,7 @@ impl<'a, 'b> Context<'a, 'b> { } Named(name) => { - let span = match self.names.find(&name) { + let span = match self.names.get(&name) { Some(e) => e.span, None => { let msg = format!("there is no argument named `{}`", name); @@ -260,7 +260,7 @@ impl<'a, 'b> Context<'a, 'b> { return; } }; - self.verify_same(span, &ty, self.name_types.find(&name)); + self.verify_same(span, &ty, self.name_types.get(&name)); if !self.name_types.contains_key(&name) { self.name_types.insert(name.clone(), ty); } @@ -555,11 +555,11 @@ impl<'a, 'b> Context<'a, 'b> { heads.push(self.ecx.expr_addr_of(e.span, e)); } for name in self.name_ordering.iter() { - let e = match self.names.pop(name) { + let e = match self.names.remove(name) { Some(e) => e, None => continue }; - let arg_ty = match self.name_types.find(name) { + let arg_ty = match self.name_types.get(name) { Some(ty) => ty, None => continue }; diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index bebe16286c9..15fe7fc42b2 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -182,7 +182,7 @@ fn resolve_internal(id: Ident, resolve_table: &mut ResolveTable) -> Name { let key = (id.name, id.ctxt); - match resolve_table.find(&key) { + match resolve_table.get(&key) { Some(&name) => return name, None => {} } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 7701f495f72..80b158a54d3 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -313,11 +313,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { experimental and likely to be removed"); }, - ast::TyUnboxedFn(..) => { - self.gate_feature("unboxed_closure_sugar", - t.span, - "unboxed closure trait sugar is experimental"); - } _ => {} } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 6535c8e89fd..cd4a3d10c48 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -166,6 +166,22 @@ pub trait Folder { noop_fold_path(p, self) } + fn fold_path_parameters(&mut self, p: PathParameters) -> PathParameters { + noop_fold_path_parameters(p, self) + } + + fn fold_angle_bracketed_parameter_data(&mut self, p: AngleBracketedParameterData) + -> AngleBracketedParameterData + { + noop_fold_angle_bracketed_parameter_data(p, self) + } + + fn fold_parenthesized_parameter_data(&mut self, p: ParenthesizedParameterData) + -> ParenthesizedParameterData + { + noop_fold_parenthesized_parameter_data(p, self) + } + fn fold_local(&mut self, l: P<Local>) -> P<Local> { noop_fold_local(l, self) } @@ -408,12 +424,6 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { decl: fld.fold_fn_decl(decl) })) } - TyUnboxedFn(f) => { - TyUnboxedFn(f.map(|UnboxedFnTy {decl, kind}| UnboxedFnTy { - decl: fld.fold_fn_decl(decl), - kind: kind, - })) - } TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))), TyParen(ty) => TyParen(fld.fold_ty(ty)), TyPath(path, bounds, id) => { @@ -480,15 +490,43 @@ pub fn noop_fold_uint<T: Folder>(i: uint, _: &mut T) -> uint { pub fn noop_fold_path<T: Folder>(Path {global, segments, span}: Path, fld: &mut T) -> Path { Path { global: global, - segments: segments.move_map(|PathSegment {identifier, lifetimes, types}| PathSegment { + segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment { identifier: fld.fold_ident(identifier), - lifetimes: fld.fold_lifetimes(lifetimes), - types: types.move_map(|typ| fld.fold_ty(typ)), + parameters: fld.fold_path_parameters(parameters), }), span: fld.new_span(span) } } +pub fn noop_fold_path_parameters<T: Folder>(path_parameters: PathParameters, fld: &mut T) + -> PathParameters +{ + match path_parameters { + AngleBracketedParameters(data) => + AngleBracketedParameters(fld.fold_angle_bracketed_parameter_data(data)), + ParenthesizedParameters(data) => + ParenthesizedParameters(fld.fold_parenthesized_parameter_data(data)), + } +} + +pub fn noop_fold_angle_bracketed_parameter_data<T: Folder>(data: AngleBracketedParameterData, + fld: &mut T) + -> AngleBracketedParameterData +{ + let AngleBracketedParameterData { lifetimes, types } = data; + AngleBracketedParameterData { lifetimes: fld.fold_lifetimes(lifetimes), + types: types.move_map(|ty| fld.fold_ty(ty)) } +} + +pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedParameterData, + fld: &mut T) + -> ParenthesizedParameterData +{ + let ParenthesizedParameterData { inputs, output } = data; + ParenthesizedParameterData { inputs: inputs.move_map(|ty| fld.fold_ty(ty)), + output: output.map(|ty| fld.fold_ty(ty)) } +} + pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> { l.map(|Local {id, pat, ty, init, source, span}| Local { id: fld.new_id(id), @@ -671,23 +709,6 @@ pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T) match tpb { TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_trait_ref(ty)), RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)), - UnboxedFnTyParamBound(bound) => { - match *bound { - UnboxedFnBound { - ref path, - ref decl, - ref lifetimes, - ref_id - } => { - UnboxedFnTyParamBound(P(UnboxedFnBound { - path: fld.fold_path(path.clone()), - decl: fld.fold_fn_decl(decl.clone()), - lifetimes: fld.fold_lifetime_defs(lifetimes.clone()), - ref_id: fld.new_id(ref_id), - })) - } - } - } } } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 83499ec54c6..996708b2174 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -749,8 +749,7 @@ mod test { segments: vec!( ast::PathSegment { identifier: str_to_ident("a"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ), }), @@ -768,13 +767,11 @@ mod test { segments: vec!( ast::PathSegment { identifier: str_to_ident("a"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), }, ast::PathSegment { identifier: str_to_ident("b"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ) }), @@ -952,8 +949,7 @@ mod test { segments: vec!( ast::PathSegment { identifier: str_to_ident("d"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ), }), @@ -974,8 +970,7 @@ mod test { segments: vec!( ast::PathSegment { identifier: str_to_ident("b"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ), }), @@ -1022,8 +1017,7 @@ mod test { ast::PathSegment { identifier: str_to_ident("int"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ), }, None, ast::DUMMY_NODE_ID), @@ -1072,10 +1066,8 @@ mod test { identifier: str_to_ident( "b"), - lifetimes: - Vec::new(), - types: - OwnedSlice::empty() + parameters: + ast::PathParameters::none(), } ), }), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 10bb9ef3625..18dd7074d28 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -53,9 +53,8 @@ use ast::{TtNonterminal, TupleVariantKind, Ty, Ty_, TyBot}; use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn}; use ast::{TyTypeof, TyInfer, TypeMethod}; use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyQPath}; -use ast::{TyRptr, TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq}; +use ast::{TyRptr, TyTup, TyU32, TyUniq, TyVec, UnUniq}; use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind}; -use ast::{UnboxedFnBound, UnboxedFnTy, UnboxedFnTyParamBound}; use ast::{UnnamedField, UnsafeBlock}; use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; @@ -1127,19 +1126,16 @@ impl<'a> Parser<'a> { Vec::new() }; - let (optional_unboxed_closure_kind, inputs) = if self.eat(&token::OrOr) { - (None, Vec::new()) + let inputs = if self.eat(&token::OrOr) { + Vec::new() } else { self.expect_or(); - let optional_unboxed_closure_kind = - self.parse_optional_unboxed_closure_kind(); - let inputs = self.parse_seq_to_before_or( &token::Comma, |p| p.parse_arg_general(false)); self.expect_or(); - (optional_unboxed_closure_kind, inputs) + inputs }; let bounds = self.parse_colon_then_ty_param_bounds(); @@ -1152,23 +1148,13 @@ impl<'a> Parser<'a> { variadic: false }); - match optional_unboxed_closure_kind { - Some(unboxed_closure_kind) => { - TyUnboxedFn(P(UnboxedFnTy { - kind: unboxed_closure_kind, - decl: decl, - })) - } - None => { - TyClosure(P(ClosureTy { - fn_style: fn_style, - onceness: onceness, - bounds: bounds, - decl: decl, - lifetimes: lifetime_defs, - })) - } - } + TyClosure(P(ClosureTy { + fn_style: fn_style, + onceness: onceness, + bounds: bounds, + decl: decl, + lifetimes: lifetime_defs, + })) } pub fn parse_unsafety(&mut self) -> FnStyle { @@ -1487,9 +1473,9 @@ impl<'a> Parser<'a> { trait_name: trait_name.path, item_name: item_name, })) - } else if self.token == token::ModSep - || self.token.is_ident() - || self.token.is_path() { + } else if self.token == token::ModSep || + self.token.is_ident() || + self.token.is_path() { // NAMED TYPE let mode = if plus_allowed { LifetimeAndTypesAndBounds @@ -1706,50 +1692,18 @@ impl<'a> Parser<'a> { // Parse any number of segments and bound sets. A segment is an // identifier followed by an optional lifetime and a set of types. // A bound set is a set of type parameter bounds. - let mut segments = Vec::new(); - loop { - // First, parse an identifier. - let identifier = self.parse_ident(); - - // Parse the '::' before type parameters if it's required. If - // it is required and wasn't present, then we're done. - if mode == LifetimeAndTypesWithColons && - !self.eat(&token::ModSep) { - segments.push(ast::PathSegment { - identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), - }); - break + let segments = match mode { + LifetimeAndTypesWithoutColons | + LifetimeAndTypesAndBounds => { + self.parse_path_segments_without_colons() } - - // Parse the `<` before the lifetime and types, if applicable. - let (any_lifetime_or_types, lifetimes, types) = { - if mode != NoTypesAllowed && self.eat_lt(false) { - let (lifetimes, types) = - self.parse_generic_values_after_lt(); - (true, lifetimes, OwnedSlice::from_vec(types)) - } else { - (false, Vec::new(), OwnedSlice::empty()) - } - }; - - // Assemble and push the result. - segments.push(ast::PathSegment { - identifier: identifier, - lifetimes: lifetimes, - types: types, - }); - - // We're done if we don't see a '::', unless the mode required - // a double colon to get here in the first place. - if !(mode == LifetimeAndTypesWithColons && - !any_lifetime_or_types) { - if !self.eat(&token::ModSep) { - break - } + LifetimeAndTypesWithColons => { + self.parse_path_segments_with_colons() } - } + NoTypesAllowed => { + self.parse_path_segments_without_types() + } + }; // Next, parse a plus and bounded type parameters, if // applicable. We need to remember whether the separate was @@ -1792,6 +1746,123 @@ impl<'a> Parser<'a> { } } + /// Examples: + /// - `a::b<T,U>::c<V,W>` + /// - `a::b<T,U>::c(V) -> W` + /// - `a::b<T,U>::c(V)` + pub fn parse_path_segments_without_colons(&mut self) -> Vec<ast::PathSegment> { + let mut segments = Vec::new(); + loop { + // First, parse an identifier. + let identifier = self.parse_ident(); + + // Parse types, optionally. + let parameters = if self.eat_lt(false) { + let (lifetimes, types) = self.parse_generic_values_after_lt(); + + ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: lifetimes, + types: OwnedSlice::from_vec(types), + }) + } else if self.eat(&token::OpenDelim(token::Paren)) { + let inputs = self.parse_seq_to_end( + &token::CloseDelim(token::Paren), + seq_sep_trailing_allowed(token::Comma), + |p| p.parse_ty(true)); + + let output_ty = if self.eat(&token::RArrow) { + Some(self.parse_ty(true)) + } else { + None + }; + + ast::ParenthesizedParameters(ast::ParenthesizedParameterData { + inputs: inputs, + output: output_ty + }) + } else { + ast::PathParameters::none() + }; + + // Assemble and push the result. + segments.push(ast::PathSegment { identifier: identifier, + parameters: parameters }); + + // Continue only if we see a `::` + if !self.eat(&token::ModSep) { + return segments; + } + } + } + + /// Examples: + /// - `a::b::<T,U>::c` + pub fn parse_path_segments_with_colons(&mut self) -> Vec<ast::PathSegment> { + let mut segments = Vec::new(); + loop { + // First, parse an identifier. + let identifier = self.parse_ident(); + + // If we do not see a `::`, stop. + if !self.eat(&token::ModSep) { + segments.push(ast::PathSegment { + identifier: identifier, + parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: Vec::new(), + types: OwnedSlice::empty(), + }) + }); + return segments; + } + + // Check for a type segment. + if self.eat_lt(false) { + // Consumed `a::b::<`, go look for types + let (lifetimes, types) = self.parse_generic_values_after_lt(); + segments.push(ast::PathSegment { + identifier: identifier, + parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: lifetimes, + types: OwnedSlice::from_vec(types), + }), + }); + + // Consumed `a::b::<T,U>`, check for `::` before proceeding + if !self.eat(&token::ModSep) { + return segments; + } + } else { + // Consumed `a::`, go look for `b` + segments.push(ast::PathSegment { + identifier: identifier, + parameters: ast::PathParameters::none(), + }); + } + } + } + + + /// Examples: + /// - `a::b::c` + pub fn parse_path_segments_without_types(&mut self) -> Vec<ast::PathSegment> { + let mut segments = Vec::new(); + loop { + // First, parse an identifier. + let identifier = self.parse_ident(); + + // Assemble and push the result. + segments.push(ast::PathSegment { + identifier: identifier, + parameters: ast::PathParameters::none() + }); + + // If we do not see a `::`, stop. + if !self.eat(&token::ModSep) { + return segments; + } + } + } + /// parses 0 or 1 lifetime pub fn parse_opt_lifetime(&mut self) -> Option<ast::Lifetime> { match self.token { @@ -3389,13 +3460,9 @@ impl<'a> Parser<'a> { }, _ => { if !enum_path.global && - enum_path.segments.len() == 1 && - enum_path.segments[0] - .lifetimes - .len() == 0 && - enum_path.segments[0] - .types - .len() == 0 { + enum_path.segments.len() == 1 && + enum_path.segments[0].parameters.is_empty() + { // it could still be either an enum // or an identifier pattern, resolve // will sort it out: @@ -3854,31 +3921,11 @@ impl<'a> Parser<'a> { token::ModSep | token::Ident(..) => { let path = self.parse_path(LifetimeAndTypesWithoutColons).path; - if self.token == token::OpenDelim(token::Paren) { - self.bump(); - let inputs = self.parse_seq_to_end( - &token::CloseDelim(token::Paren), - seq_sep_trailing_allowed(token::Comma), - |p| p.parse_arg_general(false)); - let (return_style, output) = self.parse_ret_ty(); - result.push(UnboxedFnTyParamBound(P(UnboxedFnBound { - path: path, - decl: P(FnDecl { - inputs: inputs, - output: output, - cf: return_style, - variadic: false, - }), - lifetimes: lifetime_defs, - ref_id: ast::DUMMY_NODE_ID, - }))); - } else { - result.push(TraitTyParamBound(ast::TraitRef { - path: path, - ref_id: ast::DUMMY_NODE_ID, - lifetimes: lifetime_defs, - })) - } + result.push(TraitTyParamBound(ast::TraitRef { + path: path, + ref_id: ast::DUMMY_NODE_ID, + lifetimes: lifetime_defs, + })) } _ => break, } @@ -3894,8 +3941,7 @@ impl<'a> Parser<'a> { fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef { let segment = ast::PathSegment { identifier: ident, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none() }; let path = ast::Path { span: span, @@ -5611,8 +5657,7 @@ impl<'a> Parser<'a> { segments: path.into_iter().map(|identifier| { ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } }).collect() }; @@ -5646,8 +5691,7 @@ impl<'a> Parser<'a> { segments: path.into_iter().map(|identifier| { ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } }).collect() }; @@ -5664,8 +5708,7 @@ impl<'a> Parser<'a> { segments: path.into_iter().map(|identifier| { ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } }).collect() }; @@ -5686,8 +5729,7 @@ impl<'a> Parser<'a> { segments: path.into_iter().map(|identifier| { ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } }).collect() }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 106e3f1faae..2448eacbb39 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -13,7 +13,7 @@ use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind}; use ast::{FnOnceUnboxedClosureKind}; use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound}; use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem}; -use ast::{UnboxedClosureKind, UnboxedFnTyParamBound}; +use ast::{UnboxedClosureKind}; use ast; use ast_util; use owned_slice::OwnedSlice; @@ -699,7 +699,6 @@ impl<'a> State<'a> { None, &OwnedSlice::empty(), Some(&generics), - None, None)); } ast::TyClosure(ref f) => { @@ -719,7 +718,6 @@ impl<'a> State<'a> { None, &f.bounds, Some(&generics), - None, None)); } ast::TyProc(ref f) => { @@ -739,21 +737,8 @@ impl<'a> State<'a> { None, &f.bounds, Some(&generics), - None, None)); } - ast::TyUnboxedFn(ref f) => { - try!(self.print_ty_fn(None, - None, - ast::NormalFn, - ast::Many, - &*f.decl, - None, - &OwnedSlice::empty(), - None, - None, - Some(f.kind))); - } ast::TyPath(ref path, ref bounds, _) => { try!(self.print_bounded_path(path, bounds)); } @@ -1212,8 +1197,7 @@ impl<'a> State<'a> { Some(m.ident), &OwnedSlice::empty(), Some(&m.generics), - Some(&m.explicit_self.node), - None)); + Some(&m.explicit_self.node))); word(&mut self.s, ";") } @@ -1995,14 +1979,34 @@ impl<'a> State<'a> { try!(self.print_ident(segment.identifier)); - if !segment.lifetimes.is_empty() || !segment.types.is_empty() { - if colons_before_params { - try!(word(&mut self.s, "::")) - } + try!(self.print_path_parameters(&segment.parameters, colons_before_params)); + } + + match *opt_bounds { + None => Ok(()), + Some(ref bounds) => self.print_bounds("+", bounds) + } + } + + fn print_path_parameters(&mut self, + parameters: &ast::PathParameters, + colons_before_params: bool) + -> IoResult<()> + { + if parameters.is_empty() { + return Ok(()); + } + + if colons_before_params { + try!(word(&mut self.s, "::")) + } + + match *parameters { + ast::AngleBracketedParameters(ref data) => { try!(word(&mut self.s, "<")); let mut comma = false; - for lifetime in segment.lifetimes.iter() { + for lifetime in data.lifetimes.iter() { if comma { try!(self.word_space(",")) } @@ -2010,24 +2014,38 @@ impl<'a> State<'a> { comma = true; } - if !segment.types.is_empty() { + if !data.types.is_empty() { if comma { try!(self.word_space(",")) } try!(self.commasep( Inconsistent, - segment.types.as_slice(), + data.types.as_slice(), |s, ty| s.print_type(&**ty))); } try!(word(&mut self.s, ">")) } - } - match *opt_bounds { - None => Ok(()), - Some(ref bounds) => self.print_bounds("+", bounds) + ast::ParenthesizedParameters(ref data) => { + try!(word(&mut self.s, "(")); + try!(self.commasep( + Inconsistent, + data.inputs.as_slice(), + |s, ty| s.print_type(&**ty))); + try!(word(&mut self.s, ")")); + + match data.output { + None => { } + Some(ref ty) => { + try!(self.word_space("->")); + try!(self.print_type(&**ty)); + } + } + } } + + Ok(()) } fn print_path(&mut self, path: &ast::Path, @@ -2373,15 +2391,6 @@ impl<'a> State<'a> { RegionTyParamBound(ref lt) => { self.print_lifetime(lt) } - UnboxedFnTyParamBound(ref unboxed_function_type) => { - try!(self.print_path(&unboxed_function_type.path, - false)); - try!(self.popen()); - try!(self.print_fn_args(&*unboxed_function_type.decl, - None)); - try!(self.pclose()); - self.print_fn_output(&*unboxed_function_type.decl) - } }) } Ok(()) @@ -2641,9 +2650,7 @@ impl<'a> State<'a> { id: Option<ast::Ident>, bounds: &OwnedSlice<ast::TyParamBound>, generics: Option<&ast::Generics>, - opt_explicit_self: Option<&ast::ExplicitSelf_>, - opt_unboxed_closure_kind: - Option<ast::UnboxedClosureKind>) + opt_explicit_self: Option<&ast::ExplicitSelf_>) -> IoResult<()> { try!(self.ibox(indent_unit)); @@ -2660,9 +2667,7 @@ impl<'a> State<'a> { try!(self.print_fn_style(fn_style)); try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi)); try!(self.print_onceness(onceness)); - if opt_unboxed_closure_kind.is_none() { - try!(word(&mut self.s, "fn")); - } + try!(word(&mut self.s, "fn")); } match id { @@ -2676,30 +2681,15 @@ impl<'a> State<'a> { match generics { Some(g) => try!(self.print_generics(g)), _ => () } try!(zerobreak(&mut self.s)); - if opt_unboxed_closure_kind.is_some() || opt_sigil == Some('&') { + if opt_sigil == Some('&') { try!(word(&mut self.s, "|")); } else { try!(self.popen()); } - match opt_unboxed_closure_kind { - Some(ast::FnUnboxedClosureKind) => { - try!(word(&mut self.s, "&")); - try!(self.word_space(":")); - } - Some(ast::FnMutUnboxedClosureKind) => { - try!(word(&mut self.s, "&mut")); - try!(self.word_space(":")); - } - Some(ast::FnOnceUnboxedClosureKind) => { - try!(self.word_space(":")); - } - None => {} - } - try!(self.print_fn_args(decl, opt_explicit_self)); - if opt_unboxed_closure_kind.is_some() || opt_sigil == Some('&') { + if opt_sigil == Some('&') { try!(word(&mut self.s, "|")); } else { if decl.variadic { diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 0f86fb751da..6a4ab365a50 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -14,7 +14,6 @@ use codemap::DUMMY_SP; use codemap; use fold::Folder; use fold; -use owned_slice::OwnedSlice; use parse::token::InternedString; use parse::token::special_idents; use parse::token; @@ -181,13 +180,11 @@ impl<'a> fold::Folder for PreludeInjector<'a> { segments: vec!( ast::PathSegment { identifier: token::str_to_ident("std"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), }, ast::PathSegment { identifier: token::str_to_ident("prelude"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), }), }; diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 37586f6abd7..a7db8e800a9 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -453,8 +453,7 @@ fn path_node(ids: Vec<ast::Ident> ) -> ast::Path { global: false, segments: ids.into_iter().map(|identifier| ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), }).collect() } } diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index e6c98a9e3d0..bc6d6d7a521 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -45,7 +45,7 @@ impl<T: Eq + Hash + Clone + 'static> Interner<T> { pub fn intern(&self, val: T) -> Name { let mut map = self.map.borrow_mut(); - match (*map).find(&val) { + match (*map).get(&val) { Some(&idx) => return idx, None => (), } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 86ee23d71a6..9751abacbd3 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -365,12 +365,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { visitor.visit_ty(&*function_declaration.decl.output); walk_lifetime_decls(visitor, &function_declaration.lifetimes); } - TyUnboxedFn(ref function_declaration) => { - for argument in function_declaration.decl.inputs.iter() { - visitor.visit_ty(&*argument.ty) - } - visitor.visit_ty(&*function_declaration.decl.output); - } TyPath(ref path, ref opt_bounds, id) => { visitor.visit_path(path, id); match *opt_bounds { @@ -407,11 +401,23 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { for segment in path.segments.iter() { visitor.visit_ident(path.span, segment.identifier); - for typ in segment.types.iter() { - visitor.visit_ty(&**typ); - } - for lifetime in segment.lifetimes.iter() { - visitor.visit_lifetime_ref(lifetime); + match segment.parameters { + ast::AngleBracketedParameters(ref data) => { + for typ in data.types.iter() { + visitor.visit_ty(&**typ); + } + for lifetime in data.lifetimes.iter() { + visitor.visit_lifetime_ref(lifetime); + } + } + ast::ParenthesizedParameters(ref data) => { + for typ in data.inputs.iter() { + visitor.visit_ty(&**typ); + } + for typ in data.output.iter() { + visitor.visit_ty(&**typ); + } + } } } } @@ -493,13 +499,6 @@ pub fn walk_ty_param_bounds<'v, V: Visitor<'v>>(visitor: &mut V, TraitTyParamBound(ref typ) => { walk_trait_ref_helper(visitor, typ) } - UnboxedFnTyParamBound(ref function_declaration) => { - for argument in function_declaration.decl.inputs.iter() { - visitor.visit_ty(&*argument.ty) - } - visitor.visit_ty(&*function_declaration.decl.output); - walk_lifetime_decls(visitor, &function_declaration.lifetimes); - } RegionTyParamBound(ref lifetime) => { visitor.visit_lifetime_ref(lifetime); } |
