Move for
loop desugaring to lowering
This commit is contained in:
parent
56713a1684
commit
20083c1e1f
12 changed files with 420 additions and 214 deletions
|
@ -80,13 +80,13 @@ DEPS_rustc_typeck := rustc syntax rustc_front rustc_platform_intrinsics
|
||||||
DEPS_rustc_borrowck := rustc rustc_front log graphviz syntax
|
DEPS_rustc_borrowck := rustc rustc_front log graphviz syntax
|
||||||
DEPS_rustc_resolve := rustc rustc_front log syntax
|
DEPS_rustc_resolve := rustc rustc_front log syntax
|
||||||
DEPS_rustc_privacy := rustc rustc_front log syntax
|
DEPS_rustc_privacy := rustc rustc_front log syntax
|
||||||
|
DEPS_rustc_front := std syntax log serialize
|
||||||
DEPS_rustc_lint := rustc log syntax
|
DEPS_rustc_lint := rustc log syntax
|
||||||
DEPS_rustc := syntax flate arena serialize getopts rbml \
|
DEPS_rustc := syntax flate arena serialize getopts rbml rustc_front\
|
||||||
log graphviz rustc_llvm rustc_back rustc_data_structures
|
log graphviz rustc_llvm rustc_back rustc_data_structures
|
||||||
DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
|
DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
|
||||||
DEPS_rustc_platform_intrinsics := rustc rustc_llvm
|
DEPS_rustc_platform_intrinsics := rustc rustc_llvm
|
||||||
DEPS_rustc_back := std syntax rustc_llvm rustc_front flate log libc
|
DEPS_rustc_back := std syntax rustc_llvm rustc_front flate log libc
|
||||||
DEPS_rustc_front := std syntax log serialize
|
|
||||||
DEPS_rustc_data_structures := std log serialize
|
DEPS_rustc_data_structures := std log serialize
|
||||||
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
|
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
|
||||||
test rustc_lint rustc_front
|
test rustc_lint rustc_front
|
||||||
|
|
|
@ -36,6 +36,7 @@ use middle::subst;
|
||||||
use middle::ty::{self, Ty};
|
use middle::ty::{self, Ty};
|
||||||
|
|
||||||
use syntax::{ast, ast_util, codemap};
|
use syntax::{ast, ast_util, codemap};
|
||||||
|
use syntax::ast::NodeIdAssigner;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ pub struct ctxt<'tcx> {
|
||||||
/// Common types, pre-interned for your convenience.
|
/// Common types, pre-interned for your convenience.
|
||||||
pub types: CommonTypes<'tcx>,
|
pub types: CommonTypes<'tcx>,
|
||||||
|
|
||||||
pub sess: Session,
|
pub sess: &'tcx Session,
|
||||||
pub def_map: DefMap,
|
pub def_map: DefMap,
|
||||||
|
|
||||||
pub named_region_map: resolve_lifetime::NamedRegionMap,
|
pub named_region_map: resolve_lifetime::NamedRegionMap,
|
||||||
|
@ -443,7 +443,7 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
/// to the context. The closure enforces that the type context and any interned
|
/// to the context. The closure enforces that the type context and any interned
|
||||||
/// value (types, substs, etc.) can only be used while `ty::tls` has a valid
|
/// value (types, substs, etc.) can only be used while `ty::tls` has a valid
|
||||||
/// reference to the context, to allow formatting values that need it.
|
/// reference to the context, to allow formatting values that need it.
|
||||||
pub fn create_and_enter<F, R>(s: Session,
|
pub fn create_and_enter<F, R>(s: &'tcx Session,
|
||||||
arenas: &'tcx CtxtArenas<'tcx>,
|
arenas: &'tcx CtxtArenas<'tcx>,
|
||||||
def_map: DefMap,
|
def_map: DefMap,
|
||||||
named_region_map: resolve_lifetime::NamedRegionMap,
|
named_region_map: resolve_lifetime::NamedRegionMap,
|
||||||
|
@ -452,7 +452,7 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
region_maps: RegionMaps,
|
region_maps: RegionMaps,
|
||||||
lang_items: middle::lang_items::LanguageItems,
|
lang_items: middle::lang_items::LanguageItems,
|
||||||
stability: stability::Index<'tcx>,
|
stability: stability::Index<'tcx>,
|
||||||
f: F) -> (Session, R)
|
f: F) -> R
|
||||||
where F: FnOnce(&ctxt<'tcx>) -> R
|
where F: FnOnce(&ctxt<'tcx>) -> R
|
||||||
{
|
{
|
||||||
let interner = RefCell::new(FnvHashMap());
|
let interner = RefCell::new(FnvHashMap());
|
||||||
|
@ -556,7 +556,6 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
|
||||||
|
|
||||||
pub mod tls {
|
pub mod tls {
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use session::Session;
|
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use syntax::codemap;
|
use syntax::codemap;
|
||||||
|
@ -574,17 +573,15 @@ pub mod tls {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enter<'tcx, F: FnOnce(&ty::ctxt<'tcx>) -> R, R>(tcx: ty::ctxt<'tcx>, f: F)
|
pub fn enter<'tcx, F: FnOnce(&ty::ctxt<'tcx>) -> R, R>(tcx: ty::ctxt<'tcx>, f: F) -> R {
|
||||||
-> (Session, R) {
|
codemap::SPAN_DEBUG.with(|span_dbg| {
|
||||||
let result = codemap::SPAN_DEBUG.with(|span_dbg| {
|
|
||||||
let original_span_debug = span_dbg.get();
|
let original_span_debug = span_dbg.get();
|
||||||
span_dbg.set(span_debug);
|
span_dbg.set(span_debug);
|
||||||
let tls_ptr = &tcx as *const _ as *const ThreadLocalTyCx;
|
let tls_ptr = &tcx as *const _ as *const ThreadLocalTyCx;
|
||||||
let result = TLS_TCX.set(unsafe { &*tls_ptr }, || f(&tcx));
|
let result = TLS_TCX.set(unsafe { &*tls_ptr }, || f(&tcx));
|
||||||
span_dbg.set(original_span_debug);
|
span_dbg.set(original_span_debug);
|
||||||
result
|
result
|
||||||
});
|
})
|
||||||
(tcx.sess, result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with<F: FnOnce(&ty::ctxt) -> R, R>(f: F) -> R {
|
pub fn with<F: FnOnce(&ty::ctxt) -> R, R>(f: F) -> R {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use middle::dependency_format;
|
||||||
use session::search_paths::PathKind;
|
use session::search_paths::PathKind;
|
||||||
use util::nodemap::{NodeMap, FnvHashMap};
|
use util::nodemap::{NodeMap, FnvHashMap};
|
||||||
|
|
||||||
use syntax::ast::NodeId;
|
use syntax::ast::{NodeId, NodeIdAssigner};
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::diagnostic::{self, Emitter};
|
use syntax::diagnostic::{self, Emitter};
|
||||||
use syntax::diagnostics;
|
use syntax::diagnostics;
|
||||||
|
@ -236,9 +236,6 @@ impl Session {
|
||||||
}
|
}
|
||||||
lints.insert(id, vec!((lint_id, sp, msg)));
|
lints.insert(id, vec!((lint_id, sp, msg)));
|
||||||
}
|
}
|
||||||
pub fn next_node_id(&self) -> ast::NodeId {
|
|
||||||
self.reserve_node_ids(1)
|
|
||||||
}
|
|
||||||
pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
|
pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
|
||||||
let id = self.next_node_id.get();
|
let id = self.next_node_id.get();
|
||||||
|
|
||||||
|
@ -317,6 +314,12 @@ impl Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NodeIdAssigner for Session {
|
||||||
|
fn next_node_id(&self) -> NodeId {
|
||||||
|
self.reserve_node_ids(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn split_msg_into_multilines(msg: &str) -> Option<String> {
|
fn split_msg_into_multilines(msg: &str) -> Option<String> {
|
||||||
// Conditions for enabling multi-line errors:
|
// Conditions for enabling multi-line errors:
|
||||||
if !msg.contains("mismatched types") &&
|
if !msg.contains("mismatched types") &&
|
||||||
|
|
|
@ -42,7 +42,7 @@ use std::ffi::{OsString, OsStr};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use syntax::ast;
|
use syntax::ast::{self, NodeIdAssigner};
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::attr::AttrMetaMethods;
|
use syntax::attr::AttrMetaMethods;
|
||||||
use syntax::diagnostics;
|
use syntax::diagnostics;
|
||||||
|
@ -71,7 +71,7 @@ pub fn compile_input(sess: Session,
|
||||||
// We need nested scopes here, because the intermediate results can keep
|
// We need nested scopes here, because the intermediate results can keep
|
||||||
// large chunks of memory alive and we want to free them as soon as
|
// large chunks of memory alive and we want to free them as soon as
|
||||||
// possible to keep the peak memory usage low
|
// possible to keep the peak memory usage low
|
||||||
let (sess, result) = {
|
let result = {
|
||||||
let (outputs, expanded_crate, id) = {
|
let (outputs, expanded_crate, id) = {
|
||||||
let krate = phase_1_parse_input(&sess, cfg, input);
|
let krate = phase_1_parse_input(&sess, cfg, input);
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ pub fn compile_input(sess: Session,
|
||||||
let expanded_crate = assign_node_ids(&sess, expanded_crate);
|
let expanded_crate = assign_node_ids(&sess, expanded_crate);
|
||||||
// Lower ast -> hir.
|
// Lower ast -> hir.
|
||||||
let foo = &42;
|
let foo = &42;
|
||||||
let lcx = LoweringContext::new(foo);
|
let lcx = LoweringContext::new(foo, &sess, &expanded_crate);
|
||||||
let mut hir_forest = time(sess.time_passes(),
|
let mut hir_forest = time(sess.time_passes(),
|
||||||
"lowering ast -> hir",
|
"lowering ast -> hir",
|
||||||
|| hir_map::Forest::new(lower_crate(&lcx, &expanded_crate)));
|
|| hir_map::Forest::new(lower_crate(&lcx, &expanded_crate)));
|
||||||
|
@ -141,7 +141,7 @@ pub fn compile_input(sess: Session,
|
||||||
lint::check_ast_crate(&sess, &expanded_crate)
|
lint::check_ast_crate(&sess, &expanded_crate)
|
||||||
});
|
});
|
||||||
|
|
||||||
phase_3_run_analysis_passes(sess,
|
phase_3_run_analysis_passes(&sess,
|
||||||
ast_map,
|
ast_map,
|
||||||
&arenas,
|
&arenas,
|
||||||
id,
|
id,
|
||||||
|
@ -282,7 +282,7 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> {
|
||||||
pub ast_map: Option<&'a hir_map::Map<'ast>>,
|
pub ast_map: Option<&'a hir_map::Map<'ast>>,
|
||||||
pub analysis: Option<&'a ty::CrateAnalysis>,
|
pub analysis: Option<&'a ty::CrateAnalysis>,
|
||||||
pub tcx: Option<&'a ty::ctxt<'tcx>>,
|
pub tcx: Option<&'a ty::ctxt<'tcx>>,
|
||||||
pub lcx: Option<&'a LoweringContext<'tcx>>,
|
pub lcx: Option<&'a LoweringContext<'a, 'tcx>>,
|
||||||
pub trans: Option<&'a trans::CrateTranslation>,
|
pub trans: Option<&'a trans::CrateTranslation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
||||||
krate: &'a ast::Crate,
|
krate: &'a ast::Crate,
|
||||||
hir_crate: &'a hir::Crate,
|
hir_crate: &'a hir::Crate,
|
||||||
crate_name: &'a str,
|
crate_name: &'a str,
|
||||||
lcx: &'a LoweringContext<'tcx>)
|
lcx: &'a LoweringContext<'a, 'tcx>)
|
||||||
-> CompileState<'a, 'ast, 'tcx> {
|
-> CompileState<'a, 'ast, 'tcx> {
|
||||||
CompileState {
|
CompileState {
|
||||||
crate_name: Some(crate_name),
|
crate_name: Some(crate_name),
|
||||||
|
@ -359,7 +359,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
||||||
hir_crate: &'a hir::Crate,
|
hir_crate: &'a hir::Crate,
|
||||||
analysis: &'a ty::CrateAnalysis,
|
analysis: &'a ty::CrateAnalysis,
|
||||||
tcx: &'a ty::ctxt<'tcx>,
|
tcx: &'a ty::ctxt<'tcx>,
|
||||||
lcx: &'a LoweringContext<'tcx>)
|
lcx: &'a LoweringContext<'a, 'tcx>)
|
||||||
-> CompileState<'a, 'ast, 'tcx> {
|
-> CompileState<'a, 'ast, 'tcx> {
|
||||||
CompileState {
|
CompileState {
|
||||||
analysis: Some(analysis),
|
analysis: Some(analysis),
|
||||||
|
@ -659,13 +659,13 @@ pub fn make_map<'ast>(sess: &Session,
|
||||||
/// Run the resolution, typechecking, region checking and other
|
/// Run the resolution, typechecking, region checking and other
|
||||||
/// miscellaneous analysis passes on the crate. Return various
|
/// miscellaneous analysis passes on the crate. Return various
|
||||||
/// structures carrying the results of the analysis.
|
/// structures carrying the results of the analysis.
|
||||||
pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
|
pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||||
ast_map: front::map::Map<'tcx>,
|
ast_map: front::map::Map<'tcx>,
|
||||||
arenas: &'tcx ty::CtxtArenas<'tcx>,
|
arenas: &'tcx ty::CtxtArenas<'tcx>,
|
||||||
name: String,
|
name: String,
|
||||||
make_glob_map: resolve::MakeGlobMap,
|
make_glob_map: resolve::MakeGlobMap,
|
||||||
f: F)
|
f: F)
|
||||||
-> (Session, R)
|
-> R
|
||||||
where F: for<'a> FnOnce(&'a ty::ctxt<'tcx>,
|
where F: for<'a> FnOnce(&'a ty::ctxt<'tcx>,
|
||||||
ty::CrateAnalysis) -> R
|
ty::CrateAnalysis) -> R
|
||||||
{
|
{
|
||||||
|
@ -673,7 +673,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
|
||||||
let krate = ast_map.krate();
|
let krate = ast_map.krate();
|
||||||
|
|
||||||
time(time_passes, "external crate/lib resolution", ||
|
time(time_passes, "external crate/lib resolution", ||
|
||||||
LocalCrateReader::new(&sess, &ast_map).read_crates(krate));
|
LocalCrateReader::new(sess, &ast_map).read_crates(krate));
|
||||||
|
|
||||||
let lang_items = time(time_passes, "language item collection", ||
|
let lang_items = time(time_passes, "language item collection", ||
|
||||||
middle::lang_items::collect_language_items(&sess, &ast_map));
|
middle::lang_items::collect_language_items(&sess, &ast_map));
|
||||||
|
@ -687,7 +687,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
|
||||||
glob_map,
|
glob_map,
|
||||||
} =
|
} =
|
||||||
time(time_passes, "resolution",
|
time(time_passes, "resolution",
|
||||||
|| resolve::resolve_crate(&sess, &ast_map, make_glob_map));
|
|| resolve::resolve_crate(sess, &ast_map, make_glob_map));
|
||||||
|
|
||||||
// Discard MTWT tables that aren't required past resolution.
|
// Discard MTWT tables that aren't required past resolution.
|
||||||
if !sess.opts.debugging_opts.keep_mtwt_tables {
|
if !sess.opts.debugging_opts.keep_mtwt_tables {
|
||||||
|
@ -695,10 +695,10 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
|
||||||
}
|
}
|
||||||
|
|
||||||
let named_region_map = time(time_passes, "lifetime resolution",
|
let named_region_map = time(time_passes, "lifetime resolution",
|
||||||
|| middle::resolve_lifetime::krate(&sess, krate, &def_map));
|
|| middle::resolve_lifetime::krate(sess, krate, &def_map));
|
||||||
|
|
||||||
time(time_passes, "looking for entry point",
|
time(time_passes, "looking for entry point",
|
||||||
|| middle::entry::find_entry_point(&sess, &ast_map));
|
|| middle::entry::find_entry_point(sess, &ast_map));
|
||||||
|
|
||||||
sess.plugin_registrar_fn.set(
|
sess.plugin_registrar_fn.set(
|
||||||
time(time_passes, "looking for plugin registrar", ||
|
time(time_passes, "looking for plugin registrar", ||
|
||||||
|
@ -706,13 +706,13 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
|
||||||
sess.diagnostic(), krate)));
|
sess.diagnostic(), krate)));
|
||||||
|
|
||||||
let region_map = time(time_passes, "region resolution", ||
|
let region_map = time(time_passes, "region resolution", ||
|
||||||
middle::region::resolve_crate(&sess, krate));
|
middle::region::resolve_crate(sess, krate));
|
||||||
|
|
||||||
time(time_passes, "loop checking", ||
|
time(time_passes, "loop checking", ||
|
||||||
middle::check_loop::check_crate(&sess, krate));
|
middle::check_loop::check_crate(sess, krate));
|
||||||
|
|
||||||
time(time_passes, "static item recursion checking", ||
|
time(time_passes, "static item recursion checking", ||
|
||||||
middle::check_static_recursion::check_crate(&sess, krate, &def_map, &ast_map));
|
middle::check_static_recursion::check_crate(sess, krate, &def_map, &ast_map));
|
||||||
|
|
||||||
ty::ctxt::create_and_enter(sess,
|
ty::ctxt::create_and_enter(sess,
|
||||||
arenas,
|
arenas,
|
||||||
|
|
|
@ -131,7 +131,7 @@ pub fn parse_pretty(sess: &Session,
|
||||||
impl PpSourceMode {
|
impl PpSourceMode {
|
||||||
/// Constructs a `PrinterSupport` object and passes it to `f`.
|
/// Constructs a `PrinterSupport` object and passes it to `f`.
|
||||||
fn call_with_pp_support<'tcx, A, B, F>(&self,
|
fn call_with_pp_support<'tcx, A, B, F>(&self,
|
||||||
sess: Session,
|
sess: &'tcx Session,
|
||||||
ast_map: Option<hir_map::Map<'tcx>>,
|
ast_map: Option<hir_map::Map<'tcx>>,
|
||||||
payload: B,
|
payload: B,
|
||||||
f: F) -> A where
|
f: F) -> A where
|
||||||
|
@ -155,7 +155,7 @@ impl PpSourceMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
|
fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
|
||||||
sess: Session,
|
sess: &'tcx Session,
|
||||||
ast_map: &hir_map::Map<'tcx>,
|
ast_map: &hir_map::Map<'tcx>,
|
||||||
arenas: &'tcx ty::CtxtArenas<'tcx>,
|
arenas: &'tcx ty::CtxtArenas<'tcx>,
|
||||||
id: String,
|
id: String,
|
||||||
|
@ -185,7 +185,7 @@ impl PpSourceMode {
|
||||||
|tcx, _| {
|
|tcx, _| {
|
||||||
let annotation = TypedAnnotation { tcx: tcx };
|
let annotation = TypedAnnotation { tcx: tcx };
|
||||||
f(&annotation, payload, &ast_map.forest.krate)
|
f(&annotation, payload, &ast_map.forest.krate)
|
||||||
}).1
|
})
|
||||||
}
|
}
|
||||||
_ => panic!("Should use call_with_pp_support"),
|
_ => panic!("Should use call_with_pp_support"),
|
||||||
}
|
}
|
||||||
|
@ -224,13 +224,13 @@ trait HirPrinterSupport<'ast>: pprust_hir::PpAnn {
|
||||||
fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn;
|
fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NoAnn<'ast> {
|
struct NoAnn<'ast, 'tcx> {
|
||||||
sess: Session,
|
sess: &'tcx Session,
|
||||||
ast_map: Option<hir_map::Map<'ast>>
|
ast_map: Option<hir_map::Map<'ast>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> {
|
impl<'ast, 'tcx> PrinterSupport<'ast> for NoAnn<'ast, 'tcx> {
|
||||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
fn sess<'a>(&'a self) -> &'a Session { self.sess }
|
||||||
|
|
||||||
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
||||||
self.ast_map.as_ref()
|
self.ast_map.as_ref()
|
||||||
|
@ -239,8 +239,8 @@ impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> {
|
||||||
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
|
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> HirPrinterSupport<'ast> for NoAnn<'ast> {
|
impl<'ast, 'tcx> HirPrinterSupport<'ast> for NoAnn<'ast, 'tcx> {
|
||||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
fn sess<'a>(&'a self) -> &'a Session { self.sess }
|
||||||
|
|
||||||
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
||||||
self.ast_map.as_ref()
|
self.ast_map.as_ref()
|
||||||
|
@ -249,16 +249,16 @@ impl<'ast> HirPrinterSupport<'ast> for NoAnn<'ast> {
|
||||||
fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self }
|
fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> pprust::PpAnn for NoAnn<'ast> {}
|
impl<'ast, 'tcx> pprust::PpAnn for NoAnn<'ast, 'tcx> {}
|
||||||
impl<'ast> pprust_hir::PpAnn for NoAnn<'ast> {}
|
impl<'ast, 'tcx> pprust_hir::PpAnn for NoAnn<'ast, 'tcx> {}
|
||||||
|
|
||||||
struct IdentifiedAnnotation<'ast> {
|
struct IdentifiedAnnotation<'ast, 'tcx> {
|
||||||
sess: Session,
|
sess: &'tcx Session,
|
||||||
ast_map: Option<hir_map::Map<'ast>>,
|
ast_map: Option<hir_map::Map<'ast>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
|
impl<'ast, 'tcx> PrinterSupport<'ast> for IdentifiedAnnotation<'ast, 'tcx> {
|
||||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
fn sess<'a>(&'a self) -> &'a Session { self.sess }
|
||||||
|
|
||||||
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
||||||
self.ast_map.as_ref()
|
self.ast_map.as_ref()
|
||||||
|
@ -267,7 +267,7 @@ impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
|
||||||
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
|
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
|
impl<'ast, 'tcx> pprust::PpAnn for IdentifiedAnnotation<'ast, 'tcx> {
|
||||||
fn pre(&self,
|
fn pre(&self,
|
||||||
s: &mut pprust::State,
|
s: &mut pprust::State,
|
||||||
node: pprust::AnnNode) -> io::Result<()> {
|
node: pprust::AnnNode) -> io::Result<()> {
|
||||||
|
@ -307,8 +307,8 @@ impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> HirPrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
|
impl<'ast, 'tcx> HirPrinterSupport<'ast> for IdentifiedAnnotation<'ast, 'tcx> {
|
||||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
fn sess<'a>(&'a self) -> &'a Session { self.sess }
|
||||||
|
|
||||||
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
||||||
self.ast_map.as_ref()
|
self.ast_map.as_ref()
|
||||||
|
@ -317,7 +317,7 @@ impl<'ast> HirPrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
|
||||||
fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self }
|
fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> pprust_hir::PpAnn for IdentifiedAnnotation<'ast> {
|
impl<'ast, 'tcx> pprust_hir::PpAnn for IdentifiedAnnotation<'ast, 'tcx> {
|
||||||
fn pre(&self,
|
fn pre(&self,
|
||||||
s: &mut pprust_hir::State,
|
s: &mut pprust_hir::State,
|
||||||
node: pprust_hir::AnnNode) -> io::Result<()> {
|
node: pprust_hir::AnnNode) -> io::Result<()> {
|
||||||
|
@ -356,13 +356,13 @@ impl<'ast> pprust_hir::PpAnn for IdentifiedAnnotation<'ast> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HygieneAnnotation<'ast> {
|
struct HygieneAnnotation<'ast, 'tcx> {
|
||||||
sess: Session,
|
sess: &'tcx Session,
|
||||||
ast_map: Option<hir_map::Map<'ast>>,
|
ast_map: Option<hir_map::Map<'ast>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> {
|
impl<'ast, 'tcx> PrinterSupport<'ast> for HygieneAnnotation<'ast, 'tcx> {
|
||||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
fn sess<'a>(&'a self) -> &'a Session { self.sess }
|
||||||
|
|
||||||
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
||||||
self.ast_map.as_ref()
|
self.ast_map.as_ref()
|
||||||
|
@ -371,7 +371,7 @@ impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> {
|
||||||
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
|
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
|
impl<'ast, 'tcx> pprust::PpAnn for HygieneAnnotation<'ast, 'tcx> {
|
||||||
fn post(&self,
|
fn post(&self,
|
||||||
s: &mut pprust::State,
|
s: &mut pprust::State,
|
||||||
node: pprust::AnnNode) -> io::Result<()> {
|
node: pprust::AnnNode) -> io::Result<()> {
|
||||||
|
@ -671,7 +671,7 @@ pub fn pretty_print_input(sess: Session,
|
||||||
// the ordering of stuff super-finicky.
|
// the ordering of stuff super-finicky.
|
||||||
let mut hir_forest;
|
let mut hir_forest;
|
||||||
let foo = &42;
|
let foo = &42;
|
||||||
let lcx = LoweringContext::new(foo);
|
let lcx = LoweringContext::new(foo, &sess, &krate);
|
||||||
let arenas = ty::CtxtArenas::new();
|
let arenas = ty::CtxtArenas::new();
|
||||||
let ast_map = if compute_ast_map {
|
let ast_map = if compute_ast_map {
|
||||||
hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate));
|
hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate));
|
||||||
|
@ -697,7 +697,7 @@ pub fn pretty_print_input(sess: Session,
|
||||||
// Silently ignores an identified node.
|
// Silently ignores an identified node.
|
||||||
let out: &mut Write = &mut out;
|
let out: &mut Write = &mut out;
|
||||||
s.call_with_pp_support(
|
s.call_with_pp_support(
|
||||||
sess, ast_map, box out, |annotation, out| {
|
&sess, ast_map, box out, |annotation, out| {
|
||||||
debug!("pretty printing source code {:?}", s);
|
debug!("pretty printing source code {:?}", s);
|
||||||
let sess = annotation.sess();
|
let sess = annotation.sess();
|
||||||
pprust::print_crate(sess.codemap(),
|
pprust::print_crate(sess.codemap(),
|
||||||
|
@ -714,7 +714,7 @@ pub fn pretty_print_input(sess: Session,
|
||||||
(PpmHir(s), None) => {
|
(PpmHir(s), None) => {
|
||||||
let out: &mut Write = &mut out;
|
let out: &mut Write = &mut out;
|
||||||
s.call_with_pp_support_hir(
|
s.call_with_pp_support_hir(
|
||||||
sess, &ast_map.unwrap(), &arenas, id, box out, |annotation, out, krate| {
|
&sess, &ast_map.unwrap(), &arenas, id, box out, |annotation, out, krate| {
|
||||||
debug!("pretty printing source code {:?}", s);
|
debug!("pretty printing source code {:?}", s);
|
||||||
let sess = annotation.sess();
|
let sess = annotation.sess();
|
||||||
pprust_hir::print_crate(sess.codemap(),
|
pprust_hir::print_crate(sess.codemap(),
|
||||||
|
@ -730,7 +730,7 @@ pub fn pretty_print_input(sess: Session,
|
||||||
|
|
||||||
(PpmHir(s), Some(uii)) => {
|
(PpmHir(s), Some(uii)) => {
|
||||||
let out: &mut Write = &mut out;
|
let out: &mut Write = &mut out;
|
||||||
s.call_with_pp_support_hir(sess,
|
s.call_with_pp_support_hir(&sess,
|
||||||
&ast_map.unwrap(),
|
&ast_map.unwrap(),
|
||||||
&arenas,
|
&arenas,
|
||||||
id,
|
id,
|
||||||
|
@ -778,14 +778,14 @@ pub fn pretty_print_input(sess: Session,
|
||||||
match code {
|
match code {
|
||||||
Some(code) => {
|
Some(code) => {
|
||||||
let variants = gather_flowgraph_variants(&sess);
|
let variants = gather_flowgraph_variants(&sess);
|
||||||
driver::phase_3_run_analysis_passes(sess,
|
driver::phase_3_run_analysis_passes(&sess,
|
||||||
ast_map,
|
ast_map,
|
||||||
&arenas,
|
&arenas,
|
||||||
id,
|
id,
|
||||||
resolve::MakeGlobMap::No,
|
resolve::MakeGlobMap::No,
|
||||||
|tcx, _| {
|
|tcx, _| {
|
||||||
print_flowgraph(variants, tcx, code, mode, out)
|
print_flowgraph(variants, tcx, code, mode, out)
|
||||||
}).1
|
})
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let message = format!("--pretty=flowgraph needs \
|
let message = format!("--pretty=flowgraph needs \
|
||||||
|
|
|
@ -14,20 +14,38 @@ use hir;
|
||||||
|
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
use syntax::codemap::{respan, Spanned};
|
use syntax::codemap::{respan, Spanned, Span};
|
||||||
use syntax::owned_slice::OwnedSlice;
|
use syntax::owned_slice::OwnedSlice;
|
||||||
|
use syntax::parse::token::{self, str_to_ident};
|
||||||
|
use syntax::std_inject;
|
||||||
|
|
||||||
pub struct LoweringContext<'hir> {
|
pub struct LoweringContext<'a, 'hir> {
|
||||||
// TODO
|
// TODO
|
||||||
foo: &'hir i32,
|
foo: &'hir i32,
|
||||||
|
id_assigner: &'a NodeIdAssigner,
|
||||||
|
crate_root: Option<&'static str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'hir> LoweringContext<'hir> {
|
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
pub fn new(foo: &'hir i32) -> LoweringContext<'hir> {
|
pub fn new(foo: &'hir i32, id_assigner: &'a NodeIdAssigner, c: &Crate) -> LoweringContext<'a, 'hir> {
|
||||||
|
let crate_root = if std_inject::no_core(c) {
|
||||||
|
None
|
||||||
|
} else if std_inject::no_std(c) {
|
||||||
|
Some("core")
|
||||||
|
} else {
|
||||||
|
Some("std")
|
||||||
|
};
|
||||||
|
|
||||||
LoweringContext {
|
LoweringContext {
|
||||||
foo: foo,
|
foo: foo,
|
||||||
|
id_assigner: id_assigner,
|
||||||
|
crate_root: crate_root,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn next_id(&self) -> NodeId {
|
||||||
|
self.id_assigner.next_node_id()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lower_view_path(_lctx: &LoweringContext, view_path: &ViewPath) -> P<hir::ViewPath> {
|
pub fn lower_view_path(_lctx: &LoweringContext, view_path: &ViewPath) -> P<hir::ViewPath> {
|
||||||
|
@ -727,105 +745,105 @@ pub fn lower_pat(_lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lower_expr(_lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
|
pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
|
||||||
P(hir::Expr {
|
P(hir::Expr {
|
||||||
id: e.id,
|
id: e.id,
|
||||||
node: match e.node {
|
node: match e.node {
|
||||||
ExprBox(ref e) => {
|
ExprBox(ref e) => {
|
||||||
hir::ExprBox(lower_expr(_lctx, e))
|
hir::ExprBox(lower_expr(lctx, e))
|
||||||
}
|
}
|
||||||
ExprVec(ref exprs) => {
|
ExprVec(ref exprs) => {
|
||||||
hir::ExprVec(exprs.iter().map(|x| lower_expr(_lctx, x)).collect())
|
hir::ExprVec(exprs.iter().map(|x| lower_expr(lctx, x)).collect())
|
||||||
}
|
}
|
||||||
ExprRepeat(ref expr, ref count) => {
|
ExprRepeat(ref expr, ref count) => {
|
||||||
hir::ExprRepeat(lower_expr(_lctx, expr), lower_expr(_lctx, count))
|
hir::ExprRepeat(lower_expr(lctx, expr), lower_expr(lctx, count))
|
||||||
}
|
}
|
||||||
ExprTup(ref elts) => {
|
ExprTup(ref elts) => {
|
||||||
hir::ExprTup(elts.iter().map(|x| lower_expr(_lctx, x)).collect())
|
hir::ExprTup(elts.iter().map(|x| lower_expr(lctx, x)).collect())
|
||||||
}
|
}
|
||||||
ExprCall(ref f, ref args) => {
|
ExprCall(ref f, ref args) => {
|
||||||
hir::ExprCall(lower_expr(_lctx, f),
|
hir::ExprCall(lower_expr(lctx, f),
|
||||||
args.iter().map(|x| lower_expr(_lctx, x)).collect())
|
args.iter().map(|x| lower_expr(lctx, x)).collect())
|
||||||
}
|
}
|
||||||
ExprMethodCall(i, ref tps, ref args) => {
|
ExprMethodCall(i, ref tps, ref args) => {
|
||||||
hir::ExprMethodCall(
|
hir::ExprMethodCall(
|
||||||
respan(i.span, i.node.name),
|
respan(i.span, i.node.name),
|
||||||
tps.iter().map(|x| lower_ty(_lctx, x)).collect(),
|
tps.iter().map(|x| lower_ty(lctx, x)).collect(),
|
||||||
args.iter().map(|x| lower_expr(_lctx, x)).collect())
|
args.iter().map(|x| lower_expr(lctx, x)).collect())
|
||||||
}
|
}
|
||||||
ExprBinary(binop, ref lhs, ref rhs) => {
|
ExprBinary(binop, ref lhs, ref rhs) => {
|
||||||
hir::ExprBinary(lower_binop(_lctx, binop),
|
hir::ExprBinary(lower_binop(lctx, binop),
|
||||||
lower_expr(_lctx, lhs),
|
lower_expr(lctx, lhs),
|
||||||
lower_expr(_lctx, rhs))
|
lower_expr(lctx, rhs))
|
||||||
}
|
}
|
||||||
ExprUnary(op, ref ohs) => {
|
ExprUnary(op, ref ohs) => {
|
||||||
hir::ExprUnary(lower_unop(_lctx, op), lower_expr(_lctx, ohs))
|
hir::ExprUnary(lower_unop(lctx, op), lower_expr(lctx, ohs))
|
||||||
}
|
}
|
||||||
ExprLit(ref l) => hir::ExprLit(P((**l).clone())),
|
ExprLit(ref l) => hir::ExprLit(P((**l).clone())),
|
||||||
ExprCast(ref expr, ref ty) => {
|
ExprCast(ref expr, ref ty) => {
|
||||||
hir::ExprCast(lower_expr(_lctx, expr), lower_ty(_lctx, ty))
|
hir::ExprCast(lower_expr(lctx, expr), lower_ty(lctx, ty))
|
||||||
}
|
}
|
||||||
ExprAddrOf(m, ref ohs) => {
|
ExprAddrOf(m, ref ohs) => {
|
||||||
hir::ExprAddrOf(lower_mutability(_lctx, m), lower_expr(_lctx, ohs))
|
hir::ExprAddrOf(lower_mutability(lctx, m), lower_expr(lctx, ohs))
|
||||||
}
|
}
|
||||||
ExprIf(ref cond, ref tr, ref fl) => {
|
ExprIf(ref cond, ref tr, ref fl) => {
|
||||||
hir::ExprIf(lower_expr(_lctx, cond),
|
hir::ExprIf(lower_expr(lctx, cond),
|
||||||
lower_block(_lctx, tr),
|
lower_block(lctx, tr),
|
||||||
fl.as_ref().map(|x| lower_expr(_lctx, x)))
|
fl.as_ref().map(|x| lower_expr(lctx, x)))
|
||||||
}
|
}
|
||||||
ExprWhile(ref cond, ref body, opt_ident) => {
|
ExprWhile(ref cond, ref body, opt_ident) => {
|
||||||
hir::ExprWhile(lower_expr(_lctx, cond),
|
hir::ExprWhile(lower_expr(lctx, cond),
|
||||||
lower_block(_lctx, body),
|
lower_block(lctx, body),
|
||||||
opt_ident)
|
opt_ident)
|
||||||
}
|
}
|
||||||
ExprLoop(ref body, opt_ident) => {
|
ExprLoop(ref body, opt_ident) => {
|
||||||
hir::ExprLoop(lower_block(_lctx, body),
|
hir::ExprLoop(lower_block(lctx, body),
|
||||||
opt_ident)
|
opt_ident)
|
||||||
}
|
}
|
||||||
ExprMatch(ref expr, ref arms, ref source) => {
|
ExprMatch(ref expr, ref arms, ref source) => {
|
||||||
hir::ExprMatch(lower_expr(_lctx, expr),
|
hir::ExprMatch(lower_expr(lctx, expr),
|
||||||
arms.iter().map(|x| lower_arm(_lctx, x)).collect(),
|
arms.iter().map(|x| lower_arm(lctx, x)).collect(),
|
||||||
lower_match_source(_lctx, source))
|
lower_match_source(lctx, source))
|
||||||
}
|
}
|
||||||
ExprClosure(capture_clause, ref decl, ref body) => {
|
ExprClosure(capture_clause, ref decl, ref body) => {
|
||||||
hir::ExprClosure(lower_capture_clause(_lctx, capture_clause),
|
hir::ExprClosure(lower_capture_clause(lctx, capture_clause),
|
||||||
lower_fn_decl(_lctx, decl),
|
lower_fn_decl(lctx, decl),
|
||||||
lower_block(_lctx, body))
|
lower_block(lctx, body))
|
||||||
}
|
}
|
||||||
ExprBlock(ref blk) => hir::ExprBlock(lower_block(_lctx, blk)),
|
ExprBlock(ref blk) => hir::ExprBlock(lower_block(lctx, blk)),
|
||||||
ExprAssign(ref el, ref er) => {
|
ExprAssign(ref el, ref er) => {
|
||||||
hir::ExprAssign(lower_expr(_lctx, el), lower_expr(_lctx, er))
|
hir::ExprAssign(lower_expr(lctx, el), lower_expr(lctx, er))
|
||||||
}
|
}
|
||||||
ExprAssignOp(op, ref el, ref er) => {
|
ExprAssignOp(op, ref el, ref er) => {
|
||||||
hir::ExprAssignOp(lower_binop(_lctx, op),
|
hir::ExprAssignOp(lower_binop(lctx, op),
|
||||||
lower_expr(_lctx, el),
|
lower_expr(lctx, el),
|
||||||
lower_expr(_lctx, er))
|
lower_expr(lctx, er))
|
||||||
}
|
}
|
||||||
ExprField(ref el, ident) => {
|
ExprField(ref el, ident) => {
|
||||||
hir::ExprField(lower_expr(_lctx, el), respan(ident.span, ident.node.name))
|
hir::ExprField(lower_expr(lctx, el), respan(ident.span, ident.node.name))
|
||||||
}
|
}
|
||||||
ExprTupField(ref el, ident) => {
|
ExprTupField(ref el, ident) => {
|
||||||
hir::ExprTupField(lower_expr(_lctx, el), ident)
|
hir::ExprTupField(lower_expr(lctx, el), ident)
|
||||||
}
|
}
|
||||||
ExprIndex(ref el, ref er) => {
|
ExprIndex(ref el, ref er) => {
|
||||||
hir::ExprIndex(lower_expr(_lctx, el), lower_expr(_lctx, er))
|
hir::ExprIndex(lower_expr(lctx, el), lower_expr(lctx, er))
|
||||||
}
|
}
|
||||||
ExprRange(ref e1, ref e2) => {
|
ExprRange(ref e1, ref e2) => {
|
||||||
hir::ExprRange(e1.as_ref().map(|x| lower_expr(_lctx, x)),
|
hir::ExprRange(e1.as_ref().map(|x| lower_expr(lctx, x)),
|
||||||
e2.as_ref().map(|x| lower_expr(_lctx, x)))
|
e2.as_ref().map(|x| lower_expr(lctx, x)))
|
||||||
}
|
}
|
||||||
ExprPath(ref qself, ref path) => {
|
ExprPath(ref qself, ref path) => {
|
||||||
let qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
|
let qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
|
||||||
hir::QSelf {
|
hir::QSelf {
|
||||||
ty: lower_ty(_lctx, ty),
|
ty: lower_ty(lctx, ty),
|
||||||
position: position
|
position: position
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
hir::ExprPath(qself, lower_path(_lctx, path))
|
hir::ExprPath(qself, lower_path(lctx, path))
|
||||||
}
|
}
|
||||||
ExprBreak(opt_ident) => hir::ExprBreak(opt_ident),
|
ExprBreak(opt_ident) => hir::ExprBreak(opt_ident),
|
||||||
ExprAgain(opt_ident) => hir::ExprAgain(opt_ident),
|
ExprAgain(opt_ident) => hir::ExprAgain(opt_ident),
|
||||||
ExprRet(ref e) => hir::ExprRet(e.as_ref().map(|x| lower_expr(_lctx, x))),
|
ExprRet(ref e) => hir::ExprRet(e.as_ref().map(|x| lower_expr(lctx, x))),
|
||||||
ExprInlineAsm(InlineAsm {
|
ExprInlineAsm(InlineAsm {
|
||||||
ref inputs,
|
ref inputs,
|
||||||
ref outputs,
|
ref outputs,
|
||||||
|
@ -838,10 +856,10 @@ pub fn lower_expr(_lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
|
||||||
expn_id,
|
expn_id,
|
||||||
}) => hir::ExprInlineAsm(hir::InlineAsm {
|
}) => hir::ExprInlineAsm(hir::InlineAsm {
|
||||||
inputs: inputs.iter().map(|&(ref c, ref input)| {
|
inputs: inputs.iter().map(|&(ref c, ref input)| {
|
||||||
(c.clone(), lower_expr(_lctx, input))
|
(c.clone(), lower_expr(lctx, input))
|
||||||
}).collect(),
|
}).collect(),
|
||||||
outputs: outputs.iter().map(|&(ref c, ref out, ref is_rw)| {
|
outputs: outputs.iter().map(|&(ref c, ref out, ref is_rw)| {
|
||||||
(c.clone(), lower_expr(_lctx, out), *is_rw)
|
(c.clone(), lower_expr(lctx, out), *is_rw)
|
||||||
}).collect(),
|
}).collect(),
|
||||||
asm: asm.clone(),
|
asm: asm.clone(),
|
||||||
asm_str_style: asm_str_style,
|
asm_str_style: asm_str_style,
|
||||||
|
@ -852,17 +870,124 @@ pub fn lower_expr(_lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
|
||||||
expn_id: expn_id,
|
expn_id: expn_id,
|
||||||
}),
|
}),
|
||||||
ExprStruct(ref path, ref fields, ref maybe_expr) => {
|
ExprStruct(ref path, ref fields, ref maybe_expr) => {
|
||||||
hir::ExprStruct(lower_path(_lctx, path),
|
hir::ExprStruct(lower_path(lctx, path),
|
||||||
fields.iter().map(|x| lower_field(_lctx, x)).collect(),
|
fields.iter().map(|x| lower_field(lctx, x)).collect(),
|
||||||
maybe_expr.as_ref().map(|x| lower_expr(_lctx, x)))
|
maybe_expr.as_ref().map(|x| lower_expr(lctx, x)))
|
||||||
},
|
},
|
||||||
ExprParen(ref ex) => {
|
ExprParen(ref ex) => {
|
||||||
return lower_expr(_lctx, ex);
|
return lower_expr(lctx, ex);
|
||||||
}
|
}
|
||||||
ExprInPlace(..) |
|
ExprInPlace(..) => {
|
||||||
ExprIfLet(..) |
|
panic!("todo");
|
||||||
ExprWhileLet(..) |
|
}
|
||||||
ExprForLoop(..) |
|
ExprIfLet(..) => {
|
||||||
|
panic!("todo");
|
||||||
|
}
|
||||||
|
ExprWhileLet(..) => {
|
||||||
|
panic!("todo");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Desugar ExprForLoop
|
||||||
|
// From: `[opt_ident]: for <pat> in <head> <body>`
|
||||||
|
ExprForLoop(ref pat, ref head, ref body, ref opt_ident) => {
|
||||||
|
// to:
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// let result = match ::std::iter::IntoIterator::into_iter(<head>) {
|
||||||
|
// mut iter => {
|
||||||
|
// [opt_ident]: loop {
|
||||||
|
// match ::std::iter::Iterator::next(&mut iter) {
|
||||||
|
// ::std::option::Option::Some(<pat>) => <body>,
|
||||||
|
// ::std::option::Option::None => break
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// result
|
||||||
|
// }
|
||||||
|
|
||||||
|
// expand <head>
|
||||||
|
let head = lower_expr(lctx, head);
|
||||||
|
|
||||||
|
let iter = token::gensym_ident("iter");
|
||||||
|
|
||||||
|
// `::std::option::Option::Some(<pat>) => <body>`
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
let pat = lower_pat(lctx, pat);
|
||||||
|
let some_pat = pat_some(lctx, e.span, pat);
|
||||||
|
|
||||||
|
arm(vec![some_pat], body_expr)
|
||||||
|
};
|
||||||
|
|
||||||
|
// `::std::option::Option::None => break`
|
||||||
|
let break_arm = {
|
||||||
|
let break_expr = expr_break(lctx, e.span);
|
||||||
|
|
||||||
|
arm(vec![pat_none(lctx, e.span)], break_expr)
|
||||||
|
};
|
||||||
|
|
||||||
|
// `match ::std::iter::Iterator::next(&mut iter) { ... }`
|
||||||
|
let match_expr = {
|
||||||
|
let next_path = {
|
||||||
|
let strs = std_path(lctx, &["iter", "Iterator", "next"]);
|
||||||
|
|
||||||
|
path_global(e.span, strs)
|
||||||
|
};
|
||||||
|
let ref_mut_iter = expr_mut_addr_of(lctx, e.span, expr_ident(lctx, e.span, iter));
|
||||||
|
let next_expr =
|
||||||
|
expr_call(lctx, e.span, expr_path(lctx, next_path), vec![ref_mut_iter]);
|
||||||
|
let arms = vec![pat_arm, break_arm];
|
||||||
|
|
||||||
|
expr(lctx,
|
||||||
|
e.span,
|
||||||
|
hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar))
|
||||||
|
};
|
||||||
|
|
||||||
|
// `[opt_ident]: loop { ... }`
|
||||||
|
let loop_block = block_expr(lctx, match_expr);
|
||||||
|
let loop_expr = expr(lctx, e.span, hir::ExprLoop(loop_block, opt_ident.clone()));
|
||||||
|
|
||||||
|
// `mut iter => { ... }`
|
||||||
|
let iter_arm = {
|
||||||
|
let iter_pat =
|
||||||
|
pat_ident_binding_mode(lctx, e.span, iter, hir::BindByValue(hir::MutMutable));
|
||||||
|
arm(vec![iter_pat], loop_expr)
|
||||||
|
};
|
||||||
|
|
||||||
|
// `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
|
||||||
|
let into_iter_expr = {
|
||||||
|
let into_iter_path = {
|
||||||
|
let strs = std_path(lctx, &["iter", "IntoIterator", "into_iter"]);
|
||||||
|
|
||||||
|
path_global(e.span, strs)
|
||||||
|
};
|
||||||
|
|
||||||
|
expr_call(lctx, e.span, expr_path(lctx, into_iter_path), vec![head])
|
||||||
|
};
|
||||||
|
|
||||||
|
let match_expr = expr_match(lctx, e.span, into_iter_expr, vec![iter_arm]);
|
||||||
|
|
||||||
|
// `{ let result = ...; result }`
|
||||||
|
let result_ident = token::gensym_ident("result");
|
||||||
|
let result = expr_block(lctx,
|
||||||
|
block_all(lctx,
|
||||||
|
e.span,
|
||||||
|
vec![stmt_let(lctx,
|
||||||
|
e.span,
|
||||||
|
false,
|
||||||
|
result_ident,
|
||||||
|
match_expr)],
|
||||||
|
Some(expr_ident(lctx, e.span, result_ident))));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ExprMac(_) => panic!("Shouldn't exist here"),
|
ExprMac(_) => panic!("Shouldn't exist here"),
|
||||||
},
|
},
|
||||||
span: e.span,
|
span: e.span,
|
||||||
|
@ -972,3 +1097,168 @@ pub fn lower_trait_bound_modifier(_lctx: &LoweringContext,
|
||||||
TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
|
TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper methods for building HIR.
|
||||||
|
|
||||||
|
fn arm(pats: Vec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
|
||||||
|
hir::Arm {
|
||||||
|
attrs: vec!(),
|
||||||
|
pats: pats,
|
||||||
|
guard: None,
|
||||||
|
body: expr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expr_break(lctx: &LoweringContext, span: Span) -> P<hir::Expr> {
|
||||||
|
expr(lctx, span, hir::ExprBreak(None))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expr_call(lctx: &LoweringContext, span: Span, e: P<hir::Expr>, args: Vec<P<hir::Expr>>) -> P<hir::Expr> {
|
||||||
|
expr(lctx, span, hir::ExprCall(e, args))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expr_ident(lctx: &LoweringContext, span: Span, id: Ident) -> P<hir::Expr> {
|
||||||
|
expr_path(lctx, path_ident(span, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P<hir::Expr>) -> P<hir::Expr> {
|
||||||
|
expr(lctx, span, hir::ExprAddrOf(hir::MutMutable, e))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expr_path(lctx: &LoweringContext, path: hir::Path) -> P<hir::Expr> {
|
||||||
|
expr(lctx, path.span, hir::ExprPath(None, path))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expr_match(lctx: &LoweringContext, span: Span, arg: P<hir::Expr>, arms: Vec<hir::Arm>) -> P<hir::Expr> {
|
||||||
|
expr(lctx, span, hir::ExprMatch(arg, arms, hir::MatchSource::Normal))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expr_block(lctx: &LoweringContext, b: P<hir::Block>) -> P<hir::Expr> {
|
||||||
|
expr(lctx, b.span, hir::ExprBlock(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_) -> P<hir::Expr> {
|
||||||
|
P(hir::Expr {
|
||||||
|
id: lctx.next_id(),
|
||||||
|
node: node,
|
||||||
|
span: span,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stmt_let(lctx: &LoweringContext, sp: Span, mutbl: bool, ident: Ident, ex: P<hir::Expr>) -> P<hir::Stmt> {
|
||||||
|
let pat = if mutbl {
|
||||||
|
pat_ident_binding_mode(lctx, sp, ident, hir::BindByValue(hir::MutMutable))
|
||||||
|
} else {
|
||||||
|
pat_ident(lctx, sp, ident)
|
||||||
|
};
|
||||||
|
let local = P(hir::Local {
|
||||||
|
pat: pat,
|
||||||
|
ty: None,
|
||||||
|
init: Some(ex),
|
||||||
|
id: lctx.next_id(),
|
||||||
|
span: sp,
|
||||||
|
});
|
||||||
|
let decl = respan(sp, hir::DeclLocal(local));
|
||||||
|
P(respan(sp, hir::StmtDecl(P(decl), lctx.next_id())))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_expr(lctx: &LoweringContext, expr: P<hir::Expr>) -> P<hir::Block> {
|
||||||
|
block_all(lctx, expr.span, Vec::new(), Some(expr))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_all(lctx: &LoweringContext,
|
||||||
|
span: Span,
|
||||||
|
stmts: Vec<P<hir::Stmt>>,
|
||||||
|
expr: Option<P<hir::Expr>>) -> P<hir::Block> {
|
||||||
|
P(hir::Block {
|
||||||
|
stmts: stmts,
|
||||||
|
expr: expr,
|
||||||
|
id: lctx.next_id(),
|
||||||
|
rules: hir::DefaultBlock,
|
||||||
|
span: span,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pat_some(lctx: &LoweringContext, span: Span, pat: P<hir::Pat>) -> P<hir::Pat> {
|
||||||
|
let some = std_path(lctx, &["option", "Option", "Some"]);
|
||||||
|
let path = path_global(span, some);
|
||||||
|
pat_enum(lctx, span, path, vec!(pat))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pat_none(lctx: &LoweringContext, span: Span) -> P<hir::Pat> {
|
||||||
|
let none = std_path(lctx, &["option", "Option", "None"]);
|
||||||
|
let path = path_global(span, none);
|
||||||
|
pat_enum(lctx, span, path, vec![])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pat_enum(lctx: &LoweringContext, span: Span, path: hir::Path, subpats: Vec<P<hir::Pat>>) -> P<hir::Pat> {
|
||||||
|
let pt = hir::PatEnum(path, Some(subpats));
|
||||||
|
pat(lctx, span, pt)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pat_ident(lctx: &LoweringContext, span: Span, ident: Ident) -> P<hir::Pat> {
|
||||||
|
pat_ident_binding_mode(lctx, span, ident, hir::BindByValue(hir::MutImmutable))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pat_ident_binding_mode(lctx: &LoweringContext,
|
||||||
|
span: Span,
|
||||||
|
ident: Ident,
|
||||||
|
bm: hir::BindingMode) -> P<hir::Pat> {
|
||||||
|
let pat_ident = hir::PatIdent(bm, Spanned{span: span, node: ident}, None);
|
||||||
|
pat(lctx, span, pat_ident)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pat(lctx: &LoweringContext, span: Span, pat: hir::Pat_) -> P<hir::Pat> {
|
||||||
|
P(hir::Pat { id: lctx.next_id(), node: pat, span: span })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path_ident(span: Span, id: Ident) -> hir::Path {
|
||||||
|
path(span, vec!(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(span: Span, strs: Vec<Ident> ) -> hir::Path {
|
||||||
|
path_all(span, false, strs, Vec::new(), Vec::new(), Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path_global(span: Span, strs: Vec<Ident> ) -> hir::Path {
|
||||||
|
path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path_all(sp: Span,
|
||||||
|
global: bool,
|
||||||
|
mut idents: Vec<Ident> ,
|
||||||
|
lifetimes: Vec<hir::Lifetime>,
|
||||||
|
types: Vec<P<hir::Ty>>,
|
||||||
|
bindings: Vec<P<hir::TypeBinding>> )
|
||||||
|
-> hir::Path {
|
||||||
|
let last_identifier = idents.pop().unwrap();
|
||||||
|
let mut segments: Vec<hir::PathSegment> = 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: OwnedSlice::from_vec(types),
|
||||||
|
bindings: OwnedSlice::from_vec(bindings),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
hir::Path {
|
||||||
|
span: sp,
|
||||||
|
global: global,
|
||||||
|
segments: segments,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec<Ident> {
|
||||||
|
let mut v = Vec::new();
|
||||||
|
if let Some(s) = lctx.crate_root {
|
||||||
|
v.push(str_to_ident(s));
|
||||||
|
}
|
||||||
|
v.extend(components.iter().map(|s| str_to_ident(s)));
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ pub struct DumpCsvVisitor<'l, 'tcx: 'l> {
|
||||||
|
|
||||||
impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
||||||
pub fn new(tcx: &'l ty::ctxt<'tcx>,
|
pub fn new(tcx: &'l ty::ctxt<'tcx>,
|
||||||
lcx: &'l LoweringContext<'tcx>,
|
lcx: &'l LoweringContext<'l, 'tcx>,
|
||||||
analysis: &'l ty::CrateAnalysis,
|
analysis: &'l ty::CrateAnalysis,
|
||||||
output_file: Box<File>)
|
output_file: Box<File>)
|
||||||
-> DumpCsvVisitor<'l, 'tcx> {
|
-> DumpCsvVisitor<'l, 'tcx> {
|
||||||
|
|
|
@ -38,7 +38,7 @@ mod dump_csv;
|
||||||
|
|
||||||
pub struct SaveContext<'l, 'tcx: 'l> {
|
pub struct SaveContext<'l, 'tcx: 'l> {
|
||||||
tcx: &'l ty::ctxt<'tcx>,
|
tcx: &'l ty::ctxt<'tcx>,
|
||||||
lcx: &'l lowering::LoweringContext<'tcx>,
|
lcx: &'l lowering::LoweringContext<'l, 'tcx>,
|
||||||
span_utils: SpanUtils<'l>,
|
span_utils: SpanUtils<'l>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,13 +177,15 @@ pub struct MethodCallData {
|
||||||
|
|
||||||
|
|
||||||
impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||||
pub fn new(tcx: &'l ty::ctxt<'tcx>, lcx: &'l lowering::LoweringContext<'tcx>) -> SaveContext<'l, 'tcx> {
|
pub fn new(tcx: &'l ty::ctxt<'tcx>,
|
||||||
|
lcx: &'l lowering::LoweringContext<'l, 'tcx>)
|
||||||
|
-> SaveContext<'l, 'tcx> {
|
||||||
let span_utils = SpanUtils::new(&tcx.sess);
|
let span_utils = SpanUtils::new(&tcx.sess);
|
||||||
SaveContext::from_span_utils(tcx, lcx, span_utils)
|
SaveContext::from_span_utils(tcx, lcx, span_utils)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_span_utils(tcx: &'l ty::ctxt<'tcx>,
|
pub fn from_span_utils(tcx: &'l ty::ctxt<'tcx>,
|
||||||
lcx: &'l lowering::LoweringContext<'tcx>,
|
lcx: &'l lowering::LoweringContext<'l, 'tcx>,
|
||||||
span_utils: SpanUtils<'l>)
|
span_utils: SpanUtils<'l>)
|
||||||
-> SaveContext<'l, 'tcx> {
|
-> SaveContext<'l, 'tcx> {
|
||||||
SaveContext {
|
SaveContext {
|
||||||
|
@ -709,7 +711,7 @@ impl<'v> Visitor<'v> for PathCollector {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_crate<'l, 'tcx>(tcx: &'l ty::ctxt<'tcx>,
|
pub fn process_crate<'l, 'tcx>(tcx: &'l ty::ctxt<'tcx>,
|
||||||
lcx: &'l lowering::LoweringContext<'tcx>,
|
lcx: &'l lowering::LoweringContext<'l, 'tcx>,
|
||||||
krate: &ast::Crate,
|
krate: &ast::Crate,
|
||||||
analysis: &ty::CrateAnalysis,
|
analysis: &ty::CrateAnalysis,
|
||||||
odir: Option<&Path>) {
|
odir: Option<&Path>) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::parse::token;
|
use syntax::parse::token;
|
||||||
|
use syntax::ast::NodeIdAssigner;
|
||||||
use util::nodemap::{DefIdMap, FnvHashMap};
|
use util::nodemap::{DefIdMap, FnvHashMap};
|
||||||
use rustc::front::map as hir_map;
|
use rustc::front::map as hir_map;
|
||||||
use rustc::front::map::NodeItem;
|
use rustc::front::map::NodeItem;
|
||||||
|
|
|
@ -375,6 +375,10 @@ pub const CRATE_NODE_ID: NodeId = 0;
|
||||||
/// small, positive ids.
|
/// small, positive ids.
|
||||||
pub const DUMMY_NODE_ID: NodeId = !0;
|
pub const DUMMY_NODE_ID: NodeId = !0;
|
||||||
|
|
||||||
|
pub trait NodeIdAssigner {
|
||||||
|
fn next_node_id(&self) -> NodeId;
|
||||||
|
}
|
||||||
|
|
||||||
/// The AST represents all type param bounds as types.
|
/// The AST represents all type param bounds as types.
|
||||||
/// typeck::collect::compute_bounds matches these against
|
/// typeck::collect::compute_bounds matches these against
|
||||||
/// the "special" built-in traits (see middle::lang_items) and
|
/// the "special" built-in traits (see middle::lang_items) and
|
||||||
|
|
|
@ -360,102 +360,10 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
|
||||||
fld.cx.expr(span, ast::ExprLoop(loop_block, opt_ident))
|
fld.cx.expr(span, ast::ExprLoop(loop_block, opt_ident))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Desugar ExprForLoop
|
|
||||||
// From: `[opt_ident]: for <pat> in <head> <body>`
|
|
||||||
ast::ExprForLoop(pat, head, body, opt_ident) => {
|
ast::ExprForLoop(pat, head, body, opt_ident) => {
|
||||||
// to:
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// let result = match ::std::iter::IntoIterator::into_iter(<head>) {
|
|
||||||
// mut iter => {
|
|
||||||
// [opt_ident]: loop {
|
|
||||||
// match ::std::iter::Iterator::next(&mut iter) {
|
|
||||||
// ::std::option::Option::Some(<pat>) => <body>,
|
|
||||||
// ::std::option::Option::None => break
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// result
|
|
||||||
// }
|
|
||||||
|
|
||||||
push_compiler_expansion(fld, span, CompilerExpansionFormat::ForLoop);
|
|
||||||
|
|
||||||
let span = fld.new_span(span);
|
|
||||||
|
|
||||||
// expand <head>
|
|
||||||
let head = fld.fold_expr(head);
|
let head = fld.fold_expr(head);
|
||||||
|
let (body, opt_ident) = expand_loop_block(body, opt_ident, fld);
|
||||||
let iter = token::gensym_ident("iter");
|
fld.cx.expr(span, ast::ExprForLoop(pat, head, body, opt_ident))
|
||||||
|
|
||||||
let pat_span = fld.new_span(pat.span);
|
|
||||||
// `::std::option::Option::Some(<pat>) => <body>`
|
|
||||||
let pat_arm = {
|
|
||||||
let body_expr = fld.cx.expr_block(body);
|
|
||||||
let pat = fld.fold_pat(pat);
|
|
||||||
let some_pat = fld.cx.pat_some(pat_span, pat);
|
|
||||||
|
|
||||||
fld.cx.arm(pat_span, vec![some_pat], body_expr)
|
|
||||||
};
|
|
||||||
|
|
||||||
// `::std::option::Option::None => break`
|
|
||||||
let break_arm = {
|
|
||||||
let break_expr = fld.cx.expr_break(span);
|
|
||||||
|
|
||||||
fld.cx.arm(span, vec![fld.cx.pat_none(span)], break_expr)
|
|
||||||
};
|
|
||||||
|
|
||||||
// `match ::std::iter::Iterator::next(&mut iter) { ... }`
|
|
||||||
let match_expr = {
|
|
||||||
let next_path = {
|
|
||||||
let strs = fld.cx.std_path(&["iter", "Iterator", "next"]);
|
|
||||||
|
|
||||||
fld.cx.path_global(span, strs)
|
|
||||||
};
|
|
||||||
let ref_mut_iter = fld.cx.expr_mut_addr_of(span, fld.cx.expr_ident(span, iter));
|
|
||||||
let next_expr =
|
|
||||||
fld.cx.expr_call(span, fld.cx.expr_path(next_path), vec![ref_mut_iter]);
|
|
||||||
let arms = vec![pat_arm, break_arm];
|
|
||||||
|
|
||||||
fld.cx.expr(pat_span,
|
|
||||||
ast::ExprMatch(next_expr, arms, ast::MatchSource::ForLoopDesugar))
|
|
||||||
};
|
|
||||||
|
|
||||||
// `[opt_ident]: loop { ... }`
|
|
||||||
let loop_block = fld.cx.block_expr(match_expr);
|
|
||||||
let (loop_block, opt_ident) = expand_loop_block(loop_block, opt_ident, fld);
|
|
||||||
let loop_expr = fld.cx.expr(span, ast::ExprLoop(loop_block, opt_ident));
|
|
||||||
|
|
||||||
// `mut iter => { ... }`
|
|
||||||
let iter_arm = {
|
|
||||||
let iter_pat =
|
|
||||||
fld.cx.pat_ident_binding_mode(span, iter, ast::BindByValue(ast::MutMutable));
|
|
||||||
fld.cx.arm(span, vec![iter_pat], loop_expr)
|
|
||||||
};
|
|
||||||
|
|
||||||
// `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
|
|
||||||
let into_iter_expr = {
|
|
||||||
let into_iter_path = {
|
|
||||||
let strs = fld.cx.std_path(&["iter", "IntoIterator",
|
|
||||||
"into_iter"]);
|
|
||||||
|
|
||||||
fld.cx.path_global(span, strs)
|
|
||||||
};
|
|
||||||
|
|
||||||
fld.cx.expr_call(span, fld.cx.expr_path(into_iter_path), vec![head])
|
|
||||||
};
|
|
||||||
|
|
||||||
let match_expr = fld.cx.expr_match(span, into_iter_expr, vec![iter_arm]);
|
|
||||||
|
|
||||||
// `{ let result = ...; result }`
|
|
||||||
let result_ident = token::gensym_ident("result");
|
|
||||||
let result = fld.cx.expr_block(
|
|
||||||
fld.cx.block_all(
|
|
||||||
span,
|
|
||||||
vec![fld.cx.stmt_let(span, false, result_ident, match_expr)],
|
|
||||||
Some(fld.cx.expr_ident(span, result_ident))));
|
|
||||||
fld.cx.bt_pop();
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ExprClosure(capture_clause, fn_decl, block) => {
|
ast::ExprClosure(capture_clause, fn_decl, block) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue