mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Move for
loop desugaring to lowering
This commit is contained in:
parent
56713a1684
commit
20083c1e1f
@ -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_resolve := 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 := 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
|
||||
DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
|
||||
DEPS_rustc_platform_intrinsics := rustc rustc_llvm
|
||||
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_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
|
||||
test rustc_lint rustc_front
|
||||
|
@ -36,6 +36,7 @@ use middle::subst;
|
||||
use middle::ty::{self, Ty};
|
||||
|
||||
use syntax::{ast, ast_util, codemap};
|
||||
use syntax::ast::NodeIdAssigner;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ptr::P;
|
||||
|
||||
|
@ -219,7 +219,7 @@ pub struct ctxt<'tcx> {
|
||||
/// Common types, pre-interned for your convenience.
|
||||
pub types: CommonTypes<'tcx>,
|
||||
|
||||
pub sess: Session,
|
||||
pub sess: &'tcx Session,
|
||||
pub def_map: DefMap,
|
||||
|
||||
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
|
||||
/// 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.
|
||||
pub fn create_and_enter<F, R>(s: Session,
|
||||
pub fn create_and_enter<F, R>(s: &'tcx Session,
|
||||
arenas: &'tcx CtxtArenas<'tcx>,
|
||||
def_map: DefMap,
|
||||
named_region_map: resolve_lifetime::NamedRegionMap,
|
||||
@ -452,7 +452,7 @@ impl<'tcx> ctxt<'tcx> {
|
||||
region_maps: RegionMaps,
|
||||
lang_items: middle::lang_items::LanguageItems,
|
||||
stability: stability::Index<'tcx>,
|
||||
f: F) -> (Session, R)
|
||||
f: F) -> R
|
||||
where F: FnOnce(&ctxt<'tcx>) -> R
|
||||
{
|
||||
let interner = RefCell::new(FnvHashMap());
|
||||
@ -556,7 +556,6 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> {
|
||||
|
||||
pub mod tls {
|
||||
use middle::ty;
|
||||
use session::Session;
|
||||
|
||||
use std::fmt;
|
||||
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)
|
||||
-> (Session, R) {
|
||||
let result = codemap::SPAN_DEBUG.with(|span_dbg| {
|
||||
pub fn enter<'tcx, F: FnOnce(&ty::ctxt<'tcx>) -> R, R>(tcx: ty::ctxt<'tcx>, f: F) -> R {
|
||||
codemap::SPAN_DEBUG.with(|span_dbg| {
|
||||
let original_span_debug = span_dbg.get();
|
||||
span_dbg.set(span_debug);
|
||||
let tls_ptr = &tcx as *const _ as *const ThreadLocalTyCx;
|
||||
let result = TLS_TCX.set(unsafe { &*tls_ptr }, || f(&tcx));
|
||||
span_dbg.set(original_span_debug);
|
||||
result
|
||||
});
|
||||
(tcx.sess, result)
|
||||
})
|
||||
}
|
||||
|
||||
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 util::nodemap::{NodeMap, FnvHashMap};
|
||||
|
||||
use syntax::ast::NodeId;
|
||||
use syntax::ast::{NodeId, NodeIdAssigner};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::diagnostic::{self, Emitter};
|
||||
use syntax::diagnostics;
|
||||
@ -236,9 +236,6 @@ impl Session {
|
||||
}
|
||||
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 {
|
||||
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> {
|
||||
// Conditions for enabling multi-line errors:
|
||||
if !msg.contains("mismatched types") &&
|
||||
|
@ -42,7 +42,7 @@ use std::ffi::{OsString, OsStr};
|
||||
use std::fs;
|
||||
use std::io::{self, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use syntax::ast;
|
||||
use syntax::ast::{self, NodeIdAssigner};
|
||||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::diagnostics;
|
||||
@ -71,7 +71,7 @@ pub fn compile_input(sess: Session,
|
||||
// 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
|
||||
// possible to keep the peak memory usage low
|
||||
let (sess, result) = {
|
||||
let result = {
|
||||
let (outputs, expanded_crate, id) = {
|
||||
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);
|
||||
// Lower ast -> hir.
|
||||
let foo = &42;
|
||||
let lcx = LoweringContext::new(foo);
|
||||
let lcx = LoweringContext::new(foo, &sess, &expanded_crate);
|
||||
let mut hir_forest = time(sess.time_passes(),
|
||||
"lowering ast -> hir",
|
||||
|| 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)
|
||||
});
|
||||
|
||||
phase_3_run_analysis_passes(sess,
|
||||
phase_3_run_analysis_passes(&sess,
|
||||
ast_map,
|
||||
&arenas,
|
||||
id,
|
||||
@ -282,7 +282,7 @@ pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> {
|
||||
pub ast_map: Option<&'a hir_map::Map<'ast>>,
|
||||
pub analysis: Option<&'a ty::CrateAnalysis>,
|
||||
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>,
|
||||
}
|
||||
|
||||
@ -340,7 +340,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
||||
krate: &'a ast::Crate,
|
||||
hir_crate: &'a hir::Crate,
|
||||
crate_name: &'a str,
|
||||
lcx: &'a LoweringContext<'tcx>)
|
||||
lcx: &'a LoweringContext<'a, 'tcx>)
|
||||
-> CompileState<'a, 'ast, 'tcx> {
|
||||
CompileState {
|
||||
crate_name: Some(crate_name),
|
||||
@ -359,7 +359,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
|
||||
hir_crate: &'a hir::Crate,
|
||||
analysis: &'a ty::CrateAnalysis,
|
||||
tcx: &'a ty::ctxt<'tcx>,
|
||||
lcx: &'a LoweringContext<'tcx>)
|
||||
lcx: &'a LoweringContext<'a, 'tcx>)
|
||||
-> CompileState<'a, 'ast, 'tcx> {
|
||||
CompileState {
|
||||
analysis: Some(analysis),
|
||||
@ -659,13 +659,13 @@ pub fn make_map<'ast>(sess: &Session,
|
||||
/// Run the resolution, typechecking, region checking and other
|
||||
/// miscellaneous analysis passes on the crate. Return various
|
||||
/// 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>,
|
||||
arenas: &'tcx ty::CtxtArenas<'tcx>,
|
||||
name: String,
|
||||
make_glob_map: resolve::MakeGlobMap,
|
||||
f: F)
|
||||
-> (Session, R)
|
||||
-> R
|
||||
where F: for<'a> FnOnce(&'a ty::ctxt<'tcx>,
|
||||
ty::CrateAnalysis) -> R
|
||||
{
|
||||
@ -673,7 +673,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
|
||||
let krate = ast_map.krate();
|
||||
|
||||
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", ||
|
||||
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,
|
||||
} =
|
||||
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.
|
||||
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",
|
||||
|| middle::resolve_lifetime::krate(&sess, krate, &def_map));
|
||||
|| middle::resolve_lifetime::krate(sess, krate, &def_map));
|
||||
|
||||
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(
|
||||
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)));
|
||||
|
||||
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", ||
|
||||
middle::check_loop::check_crate(&sess, krate));
|
||||
middle::check_loop::check_crate(sess, krate));
|
||||
|
||||
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,
|
||||
arenas,
|
||||
|
@ -131,7 +131,7 @@ pub fn parse_pretty(sess: &Session,
|
||||
impl PpSourceMode {
|
||||
/// Constructs a `PrinterSupport` object and passes it to `f`.
|
||||
fn call_with_pp_support<'tcx, A, B, F>(&self,
|
||||
sess: Session,
|
||||
sess: &'tcx Session,
|
||||
ast_map: Option<hir_map::Map<'tcx>>,
|
||||
payload: B,
|
||||
f: F) -> A where
|
||||
@ -155,7 +155,7 @@ impl PpSourceMode {
|
||||
}
|
||||
}
|
||||
fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
|
||||
sess: Session,
|
||||
sess: &'tcx Session,
|
||||
ast_map: &hir_map::Map<'tcx>,
|
||||
arenas: &'tcx ty::CtxtArenas<'tcx>,
|
||||
id: String,
|
||||
@ -185,7 +185,7 @@ impl PpSourceMode {
|
||||
|tcx, _| {
|
||||
let annotation = TypedAnnotation { tcx: tcx };
|
||||
f(&annotation, payload, &ast_map.forest.krate)
|
||||
}).1
|
||||
})
|
||||
}
|
||||
_ => 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;
|
||||
}
|
||||
|
||||
struct NoAnn<'ast> {
|
||||
sess: Session,
|
||||
struct NoAnn<'ast, 'tcx> {
|
||||
sess: &'tcx Session,
|
||||
ast_map: Option<hir_map::Map<'ast>>
|
||||
}
|
||||
|
||||
impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
||||
impl<'ast, 'tcx> PrinterSupport<'ast> for NoAnn<'ast, 'tcx> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { self.sess }
|
||||
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
||||
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 }
|
||||
}
|
||||
|
||||
impl<'ast> HirPrinterSupport<'ast> for NoAnn<'ast> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
||||
impl<'ast, 'tcx> HirPrinterSupport<'ast> for NoAnn<'ast, 'tcx> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { self.sess }
|
||||
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
||||
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 }
|
||||
}
|
||||
|
||||
impl<'ast> pprust::PpAnn for NoAnn<'ast> {}
|
||||
impl<'ast> pprust_hir::PpAnn for NoAnn<'ast> {}
|
||||
impl<'ast, 'tcx> pprust::PpAnn for NoAnn<'ast, 'tcx> {}
|
||||
impl<'ast, 'tcx> pprust_hir::PpAnn for NoAnn<'ast, 'tcx> {}
|
||||
|
||||
struct IdentifiedAnnotation<'ast> {
|
||||
sess: Session,
|
||||
struct IdentifiedAnnotation<'ast, 'tcx> {
|
||||
sess: &'tcx Session,
|
||||
ast_map: Option<hir_map::Map<'ast>>,
|
||||
}
|
||||
|
||||
impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
||||
impl<'ast, 'tcx> PrinterSupport<'ast> for IdentifiedAnnotation<'ast, 'tcx> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { self.sess }
|
||||
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
||||
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 }
|
||||
}
|
||||
|
||||
impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
|
||||
impl<'ast, 'tcx> pprust::PpAnn for IdentifiedAnnotation<'ast, 'tcx> {
|
||||
fn pre(&self,
|
||||
s: &mut pprust::State,
|
||||
node: pprust::AnnNode) -> io::Result<()> {
|
||||
@ -307,8 +307,8 @@ impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast> HirPrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
||||
impl<'ast, 'tcx> HirPrinterSupport<'ast> for IdentifiedAnnotation<'ast, 'tcx> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { self.sess }
|
||||
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
||||
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 }
|
||||
}
|
||||
|
||||
impl<'ast> pprust_hir::PpAnn for IdentifiedAnnotation<'ast> {
|
||||
impl<'ast, 'tcx> pprust_hir::PpAnn for IdentifiedAnnotation<'ast, 'tcx> {
|
||||
fn pre(&self,
|
||||
s: &mut pprust_hir::State,
|
||||
node: pprust_hir::AnnNode) -> io::Result<()> {
|
||||
@ -356,13 +356,13 @@ impl<'ast> pprust_hir::PpAnn for IdentifiedAnnotation<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
struct HygieneAnnotation<'ast> {
|
||||
sess: Session,
|
||||
struct HygieneAnnotation<'ast, 'tcx> {
|
||||
sess: &'tcx Session,
|
||||
ast_map: Option<hir_map::Map<'ast>>,
|
||||
}
|
||||
|
||||
impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
||||
impl<'ast, 'tcx> PrinterSupport<'ast> for HygieneAnnotation<'ast, 'tcx> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { self.sess }
|
||||
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a hir_map::Map<'ast>> {
|
||||
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 }
|
||||
}
|
||||
|
||||
impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
|
||||
impl<'ast, 'tcx> pprust::PpAnn for HygieneAnnotation<'ast, 'tcx> {
|
||||
fn post(&self,
|
||||
s: &mut pprust::State,
|
||||
node: pprust::AnnNode) -> io::Result<()> {
|
||||
@ -671,7 +671,7 @@ pub fn pretty_print_input(sess: Session,
|
||||
// the ordering of stuff super-finicky.
|
||||
let mut hir_forest;
|
||||
let foo = &42;
|
||||
let lcx = LoweringContext::new(foo);
|
||||
let lcx = LoweringContext::new(foo, &sess, &krate);
|
||||
let arenas = ty::CtxtArenas::new();
|
||||
let ast_map = if compute_ast_map {
|
||||
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.
|
||||
let out: &mut Write = &mut out;
|
||||
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);
|
||||
let sess = annotation.sess();
|
||||
pprust::print_crate(sess.codemap(),
|
||||
@ -714,7 +714,7 @@ pub fn pretty_print_input(sess: Session,
|
||||
(PpmHir(s), None) => {
|
||||
let out: &mut Write = &mut out;
|
||||
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);
|
||||
let sess = annotation.sess();
|
||||
pprust_hir::print_crate(sess.codemap(),
|
||||
@ -730,7 +730,7 @@ pub fn pretty_print_input(sess: Session,
|
||||
|
||||
(PpmHir(s), Some(uii)) => {
|
||||
let out: &mut Write = &mut out;
|
||||
s.call_with_pp_support_hir(sess,
|
||||
s.call_with_pp_support_hir(&sess,
|
||||
&ast_map.unwrap(),
|
||||
&arenas,
|
||||
id,
|
||||
@ -778,14 +778,14 @@ pub fn pretty_print_input(sess: Session,
|
||||
match code {
|
||||
Some(code) => {
|
||||
let variants = gather_flowgraph_variants(&sess);
|
||||
driver::phase_3_run_analysis_passes(sess,
|
||||
driver::phase_3_run_analysis_passes(&sess,
|
||||
ast_map,
|
||||
&arenas,
|
||||
id,
|
||||
resolve::MakeGlobMap::No,
|
||||
|tcx, _| {
|
||||
print_flowgraph(variants, tcx, code, mode, out)
|
||||
}).1
|
||||
})
|
||||
}
|
||||
None => {
|
||||
let message = format!("--pretty=flowgraph needs \
|
||||
|
@ -14,20 +14,38 @@ use hir;
|
||||
|
||||
use syntax::ast::*;
|
||||
use syntax::ptr::P;
|
||||
use syntax::codemap::{respan, Spanned};
|
||||
use syntax::codemap::{respan, Spanned, Span};
|
||||
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
|
||||
foo: &'hir i32,
|
||||
id_assigner: &'a NodeIdAssigner,
|
||||
crate_root: Option<&'static str>,
|
||||
}
|
||||
|
||||
impl<'hir> LoweringContext<'hir> {
|
||||
pub fn new(foo: &'hir i32) -> LoweringContext<'hir> {
|
||||
impl<'a, 'hir> LoweringContext<'a, '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 {
|
||||
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> {
|
||||
@ -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 {
|
||||
id: e.id,
|
||||
node: match e.node {
|
||||
ExprBox(ref e) => {
|
||||
hir::ExprBox(lower_expr(_lctx, e))
|
||||
hir::ExprBox(lower_expr(lctx, e))
|
||||
}
|
||||
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) => {
|
||||
hir::ExprRepeat(lower_expr(_lctx, expr), lower_expr(_lctx, count))
|
||||
hir::ExprRepeat(lower_expr(lctx, expr), lower_expr(lctx, count))
|
||||
}
|
||||
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) => {
|
||||
hir::ExprCall(lower_expr(_lctx, f),
|
||||
args.iter().map(|x| lower_expr(_lctx, x)).collect())
|
||||
hir::ExprCall(lower_expr(lctx, f),
|
||||
args.iter().map(|x| lower_expr(lctx, x)).collect())
|
||||
}
|
||||
ExprMethodCall(i, ref tps, ref args) => {
|
||||
hir::ExprMethodCall(
|
||||
respan(i.span, i.node.name),
|
||||
tps.iter().map(|x| lower_ty(_lctx, x)).collect(),
|
||||
args.iter().map(|x| lower_expr(_lctx, x)).collect())
|
||||
tps.iter().map(|x| lower_ty(lctx, x)).collect(),
|
||||
args.iter().map(|x| lower_expr(lctx, x)).collect())
|
||||
}
|
||||
ExprBinary(binop, ref lhs, ref rhs) => {
|
||||
hir::ExprBinary(lower_binop(_lctx, binop),
|
||||
lower_expr(_lctx, lhs),
|
||||
lower_expr(_lctx, rhs))
|
||||
hir::ExprBinary(lower_binop(lctx, binop),
|
||||
lower_expr(lctx, lhs),
|
||||
lower_expr(lctx, rhs))
|
||||
}
|
||||
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())),
|
||||
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) => {
|
||||
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) => {
|
||||
hir::ExprIf(lower_expr(_lctx, cond),
|
||||
lower_block(_lctx, tr),
|
||||
fl.as_ref().map(|x| lower_expr(_lctx, x)))
|
||||
hir::ExprIf(lower_expr(lctx, cond),
|
||||
lower_block(lctx, tr),
|
||||
fl.as_ref().map(|x| lower_expr(lctx, x)))
|
||||
}
|
||||
ExprWhile(ref cond, ref body, opt_ident) => {
|
||||
hir::ExprWhile(lower_expr(_lctx, cond),
|
||||
lower_block(_lctx, body),
|
||||
hir::ExprWhile(lower_expr(lctx, cond),
|
||||
lower_block(lctx, body),
|
||||
opt_ident)
|
||||
}
|
||||
ExprLoop(ref body, opt_ident) => {
|
||||
hir::ExprLoop(lower_block(_lctx, body),
|
||||
hir::ExprLoop(lower_block(lctx, body),
|
||||
opt_ident)
|
||||
}
|
||||
ExprMatch(ref expr, ref arms, ref source) => {
|
||||
hir::ExprMatch(lower_expr(_lctx, expr),
|
||||
arms.iter().map(|x| lower_arm(_lctx, x)).collect(),
|
||||
lower_match_source(_lctx, source))
|
||||
hir::ExprMatch(lower_expr(lctx, expr),
|
||||
arms.iter().map(|x| lower_arm(lctx, x)).collect(),
|
||||
lower_match_source(lctx, source))
|
||||
}
|
||||
ExprClosure(capture_clause, ref decl, ref body) => {
|
||||
hir::ExprClosure(lower_capture_clause(_lctx, capture_clause),
|
||||
lower_fn_decl(_lctx, decl),
|
||||
lower_block(_lctx, body))
|
||||
hir::ExprClosure(lower_capture_clause(lctx, capture_clause),
|
||||
lower_fn_decl(lctx, decl),
|
||||
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) => {
|
||||
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) => {
|
||||
hir::ExprAssignOp(lower_binop(_lctx, op),
|
||||
lower_expr(_lctx, el),
|
||||
lower_expr(_lctx, er))
|
||||
hir::ExprAssignOp(lower_binop(lctx, op),
|
||||
lower_expr(lctx, el),
|
||||
lower_expr(lctx, er))
|
||||
}
|
||||
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) => {
|
||||
hir::ExprTupField(lower_expr(_lctx, el), ident)
|
||||
hir::ExprTupField(lower_expr(lctx, el), ident)
|
||||
}
|
||||
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) => {
|
||||
hir::ExprRange(e1.as_ref().map(|x| lower_expr(_lctx, x)),
|
||||
e2.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)))
|
||||
}
|
||||
ExprPath(ref qself, ref path) => {
|
||||
let qself = qself.as_ref().map(|&QSelf { ref ty, position }| {
|
||||
hir::QSelf {
|
||||
ty: lower_ty(_lctx, ty),
|
||||
ty: lower_ty(lctx, ty),
|
||||
position: position
|
||||
}
|
||||
});
|
||||
hir::ExprPath(qself, lower_path(_lctx, path))
|
||||
hir::ExprPath(qself, lower_path(lctx, path))
|
||||
}
|
||||
ExprBreak(opt_ident) => hir::ExprBreak(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 {
|
||||
ref inputs,
|
||||
ref outputs,
|
||||
@ -838,10 +856,10 @@ pub fn lower_expr(_lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
|
||||
expn_id,
|
||||
}) => hir::ExprInlineAsm(hir::InlineAsm {
|
||||
inputs: inputs.iter().map(|&(ref c, ref input)| {
|
||||
(c.clone(), lower_expr(_lctx, input))
|
||||
(c.clone(), lower_expr(lctx, input))
|
||||
}).collect(),
|
||||
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(),
|
||||
asm: asm.clone(),
|
||||
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,
|
||||
}),
|
||||
ExprStruct(ref path, ref fields, ref maybe_expr) => {
|
||||
hir::ExprStruct(lower_path(_lctx, path),
|
||||
fields.iter().map(|x| lower_field(_lctx, x)).collect(),
|
||||
maybe_expr.as_ref().map(|x| lower_expr(_lctx, x)))
|
||||
hir::ExprStruct(lower_path(lctx, path),
|
||||
fields.iter().map(|x| lower_field(lctx, x)).collect(),
|
||||
maybe_expr.as_ref().map(|x| lower_expr(lctx, x)))
|
||||
},
|
||||
ExprParen(ref ex) => {
|
||||
return lower_expr(_lctx, ex);
|
||||
return lower_expr(lctx, ex);
|
||||
}
|
||||
ExprInPlace(..) |
|
||||
ExprIfLet(..) |
|
||||
ExprWhileLet(..) |
|
||||
ExprForLoop(..) |
|
||||
ExprInPlace(..) => {
|
||||
panic!("todo");
|
||||
}
|
||||
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"),
|
||||
},
|
||||
span: e.span,
|
||||
@ -972,3 +1097,168 @@ pub fn lower_trait_bound_modifier(_lctx: &LoweringContext,
|
||||
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> {
|
||||
pub fn new(tcx: &'l ty::ctxt<'tcx>,
|
||||
lcx: &'l LoweringContext<'tcx>,
|
||||
lcx: &'l LoweringContext<'l, 'tcx>,
|
||||
analysis: &'l ty::CrateAnalysis,
|
||||
output_file: Box<File>)
|
||||
-> DumpCsvVisitor<'l, 'tcx> {
|
||||
|
@ -38,7 +38,7 @@ mod dump_csv;
|
||||
|
||||
pub struct SaveContext<'l, 'tcx: 'l> {
|
||||
tcx: &'l ty::ctxt<'tcx>,
|
||||
lcx: &'l lowering::LoweringContext<'tcx>,
|
||||
lcx: &'l lowering::LoweringContext<'l, 'tcx>,
|
||||
span_utils: SpanUtils<'l>,
|
||||
}
|
||||
|
||||
@ -177,13 +177,15 @@ pub struct MethodCallData {
|
||||
|
||||
|
||||
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);
|
||||
SaveContext::from_span_utils(tcx, lcx, span_utils)
|
||||
}
|
||||
|
||||
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>)
|
||||
-> SaveContext<'l, 'tcx> {
|
||||
SaveContext {
|
||||
@ -709,7 +711,7 @@ impl<'v> Visitor<'v> for PathCollector {
|
||||
}
|
||||
|
||||
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,
|
||||
analysis: &ty::CrateAnalysis,
|
||||
odir: Option<&Path>) {
|
||||
|
@ -38,6 +38,7 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
use syntax::ast::NodeIdAssigner;
|
||||
use util::nodemap::{DefIdMap, FnvHashMap};
|
||||
use rustc::front::map as hir_map;
|
||||
use rustc::front::map::NodeItem;
|
||||
|
@ -375,6 +375,10 @@ pub const CRATE_NODE_ID: NodeId = 0;
|
||||
/// small, positive ids.
|
||||
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.
|
||||
/// typeck::collect::compute_bounds matches these against
|
||||
/// 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))
|
||||
}
|
||||
|
||||
// Desugar ExprForLoop
|
||||
// From: `[opt_ident]: for <pat> in <head> <body>`
|
||||
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 iter = token::gensym_ident("iter");
|
||||
|
||||
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
|
||||
let (body, opt_ident) = expand_loop_block(body, opt_ident, fld);
|
||||
fld.cx.expr(span, ast::ExprForLoop(pat, head, body, opt_ident))
|
||||
}
|
||||
|
||||
ast::ExprClosure(capture_clause, fn_decl, block) => {
|
||||
|
Loading…
Reference in New Issue
Block a user