1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // Lowers the AST to the HIR.
13 // Since the AST and HIR are fairly similar, this is mostly a simple procedure,
14 // much like a fold. Where lowering involves a bit more work things get more
15 // interesting and there are some invariants you should know about. These mostly
16 // concern spans and ids.
18 // Spans are assigned to AST nodes during parsing and then are modified during
19 // expansion to indicate the origin of a node and the process it went through
20 // being expanded. Ids are assigned to AST nodes just before lowering.
22 // For the simpler lowering steps, ids and spans should be preserved. Unlike
23 // expansion we do not preserve the process of lowering in the spans, so spans
24 // should not be modified here. When creating a new node (as opposed to
25 // 'folding' an existing one), then you create a new id using `next_id()`.
27 // You must ensure that ids are unique. That means that you should only use the
28 // id from an AST node in a single HIR node (you can assume that AST node ids
29 // are unique). Every new node must have a unique id. Avoid cloning HIR nodes.
30 // If you do, you must then set the new node's id to a fresh one.
32 // Spans are used for error messages and for tools to map semantics back to
33 // source code. It is therefore not as important with spans as ids to be strict
34 // about use (you can't break the compiler by screwing up a span). Obviously, a
35 // HIR node can only have a single span. But multiple nodes can have the same
36 // span and spans don't need to be kept in order, etc. Where code is preserved
37 // by lowering, it should have the same span as in the AST. Where HIR nodes are
38 // new it is probably best to give a span for the whole AST node being lowered.
39 // All nodes should have real spans, don't use dummy spans. Tools are likely to
40 // get confused if the spans from leaf AST nodes occur in multiple places
41 // in the HIR, especially for multiple identifiers.
44 use hir::map::Definitions;
45 use hir::map::definitions::DefPathData;
46 use hir::def_id::{DefIndex, DefId};
47 use hir::def::{Def, PathResolution};
50 use std::collections::BTreeMap;
55 use syntax::codemap::{respan, Spanned};
56 use syntax::parse::token;
57 use syntax::std_inject;
58 use syntax::visit::{self, Visitor};
61 pub struct LoweringContext<'a> {
62 crate_root: Option<&'static str>,
63 // Use to assign ids to hir nodes that do not directly correspond to an ast node
64 sess: Option<&'a Session>,
65 // As we walk the AST we must keep track of the current 'parent' def id (in
66 // the form of a DefIndex) so that if we create a new node which introduces
67 // a definition, then we can properly create the def id.
68 parent_def: Option<DefIndex>,
69 resolver: &'a mut Resolver,
73 // Resolve a global hir path generated by the lowerer when expanding `for`, `if let`, etc.
74 fn resolve_generated_global_path(&mut self, path: &hir::Path, is_value: bool) -> Def;
76 // Obtain the resolution for a node id
77 fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
79 // Record the resolution of a path or binding generated by the lowerer when expanding.
80 fn record_resolution(&mut self, id: NodeId, def: Def);
82 // We must keep the set of definitions up to date as we add nodes that weren't in the AST.
83 // This should only return `None` during testing.
84 fn definitions(&mut self) -> Option<&mut Definitions>;
87 pub struct DummyResolver;
88 impl Resolver for DummyResolver {
89 fn resolve_generated_global_path(&mut self, _path: &hir::Path, _is_value: bool) -> Def {
92 fn get_resolution(&mut self, _id: NodeId) -> Option<PathResolution> {
95 fn record_resolution(&mut self, _id: NodeId, _def: Def) {}
96 fn definitions(&mut self) -> Option<&mut Definitions> {
101 pub fn lower_crate(sess: &Session,
103 resolver: &mut Resolver)
105 // We're constructing the HIR here; we don't care what we will
106 // read, since we haven't even constructed the *input* to
108 let _ignore = sess.dep_graph.in_ignore();
111 crate_root: if std_inject::no_core(krate) {
113 } else if std_inject::no_std(krate) {
124 impl<'a> LoweringContext<'a> {
125 pub fn testing_context(resolver: &'a mut Resolver) -> Self {
134 fn lower_crate(&mut self, c: &Crate) -> hir::Crate {
135 struct ItemLowerer<'lcx, 'interner: 'lcx> {
136 items: BTreeMap<NodeId, hir::Item>,
137 lctx: &'lcx mut LoweringContext<'interner>,
140 impl<'lcx, 'interner> Visitor for ItemLowerer<'lcx, 'interner> {
141 fn visit_item(&mut self, item: &Item) {
142 self.items.insert(item.id, self.lctx.lower_item(item));
143 visit::walk_item(self, item);
148 let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: self };
149 visit::walk_crate(&mut item_lowerer, c);
154 module: self.lower_mod(&c.module),
155 attrs: self.lower_attrs(&c.attrs),
156 config: c.config.clone().into(),
158 exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(),
163 fn next_id(&self) -> NodeId {
164 self.sess.map(Session::next_node_id).unwrap_or(0)
167 fn diagnostic(&self) -> &errors::Handler {
168 self.sess.map(Session::diagnostic)
169 .unwrap_or_else(|| panic!("this lowerer cannot emit diagnostics"))
172 fn str_to_ident(&self, s: &'static str) -> Name {
176 fn with_parent_def<T, F>(&mut self, parent_id: NodeId, f: F) -> T
177 where F: FnOnce(&mut LoweringContext) -> T
179 let old_def = self.parent_def;
180 self.parent_def = match self.resolver.definitions() {
181 Some(defs) => Some(defs.opt_def_index(parent_id).unwrap()),
185 let result = f(self);
187 self.parent_def = old_def;
191 fn lower_opt_sp_ident(&mut self, o_id: Option<Spanned<Ident>>) -> Option<Spanned<Name>> {
192 o_id.map(|sp_ident| respan(sp_ident.span, sp_ident.node.name))
195 fn lower_attrs(&mut self, attrs: &Vec<Attribute>) -> hir::HirVec<Attribute> {
199 fn lower_view_path(&mut self, view_path: &ViewPath) -> P<hir::ViewPath> {
201 node: match view_path.node {
202 ViewPathSimple(ident, ref path) => {
203 hir::ViewPathSimple(ident.name, self.lower_path(path))
205 ViewPathGlob(ref path) => {
206 hir::ViewPathGlob(self.lower_path(path))
208 ViewPathList(ref path, ref path_list_idents) => {
209 hir::ViewPathList(self.lower_path(path),
210 path_list_idents.iter()
211 .map(|item| self.lower_path_list_item(item))
215 span: view_path.span,
219 fn lower_path_list_item(&mut self, path_list_ident: &PathListItem) -> hir::PathListItem {
221 node: match path_list_ident.node {
222 PathListItemKind::Ident { id, name, rename } => hir::PathListIdent {
225 rename: rename.map(|x| x.name),
227 PathListItemKind::Mod { id, rename } => hir::PathListMod {
229 rename: rename.map(|x| x.name),
232 span: path_list_ident.span,
236 fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
238 attrs: self.lower_attrs(&arm.attrs),
239 pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
240 guard: arm.guard.as_ref().map(|ref x| self.lower_expr(x)),
241 body: self.lower_expr(&arm.body),
245 fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
249 ty: self.lower_ty(&b.ty),
254 fn lower_ty(&mut self, t: &Ty) -> P<hir::Ty> {
255 use syntax::ast::TyKind::*;
259 Infer | ImplicitSelf => hir::TyInfer,
260 Vec(ref ty) => hir::TyVec(self.lower_ty(ty)),
261 Ptr(ref mt) => hir::TyPtr(self.lower_mt(mt)),
262 Rptr(ref region, ref mt) => {
263 hir::TyRptr(self.lower_opt_lifetime(region), self.lower_mt(mt))
266 hir::TyBareFn(P(hir::BareFnTy {
267 lifetimes: self.lower_lifetime_defs(&f.lifetimes),
268 unsafety: self.lower_unsafety(f.unsafety),
270 decl: self.lower_fn_decl(&f.decl),
273 Never => hir::TyNever,
274 Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty)).collect()),
276 return self.lower_ty(ty);
278 Path(ref qself, ref path) => {
279 let qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
281 ty: self.lower_ty(ty),
285 hir::TyPath(qself, self.lower_path(path))
287 ObjectSum(ref ty, ref bounds) => {
288 hir::TyObjectSum(self.lower_ty(ty), self.lower_bounds(bounds))
290 FixedLengthVec(ref ty, ref e) => {
291 hir::TyFixedLengthVec(self.lower_ty(ty), self.lower_expr(e))
293 Typeof(ref expr) => {
294 hir::TyTypeof(self.lower_expr(expr))
296 PolyTraitRef(ref bounds) => {
297 hir::TyPolyTraitRef(self.lower_bounds(bounds))
299 ImplTrait(ref bounds) => {
300 hir::TyImplTrait(self.lower_bounds(bounds))
302 Mac(_) => panic!("TyMac should have been expanded by now."),
308 fn lower_foreign_mod(&mut self, fm: &ForeignMod) -> hir::ForeignMod {
311 items: fm.items.iter().map(|x| self.lower_foreign_item(x)).collect(),
315 fn lower_variant(&mut self, v: &Variant) -> hir::Variant {
317 node: hir::Variant_ {
318 name: v.node.name.name,
319 attrs: self.lower_attrs(&v.node.attrs),
320 data: self.lower_variant_data(&v.node.data),
321 disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_expr(e)),
327 fn lower_path(&mut self, p: &Path) -> hir::Path {
332 .map(|&PathSegment { identifier, ref parameters }| {
334 name: identifier.name,
335 parameters: self.lower_path_parameters(parameters),
343 fn lower_path_parameters(&mut self, path_parameters: &PathParameters) -> hir::PathParameters {
344 match *path_parameters {
345 PathParameters::AngleBracketed(ref data) =>
346 hir::AngleBracketedParameters(self.lower_angle_bracketed_parameter_data(data)),
347 PathParameters::Parenthesized(ref data) =>
348 hir::ParenthesizedParameters(self.lower_parenthesized_parameter_data(data)),
352 fn lower_angle_bracketed_parameter_data(&mut self,
353 data: &AngleBracketedParameterData)
354 -> hir::AngleBracketedParameterData {
355 let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data;
356 hir::AngleBracketedParameterData {
357 lifetimes: self.lower_lifetimes(lifetimes),
358 types: types.iter().map(|ty| self.lower_ty(ty)).collect(),
359 bindings: bindings.iter().map(|b| self.lower_ty_binding(b)).collect(),
363 fn lower_parenthesized_parameter_data(&mut self,
364 data: &ParenthesizedParameterData)
365 -> hir::ParenthesizedParameterData {
366 let &ParenthesizedParameterData { ref inputs, ref output, span } = data;
367 hir::ParenthesizedParameterData {
368 inputs: inputs.iter().map(|ty| self.lower_ty(ty)).collect(),
369 output: output.as_ref().map(|ty| self.lower_ty(ty)),
374 fn lower_local(&mut self, l: &Local) -> P<hir::Local> {
377 ty: l.ty.as_ref().map(|t| self.lower_ty(t)),
378 pat: self.lower_pat(&l.pat),
379 init: l.init.as_ref().map(|e| self.lower_expr(e)),
381 attrs: l.attrs.clone(),
385 fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
387 Mutability::Mutable => hir::MutMutable,
388 Mutability::Immutable => hir::MutImmutable,
392 fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
395 pat: self.lower_pat(&arg.pat),
396 ty: self.lower_ty(&arg.ty),
400 fn lower_fn_decl(&mut self, decl: &FnDecl) -> P<hir::FnDecl> {
402 inputs: decl.inputs.iter().map(|x| self.lower_arg(x)).collect(),
403 output: match decl.output {
404 FunctionRetTy::Ty(ref ty) => hir::Return(self.lower_ty(ty)),
405 FunctionRetTy::Default(span) => hir::DefaultReturn(span),
407 variadic: decl.variadic,
411 fn lower_ty_param_bound(&mut self, tpb: &TyParamBound) -> hir::TyParamBound {
413 TraitTyParamBound(ref ty, modifier) => {
414 hir::TraitTyParamBound(self.lower_poly_trait_ref(ty),
415 self.lower_trait_bound_modifier(modifier))
417 RegionTyParamBound(ref lifetime) => {
418 hir::RegionTyParamBound(self.lower_lifetime(lifetime))
423 fn lower_ty_param(&mut self, tp: &TyParam) -> hir::TyParam {
427 bounds: self.lower_bounds(&tp.bounds),
428 default: tp.default.as_ref().map(|x| self.lower_ty(x)),
433 fn lower_ty_params(&mut self, tps: &P<[TyParam]>) -> hir::HirVec<hir::TyParam> {
434 tps.iter().map(|tp| self.lower_ty_param(tp)).collect()
437 fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
445 fn lower_lifetime_def(&mut self, l: &LifetimeDef) -> hir::LifetimeDef {
447 lifetime: self.lower_lifetime(&l.lifetime),
448 bounds: self.lower_lifetimes(&l.bounds),
452 fn lower_lifetimes(&mut self, lts: &Vec<Lifetime>) -> hir::HirVec<hir::Lifetime> {
453 lts.iter().map(|l| self.lower_lifetime(l)).collect()
456 fn lower_lifetime_defs(&mut self, lts: &Vec<LifetimeDef>) -> hir::HirVec<hir::LifetimeDef> {
457 lts.iter().map(|l| self.lower_lifetime_def(l)).collect()
460 fn lower_opt_lifetime(&mut self, o_lt: &Option<Lifetime>) -> Option<hir::Lifetime> {
461 o_lt.as_ref().map(|lt| self.lower_lifetime(lt))
464 fn lower_generics(&mut self, g: &Generics) -> hir::Generics {
466 ty_params: self.lower_ty_params(&g.ty_params),
467 lifetimes: self.lower_lifetime_defs(&g.lifetimes),
468 where_clause: self.lower_where_clause(&g.where_clause),
473 fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause {
476 predicates: wc.predicates
478 .map(|predicate| self.lower_where_predicate(predicate))
483 fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate {
485 WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes,
489 hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
490 bound_lifetimes: self.lower_lifetime_defs(bound_lifetimes),
491 bounded_ty: self.lower_ty(bounded_ty),
492 bounds: bounds.iter().map(|x| self.lower_ty_param_bound(x)).collect(),
496 WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime,
499 hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
501 lifetime: self.lower_lifetime(lifetime),
502 bounds: bounds.iter().map(|bound| self.lower_lifetime(bound)).collect(),
505 WherePredicate::EqPredicate(WhereEqPredicate{ id,
509 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
511 path: self.lower_path(path),
512 ty: self.lower_ty(ty),
519 fn lower_variant_data(&mut self, vdata: &VariantData) -> hir::VariantData {
521 VariantData::Struct(ref fields, id) => {
522 hir::VariantData::Struct(fields.iter()
524 .map(|f| self.lower_struct_field(f))
528 VariantData::Tuple(ref fields, id) => {
529 hir::VariantData::Tuple(fields.iter()
531 .map(|f| self.lower_struct_field(f))
535 VariantData::Unit(id) => hir::VariantData::Unit(id),
539 fn lower_trait_ref(&mut self, p: &TraitRef) -> hir::TraitRef {
541 path: self.lower_path(&p.path),
546 fn lower_poly_trait_ref(&mut self, p: &PolyTraitRef) -> hir::PolyTraitRef {
548 bound_lifetimes: self.lower_lifetime_defs(&p.bound_lifetimes),
549 trait_ref: self.lower_trait_ref(&p.trait_ref),
554 fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::StructField {
558 name: f.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())),
559 vis: self.lower_visibility(&f.vis),
560 ty: self.lower_ty(&f.ty),
561 attrs: self.lower_attrs(&f.attrs),
565 fn lower_field(&mut self, f: &Field) -> hir::Field {
567 name: respan(f.ident.span, f.ident.node.name),
568 expr: self.lower_expr(&f.expr),
573 fn lower_mt(&mut self, mt: &MutTy) -> hir::MutTy {
575 ty: self.lower_ty(&mt.ty),
576 mutbl: self.lower_mutability(mt.mutbl),
580 fn lower_bounds(&mut self, bounds: &TyParamBounds) -> hir::TyParamBounds {
581 bounds.iter().map(|bound| self.lower_ty_param_bound(bound)).collect()
584 fn lower_block(&mut self, b: &Block) -> P<hir::Block> {
585 let mut stmts = Vec::new();
588 if let Some((last, rest)) = b.stmts.split_last() {
589 stmts = rest.iter().map(|s| self.lower_stmt(s)).collect::<Vec<_>>();
590 let last = self.lower_stmt(last);
591 if let hir::StmtExpr(e, _) = last.node {
602 rules: self.lower_block_check_mode(&b.rules),
607 fn lower_item_kind(&mut self, i: &ItemKind) -> hir::Item_ {
609 ItemKind::ExternCrate(string) => hir::ItemExternCrate(string),
610 ItemKind::Use(ref view_path) => {
611 hir::ItemUse(self.lower_view_path(view_path))
613 ItemKind::Static(ref t, m, ref e) => {
614 hir::ItemStatic(self.lower_ty(t),
615 self.lower_mutability(m),
618 ItemKind::Const(ref t, ref e) => {
619 hir::ItemConst(self.lower_ty(t), self.lower_expr(e))
621 ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
622 hir::ItemFn(self.lower_fn_decl(decl),
623 self.lower_unsafety(unsafety),
624 self.lower_constness(constness),
626 self.lower_generics(generics),
627 self.lower_block(body))
629 ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
630 ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
631 ItemKind::Ty(ref t, ref generics) => {
632 hir::ItemTy(self.lower_ty(t), self.lower_generics(generics))
634 ItemKind::Enum(ref enum_definition, ref generics) => {
635 hir::ItemEnum(hir::EnumDef {
636 variants: enum_definition.variants
638 .map(|x| self.lower_variant(x))
641 self.lower_generics(generics))
643 ItemKind::Struct(ref struct_def, ref generics) => {
644 let struct_def = self.lower_variant_data(struct_def);
645 hir::ItemStruct(struct_def, self.lower_generics(generics))
647 ItemKind::DefaultImpl(unsafety, ref trait_ref) => {
648 hir::ItemDefaultImpl(self.lower_unsafety(unsafety),
649 self.lower_trait_ref(trait_ref))
651 ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => {
652 let new_impl_items = impl_items.iter()
653 .map(|item| self.lower_impl_item(item))
655 let ifce = ifce.as_ref().map(|trait_ref| self.lower_trait_ref(trait_ref));
656 hir::ItemImpl(self.lower_unsafety(unsafety),
657 self.lower_impl_polarity(polarity),
658 self.lower_generics(generics),
663 ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => {
664 let bounds = self.lower_bounds(bounds);
665 let items = items.iter().map(|item| self.lower_trait_item(item)).collect();
666 hir::ItemTrait(self.lower_unsafety(unsafety),
667 self.lower_generics(generics),
671 ItemKind::Mac(_) => panic!("Shouldn't still be around"),
675 fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
676 self.with_parent_def(i.id, |this| {
680 attrs: this.lower_attrs(&i.attrs),
682 TraitItemKind::Const(ref ty, ref default) => {
683 hir::ConstTraitItem(this.lower_ty(ty),
684 default.as_ref().map(|x| this.lower_expr(x)))
686 TraitItemKind::Method(ref sig, ref body) => {
687 hir::MethodTraitItem(this.lower_method_sig(sig),
688 body.as_ref().map(|x| this.lower_block(x)))
690 TraitItemKind::Type(ref bounds, ref default) => {
691 hir::TypeTraitItem(this.lower_bounds(bounds),
692 default.as_ref().map(|x| this.lower_ty(x)))
694 TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
701 fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
702 self.with_parent_def(i.id, |this| {
706 attrs: this.lower_attrs(&i.attrs),
707 vis: this.lower_visibility(&i.vis),
708 defaultness: this.lower_defaultness(i.defaultness),
710 ImplItemKind::Const(ref ty, ref expr) => {
711 hir::ImplItemKind::Const(this.lower_ty(ty), this.lower_expr(expr))
713 ImplItemKind::Method(ref sig, ref body) => {
714 hir::ImplItemKind::Method(this.lower_method_sig(sig),
715 this.lower_block(body))
717 ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
718 ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
725 fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
728 item_ids: m.items.iter().map(|x| self.lower_item_id(x)).collect(),
732 fn lower_macro_def(&mut self, m: &MacroDef) -> hir::MacroDef {
735 attrs: self.lower_attrs(&m.attrs),
738 imported_from: m.imported_from.map(|x| x.name),
740 use_locally: m.use_locally,
741 allow_internal_unstable: m.allow_internal_unstable,
742 body: m.body.clone().into(),
746 fn lower_item_id(&mut self, i: &Item) -> hir::ItemId {
747 hir::ItemId { id: i.id }
750 pub fn lower_item(&mut self, i: &Item) -> hir::Item {
751 let node = self.with_parent_def(i.id, |this| {
752 this.lower_item_kind(&i.node)
758 attrs: self.lower_attrs(&i.attrs),
760 vis: self.lower_visibility(&i.vis),
765 fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
766 self.with_parent_def(i.id, |this| {
770 attrs: this.lower_attrs(&i.attrs),
772 ForeignItemKind::Fn(ref fdec, ref generics) => {
773 hir::ForeignItemFn(this.lower_fn_decl(fdec), this.lower_generics(generics))
775 ForeignItemKind::Static(ref t, m) => {
776 hir::ForeignItemStatic(this.lower_ty(t), m)
779 vis: this.lower_visibility(&i.vis),
785 fn lower_method_sig(&mut self, sig: &MethodSig) -> hir::MethodSig {
786 let hir_sig = hir::MethodSig {
787 generics: self.lower_generics(&sig.generics),
789 unsafety: self.lower_unsafety(sig.unsafety),
790 constness: self.lower_constness(sig.constness),
791 decl: self.lower_fn_decl(&sig.decl),
793 // Check for `self: _` and `self: &_`
794 if let Some(SelfKind::Explicit(..)) = sig.decl.get_self().map(|eself| eself.node) {
795 match hir_sig.decl.get_self().map(|eself| eself.node) {
796 Some(hir::SelfKind::Value(..)) | Some(hir::SelfKind::Region(..)) => {
797 self.diagnostic().span_err(sig.decl.inputs[0].ty.span,
798 "the type placeholder `_` is not allowed within types on item signatures");
806 fn lower_unsafety(&mut self, u: Unsafety) -> hir::Unsafety {
808 Unsafety::Unsafe => hir::Unsafety::Unsafe,
809 Unsafety::Normal => hir::Unsafety::Normal,
813 fn lower_constness(&mut self, c: Constness) -> hir::Constness {
815 Constness::Const => hir::Constness::Const,
816 Constness::NotConst => hir::Constness::NotConst,
820 fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
822 UnOp::Deref => hir::UnDeref,
823 UnOp::Not => hir::UnNot,
824 UnOp::Neg => hir::UnNeg,
828 fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
831 BinOpKind::Add => hir::BiAdd,
832 BinOpKind::Sub => hir::BiSub,
833 BinOpKind::Mul => hir::BiMul,
834 BinOpKind::Div => hir::BiDiv,
835 BinOpKind::Rem => hir::BiRem,
836 BinOpKind::And => hir::BiAnd,
837 BinOpKind::Or => hir::BiOr,
838 BinOpKind::BitXor => hir::BiBitXor,
839 BinOpKind::BitAnd => hir::BiBitAnd,
840 BinOpKind::BitOr => hir::BiBitOr,
841 BinOpKind::Shl => hir::BiShl,
842 BinOpKind::Shr => hir::BiShr,
843 BinOpKind::Eq => hir::BiEq,
844 BinOpKind::Lt => hir::BiLt,
845 BinOpKind::Le => hir::BiLe,
846 BinOpKind::Ne => hir::BiNe,
847 BinOpKind::Ge => hir::BiGe,
848 BinOpKind::Gt => hir::BiGt,
854 fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
858 PatKind::Wild => hir::PatKind::Wild,
859 PatKind::Ident(ref binding_mode, pth1, ref sub) => {
860 self.with_parent_def(p.id, |this| {
861 match this.resolver.get_resolution(p.id).map(|d| d.base_def) {
862 // `None` can occur in body-less function signatures
863 None | Some(Def::Local(..)) => {
864 hir::PatKind::Binding(this.lower_binding_mode(binding_mode),
865 respan(pth1.span, pth1.node.name),
866 sub.as_ref().map(|x| this.lower_pat(x)))
868 _ => hir::PatKind::Path(None, hir::Path::from_name(pth1.span,
873 PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
874 PatKind::TupleStruct(ref pth, ref pats, ddpos) => {
875 hir::PatKind::TupleStruct(self.lower_path(pth),
876 pats.iter().map(|x| self.lower_pat(x)).collect(),
879 PatKind::Path(ref opt_qself, ref path) => {
880 let opt_qself = opt_qself.as_ref().map(|qself| {
881 hir::QSelf { ty: self.lower_ty(&qself.ty), position: qself.position }
883 hir::PatKind::Path(opt_qself, self.lower_path(path))
885 PatKind::Struct(ref pth, ref fields, etc) => {
886 let pth = self.lower_path(pth);
887 let fs = fields.iter()
891 node: hir::FieldPat {
892 name: f.node.ident.name,
893 pat: self.lower_pat(&f.node.pat),
894 is_shorthand: f.node.is_shorthand,
899 hir::PatKind::Struct(pth, fs, etc)
901 PatKind::Tuple(ref elts, ddpos) => {
902 hir::PatKind::Tuple(elts.iter().map(|x| self.lower_pat(x)).collect(), ddpos)
904 PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
905 PatKind::Ref(ref inner, mutbl) => {
906 hir::PatKind::Ref(self.lower_pat(inner), self.lower_mutability(mutbl))
908 PatKind::Range(ref e1, ref e2) => {
909 hir::PatKind::Range(self.lower_expr(e1), self.lower_expr(e2))
911 PatKind::Vec(ref before, ref slice, ref after) => {
912 hir::PatKind::Vec(before.iter().map(|x| self.lower_pat(x)).collect(),
913 slice.as_ref().map(|x| self.lower_pat(x)),
914 after.iter().map(|x| self.lower_pat(x)).collect())
916 PatKind::Mac(_) => panic!("Shouldn't exist here"),
922 fn lower_expr(&mut self, e: &Expr) -> P<hir::Expr> {
927 // Eventually a desugaring for `box EXPR`
928 // (similar to the desugaring above for `in PLACE BLOCK`)
929 // should go here, desugaring
933 // let mut place = BoxPlace::make_place();
934 // let raw_place = Place::pointer(&mut place);
935 // let value = $value;
937 // ::std::ptr::write(raw_place, value);
938 // Boxed::finalize(place)
941 // But for now there are type-inference issues doing that.
942 ExprKind::Box(ref e) => {
943 hir::ExprBox(self.lower_expr(e))
946 // Desugar ExprBox: `in (PLACE) EXPR`
947 ExprKind::InPlace(ref placer, ref value_expr) => {
951 // let mut place = Placer::make_place(p);
952 // let raw_place = Place::pointer(&mut place);
954 // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
955 // InPlace::finalize(place)
957 let placer_expr = self.lower_expr(placer);
958 let value_expr = self.lower_expr(value_expr);
960 let placer_ident = self.str_to_ident("placer");
961 let place_ident = self.str_to_ident("place");
962 let p_ptr_ident = self.str_to_ident("p_ptr");
964 let make_place = ["ops", "Placer", "make_place"];
965 let place_pointer = ["ops", "Place", "pointer"];
966 let move_val_init = ["intrinsics", "move_val_init"];
967 let inplace_finalize = ["ops", "InPlace", "finalize"];
969 let make_call = |this: &mut LoweringContext, p, args| {
970 let path = this.std_path(e.span, p);
971 let path = this.expr_path(path, ThinVec::new());
972 this.expr_call(e.span, path, args)
975 let mk_stmt_let = |this: &mut LoweringContext, bind, expr| {
976 this.stmt_let(e.span, false, bind, expr)
979 let mk_stmt_let_mut = |this: &mut LoweringContext, bind, expr| {
980 this.stmt_let(e.span, true, bind, expr)
983 // let placer = <placer_expr> ;
984 let (s1, placer_binding) = {
985 let placer_expr = self.signal_block_expr(hir_vec![],
988 hir::PopUnstableBlock,
990 mk_stmt_let(self, placer_ident, placer_expr)
993 // let mut place = Placer::make_place(placer);
994 let (s2, place_binding) = {
995 let placer = self.expr_ident(e.span, placer_ident, placer_binding);
996 let call = make_call(self, &make_place, hir_vec![placer]);
997 mk_stmt_let_mut(self, place_ident, call)
1000 // let p_ptr = Place::pointer(&mut place);
1001 let (s3, p_ptr_binding) = {
1002 let agent = self.expr_ident(e.span, place_ident, place_binding);
1003 let args = hir_vec![self.expr_mut_addr_of(e.span, agent)];
1004 let call = make_call(self, &place_pointer, args);
1005 mk_stmt_let(self, p_ptr_ident, call)
1008 // pop_unsafe!(EXPR));
1009 let pop_unsafe_expr = {
1010 let value_expr = self.signal_block_expr(hir_vec![],
1013 hir::PopUnstableBlock,
1015 self.signal_block_expr(hir_vec![],
1018 hir::PopUnsafeBlock(hir::CompilerGenerated),
1023 // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
1024 // InPlace::finalize(place)
1027 let ptr = self.expr_ident(e.span, p_ptr_ident, p_ptr_binding);
1028 let call_move_val_init =
1030 make_call(self, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
1032 let call_move_val_init = respan(e.span, call_move_val_init);
1034 let place = self.expr_ident(e.span, place_ident, place_binding);
1035 let call = make_call(self, &inplace_finalize, hir_vec![place]);
1036 self.signal_block_expr(hir_vec![call_move_val_init],
1039 hir::PushUnsafeBlock(hir::CompilerGenerated),
1043 return self.signal_block_expr(hir_vec![s1, s2, s3],
1046 hir::PushUnstableBlock,
1050 ExprKind::Vec(ref exprs) => {
1051 hir::ExprVec(exprs.iter().map(|x| self.lower_expr(x)).collect())
1053 ExprKind::Repeat(ref expr, ref count) => {
1054 let expr = self.lower_expr(expr);
1055 let count = self.lower_expr(count);
1056 hir::ExprRepeat(expr, count)
1058 ExprKind::Tup(ref elts) => {
1059 hir::ExprTup(elts.iter().map(|x| self.lower_expr(x)).collect())
1061 ExprKind::Call(ref f, ref args) => {
1062 let f = self.lower_expr(f);
1063 hir::ExprCall(f, args.iter().map(|x| self.lower_expr(x)).collect())
1065 ExprKind::MethodCall(i, ref tps, ref args) => {
1066 let tps = tps.iter().map(|x| self.lower_ty(x)).collect();
1067 let args = args.iter().map(|x| self.lower_expr(x)).collect();
1068 hir::ExprMethodCall(respan(i.span, i.node.name), tps, args)
1070 ExprKind::Binary(binop, ref lhs, ref rhs) => {
1071 let binop = self.lower_binop(binop);
1072 let lhs = self.lower_expr(lhs);
1073 let rhs = self.lower_expr(rhs);
1074 hir::ExprBinary(binop, lhs, rhs)
1076 ExprKind::Unary(op, ref ohs) => {
1077 let op = self.lower_unop(op);
1078 let ohs = self.lower_expr(ohs);
1079 hir::ExprUnary(op, ohs)
1081 ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())),
1082 ExprKind::Cast(ref expr, ref ty) => {
1083 let expr = self.lower_expr(expr);
1084 hir::ExprCast(expr, self.lower_ty(ty))
1086 ExprKind::Type(ref expr, ref ty) => {
1087 let expr = self.lower_expr(expr);
1088 hir::ExprType(expr, self.lower_ty(ty))
1090 ExprKind::AddrOf(m, ref ohs) => {
1091 let m = self.lower_mutability(m);
1092 let ohs = self.lower_expr(ohs);
1093 hir::ExprAddrOf(m, ohs)
1095 // More complicated than you might expect because the else branch
1096 // might be `if let`.
1097 ExprKind::If(ref cond, ref blk, ref else_opt) => {
1098 let else_opt = else_opt.as_ref().map(|els| {
1100 ExprKind::IfLet(..) => {
1101 // wrap the if-let expr in a block
1102 let span = els.span;
1103 let els = self.lower_expr(els);
1104 let id = self.next_id();
1105 let blk = P(hir::Block {
1109 rules: hir::DefaultBlock,
1112 self.expr_block(blk, ThinVec::new())
1114 _ => self.lower_expr(els),
1118 hir::ExprIf(self.lower_expr(cond), self.lower_block(blk), else_opt)
1120 ExprKind::While(ref cond, ref body, opt_ident) => {
1121 hir::ExprWhile(self.lower_expr(cond), self.lower_block(body),
1122 self.lower_opt_sp_ident(opt_ident))
1124 ExprKind::Loop(ref body, opt_ident) => {
1125 hir::ExprLoop(self.lower_block(body), self.lower_opt_sp_ident(opt_ident))
1127 ExprKind::Match(ref expr, ref arms) => {
1128 hir::ExprMatch(self.lower_expr(expr),
1129 arms.iter().map(|x| self.lower_arm(x)).collect(),
1130 hir::MatchSource::Normal)
1132 ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => {
1133 self.with_parent_def(e.id, |this| {
1134 hir::ExprClosure(this.lower_capture_clause(capture_clause),
1135 this.lower_fn_decl(decl),
1136 this.lower_block(body),
1140 ExprKind::Block(ref blk) => hir::ExprBlock(self.lower_block(blk)),
1141 ExprKind::Assign(ref el, ref er) => {
1142 hir::ExprAssign(self.lower_expr(el), self.lower_expr(er))
1144 ExprKind::AssignOp(op, ref el, ref er) => {
1145 hir::ExprAssignOp(self.lower_binop(op),
1146 self.lower_expr(el),
1147 self.lower_expr(er))
1149 ExprKind::Field(ref el, ident) => {
1150 hir::ExprField(self.lower_expr(el), respan(ident.span, ident.node.name))
1152 ExprKind::TupField(ref el, ident) => {
1153 hir::ExprTupField(self.lower_expr(el), ident)
1155 ExprKind::Index(ref el, ref er) => {
1156 hir::ExprIndex(self.lower_expr(el), self.lower_expr(er))
1158 ExprKind::Range(ref e1, ref e2, lims) => {
1159 fn make_struct(this: &mut LoweringContext,
1162 fields: &[(&str, &P<Expr>)]) -> P<hir::Expr> {
1163 let struct_path = this.std_path(ast_expr.span,
1164 &iter::once(&"ops").chain(path)
1166 .collect::<Vec<_>>());
1168 let hir_expr = if fields.len() == 0 {
1169 this.expr_path(struct_path, ast_expr.attrs.clone())
1171 let fields = fields.into_iter().map(|&(s, e)| {
1172 let expr = this.lower_expr(&e);
1173 let signal_block = this.signal_block_expr(hir_vec![],
1176 hir::PopUnstableBlock,
1178 this.field(token::intern(s), signal_block, ast_expr.span)
1180 let attrs = ast_expr.attrs.clone();
1182 this.expr_struct(ast_expr.span, struct_path, fields, None, attrs)
1185 this.signal_block_expr(hir_vec![],
1188 hir::PushUnstableBlock,
1192 use syntax::ast::RangeLimits::*;
1194 return match (e1, e2, lims) {
1195 (&None, &None, HalfOpen) =>
1196 make_struct(self, e, &["RangeFull"], &[]),
1198 (&Some(ref e1), &None, HalfOpen) =>
1199 make_struct(self, e, &["RangeFrom"],
1202 (&None, &Some(ref e2), HalfOpen) =>
1203 make_struct(self, e, &["RangeTo"],
1206 (&Some(ref e1), &Some(ref e2), HalfOpen) =>
1207 make_struct(self, e, &["Range"],
1208 &[("start", e1), ("end", e2)]),
1210 (&None, &Some(ref e2), Closed) =>
1211 make_struct(self, e, &["RangeToInclusive"],
1214 (&Some(ref e1), &Some(ref e2), Closed) =>
1215 make_struct(self, e, &["RangeInclusive", "NonEmpty"],
1216 &[("start", e1), ("end", e2)]),
1218 _ => panic!(self.diagnostic()
1219 .span_fatal(e.span, "inclusive range with no end")),
1222 ExprKind::Path(ref qself, ref path) => {
1223 let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
1225 ty: self.lower_ty(ty),
1229 hir::ExprPath(hir_qself, self.lower_path(path))
1231 ExprKind::Break(opt_ident) => hir::ExprBreak(self.lower_opt_sp_ident(opt_ident)),
1232 ExprKind::Continue(opt_ident) => hir::ExprAgain(self.lower_opt_sp_ident(opt_ident)),
1233 ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| self.lower_expr(x))),
1234 ExprKind::InlineAsm(InlineAsm {
1244 }) => hir::ExprInlineAsm(hir::InlineAsm {
1245 inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
1246 outputs: outputs.iter()
1248 hir::InlineAsmOutput {
1249 constraint: out.constraint.clone(),
1251 is_indirect: out.is_indirect,
1256 asm_str_style: asm_str_style,
1257 clobbers: clobbers.clone().into(),
1259 alignstack: alignstack,
1262 }, outputs.iter().map(|out| self.lower_expr(&out.expr)).collect(),
1263 inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect()),
1264 ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
1265 hir::ExprStruct(self.lower_path(path),
1266 fields.iter().map(|x| self.lower_field(x)).collect(),
1267 maybe_expr.as_ref().map(|x| self.lower_expr(x)))
1269 ExprKind::Paren(ref ex) => {
1270 return self.lower_expr(ex).map(|mut ex| {
1271 // include parens in span, but only if it is a super-span.
1272 if e.span.contains(ex.span) {
1275 // merge attributes into the inner expression.
1276 let mut attrs = e.attrs.clone();
1277 attrs.extend::<Vec<_>>(ex.attrs.into());
1283 // Desugar ExprIfLet
1284 // From: `if let <pat> = <sub_expr> <body> [<else_opt>]`
1285 ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => {
1288 // match <sub_expr> {
1290 // [_ if <else_opt_if_cond> => <else_opt_if_body>,]
1291 // _ => [<else_opt> | ()]
1294 // `<pat> => <body>`
1296 let body = self.lower_block(body);
1297 let body_expr = self.expr_block(body, ThinVec::new());
1298 let pat = self.lower_pat(pat);
1299 self.arm(hir_vec![pat], body_expr)
1302 // `[_ if <else_opt_if_cond> => <else_opt_if_body>,]`
1303 let mut else_opt = else_opt.as_ref().map(|e| self.lower_expr(e));
1304 let else_if_arms = {
1305 let mut arms = vec![];
1307 let else_opt_continue = else_opt.and_then(|els| {
1308 els.and_then(|els| {
1311 hir::ExprIf(cond, then, else_opt) => {
1312 let pat_under = self.pat_wild(e.span);
1313 arms.push(hir::Arm {
1315 pats: hir_vec![pat_under],
1317 body: self.expr_block(then, ThinVec::new()),
1319 else_opt.map(|else_opt| (else_opt, true))
1321 _ => Some((P(els), false)),
1325 match else_opt_continue {
1326 Some((e, true)) => {
1329 Some((e, false)) => {
1342 let contains_else_clause = else_opt.is_some();
1344 // `_ => [<else_opt> | ()]`
1346 let pat_under = self.pat_wild(e.span);
1348 else_opt.unwrap_or_else(|| self.expr_tuple(e.span, hir_vec![]));
1349 self.arm(hir_vec![pat_under], else_expr)
1352 let mut arms = Vec::with_capacity(else_if_arms.len() + 2);
1354 arms.extend(else_if_arms);
1355 arms.push(else_arm);
1357 let sub_expr = self.lower_expr(sub_expr);
1358 // add attributes to the outer returned expr node
1359 return self.expr(e.span,
1360 hir::ExprMatch(sub_expr,
1362 hir::MatchSource::IfLetDesugar {
1363 contains_else_clause: contains_else_clause,
1368 // Desugar ExprWhileLet
1369 // From: `[opt_ident]: while let <pat> = <sub_expr> <body>`
1370 ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => {
1373 // [opt_ident]: loop {
1374 // match <sub_expr> {
1380 // `<pat> => <body>`
1382 let body = self.lower_block(body);
1383 let body_expr = self.expr_block(body, ThinVec::new());
1384 let pat = self.lower_pat(pat);
1385 self.arm(hir_vec![pat], body_expr)
1390 let pat_under = self.pat_wild(e.span);
1391 let break_expr = self.expr_break(e.span, ThinVec::new());
1392 self.arm(hir_vec![pat_under], break_expr)
1395 // `match <sub_expr> { ... }`
1396 let arms = hir_vec![pat_arm, break_arm];
1397 let sub_expr = self.lower_expr(sub_expr);
1398 let match_expr = self.expr(e.span,
1399 hir::ExprMatch(sub_expr,
1401 hir::MatchSource::WhileLetDesugar),
1404 // `[opt_ident]: loop { ... }`
1405 let loop_block = self.block_expr(match_expr);
1406 let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident));
1407 // add attributes to the outer returned expr node
1408 let attrs = e.attrs.clone();
1409 return P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: attrs });
1412 // Desugar ExprForLoop
1413 // From: `[opt_ident]: for <pat> in <head> <body>`
1414 ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => {
1418 // let result = match ::std::iter::IntoIterator::into_iter(<head>) {
1420 // [opt_ident]: loop {
1421 // match ::std::iter::Iterator::next(&mut iter) {
1422 // ::std::option::Option::Some(<pat>) => <body>,
1423 // ::std::option::Option::None => break
1432 let head = self.lower_expr(head);
1434 let iter = self.str_to_ident("iter");
1436 // `::std::option::Option::Some(<pat>) => <body>`
1438 let body_block = self.lower_block(body);
1439 let body_span = body_block.span;
1440 let body_expr = P(hir::Expr {
1442 node: hir::ExprBlock(body_block),
1444 attrs: ThinVec::new(),
1446 let pat = self.lower_pat(pat);
1447 let some_pat = self.pat_some(e.span, pat);
1449 self.arm(hir_vec![some_pat], body_expr)
1452 // `::std::option::Option::None => break`
1454 let break_expr = self.expr_break(e.span, ThinVec::new());
1455 let pat = self.pat_none(e.span);
1456 self.arm(hir_vec![pat], break_expr)
1460 let iter_pat = self.pat_ident_binding_mode(e.span, iter,
1461 hir::BindByValue(hir::MutMutable));
1463 // `match ::std::iter::Iterator::next(&mut iter) { ... }`
1465 let next_path = self.std_path(e.span, &["iter", "Iterator", "next"]);
1466 let iter = self.expr_ident(e.span, iter, iter_pat.id);
1467 let ref_mut_iter = self.expr_mut_addr_of(e.span, iter);
1468 let next_path = self.expr_path(next_path, ThinVec::new());
1469 let next_expr = self.expr_call(e.span, next_path, hir_vec![ref_mut_iter]);
1470 let arms = hir_vec![pat_arm, break_arm];
1473 hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar),
1477 // `[opt_ident]: loop { ... }`
1478 let loop_block = self.block_expr(match_expr);
1479 let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident));
1480 let loop_expr = P(hir::Expr {
1484 attrs: ThinVec::new(),
1487 // `mut iter => { ... }`
1488 let iter_arm = self.arm(hir_vec![iter_pat], loop_expr);
1490 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
1491 let into_iter_expr = {
1492 let into_iter_path = self.std_path(e.span,
1493 &["iter", "IntoIterator", "into_iter"]);
1495 let into_iter = self.expr_path(into_iter_path, ThinVec::new());
1496 self.expr_call(e.span, into_iter, hir_vec![head])
1499 let match_expr = self.expr_match(e.span,
1502 hir::MatchSource::ForLoopDesugar);
1504 // `{ let _result = ...; _result }`
1505 // underscore prevents an unused_variables lint if the head diverges
1506 let result_ident = self.str_to_ident("_result");
1507 let (let_stmt, let_stmt_binding) =
1508 self.stmt_let(e.span, false, result_ident, match_expr);
1510 let result = self.expr_ident(e.span, result_ident, let_stmt_binding);
1511 let block = self.block_all(e.span, hir_vec![let_stmt], Some(result));
1512 // add the attributes to the outer returned expr node
1513 return self.expr_block(block, e.attrs.clone());
1516 // Desugar ExprKind::Try
1518 ExprKind::Try(ref sub_expr) => {
1522 // match { Carrier::translate( { <expr> } ) } {
1524 // Err(err) => { return Carrier::from_error(From::from(err)); }
1528 // { Carrier::translate( { <expr> } ) }
1531 let sub_expr = self.lower_expr(sub_expr);
1532 let sub_expr = self.signal_block_expr(hir_vec![],
1535 hir::PopUnstableBlock,
1538 let path = self.std_path(e.span, &["ops", "Carrier", "translate"]);
1539 let path = self.expr_path(path, ThinVec::new());
1540 let call = self.expr_call(e.span, path, hir_vec![sub_expr]);
1542 self.signal_block_expr(hir_vec![],
1545 hir::PushUnstableBlock,
1551 let val_ident = self.str_to_ident("val");
1552 let val_pat = self.pat_ident(e.span, val_ident);
1553 let val_expr = self.expr_ident(e.span, val_ident, val_pat.id);
1554 let ok_pat = self.pat_ok(e.span, val_pat);
1556 self.arm(hir_vec![ok_pat], val_expr)
1559 // Err(err) => { return Carrier::from_error(From::from(err)); }
1561 let err_ident = self.str_to_ident("err");
1562 let err_local = self.pat_ident(e.span, err_ident);
1564 let path = self.std_path(e.span, &["convert", "From", "from"]);
1565 let from = self.expr_path(path, ThinVec::new());
1566 let err_expr = self.expr_ident(e.span, err_ident, err_local.id);
1568 self.expr_call(e.span, from, hir_vec![err_expr])
1570 let from_err_expr = {
1571 let path = self.std_path(e.span, &["ops", "Carrier", "from_error"]);
1572 let from_err = self.expr_path(path, ThinVec::new());
1573 self.expr_call(e.span, from_err, hir_vec![from_expr])
1576 let ret_expr = self.expr(e.span,
1577 hir::Expr_::ExprRet(Some(from_err_expr)),
1579 let ret_stmt = self.stmt_expr(ret_expr);
1580 let block = self.signal_block_stmt(ret_stmt, e.span,
1581 hir::PushUnstableBlock, ThinVec::new());
1583 let err_pat = self.pat_err(e.span, err_local);
1584 self.arm(hir_vec![err_pat], block)
1587 return self.expr_match(e.span, discr, hir_vec![err_arm, ok_arm],
1588 hir::MatchSource::TryDesugar);
1591 ExprKind::Mac(_) => panic!("Shouldn't exist here"),
1594 attrs: e.attrs.clone(),
1598 fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt {
1600 StmtKind::Local(ref l) => Spanned {
1601 node: hir::StmtDecl(P(Spanned {
1602 node: hir::DeclLocal(self.lower_local(l)),
1607 StmtKind::Item(ref it) => Spanned {
1608 node: hir::StmtDecl(P(Spanned {
1609 node: hir::DeclItem(self.lower_item_id(it)),
1614 StmtKind::Expr(ref e) => {
1616 node: hir::StmtExpr(self.lower_expr(e), s.id),
1620 StmtKind::Semi(ref e) => {
1622 node: hir::StmtSemi(self.lower_expr(e), s.id),
1626 StmtKind::Mac(..) => panic!("Shouldn't exist here"),
1630 fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause {
1632 CaptureBy::Value => hir::CaptureByValue,
1633 CaptureBy::Ref => hir::CaptureByRef,
1637 fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility {
1639 Visibility::Public => hir::Public,
1640 Visibility::Crate(_) => hir::Visibility::Crate,
1641 Visibility::Restricted { ref path, id } =>
1642 hir::Visibility::Restricted { path: P(self.lower_path(path)), id: id },
1643 Visibility::Inherited => hir::Inherited,
1647 fn lower_defaultness(&mut self, d: Defaultness) -> hir::Defaultness {
1649 Defaultness::Default => hir::Defaultness::Default,
1650 Defaultness::Final => hir::Defaultness::Final,
1654 fn lower_block_check_mode(&mut self, b: &BlockCheckMode) -> hir::BlockCheckMode {
1656 BlockCheckMode::Default => hir::DefaultBlock,
1657 BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(self.lower_unsafe_source(u)),
1661 fn lower_binding_mode(&mut self, b: &BindingMode) -> hir::BindingMode {
1663 BindingMode::ByRef(m) => hir::BindByRef(self.lower_mutability(m)),
1664 BindingMode::ByValue(m) => hir::BindByValue(self.lower_mutability(m)),
1668 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
1670 CompilerGenerated => hir::CompilerGenerated,
1671 UserProvided => hir::UserProvided,
1675 fn lower_impl_polarity(&mut self, i: ImplPolarity) -> hir::ImplPolarity {
1677 ImplPolarity::Positive => hir::ImplPolarity::Positive,
1678 ImplPolarity::Negative => hir::ImplPolarity::Negative,
1682 fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
1684 TraitBoundModifier::None => hir::TraitBoundModifier::None,
1685 TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
1689 // Helper methods for building HIR.
1691 fn arm(&mut self, pats: hir::HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
1700 fn field(&mut self, name: Name, expr: P<hir::Expr>, span: Span) -> hir::Field {
1711 fn expr_break(&mut self, span: Span, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
1712 self.expr(span, hir::ExprBreak(None), attrs)
1715 fn expr_call(&mut self, span: Span, e: P<hir::Expr>, args: hir::HirVec<P<hir::Expr>>)
1717 self.expr(span, hir::ExprCall(e, args), ThinVec::new())
1720 fn expr_ident(&mut self, span: Span, id: Name, binding: NodeId) -> P<hir::Expr> {
1721 let expr_path = hir::ExprPath(None, self.path_ident(span, id));
1722 let expr = self.expr(span, expr_path, ThinVec::new());
1724 let def = self.resolver.definitions().map(|defs| {
1725 Def::Local(defs.local_def_id(binding), binding)
1726 }).unwrap_or(Def::Err);
1727 self.resolver.record_resolution(expr.id, def);
1732 fn expr_mut_addr_of(&mut self, span: Span, e: P<hir::Expr>) -> P<hir::Expr> {
1733 self.expr(span, hir::ExprAddrOf(hir::MutMutable, e), ThinVec::new())
1736 fn expr_path(&mut self, path: hir::Path, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
1737 let def = self.resolver.resolve_generated_global_path(&path, true);
1738 let expr = self.expr(path.span, hir::ExprPath(None, path), attrs);
1739 self.resolver.record_resolution(expr.id, def);
1743 fn expr_match(&mut self,
1746 arms: hir::HirVec<hir::Arm>,
1747 source: hir::MatchSource)
1749 self.expr(span, hir::ExprMatch(arg, arms, source), ThinVec::new())
1752 fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
1753 self.expr(b.span, hir::ExprBlock(b), attrs)
1756 fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<P<hir::Expr>>) -> P<hir::Expr> {
1757 self.expr(sp, hir::ExprTup(exprs), ThinVec::new())
1760 fn expr_struct(&mut self,
1763 fields: hir::HirVec<hir::Field>,
1764 e: Option<P<hir::Expr>>,
1765 attrs: ThinVec<Attribute>) -> P<hir::Expr> {
1766 let def = self.resolver.resolve_generated_global_path(&path, false);
1767 let expr = self.expr(sp, hir::ExprStruct(path, fields, e), attrs);
1768 self.resolver.record_resolution(expr.id, def);
1772 fn expr(&mut self, span: Span, node: hir::Expr_, attrs: ThinVec<Attribute>) -> P<hir::Expr> {
1781 fn stmt_let(&mut self, sp: Span, mutbl: bool, ident: Name, ex: P<hir::Expr>)
1782 -> (hir::Stmt, NodeId) {
1783 let pat = if mutbl {
1784 self.pat_ident_binding_mode(sp, ident, hir::BindByValue(hir::MutMutable))
1786 self.pat_ident(sp, ident)
1788 let pat_id = pat.id;
1789 let local = P(hir::Local {
1795 attrs: ThinVec::new(),
1797 let decl = respan(sp, hir::DeclLocal(local));
1798 (respan(sp, hir::StmtDecl(P(decl), self.next_id())), pat_id)
1801 // Turns `<expr>` into `<expr>;`, note that this produces a StmtSemi, not a
1803 fn stmt_expr(&self, expr: P<hir::Expr>) -> hir::Stmt {
1806 node: hir::StmtSemi(expr, self.next_id()),
1810 fn block_expr(&mut self, expr: P<hir::Expr>) -> P<hir::Block> {
1811 self.block_all(expr.span, hir::HirVec::new(), Some(expr))
1814 fn block_all(&mut self, span: Span, stmts: hir::HirVec<hir::Stmt>, expr: Option<P<hir::Expr>>)
1820 rules: hir::DefaultBlock,
1825 fn pat_ok(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
1826 let path = self.std_path(span, &["result", "Result", "Ok"]);
1827 self.pat_enum(span, path, hir_vec![pat])
1830 fn pat_err(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
1831 let path = self.std_path(span, &["result", "Result", "Err"]);
1832 self.pat_enum(span, path, hir_vec![pat])
1835 fn pat_some(&mut self, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
1836 let path = self.std_path(span, &["option", "Option", "Some"]);
1837 self.pat_enum(span, path, hir_vec![pat])
1840 fn pat_none(&mut self, span: Span) -> P<hir::Pat> {
1841 let path = self.std_path(span, &["option", "Option", "None"]);
1842 self.pat_enum(span, path, hir_vec![])
1845 fn pat_enum(&mut self, span: Span, path: hir::Path, subpats: hir::HirVec<P<hir::Pat>>)
1847 let def = self.resolver.resolve_generated_global_path(&path, true);
1848 let pt = if subpats.is_empty() {
1849 hir::PatKind::Path(None, path)
1851 hir::PatKind::TupleStruct(path, subpats, None)
1853 let pat = self.pat(span, pt);
1854 self.resolver.record_resolution(pat.id, def);
1858 fn pat_ident(&mut self, span: Span, name: Name) -> P<hir::Pat> {
1859 self.pat_ident_binding_mode(span, name, hir::BindByValue(hir::MutImmutable))
1862 fn pat_ident_binding_mode(&mut self, span: Span, name: Name, bm: hir::BindingMode)
1864 let pat_ident = hir::PatKind::Binding(bm,
1871 let pat = self.pat(span, pat_ident);
1873 let parent_def = self.parent_def;
1874 let def = self.resolver.definitions().map(|defs| {
1875 let def_path_data = DefPathData::Binding(name.as_str());
1876 let def_index = defs.create_def_with_parent(parent_def, pat.id, def_path_data);
1877 Def::Local(DefId::local(def_index), pat.id)
1878 }).unwrap_or(Def::Err);
1879 self.resolver.record_resolution(pat.id, def);
1884 fn pat_wild(&mut self, span: Span) -> P<hir::Pat> {
1885 self.pat(span, hir::PatKind::Wild)
1888 fn pat(&mut self, span: Span, pat: hir::PatKind) -> P<hir::Pat> {
1896 fn path_ident(&mut self, span: Span, id: Name) -> hir::Path {
1897 self.path(span, vec![id])
1900 fn path(&mut self, span: Span, strs: Vec<Name>) -> hir::Path {
1901 self.path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new())
1904 fn path_global(&mut self, span: Span, strs: Vec<Name>) -> hir::Path {
1905 self.path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new())
1908 fn path_all(&mut self,
1911 mut names: Vec<Name>,
1912 lifetimes: hir::HirVec<hir::Lifetime>,
1913 types: hir::HirVec<P<hir::Ty>>,
1914 bindings: hir::HirVec<hir::TypeBinding>)
1916 let last_identifier = names.pop().unwrap();
1917 let mut segments: Vec<hir::PathSegment> = names.into_iter().map(|name| {
1920 parameters: hir::PathParameters::none(),
1924 segments.push(hir::PathSegment {
1925 name: last_identifier,
1926 parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData {
1927 lifetimes: lifetimes,
1935 segments: segments.into(),
1939 fn std_path_components(&mut self, components: &[&str]) -> Vec<Name> {
1940 let mut v = Vec::new();
1941 if let Some(s) = self.crate_root {
1942 v.push(token::intern(s));
1944 v.extend(components.iter().map(|s| token::intern(s)));
1948 // Given suffix ["b","c","d"], returns path `::std::b::c::d` when
1949 // `fld.cx.use_std`, and `::core::b::c::d` otherwise.
1950 fn std_path(&mut self, span: Span, components: &[&str]) -> hir::Path {
1951 let idents = self.std_path_components(components);
1952 self.path_global(span, idents)
1955 fn signal_block_expr(&mut self,
1956 stmts: hir::HirVec<hir::Stmt>,
1959 rule: hir::BlockCheckMode,
1960 attrs: ThinVec<Attribute>)
1962 let id = self.next_id();
1963 let block = P(hir::Block {
1970 self.expr_block(block, attrs)
1973 fn signal_block_stmt(&mut self,
1976 rule: hir::BlockCheckMode,
1977 attrs: ThinVec<Attribute>)
1979 let id = self.next_id();
1980 let block = P(hir::Block {
1984 stmts: hir_vec![stmt],
1987 self.expr_block(block, attrs)