From df572fcf4eea79baddc0136573cbbeed88db001e Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 9 May 2016 23:52:50 +0000 Subject: [PATCH 01/16] Remove unused function `lower_opt_bounds` --- src/librustc/hir/lowering.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0026412013c8e..e4b87ab8bf344 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -593,12 +593,6 @@ pub fn lower_mt(lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy { } } -pub fn lower_opt_bounds(lctx: &LoweringContext, - b: &Option) - -> Option { - b.as_ref().map(|ref bounds| lower_bounds(lctx, bounds)) -} - fn lower_bounds(lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() } From 417fe6d16e981c01bf258cd8b47a812bfb33723d Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 9 May 2016 22:20:53 +0000 Subject: [PATCH 02/16] Refactor away method `LoweringContext::diagnostic` --- src/librustc/hir/lowering.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index e4b87ab8bf344..4bfe514c39d10 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -50,7 +50,6 @@ use std::collections::BTreeMap; use std::iter; use syntax::ast::*; use syntax::attr::{ThinAttributes, ThinAttributesExt}; -use syntax::errors::Handler; use syntax::ext::mtwt; use syntax::ptr::P; use syntax::codemap::{respan, Spanned, Span}; @@ -94,7 +93,7 @@ impl Resolver for DummyResolver { } } -impl<'a, 'hir> LoweringContext<'a> { +impl<'a> LoweringContext<'a> { pub fn new(id_assigner: &'a NodeIdAssigner, c: Option<&Crate>, resolver: &'a mut Resolver) @@ -125,11 +124,6 @@ impl<'a, 'hir> LoweringContext<'a> { hir::Ident::from_name(token::gensym(s)) } - // Panics if this LoweringContext's NodeIdAssigner is not able to emit diagnostics. - fn diagnostic(&self) -> &Handler { - self.id_assigner.diagnostic() - } - fn with_parent_def T>(&self, parent_id: NodeId, f: F) -> T { let old_def = self.parent_def.get(); self.parent_def.set(match self.resolver.borrow_mut().definitions() { @@ -1245,8 +1239,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { make_struct(lctx, e, &["RangeInclusive", "NonEmpty"], &[("start", e1), ("end", e2)]), - _ => panic!(lctx.diagnostic().span_fatal(e.span, - "inclusive range with no end")) + _ => panic!(lctx.id_assigner.diagnostic() + .span_fatal(e.span, "inclusive range with no end")), }; } ExprKind::Path(ref qself, ref path) => { From eed8d70ac5177e6f378d08318f77499231e24e32 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Mon, 9 May 2016 07:59:19 +0000 Subject: [PATCH 03/16] Give lowering functions mutable access to the lowering context --- src/librustc/hir/lowering.rs | 281 ++++++++++++++--------------- src/librustc_driver/driver.rs | 4 +- src/librustc_metadata/astencode.rs | 16 +- src/librustdoc/test.rs | 4 +- 4 files changed, 152 insertions(+), 153 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 4bfe514c39d10..dc4ed655c9b88 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -57,8 +57,6 @@ use syntax::parse::token; use syntax::std_inject; use syntax::visit::{self, Visitor}; -use std::cell::{Cell, RefCell}; - pub struct LoweringContext<'a> { crate_root: Option<&'static str>, // Use to assign ids to hir nodes that do not directly correspond to an ast node @@ -66,8 +64,8 @@ pub struct LoweringContext<'a> { // As we walk the AST we must keep track of the current 'parent' def id (in // the form of a DefIndex) so that if we create a new node which introduces // a definition, then we can properly create the def id. - parent_def: Cell>, - resolver: RefCell<&'a mut Resolver>, + parent_def: Option, + resolver: &'a mut Resolver, } pub trait Resolver { @@ -111,8 +109,8 @@ impl<'a> LoweringContext<'a> { LoweringContext { crate_root: crate_root, id_assigner: id_assigner, - parent_def: Cell::new(None), - resolver: RefCell::new(resolver), + parent_def: None, + resolver: resolver, } } @@ -124,32 +122,34 @@ impl<'a> LoweringContext<'a> { hir::Ident::from_name(token::gensym(s)) } - fn with_parent_def T>(&self, parent_id: NodeId, f: F) -> T { - let old_def = self.parent_def.get(); - self.parent_def.set(match self.resolver.borrow_mut().definitions() { + fn with_parent_def(&mut self, parent_id: NodeId, f: F) -> T + where F: FnOnce(&mut LoweringContext) -> T + { + let old_def = self.parent_def; + self.parent_def = match self.resolver.definitions() { Some(defs) => Some(defs.opt_def_index(parent_id).unwrap()), None => old_def, - }); + }; - let result = f(); + let result = f(self); - self.parent_def.set(old_def); + self.parent_def = old_def; result } } -pub fn lower_ident(_lctx: &LoweringContext, ident: Ident) -> hir::Ident { +pub fn lower_ident(_lctx: &mut LoweringContext, ident: Ident) -> hir::Ident { hir::Ident { name: mtwt::resolve(ident), unhygienic_name: ident.name, } } -pub fn lower_attrs(_lctx: &LoweringContext, attrs: &Vec) -> hir::HirVec { +pub fn lower_attrs(_lctx: &mut LoweringContext, attrs: &Vec) -> hir::HirVec { attrs.clone().into() } -pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P { +pub fn lower_view_path(lctx: &mut LoweringContext, view_path: &ViewPath) -> P { P(Spanned { node: match view_path.node { ViewPathSimple(ident, ref path) => { @@ -186,7 +186,7 @@ fn lower_path_list_item(path_list_ident: &PathListItem) -> hir::PathListItem { } } -pub fn lower_arm(lctx: &LoweringContext, arm: &Arm) -> hir::Arm { +pub fn lower_arm(lctx: &mut LoweringContext, arm: &Arm) -> hir::Arm { hir::Arm { attrs: lower_attrs(lctx, &arm.attrs), pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(), @@ -195,7 +195,7 @@ pub fn lower_arm(lctx: &LoweringContext, arm: &Arm) -> hir::Arm { } } -pub fn lower_decl(lctx: &LoweringContext, d: &Decl) -> P { +pub fn lower_decl(lctx: &mut LoweringContext, d: &Decl) -> P { match d.node { DeclKind::Local(ref l) => P(Spanned { node: hir::DeclLocal(lower_local(lctx, l)), @@ -208,7 +208,7 @@ pub fn lower_decl(lctx: &LoweringContext, d: &Decl) -> P { } } -pub fn lower_ty_binding(lctx: &LoweringContext, b: &TypeBinding) -> hir::TypeBinding { +pub fn lower_ty_binding(lctx: &mut LoweringContext, b: &TypeBinding) -> hir::TypeBinding { hir::TypeBinding { id: b.id, name: b.ident.name, @@ -217,7 +217,7 @@ pub fn lower_ty_binding(lctx: &LoweringContext, b: &TypeBinding) -> hir::TypeBin } } -pub fn lower_ty(lctx: &LoweringContext, t: &Ty) -> P { +pub fn lower_ty(lctx: &mut LoweringContext, t: &Ty) -> P { use syntax::ast::TyKind::*; P(hir::Ty { id: t.id, @@ -267,14 +267,14 @@ pub fn lower_ty(lctx: &LoweringContext, t: &Ty) -> P { }) } -pub fn lower_foreign_mod(lctx: &LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { +pub fn lower_foreign_mod(lctx: &mut LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { hir::ForeignMod { abi: fm.abi, items: fm.items.iter().map(|x| lower_foreign_item(lctx, x)).collect(), } } -pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> hir::Variant { +pub fn lower_variant(lctx: &mut LoweringContext, v: &Variant) -> hir::Variant { Spanned { node: hir::Variant_ { name: v.node.name.name, @@ -289,7 +289,7 @@ pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> hir::Variant { // Path segments are usually unhygienic, hygienic path segments can occur only in // identifier-like paths originating from `ExprPath`. // Make life simpler for rustc_resolve by renaming only such segments. -pub fn lower_path_full(lctx: &LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { +pub fn lower_path_full(lctx: &mut LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; hir::Path { global: p.global, @@ -310,11 +310,11 @@ pub fn lower_path_full(lctx: &LoweringContext, p: &Path, maybe_hygienic: bool) - } } -pub fn lower_path(lctx: &LoweringContext, p: &Path) -> hir::Path { +pub fn lower_path(lctx: &mut LoweringContext, p: &Path) -> hir::Path { lower_path_full(lctx, p, false) } -pub fn lower_path_parameters(lctx: &LoweringContext, +pub fn lower_path_parameters(lctx: &mut LoweringContext, path_parameters: &PathParameters) -> hir::PathParameters { match *path_parameters { @@ -325,7 +325,7 @@ pub fn lower_path_parameters(lctx: &LoweringContext, } } -pub fn lower_angle_bracketed_parameter_data(lctx: &LoweringContext, +pub fn lower_angle_bracketed_parameter_data(lctx: &mut LoweringContext, data: &AngleBracketedParameterData) -> hir::AngleBracketedParameterData { let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; @@ -336,7 +336,7 @@ pub fn lower_angle_bracketed_parameter_data(lctx: &LoweringContext, } } -pub fn lower_parenthesized_parameter_data(lctx: &LoweringContext, +pub fn lower_parenthesized_parameter_data(lctx: &mut LoweringContext, data: &ParenthesizedParameterData) -> hir::ParenthesizedParameterData { let &ParenthesizedParameterData { ref inputs, ref output, span } = data; @@ -347,7 +347,7 @@ pub fn lower_parenthesized_parameter_data(lctx: &LoweringContext, } } -pub fn lower_local(lctx: &LoweringContext, l: &Local) -> P { +pub fn lower_local(lctx: &mut LoweringContext, l: &Local) -> P { P(hir::Local { id: l.id, ty: l.ty.as_ref().map(|t| lower_ty(lctx, t)), @@ -358,7 +358,7 @@ pub fn lower_local(lctx: &LoweringContext, l: &Local) -> P { }) } -pub fn lower_explicit_self_underscore(lctx: &LoweringContext, +pub fn lower_explicit_self_underscore(lctx: &mut LoweringContext, es: &SelfKind) -> hir::ExplicitSelf_ { match *es { @@ -375,21 +375,21 @@ pub fn lower_explicit_self_underscore(lctx: &LoweringContext, } } -pub fn lower_mutability(_lctx: &LoweringContext, m: Mutability) -> hir::Mutability { +pub fn lower_mutability(_lctx: &mut LoweringContext, m: Mutability) -> hir::Mutability { match m { Mutability::Mutable => hir::MutMutable, Mutability::Immutable => hir::MutImmutable, } } -pub fn lower_explicit_self(lctx: &LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { +pub fn lower_explicit_self(lctx: &mut LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { Spanned { node: lower_explicit_self_underscore(lctx, &s.node), span: s.span, } } -pub fn lower_arg(lctx: &LoweringContext, arg: &Arg) -> hir::Arg { +pub fn lower_arg(lctx: &mut LoweringContext, arg: &Arg) -> hir::Arg { hir::Arg { id: arg.id, pat: lower_pat(lctx, &arg.pat), @@ -397,7 +397,7 @@ pub fn lower_arg(lctx: &LoweringContext, arg: &Arg) -> hir::Arg { } } -pub fn lower_fn_decl(lctx: &LoweringContext, decl: &FnDecl) -> P { +pub fn lower_fn_decl(lctx: &mut LoweringContext, decl: &FnDecl) -> P { P(hir::FnDecl { inputs: decl.inputs.iter().map(|x| lower_arg(lctx, x)).collect(), output: match decl.output { @@ -409,7 +409,7 @@ pub fn lower_fn_decl(lctx: &LoweringContext, decl: &FnDecl) -> P { }) } -pub fn lower_ty_param_bound(lctx: &LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { +pub fn lower_ty_param_bound(lctx: &mut LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { match *tpb { TraitTyParamBound(ref ty, modifier) => { hir::TraitTyParamBound(lower_poly_trait_ref(lctx, ty), @@ -421,7 +421,7 @@ pub fn lower_ty_param_bound(lctx: &LoweringContext, tpb: &TyParamBound) -> hir:: } } -pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam { +pub fn lower_ty_param(lctx: &mut LoweringContext, tp: &TyParam) -> hir::TyParam { hir::TyParam { id: tp.id, name: tp.ident.name, @@ -431,13 +431,13 @@ pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam { } } -pub fn lower_ty_params(lctx: &LoweringContext, +pub fn lower_ty_params(lctx: &mut LoweringContext, tps: &P<[TyParam]>) -> hir::HirVec { tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect() } -pub fn lower_lifetime(_lctx: &LoweringContext, l: &Lifetime) -> hir::Lifetime { +pub fn lower_lifetime(_lctx: &mut LoweringContext, l: &Lifetime) -> hir::Lifetime { hir::Lifetime { id: l.id, name: l.name, @@ -445,30 +445,31 @@ pub fn lower_lifetime(_lctx: &LoweringContext, l: &Lifetime) -> hir::Lifetime { } } -pub fn lower_lifetime_def(lctx: &LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { +pub fn lower_lifetime_def(lctx: &mut LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { hir::LifetimeDef { lifetime: lower_lifetime(lctx, &l.lifetime), bounds: lower_lifetimes(lctx, &l.bounds), } } -pub fn lower_lifetimes(lctx: &LoweringContext, lts: &Vec) -> hir::HirVec { +pub fn lower_lifetimes(lctx: &mut LoweringContext, lts: &Vec) + -> hir::HirVec { lts.iter().map(|l| lower_lifetime(lctx, l)).collect() } -pub fn lower_lifetime_defs(lctx: &LoweringContext, +pub fn lower_lifetime_defs(lctx: &mut LoweringContext, lts: &Vec) -> hir::HirVec { lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect() } -pub fn lower_opt_lifetime(lctx: &LoweringContext, +pub fn lower_opt_lifetime(lctx: &mut LoweringContext, o_lt: &Option) -> Option { o_lt.as_ref().map(|lt| lower_lifetime(lctx, lt)) } -pub fn lower_generics(lctx: &LoweringContext, g: &Generics) -> hir::Generics { +pub fn lower_generics(lctx: &mut LoweringContext, g: &Generics) -> hir::Generics { hir::Generics { ty_params: lower_ty_params(lctx, &g.ty_params), lifetimes: lower_lifetime_defs(lctx, &g.lifetimes), @@ -476,7 +477,7 @@ pub fn lower_generics(lctx: &LoweringContext, g: &Generics) -> hir::Generics { } } -pub fn lower_where_clause(lctx: &LoweringContext, wc: &WhereClause) -> hir::WhereClause { +pub fn lower_where_clause(lctx: &mut LoweringContext, wc: &WhereClause) -> hir::WhereClause { hir::WhereClause { id: wc.id, predicates: wc.predicates @@ -486,7 +487,7 @@ pub fn lower_where_clause(lctx: &LoweringContext, wc: &WhereClause) -> hir::Wher } } -pub fn lower_where_predicate(lctx: &LoweringContext, +pub fn lower_where_predicate(lctx: &mut LoweringContext, pred: &WherePredicate) -> hir::WherePredicate { match *pred { @@ -524,7 +525,7 @@ pub fn lower_where_predicate(lctx: &LoweringContext, } } -pub fn lower_variant_data(lctx: &LoweringContext, vdata: &VariantData) -> hir::VariantData { +pub fn lower_variant_data(lctx: &mut LoweringContext, vdata: &VariantData) -> hir::VariantData { match *vdata { VariantData::Struct(ref fields, id) => { hir::VariantData::Struct(fields.iter() @@ -544,14 +545,14 @@ pub fn lower_variant_data(lctx: &LoweringContext, vdata: &VariantData) -> hir::V } } -pub fn lower_trait_ref(lctx: &LoweringContext, p: &TraitRef) -> hir::TraitRef { +pub fn lower_trait_ref(lctx: &mut LoweringContext, p: &TraitRef) -> hir::TraitRef { hir::TraitRef { path: lower_path(lctx, &p.path), ref_id: p.ref_id, } } -pub fn lower_poly_trait_ref(lctx: &LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { +pub fn lower_poly_trait_ref(lctx: &mut LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { hir::PolyTraitRef { bound_lifetimes: lower_lifetime_defs(lctx, &p.bound_lifetimes), trait_ref: lower_trait_ref(lctx, &p.trait_ref), @@ -559,7 +560,7 @@ pub fn lower_poly_trait_ref(lctx: &LoweringContext, p: &PolyTraitRef) -> hir::Po } } -pub fn lower_struct_field(lctx: &LoweringContext, +pub fn lower_struct_field(lctx: &mut LoweringContext, (index, f): (usize, &StructField)) -> hir::StructField { hir::StructField { @@ -572,7 +573,7 @@ pub fn lower_struct_field(lctx: &LoweringContext, } } -pub fn lower_field(lctx: &LoweringContext, f: &Field) -> hir::Field { +pub fn lower_field(lctx: &mut LoweringContext, f: &Field) -> hir::Field { hir::Field { name: respan(f.ident.span, f.ident.node.name), expr: lower_expr(lctx, &f.expr), @@ -580,18 +581,18 @@ pub fn lower_field(lctx: &LoweringContext, f: &Field) -> hir::Field { } } -pub fn lower_mt(lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy { +pub fn lower_mt(lctx: &mut LoweringContext, mt: &MutTy) -> hir::MutTy { hir::MutTy { ty: lower_ty(lctx, &mt.ty), mutbl: lower_mutability(lctx, mt.mutbl), } } -fn lower_bounds(lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { +fn lower_bounds(lctx: &mut LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() } -pub fn lower_block(lctx: &LoweringContext, b: &Block) -> P { +pub fn lower_block(lctx: &mut LoweringContext, b: &Block) -> P { P(hir::Block { id: b.id, stmts: b.stmts.iter().map(|s| lower_stmt(lctx, s)).collect(), @@ -601,7 +602,7 @@ pub fn lower_block(lctx: &LoweringContext, b: &Block) -> P { }) } -pub fn lower_item_kind(lctx: &LoweringContext, i: &ItemKind) -> hir::Item_ { +pub fn lower_item_kind(lctx: &mut LoweringContext, i: &ItemKind) -> hir::Item_ { match *i { ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), ItemKind::Use(ref view_path) => { @@ -669,8 +670,8 @@ pub fn lower_item_kind(lctx: &LoweringContext, i: &ItemKind) -> hir::Item_ { } } -pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem { - lctx.with_parent_def(i.id, || { +pub fn lower_trait_item(lctx: &mut LoweringContext, i: &TraitItem) -> hir::TraitItem { + lctx.with_parent_def(i.id, |lctx| { hir::TraitItem { id: i.id, name: i.ident.name, @@ -694,8 +695,8 @@ pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem }) } -pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem { - lctx.with_parent_def(i.id, || { +pub fn lower_impl_item(lctx: &mut LoweringContext, i: &ImplItem) -> hir::ImplItem { + lctx.with_parent_def(i.id, |lctx| { hir::ImplItem { id: i.id, name: i.ident.name, @@ -717,7 +718,7 @@ pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem { }) } -pub fn lower_mod(lctx: &LoweringContext, m: &Mod) -> hir::Mod { +pub fn lower_mod(lctx: &mut LoweringContext, m: &Mod) -> hir::Mod { hir::Mod { inner: m.inner, item_ids: m.items.iter().map(|x| lower_item_id(lctx, x)).collect(), @@ -726,7 +727,7 @@ pub fn lower_mod(lctx: &LoweringContext, m: &Mod) -> hir::Mod { struct ItemLowerer<'lcx, 'interner: 'lcx> { items: BTreeMap, - lctx: &'lcx LoweringContext<'interner>, + lctx: &'lcx mut LoweringContext<'interner>, } impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { @@ -736,7 +737,7 @@ impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { } } -pub fn lower_crate(lctx: &LoweringContext, c: &Crate) -> hir::Crate { +pub fn lower_crate(lctx: &mut LoweringContext, c: &Crate) -> hir::Crate { let items = { let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: lctx }; visit::walk_crate(&mut item_lowerer, c); @@ -753,7 +754,7 @@ pub fn lower_crate(lctx: &LoweringContext, c: &Crate) -> hir::Crate { } } -pub fn lower_macro_def(lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef { +pub fn lower_macro_def(lctx: &mut LoweringContext, m: &MacroDef) -> hir::MacroDef { hir::MacroDef { name: m.ident.name, attrs: lower_attrs(lctx, &m.attrs), @@ -767,12 +768,12 @@ pub fn lower_macro_def(lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef { } } -pub fn lower_item_id(_lctx: &LoweringContext, i: &Item) -> hir::ItemId { +pub fn lower_item_id(_lctx: &mut LoweringContext, i: &Item) -> hir::ItemId { hir::ItemId { id: i.id } } -pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { - let node = lctx.with_parent_def(i.id, || { +pub fn lower_item(lctx: &mut LoweringContext, i: &Item) -> hir::Item { + let node = lctx.with_parent_def(i.id, |lctx| { lower_item_kind(lctx, &i.node) }); @@ -786,8 +787,8 @@ pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { } } -pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::ForeignItem { - lctx.with_parent_def(i.id, || { +pub fn lower_foreign_item(lctx: &mut LoweringContext, i: &ForeignItem) -> hir::ForeignItem { + lctx.with_parent_def(i.id, |lctx| { hir::ForeignItem { id: i.id, name: i.ident.name, @@ -806,7 +807,7 @@ pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::Forei }) } -pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig { +pub fn lower_method_sig(lctx: &mut LoweringContext, sig: &MethodSig) -> hir::MethodSig { hir::MethodSig { generics: lower_generics(lctx, &sig.generics), abi: sig.abi, @@ -817,21 +818,21 @@ pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodS } } -pub fn lower_unsafety(_lctx: &LoweringContext, u: Unsafety) -> hir::Unsafety { +pub fn lower_unsafety(_lctx: &mut LoweringContext, u: Unsafety) -> hir::Unsafety { match u { Unsafety::Unsafe => hir::Unsafety::Unsafe, Unsafety::Normal => hir::Unsafety::Normal, } } -pub fn lower_constness(_lctx: &LoweringContext, c: Constness) -> hir::Constness { +pub fn lower_constness(_lctx: &mut LoweringContext, c: Constness) -> hir::Constness { match c { Constness::Const => hir::Constness::Const, Constness::NotConst => hir::Constness::NotConst, } } -pub fn lower_unop(_lctx: &LoweringContext, u: UnOp) -> hir::UnOp { +pub fn lower_unop(_lctx: &mut LoweringContext, u: UnOp) -> hir::UnOp { match u { UnOp::Deref => hir::UnDeref, UnOp::Not => hir::UnNot, @@ -839,7 +840,7 @@ pub fn lower_unop(_lctx: &LoweringContext, u: UnOp) -> hir::UnOp { } } -pub fn lower_binop(_lctx: &LoweringContext, b: BinOp) -> hir::BinOp { +pub fn lower_binop(_lctx: &mut LoweringContext, b: BinOp) -> hir::BinOp { Spanned { node: match b.node { BinOpKind::Add => hir::BiAdd, @@ -865,13 +866,13 @@ pub fn lower_binop(_lctx: &LoweringContext, b: BinOp) -> hir::BinOp { } } -pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P { +pub fn lower_pat(lctx: &mut LoweringContext, p: &Pat) -> P { P(hir::Pat { id: p.id, node: match p.node { PatKind::Wild => hir::PatKind::Wild, PatKind::Ident(ref binding_mode, pth1, ref sub) => { - lctx.with_parent_def(p.id, || { + lctx.with_parent_def(p.id, |lctx| { hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode), respan(pth1.span, lower_ident(lctx, pth1.node)), sub.as_ref().map(|x| lower_pat(lctx, x))) @@ -930,7 +931,7 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P { }) } -pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { +pub fn lower_expr(lctx: &mut LoweringContext, e: &Expr) -> P { P(hir::Expr { id: e.id, node: match e.node { @@ -977,17 +978,17 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { let move_val_init = ["intrinsics", "move_val_init"]; let inplace_finalize = ["ops", "InPlace", "finalize"]; - let make_call = |lctx: &LoweringContext, p, args| { + let make_call = |lctx: &mut LoweringContext, p, args| { let path = core_path(lctx, e.span, p); let path = expr_path(lctx, path, None); expr_call(lctx, e.span, path, args, None) }; - let mk_stmt_let = |lctx: &LoweringContext, bind, expr| { + let mk_stmt_let = |lctx: &mut LoweringContext, bind, expr| { stmt_let(lctx, e.span, false, bind, expr, None) }; - let mk_stmt_let_mut = |lctx: &LoweringContext, bind, expr| { + let mk_stmt_let_mut = |lctx: &mut LoweringContext, bind, expr| { stmt_let(lctx, e.span, true, bind, expr, None) }; @@ -1145,7 +1146,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { hir::MatchSource::Normal) } ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => { - lctx.with_parent_def(e.id, || { + lctx.with_parent_def(e.id, |lctx| { hir::ExprClosure(lower_capture_clause(lctx, capture_clause), lower_fn_decl(lctx, decl), lower_block(lctx, body), @@ -1171,7 +1172,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { hir::ExprIndex(lower_expr(lctx, el), lower_expr(lctx, er)) } ExprKind::Range(ref e1, ref e2, lims) => { - fn make_struct(lctx: &LoweringContext, + fn make_struct(lctx: &mut LoweringContext, ast_expr: &Expr, path: &[&str], fields: &[(&str, &P)]) -> P { @@ -1187,21 +1188,19 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { structpath, ast_expr.attrs.clone()) } else { - expr_struct(lctx, - ast_expr.span, - structpath, - fields.into_iter().map(|&(s, e)| { - field(token::intern(s), - signal_block_expr(lctx, - hir_vec![], - lower_expr(lctx, &**e), - e.span, - hir::PopUnstableBlock, - None), - ast_expr.span) - }).collect(), - None, - ast_expr.attrs.clone()) + let fields = fields.into_iter().map(|&(s, e)| { + let expr = lower_expr(lctx, &e); + let signal_block = signal_block_expr(lctx, + hir_vec![], + expr, + e.span, + hir::PopUnstableBlock, + None); + field(token::intern(s), signal_block, ast_expr.span) + }).collect(); + let attrs = ast_expr.attrs.clone(); + + expr_struct(lctx, ast_expr.span, structpath, fields, None, attrs) }; signal_block_expr(lctx, @@ -1613,7 +1612,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { }) } -pub fn lower_stmt(lctx: &LoweringContext, s: &Stmt) -> hir::Stmt { +pub fn lower_stmt(lctx: &mut LoweringContext, s: &Stmt) -> hir::Stmt { match s.node { StmtKind::Decl(ref d, id) => { Spanned { @@ -1637,14 +1636,14 @@ pub fn lower_stmt(lctx: &LoweringContext, s: &Stmt) -> hir::Stmt { } } -pub fn lower_capture_clause(_lctx: &LoweringContext, c: CaptureBy) -> hir::CaptureClause { +pub fn lower_capture_clause(_lctx: &mut LoweringContext, c: CaptureBy) -> hir::CaptureClause { match c { CaptureBy::Value => hir::CaptureByValue, CaptureBy::Ref => hir::CaptureByRef, } } -pub fn lower_visibility(lctx: &LoweringContext, v: &Visibility) -> hir::Visibility { +pub fn lower_visibility(lctx: &mut LoweringContext, v: &Visibility) -> hir::Visibility { match *v { Visibility::Public => hir::Public, Visibility::Crate(_) => hir::Visibility::Crate, @@ -1654,42 +1653,42 @@ pub fn lower_visibility(lctx: &LoweringContext, v: &Visibility) -> hir::Visibili } } -pub fn lower_defaultness(_lctx: &LoweringContext, d: Defaultness) -> hir::Defaultness { +pub fn lower_defaultness(_lctx: &mut LoweringContext, d: Defaultness) -> hir::Defaultness { match d { Defaultness::Default => hir::Defaultness::Default, Defaultness::Final => hir::Defaultness::Final, } } -pub fn lower_block_check_mode(lctx: &LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { +pub fn lower_block_check_mode(lctx: &mut LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { match *b { BlockCheckMode::Default => hir::DefaultBlock, BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(lower_unsafe_source(lctx, u)), } } -pub fn lower_binding_mode(lctx: &LoweringContext, b: &BindingMode) -> hir::BindingMode { +pub fn lower_binding_mode(lctx: &mut LoweringContext, b: &BindingMode) -> hir::BindingMode { match *b { BindingMode::ByRef(m) => hir::BindByRef(lower_mutability(lctx, m)), BindingMode::ByValue(m) => hir::BindByValue(lower_mutability(lctx, m)), } } -pub fn lower_unsafe_source(_lctx: &LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { +pub fn lower_unsafe_source(_lctx: &mut LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { match u { CompilerGenerated => hir::CompilerGenerated, UserProvided => hir::UserProvided, } } -pub fn lower_impl_polarity(_lctx: &LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { +pub fn lower_impl_polarity(_lctx: &mut LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { match i { ImplPolarity::Positive => hir::ImplPolarity::Positive, ImplPolarity::Negative => hir::ImplPolarity::Negative, } } -pub fn lower_trait_bound_modifier(_lctx: &LoweringContext, +pub fn lower_trait_bound_modifier(_lctx: &mut LoweringContext, f: TraitBoundModifier) -> hir::TraitBoundModifier { match f { @@ -1720,12 +1719,12 @@ fn field(name: Name, expr: P, span: Span) -> hir::Field { } } -fn expr_break(lctx: &LoweringContext, span: Span, +fn expr_break(lctx: &mut LoweringContext, span: Span, attrs: ThinAttributes) -> P { expr(lctx, span, hir::ExprBreak(None), attrs) } -fn expr_call(lctx: &LoweringContext, +fn expr_call(lctx: &mut LoweringContext, span: Span, e: P, args: hir::HirVec>, @@ -1734,32 +1733,32 @@ fn expr_call(lctx: &LoweringContext, expr(lctx, span, hir::ExprCall(e, args), attrs) } -fn expr_ident(lctx: &LoweringContext, span: Span, id: hir::Ident, +fn expr_ident(lctx: &mut LoweringContext, span: Span, id: hir::Ident, attrs: ThinAttributes, binding: NodeId) -> P { let expr = expr(lctx, span, hir::ExprPath(None, path_ident(span, id)), attrs); - let mut resolver = lctx.resolver.borrow_mut(); - let def = resolver.definitions().map(|defs| Def::Local(defs.local_def_id(binding), binding)) - .unwrap_or(Def::Err); - resolver.record_resolution(expr.id, def); + let def = lctx.resolver.definitions().map(|defs| { + Def::Local(defs.local_def_id(binding), binding) + }).unwrap_or(Def::Err); + lctx.resolver.record_resolution(expr.id, def); expr } -fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P, +fn expr_mut_addr_of(lctx: &mut LoweringContext, span: Span, e: P, attrs: ThinAttributes) -> P { expr(lctx, span, hir::ExprAddrOf(hir::MutMutable, e), attrs) } -fn expr_path(lctx: &LoweringContext, path: hir::Path, +fn expr_path(lctx: &mut LoweringContext, path: hir::Path, attrs: ThinAttributes) -> P { - let def = lctx.resolver.borrow_mut().resolve_generated_global_path(&path, true); + let def = lctx.resolver.resolve_generated_global_path(&path, true); let expr = expr(lctx, path.span, hir::ExprPath(None, path), attrs); - lctx.resolver.borrow_mut().record_resolution(expr.id, def); + lctx.resolver.record_resolution(expr.id, def); expr } -fn expr_match(lctx: &LoweringContext, +fn expr_match(lctx: &mut LoweringContext, span: Span, arg: P, arms: hir::HirVec, @@ -1769,30 +1768,30 @@ fn expr_match(lctx: &LoweringContext, expr(lctx, span, hir::ExprMatch(arg, arms, source), attrs) } -fn expr_block(lctx: &LoweringContext, b: P, +fn expr_block(lctx: &mut LoweringContext, b: P, attrs: ThinAttributes) -> P { expr(lctx, b.span, hir::ExprBlock(b), attrs) } -fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: hir::HirVec>, +fn expr_tuple(lctx: &mut LoweringContext, sp: Span, exprs: hir::HirVec>, attrs: ThinAttributes) -> P { expr(lctx, sp, hir::ExprTup(exprs), attrs) } -fn expr_struct(lctx: &LoweringContext, +fn expr_struct(lctx: &mut LoweringContext, sp: Span, path: hir::Path, fields: hir::HirVec, e: Option>, attrs: ThinAttributes) -> P { - let def = lctx.resolver.borrow_mut().resolve_generated_global_path(&path, false); + let def = lctx.resolver.resolve_generated_global_path(&path, false); let expr = expr(lctx, sp, hir::ExprStruct(path, fields, e), attrs); - lctx.resolver.borrow_mut().record_resolution(expr.id, def); + lctx.resolver.record_resolution(expr.id, def); expr } -fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_, +fn expr(lctx: &mut LoweringContext, span: Span, node: hir::Expr_, attrs: ThinAttributes) -> P { P(hir::Expr { id: lctx.next_id(), @@ -1802,7 +1801,7 @@ fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_, }) } -fn stmt_let(lctx: &LoweringContext, +fn stmt_let(lctx: &mut LoweringContext, sp: Span, mutbl: bool, ident: hir::Ident, @@ -1827,11 +1826,11 @@ fn stmt_let(lctx: &LoweringContext, (respan(sp, hir::StmtDecl(P(decl), lctx.next_id())), pat_id) } -fn block_expr(lctx: &LoweringContext, expr: P) -> P { +fn block_expr(lctx: &mut LoweringContext, expr: P) -> P { block_all(lctx, expr.span, hir::HirVec::new(), Some(expr)) } -fn block_all(lctx: &LoweringContext, +fn block_all(lctx: &mut LoweringContext, span: Span, stmts: hir::HirVec, expr: Option>) @@ -1845,51 +1844,51 @@ fn block_all(lctx: &LoweringContext, }) } -fn pat_ok(lctx: &LoweringContext, span: Span, pat: P) -> P { +fn pat_ok(lctx: &mut LoweringContext, span: Span, pat: P) -> P { let ok = std_path(lctx, &["result", "Result", "Ok"]); let path = path_global(span, ok); pat_enum(lctx, span, path, hir_vec![pat]) } -fn pat_err(lctx: &LoweringContext, span: Span, pat: P) -> P { +fn pat_err(lctx: &mut LoweringContext, span: Span, pat: P) -> P { let err = std_path(lctx, &["result", "Result", "Err"]); let path = path_global(span, err); pat_enum(lctx, span, path, hir_vec![pat]) } -fn pat_some(lctx: &LoweringContext, span: Span, pat: P) -> P { +fn pat_some(lctx: &mut LoweringContext, span: Span, pat: P) -> P { let some = std_path(lctx, &["option", "Option", "Some"]); let path = path_global(span, some); pat_enum(lctx, span, path, hir_vec![pat]) } -fn pat_none(lctx: &LoweringContext, span: Span) -> P { +fn pat_none(lctx: &mut LoweringContext, span: Span) -> P { let none = std_path(lctx, &["option", "Option", "None"]); let path = path_global(span, none); pat_enum(lctx, span, path, hir_vec![]) } -fn pat_enum(lctx: &LoweringContext, +fn pat_enum(lctx: &mut LoweringContext, span: Span, path: hir::Path, subpats: hir::HirVec>) -> P { - let def = lctx.resolver.borrow_mut().resolve_generated_global_path(&path, true); + let def = lctx.resolver.resolve_generated_global_path(&path, true); let pt = if subpats.is_empty() { hir::PatKind::Path(path) } else { hir::PatKind::TupleStruct(path, Some(subpats)) }; let pat = pat(lctx, span, pt); - lctx.resolver.borrow_mut().record_resolution(pat.id, def); + lctx.resolver.record_resolution(pat.id, def); pat } -fn pat_ident(lctx: &LoweringContext, span: Span, ident: hir::Ident) -> P { +fn pat_ident(lctx: &mut LoweringContext, span: Span, ident: hir::Ident) -> P { pat_ident_binding_mode(lctx, span, ident, hir::BindByValue(hir::MutImmutable)) } -fn pat_ident_binding_mode(lctx: &LoweringContext, +fn pat_ident_binding_mode(lctx: &mut LoweringContext, span: Span, ident: hir::Ident, bm: hir::BindingMode) @@ -1903,22 +1902,22 @@ fn pat_ident_binding_mode(lctx: &LoweringContext, let pat = pat(lctx, span, pat_ident); - let mut resolver = lctx.resolver.borrow_mut(); - let def = resolver.definitions().map(|defs| { + let parent_def = lctx.parent_def; + let def = lctx.resolver.definitions().map(|defs| { let def_path_data = DefPathData::Binding(ident.name); - let def_index = defs.create_def_with_parent(lctx.parent_def.get(), pat.id, def_path_data); + let def_index = defs.create_def_with_parent(parent_def, pat.id, def_path_data); Def::Local(DefId::local(def_index), pat.id) }).unwrap_or(Def::Err); - resolver.record_resolution(pat.id, def); + lctx.resolver.record_resolution(pat.id, def); pat } -fn pat_wild(lctx: &LoweringContext, span: Span) -> P { +fn pat_wild(lctx: &mut LoweringContext, span: Span) -> P { pat(lctx, span, hir::PatKind::Wild) } -fn pat(lctx: &LoweringContext, span: Span, pat: hir::PatKind) -> P { +fn pat(lctx: &mut LoweringContext, span: Span, pat: hir::PatKind) -> P { P(hir::Pat { id: lctx.next_id(), node: pat, @@ -1969,7 +1968,7 @@ fn path_all(sp: Span, } } -fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec { +fn std_path(lctx: &mut LoweringContext, components: &[&str]) -> Vec { let mut v = Vec::new(); if let Some(s) = lctx.crate_root { v.push(hir::Ident::from_name(token::intern(s))); @@ -1980,12 +1979,12 @@ fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec { // Given suffix ["b","c","d"], returns path `::std::b::c::d` when // `fld.cx.use_std`, and `::core::b::c::d` otherwise. -fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Path { +fn core_path(lctx: &mut LoweringContext, span: Span, components: &[&str]) -> hir::Path { let idents = std_path(lctx, components); path_global(span, idents) } -fn signal_block_expr(lctx: &LoweringContext, +fn signal_block_expr(lctx: &mut LoweringContext, stmts: hir::HirVec, expr: P, span: Span, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index e72204e5e22de..66b1b28a0e505 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -787,8 +787,8 @@ pub fn lower_and_resolve<'a>(sess: &Session, // Lower ast -> hir. let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || { - let lcx = LoweringContext::new(sess, Some(krate), &mut resolver); - hir_map::Forest::new(lower_crate(&lcx, krate), dep_graph) + let mut lcx = LoweringContext::new(sess, Some(krate), &mut resolver); + hir_map::Forest::new(lower_crate(&mut lcx, krate), dep_graph) }); (ty::CrateAnalysis { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 56f6a3f7b14cb..ce525b716ff2c 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -1326,11 +1326,11 @@ fn mk_ctxt() -> parse::ParseSess { } #[cfg(test)] -fn with_testing_context T>(f: F) -> T { +fn with_testing_context T>(f: F) -> T { let assigner = FakeNodeIdAssigner; let mut resolver = DummyResolver; - let lcx = LoweringContext::new(&assigner, None, &mut resolver); - f(lcx) + let mut lcx = LoweringContext::new(&assigner, None, &mut resolver); + f(&mut lcx) } #[cfg(test)] @@ -1347,7 +1347,7 @@ fn roundtrip(in_item: hir::Item) { fn test_basic() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(&lcx, "e_item!(&cx, + roundtrip(lower_item(lcx, "e_item!(&cx, fn foo() {} ).unwrap())); }); @@ -1357,7 +1357,7 @@ fn test_basic() { fn test_smalltalk() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(&lcx, "e_item!(&cx, + roundtrip(lower_item(lcx, "e_item!(&cx, fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed. ).unwrap())); }); @@ -1367,7 +1367,7 @@ fn test_smalltalk() { fn test_more() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(&lcx, "e_item!(&cx, + roundtrip(lower_item(lcx, "e_item!(&cx, fn foo(x: usize, y: usize) -> usize { let z = x + y; return z; @@ -1387,10 +1387,10 @@ fn test_simplification() { ).unwrap(); let cx = mk_ctxt(); with_testing_context(|lcx| { - let hir_item = lower_item(&lcx, &item); + let hir_item = lower_item(lcx, &item); let item_in = InlinedItemRef::Item(&hir_item); let item_out = simplify_ast(item_in); - let item_exp = InlinedItem::Item(P(lower_item(&lcx, "e_item!(&cx, + let item_exp = InlinedItem::Item(P(lower_item(lcx, "e_item!(&cx, fn new_int_alist() -> alist { return alist {eq_fn: eq_int, data: Vec::new()}; } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index fc548924e2964..0f518900ea787 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -98,8 +98,8 @@ pub fn run(input: &str, let defs = &RefCell::new(hir_map::collect_definitions(&krate)); let mut dummy_resolver = DummyResolver; - let lcx = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver); - let krate = lower_crate(&lcx, &krate); + let mut lcx = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver); + let krate = lower_crate(&mut lcx, &krate); let opts = scrape_test_config(&krate); From 8d5c5785d58f435d2d6e6e408e20c5c0b02a8e41 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 10 May 2016 00:05:50 +0000 Subject: [PATCH 04/16] Remove needless `pub`s --- src/librustc/hir/lowering.rs | 162 +++++++++++++++++------------------ 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index dc4ed655c9b88..40f6fddf10970 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -138,18 +138,18 @@ impl<'a> LoweringContext<'a> { } } -pub fn lower_ident(_lctx: &mut LoweringContext, ident: Ident) -> hir::Ident { +fn lower_ident(_lctx: &mut LoweringContext, ident: Ident) -> hir::Ident { hir::Ident { name: mtwt::resolve(ident), unhygienic_name: ident.name, } } -pub fn lower_attrs(_lctx: &mut LoweringContext, attrs: &Vec) -> hir::HirVec { +fn lower_attrs(_lctx: &mut LoweringContext, attrs: &Vec) -> hir::HirVec { attrs.clone().into() } -pub fn lower_view_path(lctx: &mut LoweringContext, view_path: &ViewPath) -> P { +fn lower_view_path(lctx: &mut LoweringContext, view_path: &ViewPath) -> P { P(Spanned { node: match view_path.node { ViewPathSimple(ident, ref path) => { @@ -186,7 +186,7 @@ fn lower_path_list_item(path_list_ident: &PathListItem) -> hir::PathListItem { } } -pub fn lower_arm(lctx: &mut LoweringContext, arm: &Arm) -> hir::Arm { +fn lower_arm(lctx: &mut LoweringContext, arm: &Arm) -> hir::Arm { hir::Arm { attrs: lower_attrs(lctx, &arm.attrs), pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(), @@ -195,7 +195,7 @@ pub fn lower_arm(lctx: &mut LoweringContext, arm: &Arm) -> hir::Arm { } } -pub fn lower_decl(lctx: &mut LoweringContext, d: &Decl) -> P { +fn lower_decl(lctx: &mut LoweringContext, d: &Decl) -> P { match d.node { DeclKind::Local(ref l) => P(Spanned { node: hir::DeclLocal(lower_local(lctx, l)), @@ -208,7 +208,7 @@ pub fn lower_decl(lctx: &mut LoweringContext, d: &Decl) -> P { } } -pub fn lower_ty_binding(lctx: &mut LoweringContext, b: &TypeBinding) -> hir::TypeBinding { +fn lower_ty_binding(lctx: &mut LoweringContext, b: &TypeBinding) -> hir::TypeBinding { hir::TypeBinding { id: b.id, name: b.ident.name, @@ -217,7 +217,7 @@ pub fn lower_ty_binding(lctx: &mut LoweringContext, b: &TypeBinding) -> hir::Typ } } -pub fn lower_ty(lctx: &mut LoweringContext, t: &Ty) -> P { +fn lower_ty(lctx: &mut LoweringContext, t: &Ty) -> P { use syntax::ast::TyKind::*; P(hir::Ty { id: t.id, @@ -267,14 +267,14 @@ pub fn lower_ty(lctx: &mut LoweringContext, t: &Ty) -> P { }) } -pub fn lower_foreign_mod(lctx: &mut LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { +fn lower_foreign_mod(lctx: &mut LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { hir::ForeignMod { abi: fm.abi, items: fm.items.iter().map(|x| lower_foreign_item(lctx, x)).collect(), } } -pub fn lower_variant(lctx: &mut LoweringContext, v: &Variant) -> hir::Variant { +fn lower_variant(lctx: &mut LoweringContext, v: &Variant) -> hir::Variant { Spanned { node: hir::Variant_ { name: v.node.name.name, @@ -289,7 +289,7 @@ pub fn lower_variant(lctx: &mut LoweringContext, v: &Variant) -> hir::Variant { // Path segments are usually unhygienic, hygienic path segments can occur only in // identifier-like paths originating from `ExprPath`. // Make life simpler for rustc_resolve by renaming only such segments. -pub fn lower_path_full(lctx: &mut LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { +fn lower_path_full(lctx: &mut LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; hir::Path { global: p.global, @@ -310,13 +310,13 @@ pub fn lower_path_full(lctx: &mut LoweringContext, p: &Path, maybe_hygienic: boo } } -pub fn lower_path(lctx: &mut LoweringContext, p: &Path) -> hir::Path { +fn lower_path(lctx: &mut LoweringContext, p: &Path) -> hir::Path { lower_path_full(lctx, p, false) } -pub fn lower_path_parameters(lctx: &mut LoweringContext, - path_parameters: &PathParameters) - -> hir::PathParameters { +fn lower_path_parameters(lctx: &mut LoweringContext, + path_parameters: &PathParameters) + -> hir::PathParameters { match *path_parameters { PathParameters::AngleBracketed(ref data) => hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(lctx, data)), @@ -325,9 +325,9 @@ pub fn lower_path_parameters(lctx: &mut LoweringContext, } } -pub fn lower_angle_bracketed_parameter_data(lctx: &mut LoweringContext, - data: &AngleBracketedParameterData) - -> hir::AngleBracketedParameterData { +fn lower_angle_bracketed_parameter_data(lctx: &mut LoweringContext, + data: &AngleBracketedParameterData) + -> hir::AngleBracketedParameterData { let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; hir::AngleBracketedParameterData { lifetimes: lower_lifetimes(lctx, lifetimes), @@ -336,9 +336,9 @@ pub fn lower_angle_bracketed_parameter_data(lctx: &mut LoweringContext, } } -pub fn lower_parenthesized_parameter_data(lctx: &mut LoweringContext, - data: &ParenthesizedParameterData) - -> hir::ParenthesizedParameterData { +fn lower_parenthesized_parameter_data(lctx: &mut LoweringContext, + data: &ParenthesizedParameterData) + -> hir::ParenthesizedParameterData { let &ParenthesizedParameterData { ref inputs, ref output, span } = data; hir::ParenthesizedParameterData { inputs: inputs.iter().map(|ty| lower_ty(lctx, ty)).collect(), @@ -347,7 +347,7 @@ pub fn lower_parenthesized_parameter_data(lctx: &mut LoweringContext, } } -pub fn lower_local(lctx: &mut LoweringContext, l: &Local) -> P { +fn lower_local(lctx: &mut LoweringContext, l: &Local) -> P { P(hir::Local { id: l.id, ty: l.ty.as_ref().map(|t| lower_ty(lctx, t)), @@ -358,9 +358,9 @@ pub fn lower_local(lctx: &mut LoweringContext, l: &Local) -> P { }) } -pub fn lower_explicit_self_underscore(lctx: &mut LoweringContext, - es: &SelfKind) - -> hir::ExplicitSelf_ { +fn lower_explicit_self_underscore(lctx: &mut LoweringContext, + es: &SelfKind) + -> hir::ExplicitSelf_ { match *es { SelfKind::Static => hir::SelfStatic, SelfKind::Value(v) => hir::SelfValue(v.name), @@ -375,21 +375,21 @@ pub fn lower_explicit_self_underscore(lctx: &mut LoweringContext, } } -pub fn lower_mutability(_lctx: &mut LoweringContext, m: Mutability) -> hir::Mutability { +fn lower_mutability(_lctx: &mut LoweringContext, m: Mutability) -> hir::Mutability { match m { Mutability::Mutable => hir::MutMutable, Mutability::Immutable => hir::MutImmutable, } } -pub fn lower_explicit_self(lctx: &mut LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { +fn lower_explicit_self(lctx: &mut LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { Spanned { node: lower_explicit_self_underscore(lctx, &s.node), span: s.span, } } -pub fn lower_arg(lctx: &mut LoweringContext, arg: &Arg) -> hir::Arg { +fn lower_arg(lctx: &mut LoweringContext, arg: &Arg) -> hir::Arg { hir::Arg { id: arg.id, pat: lower_pat(lctx, &arg.pat), @@ -397,7 +397,7 @@ pub fn lower_arg(lctx: &mut LoweringContext, arg: &Arg) -> hir::Arg { } } -pub fn lower_fn_decl(lctx: &mut LoweringContext, decl: &FnDecl) -> P { +fn lower_fn_decl(lctx: &mut LoweringContext, decl: &FnDecl) -> P { P(hir::FnDecl { inputs: decl.inputs.iter().map(|x| lower_arg(lctx, x)).collect(), output: match decl.output { @@ -409,7 +409,7 @@ pub fn lower_fn_decl(lctx: &mut LoweringContext, decl: &FnDecl) -> P hir::TyParamBound { +fn lower_ty_param_bound(lctx: &mut LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { match *tpb { TraitTyParamBound(ref ty, modifier) => { hir::TraitTyParamBound(lower_poly_trait_ref(lctx, ty), @@ -421,7 +421,7 @@ pub fn lower_ty_param_bound(lctx: &mut LoweringContext, tpb: &TyParamBound) -> h } } -pub fn lower_ty_param(lctx: &mut LoweringContext, tp: &TyParam) -> hir::TyParam { +fn lower_ty_param(lctx: &mut LoweringContext, tp: &TyParam) -> hir::TyParam { hir::TyParam { id: tp.id, name: tp.ident.name, @@ -431,13 +431,13 @@ pub fn lower_ty_param(lctx: &mut LoweringContext, tp: &TyParam) -> hir::TyParam } } -pub fn lower_ty_params(lctx: &mut LoweringContext, - tps: &P<[TyParam]>) - -> hir::HirVec { +fn lower_ty_params(lctx: &mut LoweringContext, + tps: &P<[TyParam]>) + -> hir::HirVec { tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect() } -pub fn lower_lifetime(_lctx: &mut LoweringContext, l: &Lifetime) -> hir::Lifetime { +fn lower_lifetime(_lctx: &mut LoweringContext, l: &Lifetime) -> hir::Lifetime { hir::Lifetime { id: l.id, name: l.name, @@ -445,31 +445,31 @@ pub fn lower_lifetime(_lctx: &mut LoweringContext, l: &Lifetime) -> hir::Lifetim } } -pub fn lower_lifetime_def(lctx: &mut LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { +fn lower_lifetime_def(lctx: &mut LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { hir::LifetimeDef { lifetime: lower_lifetime(lctx, &l.lifetime), bounds: lower_lifetimes(lctx, &l.bounds), } } -pub fn lower_lifetimes(lctx: &mut LoweringContext, lts: &Vec) +fn lower_lifetimes(lctx: &mut LoweringContext, lts: &Vec) -> hir::HirVec { lts.iter().map(|l| lower_lifetime(lctx, l)).collect() } -pub fn lower_lifetime_defs(lctx: &mut LoweringContext, - lts: &Vec) - -> hir::HirVec { +fn lower_lifetime_defs(lctx: &mut LoweringContext, + lts: &Vec) + -> hir::HirVec { lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect() } -pub fn lower_opt_lifetime(lctx: &mut LoweringContext, - o_lt: &Option) - -> Option { +fn lower_opt_lifetime(lctx: &mut LoweringContext, + o_lt: &Option) + -> Option { o_lt.as_ref().map(|lt| lower_lifetime(lctx, lt)) } -pub fn lower_generics(lctx: &mut LoweringContext, g: &Generics) -> hir::Generics { +fn lower_generics(lctx: &mut LoweringContext, g: &Generics) -> hir::Generics { hir::Generics { ty_params: lower_ty_params(lctx, &g.ty_params), lifetimes: lower_lifetime_defs(lctx, &g.lifetimes), @@ -477,7 +477,7 @@ pub fn lower_generics(lctx: &mut LoweringContext, g: &Generics) -> hir::Generics } } -pub fn lower_where_clause(lctx: &mut LoweringContext, wc: &WhereClause) -> hir::WhereClause { +fn lower_where_clause(lctx: &mut LoweringContext, wc: &WhereClause) -> hir::WhereClause { hir::WhereClause { id: wc.id, predicates: wc.predicates @@ -487,9 +487,9 @@ pub fn lower_where_clause(lctx: &mut LoweringContext, wc: &WhereClause) -> hir:: } } -pub fn lower_where_predicate(lctx: &mut LoweringContext, - pred: &WherePredicate) - -> hir::WherePredicate { +fn lower_where_predicate(lctx: &mut LoweringContext, + pred: &WherePredicate) + -> hir::WherePredicate { match *pred { WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes, ref bounded_ty, @@ -525,7 +525,7 @@ pub fn lower_where_predicate(lctx: &mut LoweringContext, } } -pub fn lower_variant_data(lctx: &mut LoweringContext, vdata: &VariantData) -> hir::VariantData { +fn lower_variant_data(lctx: &mut LoweringContext, vdata: &VariantData) -> hir::VariantData { match *vdata { VariantData::Struct(ref fields, id) => { hir::VariantData::Struct(fields.iter() @@ -545,14 +545,14 @@ pub fn lower_variant_data(lctx: &mut LoweringContext, vdata: &VariantData) -> hi } } -pub fn lower_trait_ref(lctx: &mut LoweringContext, p: &TraitRef) -> hir::TraitRef { +fn lower_trait_ref(lctx: &mut LoweringContext, p: &TraitRef) -> hir::TraitRef { hir::TraitRef { path: lower_path(lctx, &p.path), ref_id: p.ref_id, } } -pub fn lower_poly_trait_ref(lctx: &mut LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { +fn lower_poly_trait_ref(lctx: &mut LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { hir::PolyTraitRef { bound_lifetimes: lower_lifetime_defs(lctx, &p.bound_lifetimes), trait_ref: lower_trait_ref(lctx, &p.trait_ref), @@ -560,9 +560,9 @@ pub fn lower_poly_trait_ref(lctx: &mut LoweringContext, p: &PolyTraitRef) -> hir } } -pub fn lower_struct_field(lctx: &mut LoweringContext, - (index, f): (usize, &StructField)) - -> hir::StructField { +fn lower_struct_field(lctx: &mut LoweringContext, + (index, f): (usize, &StructField)) + -> hir::StructField { hir::StructField { span: f.span, id: f.id, @@ -573,7 +573,7 @@ pub fn lower_struct_field(lctx: &mut LoweringContext, } } -pub fn lower_field(lctx: &mut LoweringContext, f: &Field) -> hir::Field { +fn lower_field(lctx: &mut LoweringContext, f: &Field) -> hir::Field { hir::Field { name: respan(f.ident.span, f.ident.node.name), expr: lower_expr(lctx, &f.expr), @@ -581,7 +581,7 @@ pub fn lower_field(lctx: &mut LoweringContext, f: &Field) -> hir::Field { } } -pub fn lower_mt(lctx: &mut LoweringContext, mt: &MutTy) -> hir::MutTy { +fn lower_mt(lctx: &mut LoweringContext, mt: &MutTy) -> hir::MutTy { hir::MutTy { ty: lower_ty(lctx, &mt.ty), mutbl: lower_mutability(lctx, mt.mutbl), @@ -592,7 +592,7 @@ fn lower_bounds(lctx: &mut LoweringContext, bounds: &TyParamBounds) -> hir::TyPa bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() } -pub fn lower_block(lctx: &mut LoweringContext, b: &Block) -> P { +fn lower_block(lctx: &mut LoweringContext, b: &Block) -> P { P(hir::Block { id: b.id, stmts: b.stmts.iter().map(|s| lower_stmt(lctx, s)).collect(), @@ -602,7 +602,7 @@ pub fn lower_block(lctx: &mut LoweringContext, b: &Block) -> P { }) } -pub fn lower_item_kind(lctx: &mut LoweringContext, i: &ItemKind) -> hir::Item_ { +fn lower_item_kind(lctx: &mut LoweringContext, i: &ItemKind) -> hir::Item_ { match *i { ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), ItemKind::Use(ref view_path) => { @@ -670,7 +670,7 @@ pub fn lower_item_kind(lctx: &mut LoweringContext, i: &ItemKind) -> hir::Item_ { } } -pub fn lower_trait_item(lctx: &mut LoweringContext, i: &TraitItem) -> hir::TraitItem { +fn lower_trait_item(lctx: &mut LoweringContext, i: &TraitItem) -> hir::TraitItem { lctx.with_parent_def(i.id, |lctx| { hir::TraitItem { id: i.id, @@ -695,7 +695,7 @@ pub fn lower_trait_item(lctx: &mut LoweringContext, i: &TraitItem) -> hir::Trait }) } -pub fn lower_impl_item(lctx: &mut LoweringContext, i: &ImplItem) -> hir::ImplItem { +fn lower_impl_item(lctx: &mut LoweringContext, i: &ImplItem) -> hir::ImplItem { lctx.with_parent_def(i.id, |lctx| { hir::ImplItem { id: i.id, @@ -718,7 +718,7 @@ pub fn lower_impl_item(lctx: &mut LoweringContext, i: &ImplItem) -> hir::ImplIte }) } -pub fn lower_mod(lctx: &mut LoweringContext, m: &Mod) -> hir::Mod { +fn lower_mod(lctx: &mut LoweringContext, m: &Mod) -> hir::Mod { hir::Mod { inner: m.inner, item_ids: m.items.iter().map(|x| lower_item_id(lctx, x)).collect(), @@ -754,7 +754,7 @@ pub fn lower_crate(lctx: &mut LoweringContext, c: &Crate) -> hir::Crate { } } -pub fn lower_macro_def(lctx: &mut LoweringContext, m: &MacroDef) -> hir::MacroDef { +fn lower_macro_def(lctx: &mut LoweringContext, m: &MacroDef) -> hir::MacroDef { hir::MacroDef { name: m.ident.name, attrs: lower_attrs(lctx, &m.attrs), @@ -768,7 +768,7 @@ pub fn lower_macro_def(lctx: &mut LoweringContext, m: &MacroDef) -> hir::MacroDe } } -pub fn lower_item_id(_lctx: &mut LoweringContext, i: &Item) -> hir::ItemId { +fn lower_item_id(_lctx: &mut LoweringContext, i: &Item) -> hir::ItemId { hir::ItemId { id: i.id } } @@ -787,7 +787,7 @@ pub fn lower_item(lctx: &mut LoweringContext, i: &Item) -> hir::Item { } } -pub fn lower_foreign_item(lctx: &mut LoweringContext, i: &ForeignItem) -> hir::ForeignItem { +fn lower_foreign_item(lctx: &mut LoweringContext, i: &ForeignItem) -> hir::ForeignItem { lctx.with_parent_def(i.id, |lctx| { hir::ForeignItem { id: i.id, @@ -807,7 +807,7 @@ pub fn lower_foreign_item(lctx: &mut LoweringContext, i: &ForeignItem) -> hir::F }) } -pub fn lower_method_sig(lctx: &mut LoweringContext, sig: &MethodSig) -> hir::MethodSig { +fn lower_method_sig(lctx: &mut LoweringContext, sig: &MethodSig) -> hir::MethodSig { hir::MethodSig { generics: lower_generics(lctx, &sig.generics), abi: sig.abi, @@ -818,21 +818,21 @@ pub fn lower_method_sig(lctx: &mut LoweringContext, sig: &MethodSig) -> hir::Met } } -pub fn lower_unsafety(_lctx: &mut LoweringContext, u: Unsafety) -> hir::Unsafety { +fn lower_unsafety(_lctx: &mut LoweringContext, u: Unsafety) -> hir::Unsafety { match u { Unsafety::Unsafe => hir::Unsafety::Unsafe, Unsafety::Normal => hir::Unsafety::Normal, } } -pub fn lower_constness(_lctx: &mut LoweringContext, c: Constness) -> hir::Constness { +fn lower_constness(_lctx: &mut LoweringContext, c: Constness) -> hir::Constness { match c { Constness::Const => hir::Constness::Const, Constness::NotConst => hir::Constness::NotConst, } } -pub fn lower_unop(_lctx: &mut LoweringContext, u: UnOp) -> hir::UnOp { +fn lower_unop(_lctx: &mut LoweringContext, u: UnOp) -> hir::UnOp { match u { UnOp::Deref => hir::UnDeref, UnOp::Not => hir::UnNot, @@ -840,7 +840,7 @@ pub fn lower_unop(_lctx: &mut LoweringContext, u: UnOp) -> hir::UnOp { } } -pub fn lower_binop(_lctx: &mut LoweringContext, b: BinOp) -> hir::BinOp { +fn lower_binop(_lctx: &mut LoweringContext, b: BinOp) -> hir::BinOp { Spanned { node: match b.node { BinOpKind::Add => hir::BiAdd, @@ -866,7 +866,7 @@ pub fn lower_binop(_lctx: &mut LoweringContext, b: BinOp) -> hir::BinOp { } } -pub fn lower_pat(lctx: &mut LoweringContext, p: &Pat) -> P { +fn lower_pat(lctx: &mut LoweringContext, p: &Pat) -> P { P(hir::Pat { id: p.id, node: match p.node { @@ -931,7 +931,7 @@ pub fn lower_pat(lctx: &mut LoweringContext, p: &Pat) -> P { }) } -pub fn lower_expr(lctx: &mut LoweringContext, e: &Expr) -> P { +fn lower_expr(lctx: &mut LoweringContext, e: &Expr) -> P { P(hir::Expr { id: e.id, node: match e.node { @@ -1612,7 +1612,7 @@ pub fn lower_expr(lctx: &mut LoweringContext, e: &Expr) -> P { }) } -pub fn lower_stmt(lctx: &mut LoweringContext, s: &Stmt) -> hir::Stmt { +fn lower_stmt(lctx: &mut LoweringContext, s: &Stmt) -> hir::Stmt { match s.node { StmtKind::Decl(ref d, id) => { Spanned { @@ -1636,14 +1636,14 @@ pub fn lower_stmt(lctx: &mut LoweringContext, s: &Stmt) -> hir::Stmt { } } -pub fn lower_capture_clause(_lctx: &mut LoweringContext, c: CaptureBy) -> hir::CaptureClause { +fn lower_capture_clause(_lctx: &mut LoweringContext, c: CaptureBy) -> hir::CaptureClause { match c { CaptureBy::Value => hir::CaptureByValue, CaptureBy::Ref => hir::CaptureByRef, } } -pub fn lower_visibility(lctx: &mut LoweringContext, v: &Visibility) -> hir::Visibility { +fn lower_visibility(lctx: &mut LoweringContext, v: &Visibility) -> hir::Visibility { match *v { Visibility::Public => hir::Public, Visibility::Crate(_) => hir::Visibility::Crate, @@ -1653,44 +1653,44 @@ pub fn lower_visibility(lctx: &mut LoweringContext, v: &Visibility) -> hir::Visi } } -pub fn lower_defaultness(_lctx: &mut LoweringContext, d: Defaultness) -> hir::Defaultness { +fn lower_defaultness(_lctx: &mut LoweringContext, d: Defaultness) -> hir::Defaultness { match d { Defaultness::Default => hir::Defaultness::Default, Defaultness::Final => hir::Defaultness::Final, } } -pub fn lower_block_check_mode(lctx: &mut LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { +fn lower_block_check_mode(lctx: &mut LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { match *b { BlockCheckMode::Default => hir::DefaultBlock, BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(lower_unsafe_source(lctx, u)), } } -pub fn lower_binding_mode(lctx: &mut LoweringContext, b: &BindingMode) -> hir::BindingMode { +fn lower_binding_mode(lctx: &mut LoweringContext, b: &BindingMode) -> hir::BindingMode { match *b { BindingMode::ByRef(m) => hir::BindByRef(lower_mutability(lctx, m)), BindingMode::ByValue(m) => hir::BindByValue(lower_mutability(lctx, m)), } } -pub fn lower_unsafe_source(_lctx: &mut LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { +fn lower_unsafe_source(_lctx: &mut LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { match u { CompilerGenerated => hir::CompilerGenerated, UserProvided => hir::UserProvided, } } -pub fn lower_impl_polarity(_lctx: &mut LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { +fn lower_impl_polarity(_lctx: &mut LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { match i { ImplPolarity::Positive => hir::ImplPolarity::Positive, ImplPolarity::Negative => hir::ImplPolarity::Negative, } } -pub fn lower_trait_bound_modifier(_lctx: &mut LoweringContext, - f: TraitBoundModifier) - -> hir::TraitBoundModifier { +fn lower_trait_bound_modifier(_lctx: &mut LoweringContext, + f: TraitBoundModifier) + -> hir::TraitBoundModifier { match f { TraitBoundModifier::None => hir::TraitBoundModifier::None, TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, From 0a380897a8273d6310604297cf97d8cf28eec798 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 10 May 2016 14:53:48 +1000 Subject: [PATCH 05/16] Copy more libraries from local Rust to stage0 When bootstrapping Rust using a previously built toolchain, I noticed a number of libraries were not copied in. As a result the copied in rustc fails to execute because it can't find all its dependences. Add them into the local_stage0.sh script. --- src/etc/local_stage0.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/etc/local_stage0.sh b/src/etc/local_stage0.sh index aee69a5c8bc58..fb455441910b8 100755 --- a/src/etc/local_stage0.sh +++ b/src/etc/local_stage0.sh @@ -55,6 +55,14 @@ cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}extra*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_D cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}rust*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}std*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}syntax*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}flate*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}fmt_macros*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}getopts*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}graphviz*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}log*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}rbml*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}serialize*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ +cp ${PREFIX}/${LIB_DIR}/${LIB_PREFIX}term*${LIB_SUF} ${TARG_DIR}/stage0/${LIB_DIR}/ # do not fail if one of the above fails, as all we need is a working rustc! exit 0 From 946efcd4cae78640222d855c6c8aafafc0f844ef Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 10 May 2016 01:11:59 +0000 Subject: [PATCH 06/16] Refactor the `hir::lowering::lower_*` functions into methods of `LoweringContext` --- src/librustc/hir/lowering.rs | 2759 ++++++++++++++-------------- src/librustc_driver/driver.rs | 6 +- src/librustc_metadata/astencode.rs | 12 +- src/librustdoc/test.rs | 5 +- 4 files changed, 1383 insertions(+), 1399 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 40f6fddf10970..0f65c5c64e491 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -114,6 +114,35 @@ impl<'a> LoweringContext<'a> { } } + pub fn lower_crate(&mut self, c: &Crate) -> hir::Crate { + struct ItemLowerer<'lcx, 'interner: 'lcx> { + items: BTreeMap, + lctx: &'lcx mut LoweringContext<'interner>, + } + + impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { + fn visit_item(&mut self, item: &'lcx Item) { + self.items.insert(item.id, self.lctx.lower_item(item)); + visit::walk_item(self, item); + } + } + + let items = { + let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: self }; + visit::walk_crate(&mut item_lowerer, c); + item_lowerer.items + }; + + hir::Crate { + module: self.lower_mod(&c.module), + attrs: self.lower_attrs(&c.attrs), + config: c.config.clone().into(), + span: c.span, + exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(), + items: items, + } + } + fn next_id(&self) -> NodeId { self.id_assigner.next_node_id() } @@ -136,1564 +165,1520 @@ impl<'a> LoweringContext<'a> { self.parent_def = old_def; result } -} -fn lower_ident(_lctx: &mut LoweringContext, ident: Ident) -> hir::Ident { - hir::Ident { - name: mtwt::resolve(ident), - unhygienic_name: ident.name, + fn lower_ident(&mut self, ident: Ident) -> hir::Ident { + hir::Ident { + name: mtwt::resolve(ident), + unhygienic_name: ident.name, + } } -} -fn lower_attrs(_lctx: &mut LoweringContext, attrs: &Vec) -> hir::HirVec { - attrs.clone().into() -} - -fn lower_view_path(lctx: &mut LoweringContext, view_path: &ViewPath) -> P { - P(Spanned { - node: match view_path.node { - ViewPathSimple(ident, ref path) => { - hir::ViewPathSimple(ident.name, lower_path(lctx, path)) - } - ViewPathGlob(ref path) => { - hir::ViewPathGlob(lower_path(lctx, path)) - } - ViewPathList(ref path, ref path_list_idents) => { - hir::ViewPathList(lower_path(lctx, path), - path_list_idents.iter() - .map(lower_path_list_item) - .collect()) - } - }, - span: view_path.span, - }) -} + fn lower_attrs(&mut self, attrs: &Vec) -> hir::HirVec { + attrs.clone().into() + } -fn lower_path_list_item(path_list_ident: &PathListItem) -> hir::PathListItem { - Spanned { - node: match path_list_ident.node { - PathListItemKind::Ident { id, name, rename } => hir::PathListIdent { - id: id, - name: name.name, - rename: rename.map(|x| x.name), - }, - PathListItemKind::Mod { id, rename } => hir::PathListMod { - id: id, - rename: rename.map(|x| x.name), + fn lower_view_path(&mut self, view_path: &ViewPath) -> P { + P(Spanned { + node: match view_path.node { + ViewPathSimple(ident, ref path) => { + hir::ViewPathSimple(ident.name, self.lower_path(path)) + } + ViewPathGlob(ref path) => { + hir::ViewPathGlob(self.lower_path(path)) + } + ViewPathList(ref path, ref path_list_idents) => { + hir::ViewPathList(self.lower_path(path), + path_list_idents.iter() + .map(|item| self.lower_path_list_item(item)) + .collect()) + } }, - }, - span: path_list_ident.span, + span: view_path.span, + }) } -} -fn lower_arm(lctx: &mut LoweringContext, arm: &Arm) -> hir::Arm { - hir::Arm { - attrs: lower_attrs(lctx, &arm.attrs), - pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(), - guard: arm.guard.as_ref().map(|ref x| lower_expr(lctx, x)), - body: lower_expr(lctx, &arm.body), + fn lower_path_list_item(&mut self, path_list_ident: &PathListItem) -> hir::PathListItem { + Spanned { + node: match path_list_ident.node { + PathListItemKind::Ident { id, name, rename } => hir::PathListIdent { + id: id, + name: name.name, + rename: rename.map(|x| x.name), + }, + PathListItemKind::Mod { id, rename } => hir::PathListMod { + id: id, + rename: rename.map(|x| x.name), + }, + }, + span: path_list_ident.span, + } } -} -fn lower_decl(lctx: &mut LoweringContext, d: &Decl) -> P { - match d.node { - DeclKind::Local(ref l) => P(Spanned { - node: hir::DeclLocal(lower_local(lctx, l)), - span: d.span, - }), - DeclKind::Item(ref it) => P(Spanned { - node: hir::DeclItem(lower_item_id(lctx, it)), - span: d.span, - }), + fn lower_arm(&mut self, arm: &Arm) -> hir::Arm { + hir::Arm { + attrs: self.lower_attrs(&arm.attrs), + pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(), + guard: arm.guard.as_ref().map(|ref x| self.lower_expr(x)), + body: self.lower_expr(&arm.body), + } } -} -fn lower_ty_binding(lctx: &mut LoweringContext, b: &TypeBinding) -> hir::TypeBinding { - hir::TypeBinding { - id: b.id, - name: b.ident.name, - ty: lower_ty(lctx, &b.ty), - span: b.span, + fn lower_decl(&mut self, d: &Decl) -> P { + match d.node { + DeclKind::Local(ref l) => P(Spanned { + node: hir::DeclLocal(self.lower_local(l)), + span: d.span, + }), + DeclKind::Item(ref it) => P(Spanned { + node: hir::DeclItem(self.lower_item_id(it)), + span: d.span, + }), + } } -} - -fn lower_ty(lctx: &mut LoweringContext, t: &Ty) -> P { - use syntax::ast::TyKind::*; - P(hir::Ty { - id: t.id, - node: match t.node { - Infer => hir::TyInfer, - Vec(ref ty) => hir::TyVec(lower_ty(lctx, ty)), - Ptr(ref mt) => hir::TyPtr(lower_mt(lctx, mt)), - Rptr(ref region, ref mt) => { - hir::TyRptr(lower_opt_lifetime(lctx, region), lower_mt(lctx, mt)) - } - BareFn(ref f) => { - hir::TyBareFn(P(hir::BareFnTy { - lifetimes: lower_lifetime_defs(lctx, &f.lifetimes), - unsafety: lower_unsafety(lctx, f.unsafety), - abi: f.abi, - decl: lower_fn_decl(lctx, &f.decl), - })) - } - Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| lower_ty(lctx, ty)).collect()), - Paren(ref ty) => { - return lower_ty(lctx, ty); - } - Path(ref qself, ref path) => { - let qself = qself.as_ref().map(|&QSelf { ref ty, position }| { - hir::QSelf { - ty: lower_ty(lctx, ty), - position: position, - } - }); - hir::TyPath(qself, lower_path(lctx, path)) - } - ObjectSum(ref ty, ref bounds) => { - hir::TyObjectSum(lower_ty(lctx, ty), lower_bounds(lctx, bounds)) - } - FixedLengthVec(ref ty, ref e) => { - hir::TyFixedLengthVec(lower_ty(lctx, ty), lower_expr(lctx, e)) - } - Typeof(ref expr) => { - hir::TyTypeof(lower_expr(lctx, expr)) - } - PolyTraitRef(ref bounds) => { - hir::TyPolyTraitRef(bounds.iter().map(|b| lower_ty_param_bound(lctx, b)).collect()) - } - Mac(_) => panic!("TyMac should have been expanded by now."), - }, - span: t.span, - }) -} -fn lower_foreign_mod(lctx: &mut LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { - hir::ForeignMod { - abi: fm.abi, - items: fm.items.iter().map(|x| lower_foreign_item(lctx, x)).collect(), + fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding { + hir::TypeBinding { + id: b.id, + name: b.ident.name, + ty: self.lower_ty(&b.ty), + span: b.span, + } } -} -fn lower_variant(lctx: &mut LoweringContext, v: &Variant) -> hir::Variant { - Spanned { - node: hir::Variant_ { - name: v.node.name.name, - attrs: lower_attrs(lctx, &v.node.attrs), - data: lower_variant_data(lctx, &v.node.data), - disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(lctx, e)), - }, - span: v.span, + fn lower_ty(&mut self, t: &Ty) -> P { + use syntax::ast::TyKind::*; + P(hir::Ty { + id: t.id, + node: match t.node { + Infer => hir::TyInfer, + Vec(ref ty) => hir::TyVec(self.lower_ty(ty)), + Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)), + Rptr(ref region, ref mt) => { + hir::TyRptr(self.lower_opt_lifetime(region), self.lower_mt(mt)) + } + BareFn(ref f) => { + hir::TyBareFn(P(hir::BareFnTy { + lifetimes: self.lower_lifetime_defs(&f.lifetimes), + unsafety: self.lower_unsafety(f.unsafety), + abi: f.abi, + decl: self.lower_fn_decl(&f.decl), + })) + } + Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty)).collect()), + Paren(ref ty) => { + return self.lower_ty(ty); + } + Path(ref qself, ref path) => { + let qself = qself.as_ref().map(|&QSelf { ref ty, position }| { + hir::QSelf { + ty: self.lower_ty(ty), + position: position, + } + }); + hir::TyPath(qself, self.lower_path(path)) + } + ObjectSum(ref ty, ref bounds) => { + hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds)) + } + FixedLengthVec(ref ty, ref e) => { + hir::TyFixedLengthVec(self.lower_ty(ty), self.lower_expr(e)) + } + Typeof(ref expr) => { + hir::TyTypeof(self.lower_expr(expr)) + } + PolyTraitRef(ref bounds) => { + let bounds = bounds.iter().map(|b| self.lower_ty_param_bound(b)).collect(); + hir::TyPolyTraitRef(bounds) + } + Mac(_) => panic!("TyMac should have been expanded by now."), + }, + span: t.span, + }) } -} -// Path segments are usually unhygienic, hygienic path segments can occur only in -// identifier-like paths originating from `ExprPath`. -// Make life simpler for rustc_resolve by renaming only such segments. -fn lower_path_full(lctx: &mut LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { - let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; - hir::Path { - global: p.global, - segments: p.segments - .iter() - .map(|&PathSegment { identifier, ref parameters }| { - hir::PathSegment { - identifier: if maybe_hygienic { - lower_ident(lctx, identifier) - } else { - hir::Ident::from_name(identifier.name) - }, - parameters: lower_path_parameters(lctx, parameters), - } - }) - .collect(), - span: p.span, + fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod { + hir::ForeignMod { + abi: fm.abi, + items: fm.items.iter().map(|x| self.lower_foreign_item(x)).collect(), + } } -} -fn lower_path(lctx: &mut LoweringContext, p: &Path) -> hir::Path { - lower_path_full(lctx, p, false) -} - -fn lower_path_parameters(lctx: &mut LoweringContext, - path_parameters: &PathParameters) - -> hir::PathParameters { - match *path_parameters { - PathParameters::AngleBracketed(ref data) => - hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(lctx, data)), - PathParameters::Parenthesized(ref data) => - hir::ParenthesizedParameters(lower_parenthesized_parameter_data(lctx, data)), + fn lower_variant(&mut self, v: &Variant) -> hir::Variant { + Spanned { + node: hir::Variant_ { + name: v.node.name.name, + attrs: self.lower_attrs(&v.node.attrs), + data: self.lower_variant_data(&v.node.data), + disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_expr(e)), + }, + span: v.span, + } } -} -fn lower_angle_bracketed_parameter_data(lctx: &mut LoweringContext, - data: &AngleBracketedParameterData) - -> hir::AngleBracketedParameterData { - let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; - hir::AngleBracketedParameterData { - lifetimes: lower_lifetimes(lctx, lifetimes), - types: types.iter().map(|ty| lower_ty(lctx, ty)).collect(), - bindings: bindings.iter().map(|b| lower_ty_binding(lctx, b)).collect(), + // Path segments are usually unhygienic, hygienic path segments can occur only in + // identifier-like paths originating from `ExprPath`. + // Make life simpler for rustc_resolve by renaming only such segments. + fn lower_path_full(&mut self, p: &Path, maybe_hygienic: bool) -> hir::Path { + let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; + hir::Path { + global: p.global, + segments: p.segments + .iter() + .map(|&PathSegment { identifier, ref parameters }| { + hir::PathSegment { + identifier: if maybe_hygienic { + self.lower_ident(identifier) + } else { + hir::Ident::from_name(identifier.name) + }, + parameters: self.lower_path_parameters(parameters), + } + }) + .collect(), + span: p.span, + } } -} -fn lower_parenthesized_parameter_data(lctx: &mut LoweringContext, - data: &ParenthesizedParameterData) - -> hir::ParenthesizedParameterData { - let &ParenthesizedParameterData { ref inputs, ref output, span } = data; - hir::ParenthesizedParameterData { - inputs: inputs.iter().map(|ty| lower_ty(lctx, ty)).collect(), - output: output.as_ref().map(|ty| lower_ty(lctx, ty)), - span: span, + fn lower_path(&mut self, p: &Path) -> hir::Path { + self.lower_path_full(p, false) } -} -fn lower_local(lctx: &mut LoweringContext, l: &Local) -> P { - P(hir::Local { - id: l.id, - ty: l.ty.as_ref().map(|t| lower_ty(lctx, t)), - pat: lower_pat(lctx, &l.pat), - init: l.init.as_ref().map(|e| lower_expr(lctx, e)), - span: l.span, - attrs: l.attrs.clone(), - }) -} - -fn lower_explicit_self_underscore(lctx: &mut LoweringContext, - es: &SelfKind) - -> hir::ExplicitSelf_ { - match *es { - SelfKind::Static => hir::SelfStatic, - SelfKind::Value(v) => hir::SelfValue(v.name), - SelfKind::Region(ref lifetime, m, ident) => { - hir::SelfRegion(lower_opt_lifetime(lctx, lifetime), - lower_mutability(lctx, m), - ident.name) - } - SelfKind::Explicit(ref typ, ident) => { - hir::SelfExplicit(lower_ty(lctx, typ), ident.name) + fn lower_path_parameters(&mut self, path_parameters: &PathParameters) -> hir::PathParameters { + match *path_parameters { + PathParameters::AngleBracketed(ref data) => + hir::AngleBracketedParameters(self.lower_angle_bracketed_parameter_data(data)), + PathParameters::Parenthesized(ref data) => + hir::ParenthesizedParameters(self.lower_parenthesized_parameter_data(data)), } } -} -fn lower_mutability(_lctx: &mut LoweringContext, m: Mutability) -> hir::Mutability { - match m { - Mutability::Mutable => hir::MutMutable, - Mutability::Immutable => hir::MutImmutable, + fn lower_angle_bracketed_parameter_data(&mut self, + data: &AngleBracketedParameterData) + -> hir::AngleBracketedParameterData { + let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; + hir::AngleBracketedParameterData { + lifetimes: self.lower_lifetimes(lifetimes), + types: types.iter().map(|ty| self.lower_ty(ty)).collect(), + bindings: bindings.iter().map(|b| self.lower_ty_binding(b)).collect(), + } } -} -fn lower_explicit_self(lctx: &mut LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { - Spanned { - node: lower_explicit_self_underscore(lctx, &s.node), - span: s.span, + fn lower_parenthesized_parameter_data(&mut self, + data: &ParenthesizedParameterData) + -> hir::ParenthesizedParameterData { + let &ParenthesizedParameterData { ref inputs, ref output, span } = data; + hir::ParenthesizedParameterData { + inputs: inputs.iter().map(|ty| self.lower_ty(ty)).collect(), + output: output.as_ref().map(|ty| self.lower_ty(ty)), + span: span, + } } -} -fn lower_arg(lctx: &mut LoweringContext, arg: &Arg) -> hir::Arg { - hir::Arg { - id: arg.id, - pat: lower_pat(lctx, &arg.pat), - ty: lower_ty(lctx, &arg.ty), + fn lower_local(&mut self, l: &Local) -> P { + P(hir::Local { + id: l.id, + ty: l.ty.as_ref().map(|t| self.lower_ty(t)), + pat: self.lower_pat(&l.pat), + init: l.init.as_ref().map(|e| self.lower_expr(e)), + span: l.span, + attrs: l.attrs.clone(), + }) } -} - -fn lower_fn_decl(lctx: &mut LoweringContext, decl: &FnDecl) -> P { - P(hir::FnDecl { - inputs: decl.inputs.iter().map(|x| lower_arg(lctx, x)).collect(), - output: match decl.output { - FunctionRetTy::Ty(ref ty) => hir::Return(lower_ty(lctx, ty)), - FunctionRetTy::Default(span) => hir::DefaultReturn(span), - FunctionRetTy::None(span) => hir::NoReturn(span), - }, - variadic: decl.variadic, - }) -} -fn lower_ty_param_bound(lctx: &mut LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { - match *tpb { - TraitTyParamBound(ref ty, modifier) => { - hir::TraitTyParamBound(lower_poly_trait_ref(lctx, ty), - lower_trait_bound_modifier(lctx, modifier)) - } - RegionTyParamBound(ref lifetime) => { - hir::RegionTyParamBound(lower_lifetime(lctx, lifetime)) + fn lower_explicit_self_underscore(&mut self, es: &SelfKind) -> hir::ExplicitSelf_ { + match *es { + SelfKind::Static => hir::SelfStatic, + SelfKind::Value(v) => hir::SelfValue(v.name), + SelfKind::Region(ref lifetime, m, ident) => { + hir::SelfRegion(self.lower_opt_lifetime(lifetime), + self.lower_mutability(m), + ident.name) + } + SelfKind::Explicit(ref typ, ident) => { + hir::SelfExplicit(self.lower_ty(typ), ident.name) + } } } -} -fn lower_ty_param(lctx: &mut LoweringContext, tp: &TyParam) -> hir::TyParam { - hir::TyParam { - id: tp.id, - name: tp.ident.name, - bounds: lower_bounds(lctx, &tp.bounds), - default: tp.default.as_ref().map(|x| lower_ty(lctx, x)), - span: tp.span, + fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability { + match m { + Mutability::Mutable => hir::MutMutable, + Mutability::Immutable => hir::MutImmutable, + } } -} - -fn lower_ty_params(lctx: &mut LoweringContext, - tps: &P<[TyParam]>) - -> hir::HirVec { - tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect() -} -fn lower_lifetime(_lctx: &mut LoweringContext, l: &Lifetime) -> hir::Lifetime { - hir::Lifetime { - id: l.id, - name: l.name, - span: l.span, + fn lower_explicit_self(&mut self, s: &ExplicitSelf) -> hir::ExplicitSelf { + Spanned { + node: self.lower_explicit_self_underscore(&s.node), + span: s.span, + } } -} -fn lower_lifetime_def(lctx: &mut LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { - hir::LifetimeDef { - lifetime: lower_lifetime(lctx, &l.lifetime), - bounds: lower_lifetimes(lctx, &l.bounds), + fn lower_arg(&mut self, arg: &Arg) -> hir::Arg { + hir::Arg { + id: arg.id, + pat: self.lower_pat(&arg.pat), + ty: self.lower_ty(&arg.ty), + } } -} - -fn lower_lifetimes(lctx: &mut LoweringContext, lts: &Vec) - -> hir::HirVec { - lts.iter().map(|l| lower_lifetime(lctx, l)).collect() -} -fn lower_lifetime_defs(lctx: &mut LoweringContext, - lts: &Vec) - -> hir::HirVec { - lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect() -} + fn lower_fn_decl(&mut self, decl: &FnDecl) -> P { + P(hir::FnDecl { + inputs: decl.inputs.iter().map(|x| self.lower_arg(x)).collect(), + output: match decl.output { + FunctionRetTy::Ty(ref ty) => hir::Return(self.lower_ty(ty)), + FunctionRetTy::Default(span) => hir::DefaultReturn(span), + FunctionRetTy::None(span) => hir::NoReturn(span), + }, + variadic: decl.variadic, + }) + } -fn lower_opt_lifetime(lctx: &mut LoweringContext, - o_lt: &Option) - -> Option { - o_lt.as_ref().map(|lt| lower_lifetime(lctx, lt)) -} + fn lower_ty_param_bound(&mut self, tpb: &TyParamBound) -> hir::TyParamBound { + match *tpb { + TraitTyParamBound(ref ty, modifier) => { + hir::TraitTyParamBound(self.lower_poly_trait_ref(ty), + self.lower_trait_bound_modifier(modifier)) + } + RegionTyParamBound(ref lifetime) => { + hir::RegionTyParamBound(self.lower_lifetime(lifetime)) + } + } + } -fn lower_generics(lctx: &mut LoweringContext, g: &Generics) -> hir::Generics { - hir::Generics { - ty_params: lower_ty_params(lctx, &g.ty_params), - lifetimes: lower_lifetime_defs(lctx, &g.lifetimes), - where_clause: lower_where_clause(lctx, &g.where_clause), + fn lower_ty_param(&mut self, tp: &TyParam) -> hir::TyParam { + hir::TyParam { + id: tp.id, + name: tp.ident.name, + bounds: self.lower_bounds(&tp.bounds), + default: tp.default.as_ref().map(|x| self.lower_ty(x)), + span: tp.span, + } } -} -fn lower_where_clause(lctx: &mut LoweringContext, wc: &WhereClause) -> hir::WhereClause { - hir::WhereClause { - id: wc.id, - predicates: wc.predicates - .iter() - .map(|predicate| lower_where_predicate(lctx, predicate)) - .collect(), + fn lower_ty_params(&mut self, tps: &P<[TyParam]>) -> hir::HirVec { + tps.iter().map(|tp| self.lower_ty_param(tp)).collect() } -} -fn lower_where_predicate(lctx: &mut LoweringContext, - pred: &WherePredicate) - -> hir::WherePredicate { - match *pred { - WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes, - ref bounded_ty, - ref bounds, - span}) => { - hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { - bound_lifetimes: lower_lifetime_defs(lctx, bound_lifetimes), - bounded_ty: lower_ty(lctx, bounded_ty), - bounds: bounds.iter().map(|x| lower_ty_param_bound(lctx, x)).collect(), - span: span, - }) - } - WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime, - ref bounds, - span}) => { - hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { - span: span, - lifetime: lower_lifetime(lctx, lifetime), - bounds: bounds.iter().map(|bound| lower_lifetime(lctx, bound)).collect(), - }) - } - WherePredicate::EqPredicate(WhereEqPredicate{ id, - ref path, - ref ty, - span}) => { - hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { - id: id, - path: lower_path(lctx, path), - ty: lower_ty(lctx, ty), - span: span, - }) + fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime { + hir::Lifetime { + id: l.id, + name: l.name, + span: l.span, } } -} -fn lower_variant_data(lctx: &mut LoweringContext, vdata: &VariantData) -> hir::VariantData { - match *vdata { - VariantData::Struct(ref fields, id) => { - hir::VariantData::Struct(fields.iter() - .enumerate() - .map(|f| lower_struct_field(lctx, f)) - .collect(), - id) + fn lower_lifetime_def(&mut self, l: &LifetimeDef) -> hir::LifetimeDef { + hir::LifetimeDef { + lifetime: self.lower_lifetime(&l.lifetime), + bounds: self.lower_lifetimes(&l.bounds), } - VariantData::Tuple(ref fields, id) => { - hir::VariantData::Tuple(fields.iter() - .enumerate() - .map(|f| lower_struct_field(lctx, f)) - .collect(), - id) - } - VariantData::Unit(id) => hir::VariantData::Unit(id), } -} -fn lower_trait_ref(lctx: &mut LoweringContext, p: &TraitRef) -> hir::TraitRef { - hir::TraitRef { - path: lower_path(lctx, &p.path), - ref_id: p.ref_id, + fn lower_lifetimes(&mut self, lts: &Vec) -> hir::HirVec { + lts.iter().map(|l| self.lower_lifetime(l)).collect() } -} -fn lower_poly_trait_ref(lctx: &mut LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { - hir::PolyTraitRef { - bound_lifetimes: lower_lifetime_defs(lctx, &p.bound_lifetimes), - trait_ref: lower_trait_ref(lctx, &p.trait_ref), - span: p.span, + fn lower_lifetime_defs(&mut self, lts: &Vec) -> hir::HirVec { + lts.iter().map(|l| self.lower_lifetime_def(l)).collect() } -} -fn lower_struct_field(lctx: &mut LoweringContext, - (index, f): (usize, &StructField)) - -> hir::StructField { - hir::StructField { - span: f.span, - id: f.id, - name: f.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())), - vis: lower_visibility(lctx, &f.vis), - ty: lower_ty(lctx, &f.ty), - attrs: lower_attrs(lctx, &f.attrs), + fn lower_opt_lifetime(&mut self, o_lt: &Option) -> Option { + o_lt.as_ref().map(|lt| self.lower_lifetime(lt)) } -} -fn lower_field(lctx: &mut LoweringContext, f: &Field) -> hir::Field { - hir::Field { - name: respan(f.ident.span, f.ident.node.name), - expr: lower_expr(lctx, &f.expr), - span: f.span, + fn lower_generics(&mut self, g: &Generics) -> hir::Generics { + hir::Generics { + ty_params: self.lower_ty_params(&g.ty_params), + lifetimes: self.lower_lifetime_defs(&g.lifetimes), + where_clause: self.lower_where_clause(&g.where_clause), + } } -} -fn lower_mt(lctx: &mut LoweringContext, mt: &MutTy) -> hir::MutTy { - hir::MutTy { - ty: lower_ty(lctx, &mt.ty), - mutbl: lower_mutability(lctx, mt.mutbl), + fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause { + hir::WhereClause { + id: wc.id, + predicates: wc.predicates + .iter() + .map(|predicate| self.lower_where_predicate(predicate)) + .collect(), + } } -} - -fn lower_bounds(lctx: &mut LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { - bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() -} - -fn lower_block(lctx: &mut LoweringContext, b: &Block) -> P { - P(hir::Block { - id: b.id, - stmts: b.stmts.iter().map(|s| lower_stmt(lctx, s)).collect(), - expr: b.expr.as_ref().map(|ref x| lower_expr(lctx, x)), - rules: lower_block_check_mode(lctx, &b.rules), - span: b.span, - }) -} -fn lower_item_kind(lctx: &mut LoweringContext, i: &ItemKind) -> hir::Item_ { - match *i { - ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), - ItemKind::Use(ref view_path) => { - hir::ItemUse(lower_view_path(lctx, view_path)) - } - ItemKind::Static(ref t, m, ref e) => { - hir::ItemStatic(lower_ty(lctx, t), - lower_mutability(lctx, m), - lower_expr(lctx, e)) - } - ItemKind::Const(ref t, ref e) => { - hir::ItemConst(lower_ty(lctx, t), lower_expr(lctx, e)) - } - ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => { - hir::ItemFn(lower_fn_decl(lctx, decl), - lower_unsafety(lctx, unsafety), - lower_constness(lctx, constness), - abi, - lower_generics(lctx, generics), - lower_block(lctx, body)) - } - ItemKind::Mod(ref m) => hir::ItemMod(lower_mod(lctx, m)), - ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(lower_foreign_mod(lctx, nm)), - ItemKind::Ty(ref t, ref generics) => { - hir::ItemTy(lower_ty(lctx, t), lower_generics(lctx, generics)) - } - ItemKind::Enum(ref enum_definition, ref generics) => { - hir::ItemEnum(hir::EnumDef { - variants: enum_definition.variants - .iter() - .map(|x| lower_variant(lctx, x)) - .collect(), - }, - lower_generics(lctx, generics)) - } - ItemKind::Struct(ref struct_def, ref generics) => { - let struct_def = lower_variant_data(lctx, struct_def); - hir::ItemStruct(struct_def, lower_generics(lctx, generics)) + fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate { + match *pred { + WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes, + ref bounded_ty, + ref bounds, + span}) => { + hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { + bound_lifetimes: self.lower_lifetime_defs(bound_lifetimes), + bounded_ty: self.lower_ty(bounded_ty), + bounds: bounds.iter().map(|x| self.lower_ty_param_bound(x)).collect(), + span: span, + }) + } + WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime, + ref bounds, + span}) => { + hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { + span: span, + lifetime: self.lower_lifetime(lifetime), + bounds: bounds.iter().map(|bound| self.lower_lifetime(bound)).collect(), + }) + } + WherePredicate::EqPredicate(WhereEqPredicate{ id, + ref path, + ref ty, + span}) => { + hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { + id: id, + path: self.lower_path(path), + ty: self.lower_ty(ty), + span: span, + }) + } } - ItemKind::DefaultImpl(unsafety, ref trait_ref) => { - hir::ItemDefaultImpl(lower_unsafety(lctx, unsafety), - lower_trait_ref(lctx, trait_ref)) + } + + fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData { + match *vdata { + VariantData::Struct(ref fields, id) => { + hir::VariantData::Struct(fields.iter() + .enumerate() + .map(|f| self.lower_struct_field(f)) + .collect(), + id) + } + VariantData::Tuple(ref fields, id) => { + hir::VariantData::Tuple(fields.iter() + .enumerate() + .map(|f| self.lower_struct_field(f)) + .collect(), + id) + } + VariantData::Unit(id) => hir::VariantData::Unit(id), } - ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => { - let new_impl_items = impl_items.iter() - .map(|item| lower_impl_item(lctx, item)) - .collect(); - let ifce = ifce.as_ref().map(|trait_ref| lower_trait_ref(lctx, trait_ref)); - hir::ItemImpl(lower_unsafety(lctx, unsafety), - lower_impl_polarity(lctx, polarity), - lower_generics(lctx, generics), - ifce, - lower_ty(lctx, ty), - new_impl_items) + } + + fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef { + hir::TraitRef { + path: self.lower_path(&p.path), + ref_id: p.ref_id, } - ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => { - let bounds = lower_bounds(lctx, bounds); - let items = items.iter().map(|item| lower_trait_item(lctx, item)).collect(); - hir::ItemTrait(lower_unsafety(lctx, unsafety), - lower_generics(lctx, generics), - bounds, - items) + } + + fn lower_poly_trait_ref(&mut self, p: &PolyTraitRef) -> hir::PolyTraitRef { + hir::PolyTraitRef { + bound_lifetimes: self.lower_lifetime_defs(&p.bound_lifetimes), + trait_ref: self.lower_trait_ref(&p.trait_ref), + span: p.span, } - ItemKind::Mac(_) => panic!("Shouldn't still be around"), } -} -fn lower_trait_item(lctx: &mut LoweringContext, i: &TraitItem) -> hir::TraitItem { - lctx.with_parent_def(i.id, |lctx| { - hir::TraitItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: match i.node { - TraitItemKind::Const(ref ty, ref default) => { - hir::ConstTraitItem(lower_ty(lctx, ty), - default.as_ref().map(|x| lower_expr(lctx, x))) - } - TraitItemKind::Method(ref sig, ref body) => { - hir::MethodTraitItem(lower_method_sig(lctx, sig), - body.as_ref().map(|x| lower_block(lctx, x))) - } - TraitItemKind::Type(ref bounds, ref default) => { - hir::TypeTraitItem(lower_bounds(lctx, bounds), - default.as_ref().map(|x| lower_ty(lctx, x))) - } - }, - span: i.span, + fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField { + hir::StructField { + span: f.span, + id: f.id, + name: f.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())), + vis: self.lower_visibility(&f.vis), + ty: self.lower_ty(&f.ty), + attrs: self.lower_attrs(&f.attrs), } - }) -} + } -fn lower_impl_item(lctx: &mut LoweringContext, i: &ImplItem) -> hir::ImplItem { - lctx.with_parent_def(i.id, |lctx| { - hir::ImplItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - vis: lower_visibility(lctx, &i.vis), - defaultness: lower_defaultness(lctx, i.defaultness), - node: match i.node { - ImplItemKind::Const(ref ty, ref expr) => { - hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr)) - } - ImplItemKind::Method(ref sig, ref body) => { - hir::ImplItemKind::Method(lower_method_sig(lctx, sig), lower_block(lctx, body)) - } - ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)), - ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), - }, - span: i.span, + fn lower_field(&mut self, f: &Field) -> hir::Field { + hir::Field { + name: respan(f.ident.span, f.ident.node.name), + expr: self.lower_expr(&f.expr), + span: f.span, } - }) -} + } -fn lower_mod(lctx: &mut LoweringContext, m: &Mod) -> hir::Mod { - hir::Mod { - inner: m.inner, - item_ids: m.items.iter().map(|x| lower_item_id(lctx, x)).collect(), + fn lower_mt(&mut self, mt: &MutTy) -> hir::MutTy { + hir::MutTy { + ty: self.lower_ty(&mt.ty), + mutbl: self.lower_mutability(mt.mutbl), + } } -} -struct ItemLowerer<'lcx, 'interner: 'lcx> { - items: BTreeMap, - lctx: &'lcx mut LoweringContext<'interner>, -} + fn lower_bounds(&mut self, bounds: &TyParamBounds) -> hir::TyParamBounds { + bounds.iter().map(|bound| self.lower_ty_param_bound(bound)).collect() + } -impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { - fn visit_item(&mut self, item: &'lcx Item) { - self.items.insert(item.id, lower_item(self.lctx, item)); - visit::walk_item(self, item); + fn lower_block(&mut self, b: &Block) -> P { + P(hir::Block { + id: b.id, + stmts: b.stmts.iter().map(|s| self.lower_stmt(s)).collect(), + expr: b.expr.as_ref().map(|ref x| self.lower_expr(x)), + rules: self.lower_block_check_mode(&b.rules), + span: b.span, + }) } -} -pub fn lower_crate(lctx: &mut LoweringContext, c: &Crate) -> hir::Crate { - let items = { - let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: lctx }; - visit::walk_crate(&mut item_lowerer, c); - item_lowerer.items - }; + fn lower_item_kind(&mut self, i: &ItemKind) -> hir::Item_ { + match *i { + ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), + ItemKind::Use(ref view_path) => { + hir::ItemUse(self.lower_view_path(view_path)) + } + ItemKind::Static(ref t, m, ref e) => { + hir::ItemStatic(self.lower_ty(t), + self.lower_mutability(m), + self.lower_expr(e)) + } + ItemKind::Const(ref t, ref e) => { + hir::ItemConst(self.lower_ty(t), self.lower_expr(e)) + } + ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => { + hir::ItemFn(self.lower_fn_decl(decl), + self.lower_unsafety(unsafety), + self.lower_constness(constness), + abi, + self.lower_generics(generics), + self.lower_block(body)) + } + ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)), + ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)), + ItemKind::Ty(ref t, ref generics) => { + hir::ItemTy(self.lower_ty(t), self.lower_generics(generics)) + } + ItemKind::Enum(ref enum_definition, ref generics) => { + hir::ItemEnum(hir::EnumDef { + variants: enum_definition.variants + .iter() + .map(|x| self.lower_variant(x)) + .collect(), + }, + self.lower_generics(generics)) + } + ItemKind::Struct(ref struct_def, ref generics) => { + let struct_def = self.lower_variant_data(struct_def); + hir::ItemStruct(struct_def, self.lower_generics(generics)) + } + ItemKind::DefaultImpl(unsafety, ref trait_ref) => { + hir::ItemDefaultImpl(self.lower_unsafety(unsafety), + self.lower_trait_ref(trait_ref)) + } + ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => { + let new_impl_items = impl_items.iter() + .map(|item| self.lower_impl_item(item)) + .collect(); + let ifce = ifce.as_ref().map(|trait_ref| self.lower_trait_ref(trait_ref)); + hir::ItemImpl(self.lower_unsafety(unsafety), + self.lower_impl_polarity(polarity), + self.lower_generics(generics), + ifce, + self.lower_ty(ty), + new_impl_items) + } + ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => { + let bounds = self.lower_bounds(bounds); + let items = items.iter().map(|item| self.lower_trait_item(item)).collect(); + hir::ItemTrait(self.lower_unsafety(unsafety), + self.lower_generics(generics), + bounds, + items) + } + ItemKind::Mac(_) => panic!("Shouldn't still be around"), + } + } - hir::Crate { - module: lower_mod(lctx, &c.module), - attrs: lower_attrs(lctx, &c.attrs), - config: c.config.clone().into(), - span: c.span, - exported_macros: c.exported_macros.iter().map(|m| lower_macro_def(lctx, m)).collect(), - items: items, + fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem { + self.with_parent_def(i.id, |this| { + hir::TraitItem { + id: i.id, + name: i.ident.name, + attrs: this.lower_attrs(&i.attrs), + node: match i.node { + TraitItemKind::Const(ref ty, ref default) => { + hir::ConstTraitItem(this.lower_ty(ty), + default.as_ref().map(|x| this.lower_expr(x))) + } + TraitItemKind::Method(ref sig, ref body) => { + hir::MethodTraitItem(this.lower_method_sig(sig), + body.as_ref().map(|x| this.lower_block(x))) + } + TraitItemKind::Type(ref bounds, ref default) => { + hir::TypeTraitItem(this.lower_bounds(bounds), + default.as_ref().map(|x| this.lower_ty(x))) + } + }, + span: i.span, + } + }) } -} -fn lower_macro_def(lctx: &mut LoweringContext, m: &MacroDef) -> hir::MacroDef { - hir::MacroDef { - name: m.ident.name, - attrs: lower_attrs(lctx, &m.attrs), - id: m.id, - span: m.span, - imported_from: m.imported_from.map(|x| x.name), - export: m.export, - use_locally: m.use_locally, - allow_internal_unstable: m.allow_internal_unstable, - body: m.body.clone().into(), + fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem { + self.with_parent_def(i.id, |this| { + hir::ImplItem { + id: i.id, + name: i.ident.name, + attrs: this.lower_attrs(&i.attrs), + vis: this.lower_visibility(&i.vis), + defaultness: this.lower_defaultness(i.defaultness), + node: match i.node { + ImplItemKind::Const(ref ty, ref expr) => { + hir::ImplItemKind::Const(this.lower_ty(ty), this.lower_expr(expr)) + } + ImplItemKind::Method(ref sig, ref body) => { + hir::ImplItemKind::Method(this.lower_method_sig(sig), + this.lower_block(body)) + } + ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)), + ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), + }, + span: i.span, + } + }) } -} -fn lower_item_id(_lctx: &mut LoweringContext, i: &Item) -> hir::ItemId { - hir::ItemId { id: i.id } -} + fn lower_mod(&mut self, m: &Mod) -> hir::Mod { + hir::Mod { + inner: m.inner, + item_ids: m.items.iter().map(|x| self.lower_item_id(x)).collect(), + } + } -pub fn lower_item(lctx: &mut LoweringContext, i: &Item) -> hir::Item { - let node = lctx.with_parent_def(i.id, |lctx| { - lower_item_kind(lctx, &i.node) - }); + fn lower_macro_def(&mut self, m: &MacroDef) -> hir::MacroDef { + hir::MacroDef { + name: m.ident.name, + attrs: self.lower_attrs(&m.attrs), + id: m.id, + span: m.span, + imported_from: m.imported_from.map(|x| x.name), + export: m.export, + use_locally: m.use_locally, + allow_internal_unstable: m.allow_internal_unstable, + body: m.body.clone().into(), + } + } - hir::Item { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: node, - vis: lower_visibility(lctx, &i.vis), - span: i.span, + fn lower_item_id(&mut self, i: &Item) -> hir::ItemId { + hir::ItemId { id: i.id } } -} -fn lower_foreign_item(lctx: &mut LoweringContext, i: &ForeignItem) -> hir::ForeignItem { - lctx.with_parent_def(i.id, |lctx| { - hir::ForeignItem { + pub fn lower_item(&mut self, i: &Item) -> hir::Item { + let node = self.with_parent_def(i.id, |this| { + this.lower_item_kind(&i.node) + }); + + hir::Item { id: i.id, name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: match i.node { - ForeignItemKind::Fn(ref fdec, ref generics) => { - hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics)) - } - ForeignItemKind::Static(ref t, m) => { - hir::ForeignItemStatic(lower_ty(lctx, t), m) - } - }, - vis: lower_visibility(lctx, &i.vis), + attrs: self.lower_attrs(&i.attrs), + node: node, + vis: self.lower_visibility(&i.vis), span: i.span, } - }) -} + } -fn lower_method_sig(lctx: &mut LoweringContext, sig: &MethodSig) -> hir::MethodSig { - hir::MethodSig { - generics: lower_generics(lctx, &sig.generics), - abi: sig.abi, - explicit_self: lower_explicit_self(lctx, &sig.explicit_self), - unsafety: lower_unsafety(lctx, sig.unsafety), - constness: lower_constness(lctx, sig.constness), - decl: lower_fn_decl(lctx, &sig.decl), + fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem { + self.with_parent_def(i.id, |this| { + hir::ForeignItem { + id: i.id, + name: i.ident.name, + attrs: this.lower_attrs(&i.attrs), + node: match i.node { + ForeignItemKind::Fn(ref fdec, ref generics) => { + hir::ForeignItemFn(this.lower_fn_decl(fdec), this.lower_generics(generics)) + } + ForeignItemKind::Static(ref t, m) => { + hir::ForeignItemStatic(this.lower_ty(t), m) + } + }, + vis: this.lower_visibility(&i.vis), + span: i.span, + } + }) } -} -fn lower_unsafety(_lctx: &mut LoweringContext, u: Unsafety) -> hir::Unsafety { - match u { - Unsafety::Unsafe => hir::Unsafety::Unsafe, - Unsafety::Normal => hir::Unsafety::Normal, + fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig { + hir::MethodSig { + generics: self.lower_generics(&sig.generics), + abi: sig.abi, + explicit_self: self.lower_explicit_self(&sig.explicit_self), + unsafety: self.lower_unsafety(sig.unsafety), + constness: self.lower_constness(sig.constness), + decl: self.lower_fn_decl(&sig.decl), + } } -} -fn lower_constness(_lctx: &mut LoweringContext, c: Constness) -> hir::Constness { - match c { - Constness::Const => hir::Constness::Const, - Constness::NotConst => hir::Constness::NotConst, + fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety { + match u { + Unsafety::Unsafe => hir::Unsafety::Unsafe, + Unsafety::Normal => hir::Unsafety::Normal, + } } -} -fn lower_unop(_lctx: &mut LoweringContext, u: UnOp) -> hir::UnOp { - match u { - UnOp::Deref => hir::UnDeref, - UnOp::Not => hir::UnNot, - UnOp::Neg => hir::UnNeg, + fn lower_constness(&mut self, c: Constness) -> hir::Constness { + match c { + Constness::Const => hir::Constness::Const, + Constness::NotConst => hir::Constness::NotConst, + } } -} -fn lower_binop(_lctx: &mut LoweringContext, b: BinOp) -> hir::BinOp { - Spanned { - node: match b.node { - BinOpKind::Add => hir::BiAdd, - BinOpKind::Sub => hir::BiSub, - BinOpKind::Mul => hir::BiMul, - BinOpKind::Div => hir::BiDiv, - BinOpKind::Rem => hir::BiRem, - BinOpKind::And => hir::BiAnd, - BinOpKind::Or => hir::BiOr, - BinOpKind::BitXor => hir::BiBitXor, - BinOpKind::BitAnd => hir::BiBitAnd, - BinOpKind::BitOr => hir::BiBitOr, - BinOpKind::Shl => hir::BiShl, - BinOpKind::Shr => hir::BiShr, - BinOpKind::Eq => hir::BiEq, - BinOpKind::Lt => hir::BiLt, - BinOpKind::Le => hir::BiLe, - BinOpKind::Ne => hir::BiNe, - BinOpKind::Ge => hir::BiGe, - BinOpKind::Gt => hir::BiGt, - }, - span: b.span, + fn lower_unop(&mut self, u: UnOp) -> hir::UnOp { + match u { + UnOp::Deref => hir::UnDeref, + UnOp::Not => hir::UnNot, + UnOp::Neg => hir::UnNeg, + } } -} -fn lower_pat(lctx: &mut LoweringContext, p: &Pat) -> P { - P(hir::Pat { - id: p.id, - node: match p.node { - PatKind::Wild => hir::PatKind::Wild, - PatKind::Ident(ref binding_mode, pth1, ref sub) => { - lctx.with_parent_def(p.id, |lctx| { - hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode), - respan(pth1.span, lower_ident(lctx, pth1.node)), - sub.as_ref().map(|x| lower_pat(lctx, x))) - }) - } - PatKind::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)), - PatKind::TupleStruct(ref pth, ref pats) => { - hir::PatKind::TupleStruct(lower_path(lctx, pth), - pats.as_ref() - .map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect())) - } - PatKind::Path(ref pth) => { - hir::PatKind::Path(lower_path(lctx, pth)) - } - PatKind::QPath(ref qself, ref pth) => { - let qself = hir::QSelf { - ty: lower_ty(lctx, &qself.ty), - position: qself.position, - }; - hir::PatKind::QPath(qself, lower_path(lctx, pth)) - } - PatKind::Struct(ref pth, ref fields, etc) => { - let pth = lower_path(lctx, pth); - let fs = fields.iter() - .map(|f| { - Spanned { - span: f.span, - node: hir::FieldPat { - name: f.node.ident.name, - pat: lower_pat(lctx, &f.node.pat), - is_shorthand: f.node.is_shorthand, - }, - } - }) - .collect(); - hir::PatKind::Struct(pth, fs, etc) - } - PatKind::Tup(ref elts) => { - hir::PatKind::Tup(elts.iter().map(|x| lower_pat(lctx, x)).collect()) - } - PatKind::Box(ref inner) => hir::PatKind::Box(lower_pat(lctx, inner)), - PatKind::Ref(ref inner, mutbl) => { - hir::PatKind::Ref(lower_pat(lctx, inner), lower_mutability(lctx, mutbl)) - } - PatKind::Range(ref e1, ref e2) => { - hir::PatKind::Range(lower_expr(lctx, e1), lower_expr(lctx, e2)) - } - PatKind::Vec(ref before, ref slice, ref after) => { - hir::PatKind::Vec(before.iter().map(|x| lower_pat(lctx, x)).collect(), - slice.as_ref().map(|x| lower_pat(lctx, x)), - after.iter().map(|x| lower_pat(lctx, x)).collect()) - } - PatKind::Mac(_) => panic!("Shouldn't exist here"), - }, - span: p.span, - }) -} + fn lower_binop(&mut self, b: BinOp) -> hir::BinOp { + Spanned { + node: match b.node { + BinOpKind::Add => hir::BiAdd, + BinOpKind::Sub => hir::BiSub, + BinOpKind::Mul => hir::BiMul, + BinOpKind::Div => hir::BiDiv, + BinOpKind::Rem => hir::BiRem, + BinOpKind::And => hir::BiAnd, + BinOpKind::Or => hir::BiOr, + BinOpKind::BitXor => hir::BiBitXor, + BinOpKind::BitAnd => hir::BiBitAnd, + BinOpKind::BitOr => hir::BiBitOr, + BinOpKind::Shl => hir::BiShl, + BinOpKind::Shr => hir::BiShr, + BinOpKind::Eq => hir::BiEq, + BinOpKind::Lt => hir::BiLt, + BinOpKind::Le => hir::BiLe, + BinOpKind::Ne => hir::BiNe, + BinOpKind::Ge => hir::BiGe, + BinOpKind::Gt => hir::BiGt, + }, + span: b.span, + } + } -fn lower_expr(lctx: &mut LoweringContext, e: &Expr) -> P { - P(hir::Expr { - id: e.id, - node: match e.node { - // Issue #22181: - // Eventually a desugaring for `box EXPR` - // (similar to the desugaring above for `in PLACE BLOCK`) - // should go here, desugaring - // - // to: - // - // let mut place = BoxPlace::make_place(); - // let raw_place = Place::pointer(&mut place); - // let value = $value; - // unsafe { - // ::std::ptr::write(raw_place, value); - // Boxed::finalize(place) - // } - // - // But for now there are type-inference issues doing that. - ExprKind::Box(ref e) => { - hir::ExprBox(lower_expr(lctx, e)) - } + fn lower_pat(&mut self, p: &Pat) -> P { + P(hir::Pat { + id: p.id, + node: match p.node { + PatKind::Wild => hir::PatKind::Wild, + PatKind::Ident(ref binding_mode, pth1, ref sub) => { + self.with_parent_def(p.id, |this| { + hir::PatKind::Ident(this.lower_binding_mode(binding_mode), + respan(pth1.span, this.lower_ident(pth1.node)), + sub.as_ref().map(|x| this.lower_pat(x))) + }) + } + PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)), + PatKind::TupleStruct(ref pth, ref pats) => { + hir::PatKind::TupleStruct(self.lower_path(pth), + pats.as_ref() + .map(|pats| pats.iter().map(|x| self.lower_pat(x)).collect())) + } + PatKind::Path(ref pth) => { + hir::PatKind::Path(self.lower_path(pth)) + } + PatKind::QPath(ref qself, ref pth) => { + let qself = hir::QSelf { + ty: self.lower_ty(&qself.ty), + position: qself.position, + }; + hir::PatKind::QPath(qself, self.lower_path(pth)) + } + PatKind::Struct(ref pth, ref fields, etc) => { + let pth = self.lower_path(pth); + let fs = fields.iter() + .map(|f| { + Spanned { + span: f.span, + node: hir::FieldPat { + name: f.node.ident.name, + pat: self.lower_pat(&f.node.pat), + is_shorthand: f.node.is_shorthand, + }, + } + }) + .collect(); + hir::PatKind::Struct(pth, fs, etc) + } + PatKind::Tup(ref elts) => { + hir::PatKind::Tup(elts.iter().map(|x| self.lower_pat(x)).collect()) + } + PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)), + PatKind::Ref(ref inner, mutbl) => { + hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl)) + } + PatKind::Range(ref e1, ref e2) => { + hir::PatKind::Range(self.lower_expr(e1), self.lower_expr(e2)) + } + PatKind::Vec(ref before, ref slice, ref after) => { + hir::PatKind::Vec(before.iter().map(|x| self.lower_pat(x)).collect(), + slice.as_ref().map(|x| self.lower_pat(x)), + after.iter().map(|x| self.lower_pat(x)).collect()) + } + PatKind::Mac(_) => panic!("Shouldn't exist here"), + }, + span: p.span, + }) + } - // Desugar ExprBox: `in (PLACE) EXPR` - ExprKind::InPlace(ref placer, ref value_expr) => { + fn lower_expr(&mut self, e: &Expr) -> P { + P(hir::Expr { + id: e.id, + node: match e.node { + // Issue #22181: + // Eventually a desugaring for `box EXPR` + // (similar to the desugaring above for `in PLACE BLOCK`) + // should go here, desugaring + // // to: // - // let p = PLACE; - // let mut place = Placer::make_place(p); + // let mut place = BoxPlace::make_place(); // let raw_place = Place::pointer(&mut place); - // push_unsafe!({ - // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); - // InPlace::finalize(place) - // }) - let placer_expr = lower_expr(lctx, placer); - let value_expr = lower_expr(lctx, value_expr); - - let placer_ident = lctx.str_to_ident("placer"); - let place_ident = lctx.str_to_ident("place"); - let p_ptr_ident = lctx.str_to_ident("p_ptr"); - - let make_place = ["ops", "Placer", "make_place"]; - let place_pointer = ["ops", "Place", "pointer"]; - let move_val_init = ["intrinsics", "move_val_init"]; - let inplace_finalize = ["ops", "InPlace", "finalize"]; - - let make_call = |lctx: &mut LoweringContext, p, args| { - let path = core_path(lctx, e.span, p); - let path = expr_path(lctx, path, None); - expr_call(lctx, e.span, path, args, None) - }; - - let mk_stmt_let = |lctx: &mut LoweringContext, bind, expr| { - stmt_let(lctx, e.span, false, bind, expr, None) - }; - - let mk_stmt_let_mut = |lctx: &mut LoweringContext, bind, expr| { - stmt_let(lctx, e.span, true, bind, expr, None) - }; - - // let placer = ; - let (s1, placer_binding) = { - let placer_expr = signal_block_expr(lctx, - hir_vec![], - placer_expr, - e.span, - hir::PopUnstableBlock, - None); - mk_stmt_let(lctx, placer_ident, placer_expr) - }; - - // let mut place = Placer::make_place(placer); - let (s2, place_binding) = { - let placer = expr_ident(lctx, e.span, placer_ident, None, placer_binding); - let call = make_call(lctx, &make_place, hir_vec![placer]); - mk_stmt_let_mut(lctx, place_ident, call) - }; - - // let p_ptr = Place::pointer(&mut place); - let (s3, p_ptr_binding) = { - let agent = expr_ident(lctx, e.span, place_ident, None, place_binding); - let args = hir_vec![expr_mut_addr_of(lctx, e.span, agent, None)]; - let call = make_call(lctx, &place_pointer, args); - mk_stmt_let(lctx, p_ptr_ident, call) - }; - - // pop_unsafe!(EXPR)); - let pop_unsafe_expr = { - let value_expr = signal_block_expr(lctx, - hir_vec![], - value_expr, - e.span, - hir::PopUnstableBlock, - None); - signal_block_expr(lctx, - hir_vec![], - value_expr, - e.span, - hir::PopUnsafeBlock(hir::CompilerGenerated), None) - }; - - // push_unsafe!({ - // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); - // InPlace::finalize(place) - // }) - let expr = { - let ptr = expr_ident(lctx, e.span, p_ptr_ident, None, p_ptr_binding); - let call_move_val_init = - hir::StmtSemi( - make_call(lctx, &move_val_init, hir_vec![ptr, pop_unsafe_expr]), - lctx.next_id()); - let call_move_val_init = respan(e.span, call_move_val_init); - - let place = expr_ident(lctx, e.span, place_ident, None, place_binding); - let call = make_call(lctx, &inplace_finalize, hir_vec![place]); - signal_block_expr(lctx, - hir_vec![call_move_val_init], - call, - e.span, - hir::PushUnsafeBlock(hir::CompilerGenerated), None) - }; - - return signal_block_expr(lctx, - hir_vec![s1, s2, s3], - expr, - e.span, - hir::PushUnstableBlock, - e.attrs.clone()); - } + // let value = $value; + // unsafe { + // ::std::ptr::write(raw_place, value); + // Boxed::finalize(place) + // } + // + // But for now there are type-inference issues doing that. + ExprKind::Box(ref e) => { + hir::ExprBox(self.lower_expr(e)) + } - ExprKind::Vec(ref exprs) => { - hir::ExprVec(exprs.iter().map(|x| lower_expr(lctx, x)).collect()) - } - ExprKind::Repeat(ref expr, ref count) => { - let expr = lower_expr(lctx, expr); - let count = lower_expr(lctx, count); - hir::ExprRepeat(expr, count) - } - ExprKind::Tup(ref elts) => { - hir::ExprTup(elts.iter().map(|x| lower_expr(lctx, x)).collect()) - } - ExprKind::Call(ref f, ref args) => { - let f = lower_expr(lctx, f); - hir::ExprCall(f, args.iter().map(|x| lower_expr(lctx, x)).collect()) - } - ExprKind::MethodCall(i, ref tps, ref args) => { - let tps = tps.iter().map(|x| lower_ty(lctx, x)).collect(); - let args = args.iter().map(|x| lower_expr(lctx, x)).collect(); - hir::ExprMethodCall(respan(i.span, i.node.name), tps, args) - } - ExprKind::Binary(binop, ref lhs, ref rhs) => { - let binop = lower_binop(lctx, binop); - let lhs = lower_expr(lctx, lhs); - let rhs = lower_expr(lctx, rhs); - hir::ExprBinary(binop, lhs, rhs) - } - ExprKind::Unary(op, ref ohs) => { - let op = lower_unop(lctx, op); - let ohs = lower_expr(lctx, ohs); - hir::ExprUnary(op, ohs) - } - ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())), - ExprKind::Cast(ref expr, ref ty) => { - let expr = lower_expr(lctx, expr); - hir::ExprCast(expr, lower_ty(lctx, ty)) - } - ExprKind::Type(ref expr, ref ty) => { - let expr = lower_expr(lctx, expr); - hir::ExprType(expr, lower_ty(lctx, ty)) - } - ExprKind::AddrOf(m, ref ohs) => { - let m = lower_mutability(lctx, m); - let ohs = lower_expr(lctx, ohs); - hir::ExprAddrOf(m, ohs) - } - // More complicated than you might expect because the else branch - // might be `if let`. - ExprKind::If(ref cond, ref blk, ref else_opt) => { - let else_opt = else_opt.as_ref().map(|els| { - match els.node { - ExprKind::IfLet(..) => { - // wrap the if-let expr in a block - let span = els.span; - let els = lower_expr(lctx, els); - let id = lctx.next_id(); - let blk = P(hir::Block { - stmts: hir_vec![], - expr: Some(els), - id: id, - rules: hir::DefaultBlock, - span: span, - }); - expr_block(lctx, blk, None) - } - _ => lower_expr(lctx, els), - } - }); + // Desugar ExprBox: `in (PLACE) EXPR` + ExprKind::InPlace(ref placer, ref value_expr) => { + // to: + // + // let p = PLACE; + // let mut place = Placer::make_place(p); + // let raw_place = Place::pointer(&mut place); + // push_unsafe!({ + // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); + // InPlace::finalize(place) + // }) + let placer_expr = self.lower_expr(placer); + let value_expr = self.lower_expr(value_expr); + + let placer_ident = self.str_to_ident("placer"); + let place_ident = self.str_to_ident("place"); + let p_ptr_ident = self.str_to_ident("p_ptr"); + + let make_place = ["ops", "Placer", "make_place"]; + let place_pointer = ["ops", "Place", "pointer"]; + let move_val_init = ["intrinsics", "move_val_init"]; + let inplace_finalize = ["ops", "InPlace", "finalize"]; + + let make_call = |this: &mut LoweringContext, p, args| { + let path = core_path(this, e.span, p); + let path = expr_path(this, path, None); + expr_call(this, e.span, path, args, None) + }; - hir::ExprIf(lower_expr(lctx, cond), lower_block(lctx, blk), else_opt) - } - ExprKind::While(ref cond, ref body, opt_ident) => { - hir::ExprWhile(lower_expr(lctx, cond), lower_block(lctx, body), - opt_ident.map(|ident| lower_ident(lctx, ident))) - } - ExprKind::Loop(ref body, opt_ident) => { - hir::ExprLoop(lower_block(lctx, body), - opt_ident.map(|ident| lower_ident(lctx, ident))) - } - ExprKind::Match(ref expr, ref arms) => { - hir::ExprMatch(lower_expr(lctx, expr), - arms.iter().map(|x| lower_arm(lctx, x)).collect(), - hir::MatchSource::Normal) - } - ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => { - lctx.with_parent_def(e.id, |lctx| { - hir::ExprClosure(lower_capture_clause(lctx, capture_clause), - lower_fn_decl(lctx, decl), - lower_block(lctx, body), - fn_decl_span) - }) - } - ExprKind::Block(ref blk) => hir::ExprBlock(lower_block(lctx, blk)), - ExprKind::Assign(ref el, ref er) => { - hir::ExprAssign(lower_expr(lctx, el), lower_expr(lctx, er)) - } - ExprKind::AssignOp(op, ref el, ref er) => { - hir::ExprAssignOp(lower_binop(lctx, op), - lower_expr(lctx, el), - lower_expr(lctx, er)) - } - ExprKind::Field(ref el, ident) => { - hir::ExprField(lower_expr(lctx, el), respan(ident.span, ident.node.name)) - } - ExprKind::TupField(ref el, ident) => { - hir::ExprTupField(lower_expr(lctx, el), ident) - } - ExprKind::Index(ref el, ref er) => { - hir::ExprIndex(lower_expr(lctx, el), lower_expr(lctx, er)) - } - ExprKind::Range(ref e1, ref e2, lims) => { - fn make_struct(lctx: &mut LoweringContext, - ast_expr: &Expr, - path: &[&str], - fields: &[(&str, &P)]) -> P { - let strs = std_path(lctx, &iter::once(&"ops") - .chain(path) - .map(|s| *s) - .collect::>()); - - let structpath = path_global(ast_expr.span, strs); - - let hir_expr = if fields.len() == 0 { - expr_path(lctx, - structpath, - ast_expr.attrs.clone()) - } else { - let fields = fields.into_iter().map(|&(s, e)| { - let expr = lower_expr(lctx, &e); - let signal_block = signal_block_expr(lctx, - hir_vec![], - expr, - e.span, - hir::PopUnstableBlock, - None); - field(token::intern(s), signal_block, ast_expr.span) - }).collect(); - let attrs = ast_expr.attrs.clone(); - - expr_struct(lctx, ast_expr.span, structpath, fields, None, attrs) + let mk_stmt_let = |this: &mut LoweringContext, bind, expr| { + stmt_let(this, e.span, false, bind, expr, None) }; - signal_block_expr(lctx, - hir_vec![], - hir_expr, - ast_expr.span, - hir::PushUnstableBlock, - None) - } + let mk_stmt_let_mut = |this: &mut LoweringContext, bind, expr| { + stmt_let(this, e.span, true, bind, expr, None) + }; - use syntax::ast::RangeLimits::*; + // let placer = ; + let (s1, placer_binding) = { + let placer_expr = signal_block_expr(self, + hir_vec![], + placer_expr, + e.span, + hir::PopUnstableBlock, + None); + mk_stmt_let(self, placer_ident, placer_expr) + }; - return match (e1, e2, lims) { - (&None, &None, HalfOpen) => - make_struct(lctx, e, &["RangeFull"], - &[]), + // let mut place = Placer::make_place(placer); + let (s2, place_binding) = { + let placer = expr_ident(self, e.span, placer_ident, None, placer_binding); + let call = make_call(self, &make_place, hir_vec![placer]); + mk_stmt_let_mut(self, place_ident, call) + }; - (&Some(ref e1), &None, HalfOpen) => - make_struct(lctx, e, &["RangeFrom"], - &[("start", e1)]), + // let p_ptr = Place::pointer(&mut place); + let (s3, p_ptr_binding) = { + let agent = expr_ident(self, e.span, place_ident, None, place_binding); + let args = hir_vec![expr_mut_addr_of(self, e.span, agent, None)]; + let call = make_call(self, &place_pointer, args); + mk_stmt_let(self, p_ptr_ident, call) + }; - (&None, &Some(ref e2), HalfOpen) => - make_struct(lctx, e, &["RangeTo"], - &[("end", e2)]), + // pop_unsafe!(EXPR)); + let pop_unsafe_expr = { + let value_expr = signal_block_expr(self, + hir_vec![], + value_expr, + e.span, + hir::PopUnstableBlock, + None); + signal_block_expr(self, + hir_vec![], + value_expr, + e.span, + hir::PopUnsafeBlock(hir::CompilerGenerated), None) + }; - (&Some(ref e1), &Some(ref e2), HalfOpen) => - make_struct(lctx, e, &["Range"], - &[("start", e1), ("end", e2)]), + // push_unsafe!({ + // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); + // InPlace::finalize(place) + // }) + let expr = { + let ptr = expr_ident(self, e.span, p_ptr_ident, None, p_ptr_binding); + let call_move_val_init = + hir::StmtSemi( + make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]), + self.next_id()); + let call_move_val_init = respan(e.span, call_move_val_init); + + let place = expr_ident(self, e.span, place_ident, None, place_binding); + let call = make_call(self, &inplace_finalize, hir_vec![place]); + signal_block_expr(self, + hir_vec![call_move_val_init], + call, + e.span, + hir::PushUnsafeBlock(hir::CompilerGenerated), None) + }; - (&None, &Some(ref e2), Closed) => - make_struct(lctx, e, &["RangeToInclusive"], - &[("end", e2)]), + return signal_block_expr(self, + hir_vec![s1, s2, s3], + expr, + e.span, + hir::PushUnstableBlock, + e.attrs.clone()); + } - (&Some(ref e1), &Some(ref e2), Closed) => - make_struct(lctx, e, &["RangeInclusive", "NonEmpty"], - &[("start", e1), ("end", e2)]), + ExprKind::Vec(ref exprs) => { + hir::ExprVec(exprs.iter().map(|x| self.lower_expr(x)).collect()) + } + ExprKind::Repeat(ref expr, ref count) => { + let expr = self.lower_expr(expr); + let count = self.lower_expr(count); + hir::ExprRepeat(expr, count) + } + ExprKind::Tup(ref elts) => { + hir::ExprTup(elts.iter().map(|x| self.lower_expr(x)).collect()) + } + ExprKind::Call(ref f, ref args) => { + let f = self.lower_expr(f); + hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect()) + } + ExprKind::MethodCall(i, ref tps, ref args) => { + let tps = tps.iter().map(|x| self.lower_ty(x)).collect(); + let args = args.iter().map(|x| self.lower_expr(x)).collect(); + hir::ExprMethodCall(respan(i.span, i.node.name), tps, args) + } + ExprKind::Binary(binop, ref lhs, ref rhs) => { + let binop = self.lower_binop(binop); + let lhs = self.lower_expr(lhs); + let rhs = self.lower_expr(rhs); + hir::ExprBinary(binop, lhs, rhs) + } + ExprKind::Unary(op, ref ohs) => { + let op = self.lower_unop(op); + let ohs = self.lower_expr(ohs); + hir::ExprUnary(op, ohs) + } + ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())), + ExprKind::Cast(ref expr, ref ty) => { + let expr = self.lower_expr(expr); + hir::ExprCast(expr, self.lower_ty(ty)) + } + ExprKind::Type(ref expr, ref ty) => { + let expr = self.lower_expr(expr); + hir::ExprType(expr, self.lower_ty(ty)) + } + ExprKind::AddrOf(m, ref ohs) => { + let m = self.lower_mutability(m); + let ohs = self.lower_expr(ohs); + hir::ExprAddrOf(m, ohs) + } + // More complicated than you might expect because the else branch + // might be `if let`. + ExprKind::If(ref cond, ref blk, ref else_opt) => { + let else_opt = else_opt.as_ref().map(|els| { + match els.node { + ExprKind::IfLet(..) => { + // wrap the if-let expr in a block + let span = els.span; + let els = self.lower_expr(els); + let id = self.next_id(); + let blk = P(hir::Block { + stmts: hir_vec![], + expr: Some(els), + id: id, + rules: hir::DefaultBlock, + span: span, + }); + expr_block(self, blk, None) + } + _ => self.lower_expr(els), + } + }); - _ => panic!(lctx.id_assigner.diagnostic() - .span_fatal(e.span, "inclusive range with no end")), - }; - } - ExprKind::Path(ref qself, ref path) => { - let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| { - hir::QSelf { - ty: lower_ty(lctx, ty), - position: position, + hir::ExprIf(self.lower_expr(cond), self.lower_block(blk), else_opt) + } + ExprKind::While(ref cond, ref body, opt_ident) => { + hir::ExprWhile(self.lower_expr(cond), self.lower_block(body), + opt_ident.map(|ident| self.lower_ident(ident))) + } + ExprKind::Loop(ref body, opt_ident) => { + hir::ExprLoop(self.lower_block(body), + opt_ident.map(|ident| self.lower_ident(ident))) + } + ExprKind::Match(ref expr, ref arms) => { + hir::ExprMatch(self.lower_expr(expr), + arms.iter().map(|x| self.lower_arm(x)).collect(), + hir::MatchSource::Normal) + } + ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => { + self.with_parent_def(e.id, |this| { + hir::ExprClosure(this.lower_capture_clause(capture_clause), + this.lower_fn_decl(decl), + this.lower_block(body), + fn_decl_span) + }) + } + ExprKind::Block(ref blk) => hir::ExprBlock(self.lower_block(blk)), + ExprKind::Assign(ref el, ref er) => { + hir::ExprAssign(self.lower_expr(el), self.lower_expr(er)) + } + ExprKind::AssignOp(op, ref el, ref er) => { + hir::ExprAssignOp(self.lower_binop(op), + self.lower_expr(el), + self.lower_expr(er)) + } + ExprKind::Field(ref el, ident) => { + hir::ExprField(self.lower_expr(el), respan(ident.span, ident.node.name)) + } + ExprKind::TupField(ref el, ident) => { + hir::ExprTupField(self.lower_expr(el), ident) + } + ExprKind::Index(ref el, ref er) => { + hir::ExprIndex(self.lower_expr(el), self.lower_expr(er)) + } + ExprKind::Range(ref e1, ref e2, lims) => { + fn make_struct(this: &mut LoweringContext, + ast_expr: &Expr, + path: &[&str], + fields: &[(&str, &P)]) -> P { + let strs = std_path(this, &iter::once(&"ops") + .chain(path) + .map(|s| *s) + .collect::>()); + + let structpath = path_global(ast_expr.span, strs); + + let hir_expr = if fields.len() == 0 { + expr_path(this, + structpath, + ast_expr.attrs.clone()) + } else { + let fields = fields.into_iter().map(|&(s, e)| { + let expr = this.lower_expr(&e); + let signal_block = signal_block_expr(this, + hir_vec![], + expr, + e.span, + hir::PopUnstableBlock, + None); + field(token::intern(s), signal_block, ast_expr.span) + }).collect(); + let attrs = ast_expr.attrs.clone(); + + expr_struct(this, ast_expr.span, structpath, fields, None, attrs) + }; + + signal_block_expr(this, + hir_vec![], + hir_expr, + ast_expr.span, + hir::PushUnstableBlock, + None) } - }); - hir::ExprPath(hir_qself, lower_path_full(lctx, path, qself.is_none())) - } - ExprKind::Break(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| { - respan(sp_ident.span, lower_ident(lctx, sp_ident.node)) - })), - ExprKind::Again(opt_ident) => hir::ExprAgain(opt_ident.map(|sp_ident| { - respan(sp_ident.span, lower_ident(lctx, sp_ident.node)) - })), - ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| lower_expr(lctx, x))), - ExprKind::InlineAsm(InlineAsm { - ref inputs, - ref outputs, - ref asm, - asm_str_style, - ref clobbers, - volatile, - alignstack, - dialect, - expn_id, - }) => hir::ExprInlineAsm(hir::InlineAsm { - inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(), - outputs: outputs.iter() - .map(|out| { - hir::InlineAsmOutput { - constraint: out.constraint.clone(), - is_rw: out.is_rw, - is_indirect: out.is_indirect, - } - }) - .collect(), - asm: asm.clone(), - asm_str_style: asm_str_style, - clobbers: clobbers.clone().into(), - volatile: volatile, - alignstack: alignstack, - dialect: dialect, - expn_id: expn_id, - }, outputs.iter().map(|out| lower_expr(lctx, &out.expr)).collect(), - inputs.iter().map(|&(_, ref input)| lower_expr(lctx, input)).collect()), - ExprKind::Struct(ref path, ref fields, ref maybe_expr) => { - hir::ExprStruct(lower_path(lctx, path), - fields.iter().map(|x| lower_field(lctx, x)).collect(), - maybe_expr.as_ref().map(|x| lower_expr(lctx, x))) - } - ExprKind::Paren(ref ex) => { - // merge attributes into the inner expression. - return lower_expr(lctx, ex).map(|mut ex| { - ex.attrs.update(|attrs| { - attrs.prepend(e.attrs.clone()) + + use syntax::ast::RangeLimits::*; + + return match (e1, e2, lims) { + (&None, &None, HalfOpen) => + make_struct(self, e, &["RangeFull"], + &[]), + + (&Some(ref e1), &None, HalfOpen) => + make_struct(self, e, &["RangeFrom"], + &[("start", e1)]), + + (&None, &Some(ref e2), HalfOpen) => + make_struct(self, e, &["RangeTo"], + &[("end", e2)]), + + (&Some(ref e1), &Some(ref e2), HalfOpen) => + make_struct(self, e, &["Range"], + &[("start", e1), ("end", e2)]), + + (&None, &Some(ref e2), Closed) => + make_struct(self, e, &["RangeToInclusive"], + &[("end", e2)]), + + (&Some(ref e1), &Some(ref e2), Closed) => + make_struct(self, e, &["RangeInclusive", "NonEmpty"], + &[("start", e1), ("end", e2)]), + + _ => panic!(self.id_assigner.diagnostic() + .span_fatal(e.span, "inclusive range with no end")), + }; + } + ExprKind::Path(ref qself, ref path) => { + let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| { + hir::QSelf { + ty: self.lower_ty(ty), + position: position, + } }); - ex - }); - } + hir::ExprPath(hir_qself, self.lower_path_full(path, qself.is_none())) + } + ExprKind::Break(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| { + respan(sp_ident.span, self.lower_ident(sp_ident.node)) + })), + ExprKind::Again(opt_ident) => hir::ExprAgain(opt_ident.map(|sp_ident| { + respan(sp_ident.span, self.lower_ident(sp_ident.node)) + })), + ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| self.lower_expr(x))), + ExprKind::InlineAsm(InlineAsm { + ref inputs, + ref outputs, + ref asm, + asm_str_style, + ref clobbers, + volatile, + alignstack, + dialect, + expn_id, + }) => hir::ExprInlineAsm(hir::InlineAsm { + inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(), + outputs: outputs.iter() + .map(|out| { + hir::InlineAsmOutput { + constraint: out.constraint.clone(), + is_rw: out.is_rw, + is_indirect: out.is_indirect, + } + }) + .collect(), + asm: asm.clone(), + asm_str_style: asm_str_style, + clobbers: clobbers.clone().into(), + volatile: volatile, + alignstack: alignstack, + dialect: dialect, + expn_id: expn_id, + }, outputs.iter().map(|out| self.lower_expr(&out.expr)).collect(), + inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect()), + ExprKind::Struct(ref path, ref fields, ref maybe_expr) => { + hir::ExprStruct(self.lower_path(path), + fields.iter().map(|x| self.lower_field(x)).collect(), + maybe_expr.as_ref().map(|x| self.lower_expr(x))) + } + ExprKind::Paren(ref ex) => { + // merge attributes into the inner expression. + return self.lower_expr(ex).map(|mut ex| { + ex.attrs.update(|attrs| { + attrs.prepend(e.attrs.clone()) + }); + ex + }); + } - // Desugar ExprIfLet - // From: `if let = []` - ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => { - // to: - // - // match { - // => , - // [_ if => ,] - // _ => [ | ()] - // } - - // ` => ` - let pat_arm = { - let body = lower_block(lctx, body); - let body_expr = expr_block(lctx, body, None); - arm(hir_vec![lower_pat(lctx, pat)], body_expr) - }; - - // `[_ if => ,]` - let mut else_opt = else_opt.as_ref().map(|e| lower_expr(lctx, e)); - let else_if_arms = { - let mut arms = vec![]; - loop { - let else_opt_continue = else_opt.and_then(|els| { - els.and_then(|els| { - match els.node { - // else if - hir::ExprIf(cond, then, else_opt) => { - let pat_under = pat_wild(lctx, e.span); - arms.push(hir::Arm { - attrs: hir_vec![], - pats: hir_vec![pat_under], - guard: Some(cond), - body: expr_block(lctx, then, None), - }); - else_opt.map(|else_opt| (else_opt, true)) + // Desugar ExprIfLet + // From: `if let = []` + ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => { + // to: + // + // match { + // => , + // [_ if => ,] + // _ => [ | ()] + // } + + // ` => ` + let pat_arm = { + let body = self.lower_block(body); + let body_expr = expr_block(self, body, None); + arm(hir_vec![self.lower_pat(pat)], body_expr) + }; + + // `[_ if => ,]` + let mut else_opt = else_opt.as_ref().map(|e| self.lower_expr(e)); + let else_if_arms = { + let mut arms = vec![]; + loop { + let else_opt_continue = else_opt.and_then(|els| { + els.and_then(|els| { + match els.node { + // else if + hir::ExprIf(cond, then, else_opt) => { + let pat_under = pat_wild(self, e.span); + arms.push(hir::Arm { + attrs: hir_vec![], + pats: hir_vec![pat_under], + guard: Some(cond), + body: expr_block(self, then, None), + }); + else_opt.map(|else_opt| (else_opt, true)) + } + _ => Some((P(els), false)), } - _ => Some((P(els), false)), + }) + }); + match else_opt_continue { + Some((e, true)) => { + else_opt = Some(e); + } + Some((e, false)) => { + else_opt = Some(e); + break; + } + None => { + else_opt = None; + break; } - }) - }); - match else_opt_continue { - Some((e, true)) => { - else_opt = Some(e); - } - Some((e, false)) => { - else_opt = Some(e); - break; - } - None => { - else_opt = None; - break; } } - } - arms - }; - - let contains_else_clause = else_opt.is_some(); - - // `_ => [ | ()]` - let else_arm = { - let pat_under = pat_wild(lctx, e.span); - let else_expr = - else_opt.unwrap_or_else( - || expr_tuple(lctx, e.span, hir_vec![], None)); - arm(hir_vec![pat_under], else_expr) - }; - - let mut arms = Vec::with_capacity(else_if_arms.len() + 2); - arms.push(pat_arm); - arms.extend(else_if_arms); - arms.push(else_arm); - - let sub_expr = lower_expr(lctx, sub_expr); - // add attributes to the outer returned expr node - return expr(lctx, - e.span, - hir::ExprMatch(sub_expr, - arms.into(), - hir::MatchSource::IfLetDesugar { - contains_else_clause: contains_else_clause, - }), - e.attrs.clone()); - } + arms + }; - // Desugar ExprWhileLet - // From: `[opt_ident]: while let = ` - ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => { - // to: - // - // [opt_ident]: loop { - // match { - // => , - // _ => break - // } - // } - - // ` => ` - let pat_arm = { - let body = lower_block(lctx, body); - let body_expr = expr_block(lctx, body, None); - arm(hir_vec![lower_pat(lctx, pat)], body_expr) - }; - - // `_ => break` - let break_arm = { - let pat_under = pat_wild(lctx, e.span); - let break_expr = expr_break(lctx, e.span, None); - arm(hir_vec![pat_under], break_expr) - }; - - // `match { ... }` - let arms = hir_vec![pat_arm, break_arm]; - let sub_expr = lower_expr(lctx, sub_expr); - let match_expr = expr(lctx, - e.span, - hir::ExprMatch(sub_expr, - arms, - hir::MatchSource::WhileLetDesugar), - None); - - // `[opt_ident]: loop { ... }` - let loop_block = block_expr(lctx, match_expr); - let loop_expr = hir::ExprLoop(loop_block, - opt_ident.map(|ident| lower_ident(lctx, ident))); - // add attributes to the outer returned expr node - let attrs = e.attrs.clone(); - return P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: attrs }); - } + let contains_else_clause = else_opt.is_some(); - // Desugar ExprForLoop - // From: `[opt_ident]: for in ` - ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => { - // to: - // - // { - // let result = match ::std::iter::IntoIterator::into_iter() { - // mut iter => { - // [opt_ident]: loop { - // match ::std::iter::Iterator::next(&mut iter) { - // ::std::option::Option::Some() => , - // ::std::option::Option::None => break - // } - // } - // } - // }; - // result - // } - - // expand - let head = lower_expr(lctx, head); - - let iter = lctx.str_to_ident("iter"); - - // `::std::option::Option::Some() => ` - let pat_arm = { - let body_block = lower_block(lctx, body); - let body_span = body_block.span; - let body_expr = P(hir::Expr { - id: lctx.next_id(), - node: hir::ExprBlock(body_block), - span: body_span, - attrs: None, - }); - let pat = lower_pat(lctx, pat); - let some_pat = pat_some(lctx, e.span, pat); + // `_ => [ | ()]` + let else_arm = { + let pat_under = pat_wild(self, e.span); + let else_expr = + else_opt.unwrap_or_else( + || expr_tuple(self, e.span, hir_vec![], None)); + arm(hir_vec![pat_under], else_expr) + }; - arm(hir_vec![some_pat], body_expr) - }; + let mut arms = Vec::with_capacity(else_if_arms.len() + 2); + arms.push(pat_arm); + arms.extend(else_if_arms); + arms.push(else_arm); + + let sub_expr = self.lower_expr(sub_expr); + // add attributes to the outer returned expr node + return expr(self, + e.span, + hir::ExprMatch(sub_expr, + arms.into(), + hir::MatchSource::IfLetDesugar { + contains_else_clause: contains_else_clause, + }), + e.attrs.clone()); + } - // `::std::option::Option::None => break` - let break_arm = { - let break_expr = expr_break(lctx, e.span, None); + // Desugar ExprWhileLet + // From: `[opt_ident]: while let = ` + ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => { + // to: + // + // [opt_ident]: loop { + // match { + // => , + // _ => break + // } + // } + + // ` => ` + let pat_arm = { + let body = self.lower_block(body); + let body_expr = expr_block(self, body, None); + arm(hir_vec![self.lower_pat(pat)], body_expr) + }; - arm(hir_vec![pat_none(lctx, e.span)], break_expr) - }; + // `_ => break` + let break_arm = { + let pat_under = pat_wild(self, e.span); + let break_expr = expr_break(self, e.span, None); + arm(hir_vec![pat_under], break_expr) + }; - // `mut iter` - let iter_pat = - pat_ident_binding_mode(lctx, e.span, iter, hir::BindByValue(hir::MutMutable)); + // `match { ... }` + let arms = hir_vec![pat_arm, break_arm]; + let sub_expr = self.lower_expr(sub_expr); + let match_expr = expr(self, + e.span, + hir::ExprMatch(sub_expr, + arms, + hir::MatchSource::WhileLetDesugar), + None); + + // `[opt_ident]: loop { ... }` + let loop_block = block_expr(self, match_expr); + let loop_expr = hir::ExprLoop(loop_block, + opt_ident.map(|ident| self.lower_ident(ident))); + // add attributes to the outer returned expr node + let attrs = e.attrs.clone(); + return P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: attrs }); + } - // `match ::std::iter::Iterator::next(&mut iter) { ... }` - let match_expr = { - let next_path = { - let strs = std_path(lctx, &["iter", "Iterator", "next"]); + // Desugar ExprForLoop + // From: `[opt_ident]: for in ` + ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => { + // to: + // + // { + // let result = match ::std::iter::IntoIterator::into_iter() { + // mut iter => { + // [opt_ident]: loop { + // match ::std::iter::Iterator::next(&mut iter) { + // ::std::option::Option::Some() => , + // ::std::option::Option::None => break + // } + // } + // } + // }; + // result + // } + + // expand + let head = self.lower_expr(head); + + let iter = self.str_to_ident("iter"); + + // `::std::option::Option::Some() => ` + let pat_arm = { + let body_block = self.lower_block(body); + let body_span = body_block.span; + let body_expr = P(hir::Expr { + id: self.next_id(), + node: hir::ExprBlock(body_block), + span: body_span, + attrs: None, + }); + let pat = self.lower_pat(pat); + let some_pat = pat_some(self, e.span, pat); - path_global(e.span, strs) + arm(hir_vec![some_pat], body_expr) }; - let iter = expr_ident(lctx, e.span, iter, None, iter_pat.id); - let ref_mut_iter = expr_mut_addr_of(lctx, e.span, iter, None); - let next_path = expr_path(lctx, next_path, None); - let next_expr = expr_call(lctx, - e.span, - next_path, - hir_vec![ref_mut_iter], - None); - let arms = hir_vec![pat_arm, break_arm]; - expr(lctx, - e.span, - hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), - None) - }; + // `::std::option::Option::None => break` + let break_arm = { + let break_expr = expr_break(self, e.span, None); - // `[opt_ident]: loop { ... }` - let loop_block = block_expr(lctx, match_expr); - let loop_expr = hir::ExprLoop(loop_block, - opt_ident.map(|ident| lower_ident(lctx, ident))); - let loop_expr = - P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None }); + arm(hir_vec![pat_none(self, e.span)], break_expr) + }; - // `mut iter => { ... }` - let iter_arm = arm(hir_vec![iter_pat], loop_expr); + // `mut iter` + let iter_pat = pat_ident_binding_mode(self, e.span, iter, + hir::BindByValue(hir::MutMutable)); + + // `match ::std::iter::Iterator::next(&mut iter) { ... }` + let match_expr = { + let next_path = { + let strs = std_path(self, &["iter", "Iterator", "next"]); + + path_global(e.span, strs) + }; + let iter = expr_ident(self, e.span, iter, None, iter_pat.id); + let ref_mut_iter = expr_mut_addr_of(self, e.span, iter, None); + let next_path = expr_path(self, next_path, None); + let next_expr = expr_call(self, + e.span, + next_path, + hir_vec![ref_mut_iter], + None); + let arms = hir_vec![pat_arm, break_arm]; + + expr(self, + e.span, + hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), + None) + }; - // `match ::std::iter::IntoIterator::into_iter() { ... }` - let into_iter_expr = { - let into_iter_path = { - let strs = std_path(lctx, &["iter", "IntoIterator", "into_iter"]); + // `[opt_ident]: loop { ... }` + let loop_block = block_expr(self, match_expr); + let loop_expr = hir::ExprLoop(loop_block, + opt_ident.map(|ident| self.lower_ident(ident))); + let loop_expr = + P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None }); - path_global(e.span, strs) - }; + // `mut iter => { ... }` + let iter_arm = arm(hir_vec![iter_pat], loop_expr); - let into_iter = expr_path(lctx, into_iter_path, None); - expr_call(lctx, e.span, into_iter, hir_vec![head], None) - }; - - let match_expr = expr_match(lctx, - e.span, - into_iter_expr, - hir_vec![iter_arm], - hir::MatchSource::ForLoopDesugar, - None); - - // `{ let _result = ...; _result }` - // underscore prevents an unused_variables lint if the head diverges - let result_ident = lctx.str_to_ident("_result"); - let (let_stmt, let_stmt_binding) = - stmt_let(lctx, e.span, false, result_ident, match_expr, None); - - let result = expr_ident(lctx, e.span, result_ident, None, let_stmt_binding); - let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result)); - // add the attributes to the outer returned expr node - return expr_block(lctx, block, e.attrs.clone()); - } + // `match ::std::iter::IntoIterator::into_iter() { ... }` + let into_iter_expr = { + let into_iter_path = { + let strs = std_path(self, &["iter", "IntoIterator", "into_iter"]); - // Desugar ExprKind::Try - // From: `?` - ExprKind::Try(ref sub_expr) => { - // to: - // - // { - // match { - // Ok(val) => val, - // Err(err) => { - // return Err(From::from(err)) - // } - // } - // } + path_global(e.span, strs) + }; - // expand - let sub_expr = lower_expr(lctx, sub_expr); - - // Ok(val) => val - let ok_arm = { - let val_ident = lctx.str_to_ident("val"); - let val_pat = pat_ident(lctx, e.span, val_ident); - let val_expr = expr_ident(lctx, e.span, val_ident, None, val_pat.id); - let ok_pat = pat_ok(lctx, e.span, val_pat); - - arm(hir_vec![ok_pat], val_expr) - }; - - // Err(err) => return Err(From::from(err)) - let err_arm = { - let err_ident = lctx.str_to_ident("err"); - let err_local = pat_ident(lctx, e.span, err_ident); - let from_expr = { - let path = std_path(lctx, &["convert", "From", "from"]); - let path = path_global(e.span, path); - let from = expr_path(lctx, path, None); - let err_expr = expr_ident(lctx, e.span, err_ident, None, err_local.id); - - expr_call(lctx, e.span, from, hir_vec![err_expr], None) + let into_iter = expr_path(self, into_iter_path, None); + expr_call(self, e.span, into_iter, hir_vec![head], None) }; - let err_expr = { - let path = std_path(lctx, &["result", "Result", "Err"]); - let path = path_global(e.span, path); - let err_ctor = expr_path(lctx, path, None); - expr_call(lctx, e.span, err_ctor, hir_vec![from_expr], None) + + let match_expr = expr_match(self, + e.span, + into_iter_expr, + hir_vec![iter_arm], + hir::MatchSource::ForLoopDesugar, + None); + + // `{ let _result = ...; _result }` + // underscore prevents an unused_variables lint if the head diverges + let result_ident = self.str_to_ident("_result"); + let (let_stmt, let_stmt_binding) = + stmt_let(self, e.span, false, result_ident, match_expr, None); + + let result = expr_ident(self, e.span, result_ident, None, let_stmt_binding); + let block = block_all(self, e.span, hir_vec![let_stmt], Some(result)); + // add the attributes to the outer returned expr node + return expr_block(self, block, e.attrs.clone()); + } + + // Desugar ExprKind::Try + // From: `?` + ExprKind::Try(ref sub_expr) => { + // to: + // + // { + // match { + // Ok(val) => val, + // Err(err) => { + // return Err(From::from(err)) + // } + // } + // } + + // expand + let sub_expr = self.lower_expr(sub_expr); + + // Ok(val) => val + let ok_arm = { + let val_ident = self.str_to_ident("val"); + let val_pat = pat_ident(self, e.span, val_ident); + let val_expr = expr_ident(self, e.span, val_ident, None, val_pat.id); + let ok_pat = pat_ok(self, e.span, val_pat); + + arm(hir_vec![ok_pat], val_expr) }; - let err_pat = pat_err(lctx, e.span, err_local); - let ret_expr = expr(lctx, e.span, - hir::Expr_::ExprRet(Some(err_expr)), None); - arm(hir_vec![err_pat], ret_expr) - }; + // Err(err) => return Err(From::from(err)) + let err_arm = { + let err_ident = self.str_to_ident("err"); + let err_local = pat_ident(self, e.span, err_ident); + let from_expr = { + let path = std_path(self, &["convert", "From", "from"]); + let path = path_global(e.span, path); + let from = expr_path(self, path, None); + let err_expr = expr_ident(self, e.span, err_ident, None, err_local.id); + + expr_call(self, e.span, from, hir_vec![err_expr], None) + }; + let err_expr = { + let path = std_path(self, &["result", "Result", "Err"]); + let path = path_global(e.span, path); + let err_ctor = expr_path(self, path, None); + expr_call(self, e.span, err_ctor, hir_vec![from_expr], None) + }; + let err_pat = pat_err(self, e.span, err_local); + let ret_expr = expr(self, e.span, + hir::Expr_::ExprRet(Some(err_expr)), None); + + arm(hir_vec![err_pat], ret_expr) + }; - return expr_match(lctx, e.span, sub_expr, hir_vec![err_arm, ok_arm], - hir::MatchSource::TryDesugar, None); - } + return expr_match(self, e.span, sub_expr, hir_vec![err_arm, ok_arm], + hir::MatchSource::TryDesugar, None); + } - ExprKind::Mac(_) => panic!("Shouldn't exist here"), - }, - span: e.span, - attrs: e.attrs.clone(), - }) -} + ExprKind::Mac(_) => panic!("Shouldn't exist here"), + }, + span: e.span, + attrs: e.attrs.clone(), + }) + } -fn lower_stmt(lctx: &mut LoweringContext, s: &Stmt) -> hir::Stmt { - match s.node { - StmtKind::Decl(ref d, id) => { - Spanned { - node: hir::StmtDecl(lower_decl(lctx, d), id), - span: s.span, + fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt { + match s.node { + StmtKind::Decl(ref d, id) => { + Spanned { + node: hir::StmtDecl(self.lower_decl(d), id), + span: s.span, + } } - } - StmtKind::Expr(ref e, id) => { - Spanned { - node: hir::StmtExpr(lower_expr(lctx, e), id), - span: s.span, + StmtKind::Expr(ref e, id) => { + Spanned { + node: hir::StmtExpr(self.lower_expr(e), id), + span: s.span, + } } - } - StmtKind::Semi(ref e, id) => { - Spanned { - node: hir::StmtSemi(lower_expr(lctx, e), id), - span: s.span, + StmtKind::Semi(ref e, id) => { + Spanned { + node: hir::StmtSemi(self.lower_expr(e), id), + span: s.span, + } } + StmtKind::Mac(..) => panic!("Shouldn't exist here"), } - StmtKind::Mac(..) => panic!("Shouldn't exist here"), } -} -fn lower_capture_clause(_lctx: &mut LoweringContext, c: CaptureBy) -> hir::CaptureClause { - match c { - CaptureBy::Value => hir::CaptureByValue, - CaptureBy::Ref => hir::CaptureByRef, + fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause { + match c { + CaptureBy::Value => hir::CaptureByValue, + CaptureBy::Ref => hir::CaptureByRef, + } } -} -fn lower_visibility(lctx: &mut LoweringContext, v: &Visibility) -> hir::Visibility { - match *v { - Visibility::Public => hir::Public, - Visibility::Crate(_) => hir::Visibility::Crate, - Visibility::Restricted { ref path, id } => - hir::Visibility::Restricted { path: P(lower_path(lctx, path)), id: id }, - Visibility::Inherited => hir::Inherited, + fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility { + match *v { + Visibility::Public => hir::Public, + Visibility::Crate(_) => hir::Visibility::Crate, + Visibility::Restricted { ref path, id } => + hir::Visibility::Restricted { path: P(self.lower_path(path)), id: id }, + Visibility::Inherited => hir::Inherited, + } } -} -fn lower_defaultness(_lctx: &mut LoweringContext, d: Defaultness) -> hir::Defaultness { - match d { - Defaultness::Default => hir::Defaultness::Default, - Defaultness::Final => hir::Defaultness::Final, + fn lower_defaultness(&mut self, d: Defaultness) -> hir::Defaultness { + match d { + Defaultness::Default => hir::Defaultness::Default, + Defaultness::Final => hir::Defaultness::Final, + } } -} -fn lower_block_check_mode(lctx: &mut LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { - match *b { - BlockCheckMode::Default => hir::DefaultBlock, - BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(lower_unsafe_source(lctx, u)), + fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode { + match *b { + BlockCheckMode::Default => hir::DefaultBlock, + BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(self.lower_unsafe_source(u)), + } } -} -fn lower_binding_mode(lctx: &mut LoweringContext, b: &BindingMode) -> hir::BindingMode { - match *b { - BindingMode::ByRef(m) => hir::BindByRef(lower_mutability(lctx, m)), - BindingMode::ByValue(m) => hir::BindByValue(lower_mutability(lctx, m)), + fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingMode { + match *b { + BindingMode::ByRef(m) => hir::BindByRef(self.lower_mutability(m)), + BindingMode::ByValue(m) => hir::BindByValue(self.lower_mutability(m)), + } } -} -fn lower_unsafe_source(_lctx: &mut LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { - match u { - CompilerGenerated => hir::CompilerGenerated, - UserProvided => hir::UserProvided, + fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource { + match u { + CompilerGenerated => hir::CompilerGenerated, + UserProvided => hir::UserProvided, + } } -} -fn lower_impl_polarity(_lctx: &mut LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { - match i { - ImplPolarity::Positive => hir::ImplPolarity::Positive, - ImplPolarity::Negative => hir::ImplPolarity::Negative, + fn lower_impl_polarity(&mut self, i: ImplPolarity) -> hir::ImplPolarity { + match i { + ImplPolarity::Positive => hir::ImplPolarity::Positive, + ImplPolarity::Negative => hir::ImplPolarity::Negative, + } } -} -fn lower_trait_bound_modifier(_lctx: &mut LoweringContext, - f: TraitBoundModifier) - -> hir::TraitBoundModifier { - match f { - TraitBoundModifier::None => hir::TraitBoundModifier::None, - TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, + fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier { + match f { + TraitBoundModifier::None => hir::TraitBoundModifier::None, + TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, + } } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 66b1b28a0e505..492d36cfb31a5 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -37,7 +37,7 @@ use rustc_typeck as typeck; use rustc_privacy; use rustc_plugin::registry::Registry; use rustc_plugin as plugin; -use rustc::hir::lowering::{lower_crate, LoweringContext}; +use rustc::hir::lowering::LoweringContext; use rustc_passes::{no_asm, loops, consts, rvalues, static_recursion}; use rustc_const_eval::check_match; use super::Compilation; @@ -787,8 +787,8 @@ pub fn lower_and_resolve<'a>(sess: &Session, // Lower ast -> hir. let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || { - let mut lcx = LoweringContext::new(sess, Some(krate), &mut resolver); - hir_map::Forest::new(lower_crate(&mut lcx, krate), dep_graph) + let krate = LoweringContext::new(sess, Some(krate), &mut resolver).lower_crate(krate); + hir_map::Forest::new(krate, dep_graph) }); (ty::CrateAnalysis { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index ce525b716ff2c..8c17ef02615fe 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -57,7 +57,7 @@ use rustc_serialize::{Encodable, EncoderHelpers}; #[cfg(test)] use syntax::parse; #[cfg(test)] use syntax::ast::NodeId; #[cfg(test)] use rustc::hir::print as pprust; -#[cfg(test)] use rustc::hir::lowering::{lower_item, LoweringContext, DummyResolver}; +#[cfg(test)] use rustc::hir::lowering::{LoweringContext, DummyResolver}; struct DecodeContext<'a, 'b, 'tcx: 'a> { tcx: &'a TyCtxt<'tcx>, @@ -1347,7 +1347,7 @@ fn roundtrip(in_item: hir::Item) { fn test_basic() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(lcx, "e_item!(&cx, + roundtrip(lcx.lower_item("e_item!(&cx, fn foo() {} ).unwrap())); }); @@ -1357,7 +1357,7 @@ fn test_basic() { fn test_smalltalk() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(lcx, "e_item!(&cx, + roundtrip(lcx.lower_item("e_item!(&cx, fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed. ).unwrap())); }); @@ -1367,7 +1367,7 @@ fn test_smalltalk() { fn test_more() { let cx = mk_ctxt(); with_testing_context(|lcx| { - roundtrip(lower_item(lcx, "e_item!(&cx, + roundtrip(lcx.lower_item("e_item!(&cx, fn foo(x: usize, y: usize) -> usize { let z = x + y; return z; @@ -1387,10 +1387,10 @@ fn test_simplification() { ).unwrap(); let cx = mk_ctxt(); with_testing_context(|lcx| { - let hir_item = lower_item(lcx, &item); + let hir_item = lcx.lower_item(&item); let item_in = InlinedItemRef::Item(&hir_item); let item_out = simplify_ast(item_in); - let item_exp = InlinedItem::Item(P(lower_item(lcx, "e_item!(&cx, + let item_exp = InlinedItem::Item(P(lcx.lower_item("e_item!(&cx, fn new_int_alist() -> alist { return alist {eq_fn: eq_int, data: Vec::new()}; } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 0f518900ea787..d4c08552edfc3 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -28,7 +28,7 @@ use rustc::hir::map as hir_map; use rustc::session::{self, config}; use rustc::session::config::{get_unstable_features_setting, OutputType}; use rustc::session::search_paths::{SearchPaths, PathKind}; -use rustc::hir::lowering::{lower_crate, LoweringContext, DummyResolver}; +use rustc::hir::lowering::{LoweringContext, DummyResolver}; use rustc_back::dynamic_lib::DynamicLibrary; use rustc_back::tempdir::TempDir; use rustc_driver::{driver, Compilation}; @@ -98,8 +98,7 @@ pub fn run(input: &str, let defs = &RefCell::new(hir_map::collect_definitions(&krate)); let mut dummy_resolver = DummyResolver; - let mut lcx = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver); - let krate = lower_crate(&mut lcx, &krate); + let krate = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver).lower_crate(&krate); let opts = scrape_test_config(&krate); From 3927ff4fecea17f56a57c59253afce3acdc89bec Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 10 May 2016 01:15:11 +0000 Subject: [PATCH 07/16] Make the remaining functions in `hir::lowering` methods of `LoweringContext` --- src/librustc/hir/lowering.rs | 794 +++++++++++++++++------------------ 1 file changed, 383 insertions(+), 411 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0f65c5c64e491..0c7123a570e14 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -965,58 +965,55 @@ impl<'a> LoweringContext<'a> { let inplace_finalize = ["ops", "InPlace", "finalize"]; let make_call = |this: &mut LoweringContext, p, args| { - let path = core_path(this, e.span, p); - let path = expr_path(this, path, None); - expr_call(this, e.span, path, args, None) + let path = this.core_path(e.span, p); + let path = this.expr_path(path, None); + this.expr_call(e.span, path, args, None) }; let mk_stmt_let = |this: &mut LoweringContext, bind, expr| { - stmt_let(this, e.span, false, bind, expr, None) + this.stmt_let(e.span, false, bind, expr, None) }; let mk_stmt_let_mut = |this: &mut LoweringContext, bind, expr| { - stmt_let(this, e.span, true, bind, expr, None) + this.stmt_let(e.span, true, bind, expr, None) }; // let placer = ; let (s1, placer_binding) = { - let placer_expr = signal_block_expr(self, - hir_vec![], - placer_expr, - e.span, - hir::PopUnstableBlock, - None); + let placer_expr = self.signal_block_expr(hir_vec![], + placer_expr, + e.span, + hir::PopUnstableBlock, + None); mk_stmt_let(self, placer_ident, placer_expr) }; // let mut place = Placer::make_place(placer); let (s2, place_binding) = { - let placer = expr_ident(self, e.span, placer_ident, None, placer_binding); + let placer = self.expr_ident(e.span, placer_ident, None, placer_binding); let call = make_call(self, &make_place, hir_vec![placer]); mk_stmt_let_mut(self, place_ident, call) }; // let p_ptr = Place::pointer(&mut place); let (s3, p_ptr_binding) = { - let agent = expr_ident(self, e.span, place_ident, None, place_binding); - let args = hir_vec![expr_mut_addr_of(self, e.span, agent, None)]; + let agent = self.expr_ident(e.span, place_ident, None, place_binding); + let args = hir_vec![self.expr_mut_addr_of(e.span, agent, None)]; let call = make_call(self, &place_pointer, args); mk_stmt_let(self, p_ptr_ident, call) }; // pop_unsafe!(EXPR)); let pop_unsafe_expr = { - let value_expr = signal_block_expr(self, - hir_vec![], - value_expr, - e.span, - hir::PopUnstableBlock, - None); - signal_block_expr(self, - hir_vec![], - value_expr, - e.span, - hir::PopUnsafeBlock(hir::CompilerGenerated), None) + let value_expr = self.signal_block_expr(hir_vec![], + value_expr, + e.span, + hir::PopUnstableBlock, + None); + self.signal_block_expr(hir_vec![], + value_expr, + e.span, + hir::PopUnsafeBlock(hir::CompilerGenerated), None) }; // push_unsafe!({ @@ -1024,28 +1021,26 @@ impl<'a> LoweringContext<'a> { // InPlace::finalize(place) // }) let expr = { - let ptr = expr_ident(self, e.span, p_ptr_ident, None, p_ptr_binding); + let ptr = self.expr_ident(e.span, p_ptr_ident, None, p_ptr_binding); let call_move_val_init = hir::StmtSemi( make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]), self.next_id()); let call_move_val_init = respan(e.span, call_move_val_init); - let place = expr_ident(self, e.span, place_ident, None, place_binding); + let place = self.expr_ident(e.span, place_ident, None, place_binding); let call = make_call(self, &inplace_finalize, hir_vec![place]); - signal_block_expr(self, - hir_vec![call_move_val_init], - call, - e.span, - hir::PushUnsafeBlock(hir::CompilerGenerated), None) + self.signal_block_expr(hir_vec![call_move_val_init], + call, + e.span, + hir::PushUnsafeBlock(hir::CompilerGenerated), None) }; - return signal_block_expr(self, - hir_vec![s1, s2, s3], - expr, - e.span, - hir::PushUnstableBlock, - e.attrs.clone()); + return self.signal_block_expr(hir_vec![s1, s2, s3], + expr, + e.span, + hir::PushUnstableBlock, + e.attrs.clone()); } ExprKind::Vec(ref exprs) => { @@ -1110,7 +1105,7 @@ impl<'a> LoweringContext<'a> { rules: hir::DefaultBlock, span: span, }); - expr_block(self, blk, None) + self.expr_block(blk, None) } _ => self.lower_expr(els), } @@ -1162,47 +1157,42 @@ impl<'a> LoweringContext<'a> { ast_expr: &Expr, path: &[&str], fields: &[(&str, &P)]) -> P { - let strs = std_path(this, &iter::once(&"ops") + let strs = this.std_path(&iter::once(&"ops") .chain(path) .map(|s| *s) .collect::>()); - let structpath = path_global(ast_expr.span, strs); + let structpath = this.path_global(ast_expr.span, strs); let hir_expr = if fields.len() == 0 { - expr_path(this, - structpath, - ast_expr.attrs.clone()) + this.expr_path(structpath, ast_expr.attrs.clone()) } else { let fields = fields.into_iter().map(|&(s, e)| { let expr = this.lower_expr(&e); - let signal_block = signal_block_expr(this, - hir_vec![], - expr, - e.span, - hir::PopUnstableBlock, - None); - field(token::intern(s), signal_block, ast_expr.span) + let signal_block = this.signal_block_expr(hir_vec![], + expr, + e.span, + hir::PopUnstableBlock, + None); + this.field(token::intern(s), signal_block, ast_expr.span) }).collect(); let attrs = ast_expr.attrs.clone(); - expr_struct(this, ast_expr.span, structpath, fields, None, attrs) + this.expr_struct(ast_expr.span, structpath, fields, None, attrs) }; - signal_block_expr(this, - hir_vec![], - hir_expr, - ast_expr.span, - hir::PushUnstableBlock, - None) + this.signal_block_expr(hir_vec![], + hir_expr, + ast_expr.span, + hir::PushUnstableBlock, + None) } use syntax::ast::RangeLimits::*; return match (e1, e2, lims) { (&None, &None, HalfOpen) => - make_struct(self, e, &["RangeFull"], - &[]), + make_struct(self, e, &["RangeFull"], &[]), (&Some(ref e1), &None, HalfOpen) => make_struct(self, e, &["RangeFrom"], @@ -1303,8 +1293,9 @@ impl<'a> LoweringContext<'a> { // ` => ` let pat_arm = { let body = self.lower_block(body); - let body_expr = expr_block(self, body, None); - arm(hir_vec![self.lower_pat(pat)], body_expr) + let body_expr = self.expr_block(body, None); + let pat = self.lower_pat(pat); + self.arm(hir_vec![pat], body_expr) }; // `[_ if => ,]` @@ -1317,12 +1308,12 @@ impl<'a> LoweringContext<'a> { match els.node { // else if hir::ExprIf(cond, then, else_opt) => { - let pat_under = pat_wild(self, e.span); + let pat_under = self.pat_wild(e.span); arms.push(hir::Arm { attrs: hir_vec![], pats: hir_vec![pat_under], guard: Some(cond), - body: expr_block(self, then, None), + body: self.expr_block(then, None), }); else_opt.map(|else_opt| (else_opt, true)) } @@ -1351,11 +1342,10 @@ impl<'a> LoweringContext<'a> { // `_ => [ | ()]` let else_arm = { - let pat_under = pat_wild(self, e.span); + let pat_under = self.pat_wild(e.span); let else_expr = - else_opt.unwrap_or_else( - || expr_tuple(self, e.span, hir_vec![], None)); - arm(hir_vec![pat_under], else_expr) + else_opt.unwrap_or_else(|| self.expr_tuple(e.span, hir_vec![], None)); + self.arm(hir_vec![pat_under], else_expr) }; let mut arms = Vec::with_capacity(else_if_arms.len() + 2); @@ -1365,14 +1355,13 @@ impl<'a> LoweringContext<'a> { let sub_expr = self.lower_expr(sub_expr); // add attributes to the outer returned expr node - return expr(self, - e.span, - hir::ExprMatch(sub_expr, - arms.into(), - hir::MatchSource::IfLetDesugar { - contains_else_clause: contains_else_clause, - }), - e.attrs.clone()); + return self.expr(e.span, + hir::ExprMatch(sub_expr, + arms.into(), + hir::MatchSource::IfLetDesugar { + contains_else_clause: contains_else_clause, + }), + e.attrs.clone()); } // Desugar ExprWhileLet @@ -1390,29 +1379,29 @@ impl<'a> LoweringContext<'a> { // ` => ` let pat_arm = { let body = self.lower_block(body); - let body_expr = expr_block(self, body, None); - arm(hir_vec![self.lower_pat(pat)], body_expr) + let body_expr = self.expr_block(body, None); + let pat = self.lower_pat(pat); + self.arm(hir_vec![pat], body_expr) }; // `_ => break` let break_arm = { - let pat_under = pat_wild(self, e.span); - let break_expr = expr_break(self, e.span, None); - arm(hir_vec![pat_under], break_expr) + let pat_under = self.pat_wild(e.span); + let break_expr = self.expr_break(e.span, None); + self.arm(hir_vec![pat_under], break_expr) }; // `match { ... }` let arms = hir_vec![pat_arm, break_arm]; let sub_expr = self.lower_expr(sub_expr); - let match_expr = expr(self, - e.span, - hir::ExprMatch(sub_expr, - arms, - hir::MatchSource::WhileLetDesugar), - None); + let match_expr = self.expr(e.span, + hir::ExprMatch(sub_expr, + arms, + hir::MatchSource::WhileLetDesugar), + None); // `[opt_ident]: loop { ... }` - let loop_block = block_expr(self, match_expr); + let loop_block = self.block_expr(match_expr); let loop_expr = hir::ExprLoop(loop_block, opt_ident.map(|ident| self.lower_ident(ident))); // add attributes to the outer returned expr node @@ -1455,84 +1444,81 @@ impl<'a> LoweringContext<'a> { attrs: None, }); let pat = self.lower_pat(pat); - let some_pat = pat_some(self, e.span, pat); + let some_pat = self.pat_some(e.span, pat); - arm(hir_vec![some_pat], body_expr) + self.arm(hir_vec![some_pat], body_expr) }; // `::std::option::Option::None => break` let break_arm = { - let break_expr = expr_break(self, e.span, None); - - arm(hir_vec![pat_none(self, e.span)], break_expr) + let break_expr = self.expr_break(e.span, None); + let pat = self.pat_none(e.span); + self.arm(hir_vec![pat], break_expr) }; // `mut iter` - let iter_pat = pat_ident_binding_mode(self, e.span, iter, - hir::BindByValue(hir::MutMutable)); + let iter_pat = self.pat_ident_binding_mode(e.span, iter, + hir::BindByValue(hir::MutMutable)); // `match ::std::iter::Iterator::next(&mut iter) { ... }` let match_expr = { let next_path = { - let strs = std_path(self, &["iter", "Iterator", "next"]); + let strs = self.std_path(&["iter", "Iterator", "next"]); - path_global(e.span, strs) + self.path_global(e.span, strs) }; - let iter = expr_ident(self, e.span, iter, None, iter_pat.id); - let ref_mut_iter = expr_mut_addr_of(self, e.span, iter, None); - let next_path = expr_path(self, next_path, None); - let next_expr = expr_call(self, - e.span, - next_path, - hir_vec![ref_mut_iter], - None); + let iter = self.expr_ident(e.span, iter, None, iter_pat.id); + let ref_mut_iter = self.expr_mut_addr_of(e.span, iter, None); + let next_path = self.expr_path(next_path, None); + let next_expr = self.expr_call(e.span, + next_path, + hir_vec![ref_mut_iter], + None); let arms = hir_vec![pat_arm, break_arm]; - expr(self, - e.span, - hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), - None) + self.expr(e.span, + hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), + None) }; // `[opt_ident]: loop { ... }` - let loop_block = block_expr(self, match_expr); + let loop_block = self.block_expr(match_expr); let loop_expr = hir::ExprLoop(loop_block, opt_ident.map(|ident| self.lower_ident(ident))); let loop_expr = P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None }); // `mut iter => { ... }` - let iter_arm = arm(hir_vec![iter_pat], loop_expr); + let iter_arm = self.arm(hir_vec![iter_pat], loop_expr); // `match ::std::iter::IntoIterator::into_iter() { ... }` let into_iter_expr = { let into_iter_path = { - let strs = std_path(self, &["iter", "IntoIterator", "into_iter"]); + let strs = self.std_path(&["iter", "IntoIterator", "into_iter"]); - path_global(e.span, strs) + self.path_global(e.span, strs) }; - let into_iter = expr_path(self, into_iter_path, None); - expr_call(self, e.span, into_iter, hir_vec![head], None) + let into_iter = self.expr_path(into_iter_path, None); + self.expr_call(e.span, into_iter, hir_vec![head], None) }; - let match_expr = expr_match(self, - e.span, - into_iter_expr, - hir_vec![iter_arm], - hir::MatchSource::ForLoopDesugar, - None); + let match_expr = self.expr_match(e.span, + into_iter_expr, + hir_vec![iter_arm], + hir::MatchSource::ForLoopDesugar, + None); // `{ let _result = ...; _result }` // underscore prevents an unused_variables lint if the head diverges let result_ident = self.str_to_ident("_result"); let (let_stmt, let_stmt_binding) = - stmt_let(self, e.span, false, result_ident, match_expr, None); + self.stmt_let(e.span, false, result_ident, match_expr, None); - let result = expr_ident(self, e.span, result_ident, None, let_stmt_binding); - let block = block_all(self, e.span, hir_vec![let_stmt], Some(result)); + let result = self.expr_ident(e.span, result_ident, None, let_stmt_binding); + let block = self.block_all(e.span, hir_vec![let_stmt], Some(result)); // add the attributes to the outer returned expr node - return expr_block(self, block, e.attrs.clone()); + return self.expr_block(block, e.attrs.clone()); } // Desugar ExprKind::Try @@ -1555,40 +1541,40 @@ impl<'a> LoweringContext<'a> { // Ok(val) => val let ok_arm = { let val_ident = self.str_to_ident("val"); - let val_pat = pat_ident(self, e.span, val_ident); - let val_expr = expr_ident(self, e.span, val_ident, None, val_pat.id); - let ok_pat = pat_ok(self, e.span, val_pat); + let val_pat = self.pat_ident(e.span, val_ident); + let val_expr = self.expr_ident(e.span, val_ident, None, val_pat.id); + let ok_pat = self.pat_ok(e.span, val_pat); - arm(hir_vec![ok_pat], val_expr) + self.arm(hir_vec![ok_pat], val_expr) }; // Err(err) => return Err(From::from(err)) let err_arm = { let err_ident = self.str_to_ident("err"); - let err_local = pat_ident(self, e.span, err_ident); + let err_local = self.pat_ident(e.span, err_ident); let from_expr = { - let path = std_path(self, &["convert", "From", "from"]); - let path = path_global(e.span, path); - let from = expr_path(self, path, None); - let err_expr = expr_ident(self, e.span, err_ident, None, err_local.id); + let path = self.std_path(&["convert", "From", "from"]); + let path = self.path_global(e.span, path); + let from = self.expr_path(path, None); + let err_expr = self.expr_ident(e.span, err_ident, None, err_local.id); - expr_call(self, e.span, from, hir_vec![err_expr], None) + self.expr_call(e.span, from, hir_vec![err_expr], None) }; let err_expr = { - let path = std_path(self, &["result", "Result", "Err"]); - let path = path_global(e.span, path); - let err_ctor = expr_path(self, path, None); - expr_call(self, e.span, err_ctor, hir_vec![from_expr], None) + let path = self.std_path(&["result", "Result", "Err"]); + let path = self.path_global(e.span, path); + let err_ctor = self.expr_path(path, None); + self.expr_call(e.span, err_ctor, hir_vec![from_expr], None) }; - let err_pat = pat_err(self, e.span, err_local); - let ret_expr = expr(self, e.span, - hir::Expr_::ExprRet(Some(err_expr)), None); + let err_pat = self.pat_err(e.span, err_local); + let ret_expr = self.expr(e.span, + hir::Expr_::ExprRet(Some(err_expr)), None); - arm(hir_vec![err_pat], ret_expr) + self.arm(hir_vec![err_pat], ret_expr) }; - return expr_match(self, e.span, sub_expr, hir_vec![err_arm, ok_arm], - hir::MatchSource::TryDesugar, None); + return self.expr_match(e.span, sub_expr, hir_vec![err_arm, ok_arm], + hir::MatchSource::TryDesugar, None); } ExprKind::Mac(_) => panic!("Shouldn't exist here"), @@ -1680,310 +1666,296 @@ impl<'a> LoweringContext<'a> { TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, } } -} -// Helper methods for building HIR. + // Helper methods for building HIR. -fn arm(pats: hir::HirVec>, expr: P) -> hir::Arm { - hir::Arm { - attrs: hir_vec![], - pats: pats, - guard: None, - body: expr, + fn arm(&mut self, pats: hir::HirVec>, expr: P) -> hir::Arm { + hir::Arm { + attrs: hir_vec![], + pats: pats, + guard: None, + body: expr, + } } -} -fn field(name: Name, expr: P, span: Span) -> hir::Field { - hir::Field { - name: Spanned { - node: name, + fn field(&mut self, name: Name, expr: P, span: Span) -> hir::Field { + hir::Field { + name: Spanned { + node: name, + span: span, + }, span: span, - }, - span: span, - expr: expr, + expr: expr, + } } -} -fn expr_break(lctx: &mut LoweringContext, span: Span, - attrs: ThinAttributes) -> P { - expr(lctx, span, hir::ExprBreak(None), attrs) -} + fn expr_break(&mut self, span: Span, attrs: ThinAttributes) -> P { + self.expr(span, hir::ExprBreak(None), attrs) + } -fn expr_call(lctx: &mut LoweringContext, - span: Span, - e: P, - args: hir::HirVec>, - attrs: ThinAttributes) - -> P { - expr(lctx, span, hir::ExprCall(e, args), attrs) -} + fn expr_call(&mut self, + span: Span, + e: P, + args: hir::HirVec>, + attrs: ThinAttributes) + -> P { + self.expr(span, hir::ExprCall(e, args), attrs) + } -fn expr_ident(lctx: &mut LoweringContext, span: Span, id: hir::Ident, - attrs: ThinAttributes, binding: NodeId) -> P { - let expr = expr(lctx, span, hir::ExprPath(None, path_ident(span, id)), attrs); + fn expr_ident(&mut self, span: Span, id: hir::Ident, attrs: ThinAttributes, binding: NodeId) + -> P { + let expr_path = hir::ExprPath(None, self.path_ident(span, id)); + let expr = self.expr(span, expr_path, attrs); - let def = lctx.resolver.definitions().map(|defs| { - Def::Local(defs.local_def_id(binding), binding) - }).unwrap_or(Def::Err); - lctx.resolver.record_resolution(expr.id, def); + let def = self.resolver.definitions().map(|defs| { + Def::Local(defs.local_def_id(binding), binding) + }).unwrap_or(Def::Err); + self.resolver.record_resolution(expr.id, def); - expr -} + expr + } -fn expr_mut_addr_of(lctx: &mut LoweringContext, span: Span, e: P, - attrs: ThinAttributes) -> P { - expr(lctx, span, hir::ExprAddrOf(hir::MutMutable, e), attrs) -} + fn expr_mut_addr_of(&mut self, span: Span, e: P, attrs: ThinAttributes) + -> P { + self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), attrs) + } -fn expr_path(lctx: &mut LoweringContext, path: hir::Path, - attrs: ThinAttributes) -> P { - let def = lctx.resolver.resolve_generated_global_path(&path, true); - let expr = expr(lctx, path.span, hir::ExprPath(None, path), attrs); - lctx.resolver.record_resolution(expr.id, def); - expr -} + fn expr_path(&mut self, path: hir::Path, attrs: ThinAttributes) -> P { + let def = self.resolver.resolve_generated_global_path(&path, true); + let expr = self.expr(path.span, hir::ExprPath(None, path), attrs); + self.resolver.record_resolution(expr.id, def); + expr + } -fn expr_match(lctx: &mut LoweringContext, - span: Span, - arg: P, - arms: hir::HirVec, - source: hir::MatchSource, - attrs: ThinAttributes) - -> P { - expr(lctx, span, hir::ExprMatch(arg, arms, source), attrs) -} + fn expr_match(&mut self, + span: Span, + arg: P, + arms: hir::HirVec, + source: hir::MatchSource, + attrs: ThinAttributes) + -> P { + self.expr(span, hir::ExprMatch(arg, arms, source), attrs) + } -fn expr_block(lctx: &mut LoweringContext, b: P, - attrs: ThinAttributes) -> P { - expr(lctx, b.span, hir::ExprBlock(b), attrs) -} + fn expr_block(&mut self, b: P, attrs: ThinAttributes) -> P { + self.expr(b.span, hir::ExprBlock(b), attrs) + } -fn expr_tuple(lctx: &mut LoweringContext, sp: Span, exprs: hir::HirVec>, - attrs: ThinAttributes) -> P { - expr(lctx, sp, hir::ExprTup(exprs), attrs) -} + fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec>, attrs: ThinAttributes) + -> P { + self.expr(sp, hir::ExprTup(exprs), attrs) + } -fn expr_struct(lctx: &mut LoweringContext, - sp: Span, - path: hir::Path, - fields: hir::HirVec, - e: Option>, - attrs: ThinAttributes) -> P { - let def = lctx.resolver.resolve_generated_global_path(&path, false); - let expr = expr(lctx, sp, hir::ExprStruct(path, fields, e), attrs); - lctx.resolver.record_resolution(expr.id, def); - expr + fn expr_struct(&mut self, + sp: Span, + path: hir::Path, + fields: hir::HirVec, + e: Option>, + attrs: ThinAttributes) -> P { + let def = self.resolver.resolve_generated_global_path(&path, false); + let expr = self.expr(sp, hir::ExprStruct(path, fields, e), attrs); + self.resolver.record_resolution(expr.id, def); + expr + } -} + fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinAttributes) -> P { + P(hir::Expr { + id: self.next_id(), + node: node, + span: span, + attrs: attrs, + }) + } -fn expr(lctx: &mut LoweringContext, span: Span, node: hir::Expr_, - attrs: ThinAttributes) -> P { - P(hir::Expr { - id: lctx.next_id(), - node: node, - span: span, - attrs: attrs, - }) -} + fn stmt_let(&mut self, + sp: Span, + mutbl: bool, + ident: hir::Ident, + ex: P, + attrs: ThinAttributes) + -> (hir::Stmt, NodeId) { + let pat = if mutbl { + self.pat_ident_binding_mode(sp, ident, hir::BindByValue(hir::MutMutable)) + } else { + self.pat_ident(sp, ident) + }; + let pat_id = pat.id; + let local = P(hir::Local { + pat: pat, + ty: None, + init: Some(ex), + id: self.next_id(), + span: sp, + attrs: attrs, + }); + let decl = respan(sp, hir::DeclLocal(local)); + (respan(sp, hir::StmtDecl(P(decl), self.next_id())), pat_id) + } -fn stmt_let(lctx: &mut LoweringContext, - sp: Span, - mutbl: bool, - ident: hir::Ident, - ex: P, - attrs: ThinAttributes) - -> (hir::Stmt, NodeId) { - let pat = if mutbl { - pat_ident_binding_mode(lctx, sp, ident, hir::BindByValue(hir::MutMutable)) - } else { - pat_ident(lctx, sp, ident) - }; - let pat_id = pat.id; - let local = P(hir::Local { - pat: pat, - ty: None, - init: Some(ex), - id: lctx.next_id(), - span: sp, - attrs: attrs, - }); - let decl = respan(sp, hir::DeclLocal(local)); - (respan(sp, hir::StmtDecl(P(decl), lctx.next_id())), pat_id) -} + fn block_expr(&mut self, expr: P) -> P { + self.block_all(expr.span, hir::HirVec::new(), Some(expr)) + } -fn block_expr(lctx: &mut LoweringContext, expr: P) -> P { - block_all(lctx, expr.span, hir::HirVec::new(), Some(expr)) -} + fn block_all(&mut self, span: Span, stmts: hir::HirVec, expr: Option>) + -> P { + P(hir::Block { + stmts: stmts, + expr: expr, + id: self.next_id(), + rules: hir::DefaultBlock, + span: span, + }) + } -fn block_all(lctx: &mut LoweringContext, - span: Span, - stmts: hir::HirVec, - expr: Option>) - -> P { - P(hir::Block { - stmts: stmts, - expr: expr, - id: lctx.next_id(), - rules: hir::DefaultBlock, - span: span, - }) -} + fn pat_ok(&mut self, span: Span, pat: P) -> P { + let ok = self.std_path(&["result", "Result", "Ok"]); + let path = self.path_global(span, ok); + self.pat_enum(span, path, hir_vec![pat]) + } -fn pat_ok(lctx: &mut LoweringContext, span: Span, pat: P) -> P { - let ok = std_path(lctx, &["result", "Result", "Ok"]); - let path = path_global(span, ok); - pat_enum(lctx, span, path, hir_vec![pat]) -} + fn pat_err(&mut self, span: Span, pat: P) -> P { + let err = self.std_path(&["result", "Result", "Err"]); + let path = self.path_global(span, err); + self.pat_enum(span, path, hir_vec![pat]) + } -fn pat_err(lctx: &mut LoweringContext, span: Span, pat: P) -> P { - let err = std_path(lctx, &["result", "Result", "Err"]); - let path = path_global(span, err); - pat_enum(lctx, span, path, hir_vec![pat]) -} + fn pat_some(&mut self, span: Span, pat: P) -> P { + let some = self.std_path(&["option", "Option", "Some"]); + let path = self.path_global(span, some); + self.pat_enum(span, path, hir_vec![pat]) + } -fn pat_some(lctx: &mut LoweringContext, span: Span, pat: P) -> P { - let some = std_path(lctx, &["option", "Option", "Some"]); - let path = path_global(span, some); - pat_enum(lctx, span, path, hir_vec![pat]) -} + fn pat_none(&mut self, span: Span) -> P { + let none = self.std_path(&["option", "Option", "None"]); + let path = self.path_global(span, none); + self.pat_enum(span, path, hir_vec![]) + } -fn pat_none(lctx: &mut LoweringContext, span: Span) -> P { - let none = std_path(lctx, &["option", "Option", "None"]); - let path = path_global(span, none); - pat_enum(lctx, span, path, hir_vec![]) -} + fn pat_enum(&mut self, span: Span, path: hir::Path, subpats: hir::HirVec>) + -> P { + let def = self.resolver.resolve_generated_global_path(&path, true); + let pt = if subpats.is_empty() { + hir::PatKind::Path(path) + } else { + hir::PatKind::TupleStruct(path, Some(subpats)) + }; + let pat = self.pat(span, pt); + self.resolver.record_resolution(pat.id, def); + pat + } -fn pat_enum(lctx: &mut LoweringContext, - span: Span, - path: hir::Path, - subpats: hir::HirVec>) - -> P { - let def = lctx.resolver.resolve_generated_global_path(&path, true); - let pt = if subpats.is_empty() { - hir::PatKind::Path(path) - } else { - hir::PatKind::TupleStruct(path, Some(subpats)) - }; - let pat = pat(lctx, span, pt); - lctx.resolver.record_resolution(pat.id, def); - pat -} + fn pat_ident(&mut self, span: Span, ident: hir::Ident) -> P { + self.pat_ident_binding_mode(span, ident, hir::BindByValue(hir::MutImmutable)) + } -fn pat_ident(lctx: &mut LoweringContext, span: Span, ident: hir::Ident) -> P { - pat_ident_binding_mode(lctx, span, ident, hir::BindByValue(hir::MutImmutable)) -} + fn pat_ident_binding_mode(&mut self, span: Span, ident: hir::Ident, bm: hir::BindingMode) + -> P { + let pat_ident = hir::PatKind::Ident(bm, + Spanned { + span: span, + node: ident, + }, + None); -fn pat_ident_binding_mode(lctx: &mut LoweringContext, - span: Span, - ident: hir::Ident, - bm: hir::BindingMode) - -> P { - let pat_ident = hir::PatKind::Ident(bm, - Spanned { - span: span, - node: ident, - }, - None); - - let pat = pat(lctx, span, pat_ident); - - let parent_def = lctx.parent_def; - let def = lctx.resolver.definitions().map(|defs| { - let def_path_data = DefPathData::Binding(ident.name); - let def_index = defs.create_def_with_parent(parent_def, pat.id, def_path_data); - Def::Local(DefId::local(def_index), pat.id) - }).unwrap_or(Def::Err); - lctx.resolver.record_resolution(pat.id, def); - - pat -} + let pat = self.pat(span, pat_ident); -fn pat_wild(lctx: &mut LoweringContext, span: Span) -> P { - pat(lctx, span, hir::PatKind::Wild) -} + let parent_def = self.parent_def; + let def = self.resolver.definitions().map(|defs| { + let def_path_data = DefPathData::Binding(ident.name); + let def_index = defs.create_def_with_parent(parent_def, pat.id, def_path_data); + Def::Local(DefId::local(def_index), pat.id) + }).unwrap_or(Def::Err); + self.resolver.record_resolution(pat.id, def); -fn pat(lctx: &mut LoweringContext, span: Span, pat: hir::PatKind) -> P { - P(hir::Pat { - id: lctx.next_id(), - node: pat, - span: span, - }) -} + pat + } -fn path_ident(span: Span, id: hir::Ident) -> hir::Path { - path(span, vec![id]) -} + fn pat_wild(&mut self, span: Span) -> P { + self.pat(span, hir::PatKind::Wild) + } -fn path(span: Span, strs: Vec) -> hir::Path { - path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) -} + fn pat(&mut self, span: Span, pat: hir::PatKind) -> P { + P(hir::Pat { + id: self.next_id(), + node: pat, + span: span, + }) + } -fn path_global(span: Span, strs: Vec) -> hir::Path { - path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) -} + fn path_ident(&mut self, span: Span, id: hir::Ident) -> hir::Path { + self.path(span, vec![id]) + } -fn path_all(sp: Span, - global: bool, - mut idents: Vec, - lifetimes: hir::HirVec, - types: hir::HirVec>, - bindings: hir::HirVec) - -> hir::Path { - let last_identifier = idents.pop().unwrap(); - let mut segments: Vec = idents.into_iter() - .map(|ident| { - hir::PathSegment { - identifier: ident, - parameters: hir::PathParameters::none(), - } - }) - .collect(); - segments.push(hir::PathSegment { - identifier: last_identifier, - parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { - lifetimes: lifetimes, - types: types, - bindings: bindings, - }), - }); - hir::Path { - span: sp, - global: global, - segments: segments.into(), + fn path(&mut self, span: Span, strs: Vec) -> hir::Path { + self.path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) } -} -fn std_path(lctx: &mut LoweringContext, components: &[&str]) -> Vec { - let mut v = Vec::new(); - if let Some(s) = lctx.crate_root { - v.push(hir::Ident::from_name(token::intern(s))); + fn path_global(&mut self, span: Span, strs: Vec) -> hir::Path { + self.path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) } - v.extend(components.iter().map(|s| hir::Ident::from_name(token::intern(s)))); - return v; -} -// Given suffix ["b","c","d"], returns path `::std::b::c::d` when -// `fld.cx.use_std`, and `::core::b::c::d` otherwise. -fn core_path(lctx: &mut LoweringContext, span: Span, components: &[&str]) -> hir::Path { - let idents = std_path(lctx, components); - path_global(span, idents) -} + fn path_all(&mut self, + sp: Span, + global: bool, + mut idents: Vec, + lifetimes: hir::HirVec, + types: hir::HirVec>, + bindings: hir::HirVec) + -> hir::Path { + let last_identifier = idents.pop().unwrap(); + let mut segments: Vec = idents.into_iter().map(|ident| { + hir::PathSegment { + identifier: ident, + parameters: hir::PathParameters::none(), + } + }).collect(); -fn signal_block_expr(lctx: &mut LoweringContext, - stmts: hir::HirVec, - expr: P, - span: Span, - rule: hir::BlockCheckMode, - attrs: ThinAttributes) - -> P { - let id = lctx.next_id(); - expr_block(lctx, - P(hir::Block { - rules: rule, - span: span, - id: id, - stmts: stmts, - expr: Some(expr), - }), - attrs) + segments.push(hir::PathSegment { + identifier: last_identifier, + parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { + lifetimes: lifetimes, + types: types, + bindings: bindings, + }), + }); + hir::Path { + span: sp, + global: global, + segments: segments.into(), + } + } + + fn std_path(&mut self, components: &[&str]) -> Vec { + let mut v = Vec::new(); + if let Some(s) = self.crate_root { + v.push(hir::Ident::from_name(token::intern(s))); + } + v.extend(components.iter().map(|s| hir::Ident::from_name(token::intern(s)))); + return v; + } + + // Given suffix ["b","c","d"], returns path `::std::b::c::d` when + // `fld.cx.use_std`, and `::core::b::c::d` otherwise. + fn core_path(&mut self, span: Span, components: &[&str]) -> hir::Path { + let idents = self.std_path(components); + self.path_global(span, idents) + } + + fn signal_block_expr(&mut self, + stmts: hir::HirVec, + expr: P, + span: Span, + rule: hir::BlockCheckMode, + attrs: ThinAttributes) + -> P { + let id = self.next_id(); + let block = P(hir::Block { + rules: rule, + span: span, + id: id, + stmts: stmts, + expr: Some(expr), + }); + self.expr_block(block, attrs) + } } From 33978b0728640f3345479bd3fc0055a36507cf32 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Tue, 10 May 2016 05:29:13 +0000 Subject: [PATCH 08/16] Refactor `hir::lowering` API --- src/librustc/hir/lowering.rs | 35 ++++++++++++++++-------------- src/librustc_driver/driver.rs | 5 ++--- src/librustc_metadata/astencode.rs | 2 +- src/librustdoc/test.rs | 4 ++-- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0c7123a570e14..5ca99a7db67f5 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -91,30 +91,33 @@ impl Resolver for DummyResolver { } } -impl<'a> LoweringContext<'a> { - pub fn new(id_assigner: &'a NodeIdAssigner, - c: Option<&Crate>, - resolver: &'a mut Resolver) - -> LoweringContext<'a> { - let crate_root = c.and_then(|c| { - if std_inject::no_core(c) { - None - } else if std_inject::no_std(c) { - Some("core") - } else { - Some("std") - } - }); +pub fn lower_crate(krate: &Crate, id_assigner: &NodeIdAssigner, resolver: &mut Resolver) + -> hir::Crate { + LoweringContext { + crate_root: if std_inject::no_core(krate) { + None + } else if std_inject::no_std(krate) { + Some("core") + } else { + Some("std") + }, + id_assigner: id_assigner, + parent_def: None, + resolver: resolver, + }.lower_crate(krate) +} +impl<'a> LoweringContext<'a> { + pub fn testing_context(id_assigner: &'a NodeIdAssigner, resolver: &'a mut Resolver) -> Self { LoweringContext { - crate_root: crate_root, + crate_root: None, id_assigner: id_assigner, parent_def: None, resolver: resolver, } } - pub fn lower_crate(&mut self, c: &Crate) -> hir::Crate { + fn lower_crate(&mut self, c: &Crate) -> hir::Crate { struct ItemLowerer<'lcx, 'interner: 'lcx> { items: BTreeMap, lctx: &'lcx mut LoweringContext<'interner>, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 492d36cfb31a5..01e2b410c1b24 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -37,7 +37,7 @@ use rustc_typeck as typeck; use rustc_privacy; use rustc_plugin::registry::Registry; use rustc_plugin as plugin; -use rustc::hir::lowering::LoweringContext; +use rustc::hir::lowering::lower_crate; use rustc_passes::{no_asm, loops, consts, rvalues, static_recursion}; use rustc_const_eval::check_match; use super::Compilation; @@ -787,8 +787,7 @@ pub fn lower_and_resolve<'a>(sess: &Session, // Lower ast -> hir. let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || { - let krate = LoweringContext::new(sess, Some(krate), &mut resolver).lower_crate(krate); - hir_map::Forest::new(krate, dep_graph) + hir_map::Forest::new(lower_crate(krate, sess, &mut resolver), dep_graph) }); (ty::CrateAnalysis { diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 8c17ef02615fe..2a847c4c19538 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -1329,7 +1329,7 @@ fn mk_ctxt() -> parse::ParseSess { fn with_testing_context T>(f: F) -> T { let assigner = FakeNodeIdAssigner; let mut resolver = DummyResolver; - let mut lcx = LoweringContext::new(&assigner, None, &mut resolver); + let mut lcx = LoweringContext::testing_context(&assigner, &mut resolver); f(&mut lcx) } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index d4c08552edfc3..44c3ded4a115a 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -28,7 +28,7 @@ use rustc::hir::map as hir_map; use rustc::session::{self, config}; use rustc::session::config::{get_unstable_features_setting, OutputType}; use rustc::session::search_paths::{SearchPaths, PathKind}; -use rustc::hir::lowering::{LoweringContext, DummyResolver}; +use rustc::hir::lowering::{lower_crate, DummyResolver}; use rustc_back::dynamic_lib::DynamicLibrary; use rustc_back::tempdir::TempDir; use rustc_driver::{driver, Compilation}; @@ -98,7 +98,7 @@ pub fn run(input: &str, let defs = &RefCell::new(hir_map::collect_definitions(&krate)); let mut dummy_resolver = DummyResolver; - let krate = LoweringContext::new(&sess, Some(&krate), &mut dummy_resolver).lower_crate(&krate); + let krate = lower_crate(&krate, &sess, &mut dummy_resolver); let opts = scrape_test_config(&krate); From e5a91b7ba1a22e34c7d09105e7a115e696ffcd0f Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 10 May 2016 21:26:34 +0300 Subject: [PATCH 09/16] mir: don't attempt to promote Unpromotable constant temps. --- src/librustc_mir/transform/qualify_consts.rs | 24 +++++++++++++++----- src/test/run-pass/issue-33537.rs | 24 ++++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 src/test/run-pass/issue-33537.rs diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 90823528973b9..e7693d2691bfd 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -65,13 +65,18 @@ bitflags! { // pointer comparisons, ptr-to-int casts, etc. const NOT_CONST = 1 << 6, + // Refers to temporaries which cannot be promoted as + // promote_consts decided they weren't simple enough. + const NOT_PROMOTABLE = 1 << 7, + // Borrows of temporaries can be promoted only // if they have none of the above qualifications. - const UNPROMOTABLE = !0, + const NEVER_PROMOTE = !0, // Const items can only have MUTABLE_INTERIOR - // without producing an error. - const CONST_ERROR = !Qualif::MUTABLE_INTERIOR.bits + // and NOT_PROMOTABLE without producing an error. + const CONST_ERROR = !Qualif::MUTABLE_INTERIOR.bits & + !Qualif::NOT_PROMOTABLE.bits } } @@ -502,6 +507,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx> { self.add(Qualif::NOT_CONST); } Lvalue::Temp(index) => { + if !self.temp_promotion_state[index as usize].is_promotable() { + self.add(Qualif::NOT_PROMOTABLE); + } + if let Some(qualif) = self.temp_qualif[index as usize] { self.add(qualif); } else { @@ -687,8 +696,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx> { // We might have a candidate for promotion. let candidate = Candidate::Ref(self.location); if self.mode == Mode::Fn || self.mode == Mode::ConstFn { - if !self.qualif.intersects(Qualif::UNPROMOTABLE) { - self.promotion_candidates.push(candidate); + if !self.qualif.intersects(Qualif::NEVER_PROMOTE) { + // We can only promote direct borrows of temps. + if let Lvalue::Temp(_) = *lvalue { + self.promotion_candidates.push(candidate); + } } } } @@ -780,7 +792,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx> { this.visit_operand(arg); if is_shuffle && i == 2 && this.mode == Mode::Fn { let candidate = Candidate::ShuffleIndices(bb); - if !this.qualif.intersects(Qualif::UNPROMOTABLE) { + if !this.qualif.intersects(Qualif::NEVER_PROMOTE) { this.promotion_candidates.push(candidate); } else { span_err!(this.tcx.sess, this.span, E0526, diff --git a/src/test/run-pass/issue-33537.rs b/src/test/run-pass/issue-33537.rs new file mode 100644 index 0000000000000..24f4c9f590b11 --- /dev/null +++ b/src/test/run-pass/issue-33537.rs @@ -0,0 +1,24 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(const_fn)] + +const fn foo() -> *const i8 { + b"foo" as *const _ as *const i8 +} + +const fn bar() -> i32 { + *&{(1, 2, 3).1} +} + +fn main() { + assert_eq!(foo(), b"foo" as *const _ as *const i8); + assert_eq!(bar(), 2); +} From 9c2e691a98b3d3300066ad57c32930a29495a598 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 8 May 2016 12:07:50 -0700 Subject: [PATCH 10/16] Don't use env::current_exe with libbacktrace If the path we give to libbacktrace doesn't actually correspond to the current process, libbacktrace will segfault *at best*. cc #21889 --- src/libstd/sys/common/gnu/libbacktrace.rs | 49 ++++++----------------- src/test/run-pass/backtrace-debuginfo.rs | 14 ++++--- 2 files changed, 21 insertions(+), 42 deletions(-) diff --git a/src/libstd/sys/common/gnu/libbacktrace.rs b/src/libstd/sys/common/gnu/libbacktrace.rs index db719ccce61e8..b5802afc10943 100644 --- a/src/libstd/sys/common/gnu/libbacktrace.rs +++ b/src/libstd/sys/common/gnu/libbacktrace.rs @@ -15,7 +15,6 @@ use sys_common::backtrace::{output, output_fileline}; pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, symaddr: *mut libc::c_void) -> io::Result<()> { - use env; use ffi::CStr; use ptr; @@ -110,46 +109,22 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void, // that is calculated the first time this is requested. Remember that // backtracing all happens serially (one global lock). // - // An additionally oddity in this function is that we initialize the - // filename via self_exe_name() to pass to libbacktrace. It turns out - // that on Linux libbacktrace seamlessly gets the filename of the - // current executable, but this fails on freebsd. by always providing - // it, we make sure that libbacktrace never has a reason to not look up - // the symbols. The libbacktrace API also states that the filename must - // be in "permanent memory", so we copy it to a static and then use the - // static as the pointer. + // Things don't work so well on not-Linux since libbacktrace can't track + // down that executable this is. We at one point used env::current_exe but + // it turns out that there are some serious security issues with that + // approach. // - // FIXME: We also call self_exe_name() on DragonFly BSD. I haven't - // tested if this is required or not. + // Specifically, on certain platforms like BSDs, a malicious actor can cause + // an arbitrary file to be placed at the path returned by current_exe. + // libbacktrace does not behave defensively in the presence of ill-formed + // DWARF information, and has been demonstrated to segfault in at least one + // case. There is no evidence at the moment to suggest that a more carefully + // constructed file can't cause arbitrary code execution. As a result of all + // of this, we don't hint libbacktrace with the path to the current process. unsafe fn init_state() -> *mut backtrace_state { static mut STATE: *mut backtrace_state = ptr::null_mut(); - static mut LAST_FILENAME: [libc::c_char; 256] = [0; 256]; if !STATE.is_null() { return STATE } - let selfname = if cfg!(target_os = "freebsd") || - cfg!(target_os = "dragonfly") || - cfg!(target_os = "bitrig") || - cfg!(target_os = "openbsd") || - cfg!(target_os = "windows") { - env::current_exe().ok() - } else { - None - }; - let filename = match selfname.as_ref().and_then(|s| s.to_str()) { - Some(path) => { - let bytes = path.as_bytes(); - if bytes.len() < LAST_FILENAME.len() { - let i = bytes.iter(); - for (slot, val) in LAST_FILENAME.iter_mut().zip(i) { - *slot = *val as libc::c_char; - } - LAST_FILENAME.as_ptr() - } else { - ptr::null() - } - } - None => ptr::null(), - }; - STATE = backtrace_create_state(filename, 0, error_cb, + STATE = backtrace_create_state(ptr::null(), 0, error_cb, ptr::null_mut()); STATE } diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index 8b2b26948824f..f42a6ab162b70 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -32,11 +32,15 @@ macro_rules! dump_and_die { ($($pos:expr),*) => ({ // FIXME(#18285): we cannot include the current position because // the macro span takes over the last frame's file/line. - if cfg!(target_os = "macos") || - cfg!(target_os = "ios") || - cfg!(target_os = "android") || - cfg!(all(target_os = "linux", target_arch = "arm")) || - cfg!(all(windows, target_env = "gnu")) { + if cfg!(any(target_os = "macos", + target_os = "ios", + target_os = "android", + all(target_os = "linux", target_arch = "arm"), + target_os = "windows", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "bitrig", + target_os = "openbsd")) { // skip these platforms as this support isn't implemented yet. } else { dump_filelines(&[$($pos),*]); From 00f6513259c12af733d22398b1ea77cff67b7beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 10 May 2016 21:03:47 +0200 Subject: [PATCH 11/16] Only break critical edges where actually needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, to prepare for MIR trans, we break _all_ critical edges, although we only actually need to do this for edges originating from a call that gets translated to an invoke instruction in LLVM. This has the unfortunate effect of undoing a bunch of the things that SimplifyCfg has done. A particularly bad case arises when you have a C-like enum with N variants and a derived PartialEq implementation. In that case, the match on the (&lhs, &rhs) tuple gets translated into nested matches with N arms each and a basic block each, resulting in N² basic blocks. SimplifyCfg reduces that to roughly 2*N basic blocks, but breaking the critical edges means that we go back to N². In nickel.rs, there is such an enum with roughly N=800. So we get about 640K basic blocks or 2.5M lines of LLVM IR. LLVM takes a while to reduce that to the final "disr_a == disr_b". So before this patch, we had 2.5M lines of IR with 640K basic blocks, which took about about 3.6s in LLVM to get optimized and translated. After this patch, we get about 650K lines with about 1.6K basic blocks and spent a little less than 0.2s in LLVM. cc #33111 --- src/librustc_driver/driver.rs | 2 +- .../transform/break_cleanup_edges.rs | 111 +++++++++++++++++ .../transform/break_critical_edges.rs | 117 ------------------ src/librustc_mir/transform/mod.rs | 2 +- 4 files changed, 113 insertions(+), 119 deletions(-) create mode 100644 src/librustc_mir/transform/break_cleanup_edges.rs delete mode 100644 src/librustc_mir/transform/break_critical_edges.rs diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f0c2de2932775..519329a10d0a9 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1009,7 +1009,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, passes.push_pass(box mir::transform::no_landing_pads::NoLandingPads); passes.push_pass(box mir::transform::remove_dead_blocks::RemoveDeadBlocks); passes.push_pass(box mir::transform::erase_regions::EraseRegions); - passes.push_pass(box mir::transform::break_critical_edges::BreakCriticalEdges); + passes.push_pass(box mir::transform::break_cleanup_edges::BreakCleanupEdges); passes.run_passes(tcx, &mut mir_map); }); diff --git a/src/librustc_mir/transform/break_cleanup_edges.rs b/src/librustc_mir/transform/break_cleanup_edges.rs new file mode 100644 index 0000000000000..0eb6223a71e54 --- /dev/null +++ b/src/librustc_mir/transform/break_cleanup_edges.rs @@ -0,0 +1,111 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use rustc::ty::TyCtxt; +use rustc::mir::repr::*; +use rustc::mir::transform::{MirPass, MirSource, Pass}; + +use rustc_data_structures::bitvec::BitVector; + +use pretty; + +use traversal; + +pub struct BreakCleanupEdges; + +/** + * Breaks outgoing critical edges for call terminators in the MIR. + * + * Critical edges are edges that are neither the only edge leaving a + * block, nor the only edge entering one. + * + * When you want something to happen "along" an edge, you can either + * do at the end of the predecessor block, or at the start of the + * successor block. Critical edges have to be broken in order to prevent + * "edge actions" from affecting other edges. We need this for calls that are + * translated to LLVM invoke instructions, because invoke is a block terminator + * in LLVM so we can't insert any code to handle the call's result into the + * block that performs the call. + * + * This function will break those edges by inserting new blocks along them. + * + * NOTE: Simplify CFG will happily undo most of the work this pass does. + * + */ + +impl<'tcx> MirPass<'tcx> for BreakCleanupEdges { + fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { + let mut pred_count = vec![0u32; mir.basic_blocks.len()]; + + // Build the precedecessor map for the MIR + for (_, data) in traversal::preorder(mir) { + if let Some(ref term) = data.terminator { + for &tgt in term.successors().iter() { + pred_count[tgt.index()] += 1; + } + } + } + + let cleanup_map : BitVector = mir.basic_blocks + .iter().map(|bb| bb.is_cleanup).collect(); + + // We need a place to store the new blocks generated + let mut new_blocks = Vec::new(); + + let bbs = mir.all_basic_blocks(); + let cur_len = mir.basic_blocks.len(); + + for &bb in &bbs { + let data = mir.basic_block_data_mut(bb); + + if let Some(ref mut term) = data.terminator { + if term_is_invoke(term) { + let term_span = term.span; + let term_scope = term.scope; + let succs = term.successors_mut(); + for tgt in succs { + let num_preds = pred_count[tgt.index()]; + if num_preds > 1 { + // It's a critical edge, break it + let goto = Terminator { + span: term_span, + scope: term_scope, + kind: TerminatorKind::Goto { target: *tgt } + }; + let mut data = BasicBlockData::new(Some(goto)); + data.is_cleanup = cleanup_map.contains(tgt.index()); + + // Get the index it will be when inserted into the MIR + let idx = cur_len + new_blocks.len(); + new_blocks.push(data); + *tgt = BasicBlock::new(idx); + } + } + } + } + } + + pretty::dump_mir(tcx, "break_cleanup_edges", &0, src, mir, None); + debug!("Broke {} N edges", new_blocks.len()); + + mir.basic_blocks.extend_from_slice(&new_blocks); + } +} + +impl Pass for BreakCleanupEdges {} + +// Returns true if the terminator is a call that would use an invoke in LLVM. +fn term_is_invoke(term: &Terminator) -> bool { + match term.kind { + TerminatorKind::Call { cleanup: Some(_), .. } | + TerminatorKind::Drop { unwind: Some(_), .. } => true, + _ => false + } +} diff --git a/src/librustc_mir/transform/break_critical_edges.rs b/src/librustc_mir/transform/break_critical_edges.rs deleted file mode 100644 index a6af30b7eec08..0000000000000 --- a/src/librustc_mir/transform/break_critical_edges.rs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2016 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use rustc::ty::TyCtxt; -use rustc::mir::repr::*; -use rustc::mir::transform::{MirPass, MirSource, Pass}; - -use rustc_data_structures::bitvec::BitVector; - -use traversal; - -pub struct BreakCriticalEdges; - -/** - * Breaks critical edges in the MIR. - * - * Critical edges are edges that are neither the only edge leaving a - * block, nor the only edge entering one. - * - * When you want something to happen "along" an edge, you can either - * do at the end of the predecessor block, or at the start of the - * successor block. Critical edges have to be broken in order to prevent - * "edge actions" from affecting other edges. - * - * This function will break those edges by inserting new blocks along them. - * - * A special case is Drop and Call terminators with unwind/cleanup successors, - * They use `invoke` in LLVM, which terminates a block, meaning that code cannot - * be inserted after them, so even if an edge is the only edge leaving a block - * like that, we still insert blocks if the edge is one of many entering the - * target. - * - * NOTE: Simplify CFG will happily undo most of the work this pass does. - * - */ - -impl<'tcx> MirPass<'tcx> for BreakCriticalEdges { - fn run_pass<'a>(&mut self, _: TyCtxt<'a, 'tcx, 'tcx>, - _: MirSource, mir: &mut Mir<'tcx>) { - break_critical_edges(mir); - } -} - -impl Pass for BreakCriticalEdges {} - -fn break_critical_edges(mir: &mut Mir) { - let mut pred_count = vec![0u32; mir.basic_blocks.len()]; - - // Build the precedecessor map for the MIR - for (_, data) in traversal::preorder(mir) { - if let Some(ref term) = data.terminator { - for &tgt in term.successors().iter() { - pred_count[tgt.index()] += 1; - } - } - } - - let cleanup_map : BitVector = mir.basic_blocks - .iter().map(|bb| bb.is_cleanup).collect(); - - // We need a place to store the new blocks generated - let mut new_blocks = Vec::new(); - - let bbs = mir.all_basic_blocks(); - let cur_len = mir.basic_blocks.len(); - - for &bb in &bbs { - let data = mir.basic_block_data_mut(bb); - - if let Some(ref mut term) = data.terminator { - let is_invoke = term_is_invoke(term); - let term_span = term.span; - let term_scope = term.scope; - let succs = term.successors_mut(); - if succs.len() > 1 || (succs.len() > 0 && is_invoke) { - for tgt in succs { - let num_preds = pred_count[tgt.index()]; - if num_preds > 1 { - // It's a critical edge, break it - let goto = Terminator { - span: term_span, - scope: term_scope, - kind: TerminatorKind::Goto { target: *tgt } - }; - let mut data = BasicBlockData::new(Some(goto)); - data.is_cleanup = cleanup_map.contains(tgt.index()); - - // Get the index it will be when inserted into the MIR - let idx = cur_len + new_blocks.len(); - new_blocks.push(data); - *tgt = BasicBlock::new(idx); - } - } - } - } - } - - debug!("Broke {} N edges", new_blocks.len()); - - mir.basic_blocks.extend_from_slice(&new_blocks); -} - -// Returns true if the terminator would use an invoke in LLVM. -fn term_is_invoke(term: &Terminator) -> bool { - match term.kind { - TerminatorKind::Call { cleanup: Some(_), .. } | - TerminatorKind::Drop { unwind: Some(_), .. } => true, - _ => false - } -} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 51f5c3cd7f53d..0dcb7ef84d01d 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -13,6 +13,6 @@ pub mod simplify_cfg; pub mod erase_regions; pub mod no_landing_pads; pub mod type_check; -pub mod break_critical_edges; +pub mod break_cleanup_edges; pub mod promote_consts; pub mod qualify_consts; From 1ebb07ee24ad70117e46a9e5f446c3964aa25dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 14 Nov 2015 23:52:17 +0100 Subject: [PATCH 12/16] [MIR] Enhance the SimplifyCfg pass to merge consecutive blocks --- src/librustc_mir/transform/mod.rs | 1 + src/librustc_mir/transform/predecessor_map.rs | 68 +++++++ src/librustc_mir/transform/simplify_cfg.rs | 178 ++++++++++++------ 3 files changed, 188 insertions(+), 59 deletions(-) create mode 100644 src/librustc_mir/transform/predecessor_map.rs diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 51f5c3cd7f53d..cfa265918e727 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -12,6 +12,7 @@ pub mod remove_dead_blocks; pub mod simplify_cfg; pub mod erase_regions; pub mod no_landing_pads; +pub mod predecessor_map; pub mod type_check; pub mod break_critical_edges; pub mod promote_consts; diff --git a/src/librustc_mir/transform/predecessor_map.rs b/src/librustc_mir/transform/predecessor_map.rs new file mode 100644 index 0000000000000..cda75946095b4 --- /dev/null +++ b/src/librustc_mir/transform/predecessor_map.rs @@ -0,0 +1,68 @@ +// Copyright 2016 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use rustc::mir::repr::*; +use rustc::mir::visit::Visitor; + +// A simple map to perform quick lookups of the predecessors of a BasicBlock. +// Since BasicBlocks usually only have a small number of predecessors, we use a +// simple vector. Also, if a block has the same target more than once, for +// example in a switch, it will appear in the target's predecessor list multiple +// times. This allows to update the map more easily when modifying the graph. +pub struct PredecessorMap { + map: Vec>, +} + +impl PredecessorMap { + pub fn from_mir(mir: &Mir) -> PredecessorMap { + let mut map = PredecessorMap { + map: vec![Vec::new(); mir.basic_blocks.len()], + }; + + PredecessorVisitor { predecessor_map: &mut map }.visit_mir(mir); + + map + } + + pub fn predecessors(&self, block: BasicBlock) -> &[BasicBlock] { + &self.map[block.index()] + } + + pub fn add_predecessor(&mut self, block: BasicBlock, predecessor: BasicBlock) { + self.map[block.index()].push(predecessor); + } + + pub fn remove_predecessor(&mut self, block: BasicBlock, predecessor: BasicBlock) { + let pos = self.map[block.index()].iter().position(|&p| p == predecessor).expect( + &format!("{:?} is not registered as a predecessor of {:?}", predecessor, block)); + + self.map[block.index()].swap_remove(pos); + } + + pub fn replace_predecessor(&mut self, block: BasicBlock, old: BasicBlock, new: BasicBlock) { + self.remove_predecessor(block, old); + self.add_predecessor(block, new); + } + + pub fn replace_successor(&mut self, block: BasicBlock, old: BasicBlock, new: BasicBlock) { + self.remove_predecessor(old, block); + self.add_predecessor(new, block); + } +} + +struct PredecessorVisitor<'a> { + predecessor_map: &'a mut PredecessorMap, +} + +impl<'a, 'tcx> Visitor<'tcx> for PredecessorVisitor<'a> { + fn visit_branch(&mut self, source: BasicBlock, target: BasicBlock) { + self.predecessor_map.add_predecessor(target, source); + } +} diff --git a/src/librustc_mir/transform/simplify_cfg.rs b/src/librustc_mir/transform/simplify_cfg.rs index fa897384a542a..bb17bb006538f 100644 --- a/src/librustc_mir/transform/simplify_cfg.rs +++ b/src/librustc_mir/transform/simplify_cfg.rs @@ -8,12 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use rustc_data_structures::bitvec::BitVector; use rustc::middle::const_val::ConstVal; use rustc::ty::TyCtxt; use rustc::mir::repr::*; use rustc::mir::transform::{MirPass, MirSource, Pass}; use pretty; +use std::mem; +use super::predecessor_map::PredecessorMap; use super::remove_dead_blocks::RemoveDeadBlocks; pub struct SimplifyCfg; @@ -22,59 +25,133 @@ impl SimplifyCfg { pub fn new() -> SimplifyCfg { SimplifyCfg } +} + +impl<'tcx> MirPass<'tcx> for SimplifyCfg { + fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) { + simplify_branches(mir); + RemoveDeadBlocks.run_pass(tcx, src, mir); + merge_consecutive_blocks(mir); + RemoveDeadBlocks.run_pass(tcx, src, mir); + pretty::dump_mir(tcx, "simplify_cfg", &0, src, mir, None); - fn remove_goto_chains(&self, mir: &mut Mir) -> bool { - // Find the target at the end of the jump chain, return None if there is a loop - fn final_target(mir: &Mir, mut target: BasicBlock) -> Option { - // Keep track of already seen blocks to detect loops - let mut seen: Vec = Vec::with_capacity(8); - - while mir.basic_block_data(target).statements.is_empty() { - // NB -- terminator may have been swapped with `None` - // below, in which case we have a cycle and just want - // to stop - if let Some(ref terminator) = mir.basic_block_data(target).terminator { - match terminator.kind { - TerminatorKind::Goto { target: next } => { - if seen.contains(&next) { - return None; + // FIXME: Should probably be moved into some kind of pass manager + mir.basic_blocks.shrink_to_fit(); + } +} + +impl Pass for SimplifyCfg {} + +fn merge_consecutive_blocks(mir: &mut Mir) { + let mut predecessor_map = PredecessorMap::from_mir(mir); + + loop { + let mut changed = false; + let mut seen = BitVector::new(mir.basic_blocks.len()); + let mut worklist = vec![START_BLOCK]; + while let Some(bb) = worklist.pop() { + // Temporarily take ownership of the terminator we're modifying to keep borrowck happy + let mut terminator = mir.basic_block_data_mut(bb).terminator.take() + .expect("invalid terminator state"); + + // See if we can merge the target block into this one + loop { + let mut inner_change = false; + + if let TerminatorKind::Goto { target } = terminator.kind { + // Don't bother trying to merge a block into itself + if target == bb { + break; + } + + let num_preds = predecessor_map.predecessors(target).len(); + let num_insts = mir.basic_block_data(target).statements.len(); + match mir.basic_block_data(target).terminator().kind { + _ if num_preds == 1 => { + inner_change = true; + let mut stmts = Vec::new(); + { + let target_data = mir.basic_block_data_mut(target); + mem::swap(&mut stmts, &mut target_data.statements); + mem::swap(&mut terminator, target_data.terminator_mut()); + } + + mir.basic_block_data_mut(bb).statements.append(&mut stmts); + + predecessor_map.replace_predecessor(target, bb, target); + for succ in terminator.successors().iter() { + predecessor_map.replace_predecessor(*succ, target, bb); } - seen.push(next); - target = next; } - _ => break + TerminatorKind::Goto { target: new_target } if num_insts == 0 => { + inner_change = true; + terminator.kind = TerminatorKind::Goto { target: new_target }; + predecessor_map.replace_successor(bb, target, new_target); + } + _ => {} + }; + } + + for target in terminator.successors_mut() { + let new_target = match final_target(mir, *target) { + Some(new_target) => new_target, + None if mir.basic_block_data(bb).statements.is_empty() => bb, + None => continue + }; + if *target != new_target { + inner_change = true; + predecessor_map.replace_successor(bb, *target, new_target); + *target = new_target; } - } else { - break + } + + changed |= inner_change; + if !inner_change { + break; } } - Some(target) + mir.basic_block_data_mut(bb).terminator = Some(terminator); + + for succ in mir.basic_block_data(bb).terminator().successors().iter() { + if seen.insert(succ.index()) { + worklist.push(*succ); + } + } } - let mut changed = false; - for bb in mir.all_basic_blocks() { - // Temporarily take ownership of the terminator we're modifying to keep borrowck happy - let mut terminator = mir.basic_block_data_mut(bb).terminator.take() - .expect("invalid terminator state"); - - debug!("remove_goto_chains: bb={:?} terminator={:?}", bb, terminator); - - for target in terminator.successors_mut() { - let new_target = match final_target(mir, *target) { - Some(new_target) => new_target, - None if mir.basic_block_data(bb).statements.is_empty() => bb, - None => continue - }; - changed |= *target != new_target; - *target = new_target; + if !changed { + break; + } + } +} + +// Find the target at the end of the jump chain, return None if there is a loop +fn final_target(mir: &Mir, mut target: BasicBlock) -> Option { + // Keep track of already seen blocks to detect loops + let mut seen: Vec = Vec::with_capacity(8); + + while mir.basic_block_data(target).statements.is_empty() { + // NB -- terminator may have been swapped with `None` in + // merge_consecutive_blocks, in which case we have a cycle and just want + // to stop + match mir.basic_block_data(target).terminator { + Some(Terminator { kind: TerminatorKind::Goto { target: next }, .. }) => { + if seen.contains(&next) { + return None; + } + seen.push(next); + target = next; } - mir.basic_block_data_mut(bb).terminator = Some(terminator); + _ => break } - changed } - fn simplify_branches(&self, mir: &mut Mir) -> bool { + Some(target) +} + +fn simplify_branches(mir: &mut Mir) { + loop { let mut changed = false; for bb in mir.all_basic_blocks() { @@ -106,25 +183,8 @@ impl SimplifyCfg { } } - changed - } -} - -impl<'tcx> MirPass<'tcx> for SimplifyCfg { - fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - src: MirSource, mir: &mut Mir<'tcx>) { - let mut counter = 0; - let mut changed = true; - while changed { - pretty::dump_mir(tcx, "simplify_cfg", &counter, src, mir, None); - counter += 1; - changed = self.simplify_branches(mir); - changed |= self.remove_goto_chains(mir); - RemoveDeadBlocks.run_pass(tcx, src, mir); + if !changed { + break; } - // FIXME: Should probably be moved into some kind of pass manager - mir.basic_blocks.shrink_to_fit(); } } - -impl Pass for SimplifyCfg {} From 5541fdfcd1b94294fcd7d356c2948bb272d20b9f Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 11 May 2016 20:09:50 +0300 Subject: [PATCH 13/16] Use symlink_metadata in tidy to avoid panicking on broken symlinks. --- src/tools/tidy/src/bins.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index 43475f203d57c..e91b8fb0967a8 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -35,7 +35,7 @@ pub fn check(path: &Path, bad: &mut bool) { return } - let metadata = t!(fs::metadata(&file), &file); + let metadata = t!(fs::symlink_metadata(&file), &file); if metadata.mode() & 0o111 != 0 { println!("binary checked into source: {}", file.display()); *bad = true; From 4e5a2e01cf7fd13dccac12deaf7868f3855e54c5 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Tue, 10 May 2016 23:25:34 -0700 Subject: [PATCH 14/16] Remove unification despite ambiguity in projection --- src/librustc/traits/project.rs | 58 +--------------------------------- 1 file changed, 1 insertion(+), 57 deletions(-) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 4c338219ffbf7..a67188713c628 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -218,10 +218,7 @@ fn project_and_unify_type<'cx, 'gcx, 'tcx>( obligation.cause.clone(), obligation.recursion_depth) { Some(n) => n, - None => { - consider_unification_despite_ambiguity(selcx, obligation); - return Ok(None); - } + None => return Ok(None), }; debug!("project_and_unify_type: normalized_ty={:?} obligations={:?}", @@ -240,59 +237,6 @@ fn project_and_unify_type<'cx, 'gcx, 'tcx>( } } -fn consider_unification_despite_ambiguity<'cx, 'gcx, 'tcx>( - selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, - obligation: &ProjectionObligation<'tcx>) -{ - debug!("consider_unification_despite_ambiguity(obligation={:?})", - obligation); - - let def_id = obligation.predicate.projection_ty.trait_ref.def_id; - match selcx.tcx().lang_items.fn_trait_kind(def_id) { - Some(_) => { } - None => { return; } - } - - let infcx = selcx.infcx(); - let self_ty = obligation.predicate.projection_ty.trait_ref.self_ty(); - let self_ty = infcx.shallow_resolve(self_ty); - debug!("consider_unification_despite_ambiguity: self_ty.sty={:?}", - self_ty.sty); - match self_ty.sty { - ty::TyClosure(closure_def_id, substs) => { - let closure_typer = selcx.closure_typer(); - let closure_type = closure_typer.closure_type(closure_def_id, substs); - let ty::Binder((_, ret_type)) = - infcx.tcx.closure_trait_ref_and_return_type(def_id, - self_ty, - &closure_type.sig, - util::TupleArgumentsFlag::No); - // We don't have to normalize the return type here - this is only - // reached for TyClosure: Fn inputs where the closure kind is - // still unknown, which should only occur in typeck where the - // closure type is already normalized. - let (ret_type, _) = - infcx.replace_late_bound_regions_with_fresh_var( - obligation.cause.span, - infer::AssocTypeProjection(obligation.predicate.projection_ty.item_name), - &ty::Binder(ret_type)); - - debug!("consider_unification_despite_ambiguity: ret_type={:?}", - ret_type); - let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span); - let obligation_ty = obligation.predicate.ty; - match infcx.eq_types(true, origin, obligation_ty, ret_type) { - Ok(InferOk { obligations, .. }) => { - // FIXME(#32730) propagate obligations - assert!(obligations.is_empty()); - } - Err(_) => { /* ignore errors */ } - } - } - _ => { } - } -} - /// Normalizes any associated type projections in `value`, replacing /// them with a fully resolved type where possible. The return value /// combines the normalized result and any additional obligations that From c91b1048847663fabf99cd48dd1d9bb1644bcd77 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 11 May 2016 20:30:20 +0100 Subject: [PATCH 15/16] Export OnceState from libstd --- src/libstd/sync/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs index c20b422d40cf5..21008ee3989a7 100644 --- a/src/libstd/sync/mod.rs +++ b/src/libstd/sync/mod.rs @@ -31,7 +31,7 @@ pub use self::mutex::MUTEX_INIT; #[stable(feature = "rust1", since = "1.0.0")] pub use self::mutex::{Mutex, MutexGuard, StaticMutex}; #[stable(feature = "rust1", since = "1.0.0")] -pub use self::once::{Once, ONCE_INIT}; +pub use self::once::{Once, OnceState, ONCE_INIT}; #[stable(feature = "rust1", since = "1.0.0")] pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResult}; #[stable(feature = "rust1", since = "1.0.0")] From 49b2cdf47c983d5ea8a576346d08120f0e3af30a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Wed, 11 May 2016 21:31:19 +0200 Subject: [PATCH 16/16] [MIR trans] Optimize trans for biased switches Currently, all switches in MIR are exhausitive, meaning that we can have a lot of arms that all go to the same basic block, the extreme case being an if-let expression which results in just 2 possible cases, be might end up with hundreds of arms for large enums. To improve this situation and give LLVM less code to chew on, we can detect whether there's a pre-dominant target basic block in a switch and then promote this to be the default target, not translating the corresponding arms at all. In combination with #33544 this makes unoptimized MIR trans of nickel.rs as fast as using old trans and greatly improves the times for optimized builds, which are only 30-40% slower instead of ~300%. cc #33111 --- src/librustc_trans/mir/block.rs | 36 ++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index e1318396e317d..4e3386bc73677 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -24,6 +24,7 @@ use meth; use type_of; use glue; use type_::Type; +use rustc_data_structures::fnv::FnvHashMap; use super::{MirContext, TempRef, drop}; use super::constant::Const; @@ -95,17 +96,32 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { adt::trans_get_discr(bcx, &repr, discr_lvalue.llval, None, true) ); - // The else branch of the Switch can't be hit, so branch to an unreachable - // instruction so LLVM knows that - let unreachable_blk = self.unreachable_block(); - let switch = bcx.switch(discr, unreachable_blk.llbb, targets.len()); + let mut bb_hist = FnvHashMap(); + for target in targets { + *bb_hist.entry(target).or_insert(0) += 1; + } + let (default_bb, default_blk) = match bb_hist.iter().max_by_key(|&(_, c)| c) { + // If a single target basic blocks is predominant, promote that to be the + // default case for the switch instruction to reduce the size of the generated + // code. This is especially helpful in cases like an if-let on a huge enum. + // Note: This optimization is only valid for exhaustive matches. + Some((&&bb, &c)) if c > targets.len() / 2 => { + (Some(bb), self.blocks[bb.index()]) + } + // We're generating an exhaustive switch, so the else branch + // can't be hit. Branching to an unreachable instruction + // lets LLVM know this + _ => (None, self.unreachable_block()) + }; + let switch = bcx.switch(discr, default_blk.llbb, targets.len()); assert_eq!(adt_def.variants.len(), targets.len()); - for (adt_variant, target) in adt_def.variants.iter().zip(targets) { - let llval = bcx.with_block(|bcx| - adt::trans_case(bcx, &repr, Disr::from(adt_variant.disr_val)) - ); - let llbb = self.llblock(*target); - build::AddCase(switch, llval, llbb) + for (adt_variant, &target) in adt_def.variants.iter().zip(targets) { + if default_bb != Some(target) { + let llbb = self.llblock(target); + let llval = bcx.with_block(|bcx| adt::trans_case( + bcx, &repr, Disr::from(adt_variant.disr_val))); + build::AddCase(switch, llval, llbb) + } } }