rustc: fix fallout from using ptr::P.
This commit is contained in:
parent
d379ad111c
commit
b06212864f
64 changed files with 1978 additions and 2092 deletions
|
|
@ -35,6 +35,7 @@ use std::io::fs;
|
|||
use std::os;
|
||||
use arena::TypedArena;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::attr;
|
||||
use syntax::attr::{AttrMetaMethods};
|
||||
use syntax::diagnostics;
|
||||
|
|
@ -65,7 +66,7 @@ pub fn compile_input(sess: Session,
|
|||
// large chunks of memory alive and we want to free them as soon as
|
||||
// possible to keep the peak memory usage low
|
||||
let (outputs, trans, sess) = {
|
||||
let (outputs, expanded_crate, ast_map, id) = {
|
||||
let (outputs, expanded_crate, id) = {
|
||||
let krate = phase_1_parse_input(&sess, cfg, input);
|
||||
if stop_after_phase_1(&sess) { return; }
|
||||
let outputs = build_output_filenames(input,
|
||||
|
|
@ -75,25 +76,28 @@ pub fn compile_input(sess: Session,
|
|||
&sess);
|
||||
let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
|
||||
input);
|
||||
let (expanded_crate, ast_map)
|
||||
let expanded_crate
|
||||
= match phase_2_configure_and_expand(&sess, krate, id.as_slice(),
|
||||
addl_plugins) {
|
||||
None => return,
|
||||
Some(p) => p,
|
||||
Some(k) => k
|
||||
};
|
||||
|
||||
(outputs, expanded_crate, ast_map, id)
|
||||
(outputs, expanded_crate, id)
|
||||
};
|
||||
|
||||
let mut forest = ast_map::Forest::new(expanded_crate);
|
||||
let ast_map = assign_node_ids_and_map(&sess, &mut forest);
|
||||
|
||||
write_out_deps(&sess, input, &outputs, id.as_slice());
|
||||
|
||||
if stop_after_phase_2(&sess) { return; }
|
||||
|
||||
let type_arena = TypedArena::new();
|
||||
let analysis = phase_3_run_analysis_passes(sess, &expanded_crate,
|
||||
ast_map, &type_arena, id);
|
||||
phase_save_analysis(&analysis.ty_cx.sess, &expanded_crate, &analysis, outdir);
|
||||
let analysis = phase_3_run_analysis_passes(sess, ast_map, &type_arena, id);
|
||||
phase_save_analysis(&analysis.ty_cx.sess, analysis.ty_cx.map.krate(), &analysis, outdir);
|
||||
if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
|
||||
let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate, analysis);
|
||||
let (tcx, trans) = phase_4_translate_to_llvm(analysis);
|
||||
|
||||
// Discard interned strings as they are no longer required.
|
||||
token::get_ident_interner().clear();
|
||||
|
|
@ -182,7 +186,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
|||
mut krate: ast::Crate,
|
||||
crate_name: &str,
|
||||
addl_plugins: Option<Plugins>)
|
||||
-> Option<(ast::Crate, syntax::ast_map::Map)> {
|
||||
-> Option<ast::Crate> {
|
||||
let time_passes = sess.time_passes();
|
||||
|
||||
*sess.crate_types.borrow_mut() =
|
||||
|
|
@ -294,20 +298,37 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
|||
krate = time(time_passes, "prelude injection", krate, |krate|
|
||||
front::std_inject::maybe_inject_prelude(sess, krate));
|
||||
|
||||
let (krate, map) = time(time_passes, "assigning node ids and indexing ast", krate, |krate|
|
||||
front::assign_node_ids_and_map::assign_node_ids_and_map(sess, krate));
|
||||
time(time_passes, "checking that all macro invocations are gone", &krate, |krate|
|
||||
syntax::ext::expand::check_for_macros(&sess.parse_sess, krate));
|
||||
|
||||
Some(krate)
|
||||
}
|
||||
|
||||
pub fn assign_node_ids_and_map<'ast>(sess: &Session,
|
||||
forest: &'ast mut ast_map::Forest)
|
||||
-> ast_map::Map<'ast> {
|
||||
struct NodeIdAssigner<'a> {
|
||||
sess: &'a Session
|
||||
}
|
||||
|
||||
impl<'a> ast_map::FoldOps for NodeIdAssigner<'a> {
|
||||
fn new_id(&self, old_id: ast::NodeId) -> ast::NodeId {
|
||||
assert_eq!(old_id, ast::DUMMY_NODE_ID);
|
||||
self.sess.next_node_id()
|
||||
}
|
||||
}
|
||||
|
||||
let map = time(sess.time_passes(), "assigning node ids and indexing ast", forest, |forest|
|
||||
ast_map::map_crate(forest, NodeIdAssigner { sess: sess }));
|
||||
|
||||
if sess.opts.debugging_opts & config::AST_JSON != 0 {
|
||||
let mut stdout = io::BufferedWriter::new(io::stdout());
|
||||
let mut json = json::PrettyEncoder::new(&mut stdout);
|
||||
// unwrapping so IoError isn't ignored
|
||||
krate.encode(&mut json).unwrap();
|
||||
map.krate().encode(&mut json).unwrap();
|
||||
}
|
||||
|
||||
time(time_passes, "checking that all macro invocations are gone", &krate, |krate|
|
||||
syntax::ext::expand::check_for_macros(&sess.parse_sess, krate));
|
||||
|
||||
Some((krate, map))
|
||||
map
|
||||
}
|
||||
|
||||
pub struct CrateAnalysis<'tcx> {
|
||||
|
|
@ -324,11 +345,11 @@ pub struct CrateAnalysis<'tcx> {
|
|||
/// miscellaneous analysis passes on the crate. Return various
|
||||
/// structures carrying the results of the analysis.
|
||||
pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
|
||||
krate: &ast::Crate,
|
||||
ast_map: syntax::ast_map::Map,
|
||||
ast_map: ast_map::Map<'tcx>,
|
||||
type_arena: &'tcx TypedArena<ty::t_box_>,
|
||||
name: String) -> CrateAnalysis<'tcx> {
|
||||
let time_passes = sess.time_passes();
|
||||
let krate = ast_map.krate();
|
||||
|
||||
time(time_passes, "external crate/lib resolution", (), |_|
|
||||
creader::read_crates(&sess, krate));
|
||||
|
|
@ -353,7 +374,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
|
|||
|_| middle::resolve_lifetime::krate(&sess, krate));
|
||||
|
||||
time(time_passes, "looking for entry point", (),
|
||||
|_| middle::entry::find_entry_point(&sess, krate, &ast_map));
|
||||
|_| middle::entry::find_entry_point(&sess, &ast_map));
|
||||
|
||||
sess.plugin_registrar_fn.set(
|
||||
time(time_passes, "looking for plugin registrar", (), |_|
|
||||
|
|
@ -385,43 +406,43 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
|
|||
stability_index);
|
||||
|
||||
// passes are timed inside typeck
|
||||
typeck::check_crate(&ty_cx, trait_map, krate);
|
||||
typeck::check_crate(&ty_cx, trait_map);
|
||||
|
||||
time(time_passes, "check static items", (), |_|
|
||||
middle::check_static::check_crate(&ty_cx, krate));
|
||||
middle::check_static::check_crate(&ty_cx));
|
||||
|
||||
// These next two const passes can probably be merged
|
||||
time(time_passes, "const marking", (), |_|
|
||||
middle::const_eval::process_crate(krate, &ty_cx));
|
||||
middle::const_eval::process_crate(&ty_cx));
|
||||
|
||||
time(time_passes, "const checking", (), |_|
|
||||
middle::check_const::check_crate(krate, &ty_cx));
|
||||
middle::check_const::check_crate(&ty_cx));
|
||||
|
||||
let maps = (external_exports, last_private_map);
|
||||
let (exported_items, public_items) =
|
||||
time(time_passes, "privacy checking", maps, |(a, b)|
|
||||
middle::privacy::check_crate(&ty_cx, &exp_map2, a, b, krate));
|
||||
middle::privacy::check_crate(&ty_cx, &exp_map2, a, b));
|
||||
|
||||
time(time_passes, "intrinsic checking", (), |_|
|
||||
middle::intrinsicck::check_crate(&ty_cx, krate));
|
||||
middle::intrinsicck::check_crate(&ty_cx));
|
||||
|
||||
time(time_passes, "effect checking", (), |_|
|
||||
middle::effect::check_crate(&ty_cx, krate));
|
||||
middle::effect::check_crate(&ty_cx));
|
||||
|
||||
time(time_passes, "match checking", (), |_|
|
||||
middle::check_match::check_crate(&ty_cx, krate));
|
||||
middle::check_match::check_crate(&ty_cx));
|
||||
|
||||
time(time_passes, "liveness checking", (), |_|
|
||||
middle::liveness::check_crate(&ty_cx, krate));
|
||||
middle::liveness::check_crate(&ty_cx));
|
||||
|
||||
time(time_passes, "borrow checking", (), |_|
|
||||
middle::borrowck::check_crate(&ty_cx, krate));
|
||||
middle::borrowck::check_crate(&ty_cx));
|
||||
|
||||
time(time_passes, "rvalue checking", (), |_|
|
||||
middle::check_rvalues::check_crate(&ty_cx, krate));
|
||||
|
||||
time(time_passes, "kind checking", (), |_|
|
||||
kind::check_crate(&ty_cx, krate));
|
||||
kind::check_crate(&ty_cx));
|
||||
|
||||
let reachable_map =
|
||||
time(time_passes, "reachability checking", (), |_|
|
||||
|
|
@ -430,12 +451,11 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
|
|||
time(time_passes, "death checking", (), |_| {
|
||||
middle::dead::check_crate(&ty_cx,
|
||||
&exported_items,
|
||||
&reachable_map,
|
||||
krate)
|
||||
&reachable_map)
|
||||
});
|
||||
|
||||
time(time_passes, "lint checking", (), |_|
|
||||
lint::check_crate(&ty_cx, krate, &exported_items));
|
||||
lint::check_crate(&ty_cx, &exported_items));
|
||||
|
||||
CrateAnalysis {
|
||||
exp_map2: exp_map2,
|
||||
|
|
@ -475,16 +495,16 @@ pub struct CrateTranslation {
|
|||
|
||||
/// Run the translation phase to LLVM, after which the AST and analysis can
|
||||
/// be discarded.
|
||||
pub fn phase_4_translate_to_llvm(krate: ast::Crate,
|
||||
analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
|
||||
pub fn phase_4_translate_to_llvm<'tcx>(analysis: CrateAnalysis<'tcx>)
|
||||
-> (ty::ctxt<'tcx>, CrateTranslation) {
|
||||
let time_passes = analysis.ty_cx.sess.time_passes();
|
||||
|
||||
time(time_passes, "resolving dependency formats", (), |_|
|
||||
dependency_format::calculate(&analysis.ty_cx));
|
||||
|
||||
// Option dance to work around the lack of stack once closures.
|
||||
time(time_passes, "translation", (krate, analysis), |(krate, analysis)|
|
||||
trans::base::trans_crate(krate, analysis))
|
||||
time(time_passes, "translation", analysis, |analysis|
|
||||
trans::base::trans_crate(analysis))
|
||||
}
|
||||
|
||||
/// Run LLVM itself, producing a bitcode file, assembly file or object file
|
||||
|
|
|
|||
|
|
@ -91,13 +91,13 @@ pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option<UserIdentifie
|
|||
|
||||
impl PpSourceMode {
|
||||
/// Constructs a `PrinterSupport` object and passes it to `f`.
|
||||
fn call_with_pp_support<A,B>(&self,
|
||||
sess: Session,
|
||||
krate: &ast::Crate,
|
||||
ast_map: Option<ast_map::Map>,
|
||||
id: String,
|
||||
payload: B,
|
||||
f: |&PrinterSupport, B| -> A) -> A {
|
||||
fn call_with_pp_support<'tcx, A, B>(&self,
|
||||
sess: Session,
|
||||
ast_map: Option<ast_map::Map<'tcx>>,
|
||||
type_arena: &'tcx TypedArena<ty::t_box_>,
|
||||
id: String,
|
||||
payload: B,
|
||||
f: |&PrinterSupport, B| -> A) -> A {
|
||||
match *self {
|
||||
PpmNormal | PpmExpanded => {
|
||||
let annotation = NoAnn { sess: sess, ast_map: ast_map };
|
||||
|
|
@ -114,9 +114,8 @@ impl PpSourceMode {
|
|||
}
|
||||
PpmTyped => {
|
||||
let ast_map = ast_map.expect("--pretty=typed missing ast_map");
|
||||
let type_arena = TypedArena::new();
|
||||
let analysis = driver::phase_3_run_analysis_passes(sess, krate, ast_map,
|
||||
&type_arena, id);
|
||||
let analysis = driver::phase_3_run_analysis_passes(sess, ast_map,
|
||||
type_arena, id);
|
||||
let annotation = TypedAnnotation { analysis: analysis };
|
||||
f(&annotation, payload)
|
||||
}
|
||||
|
|
@ -124,69 +123,51 @@ impl PpSourceMode {
|
|||
}
|
||||
}
|
||||
|
||||
trait SessionCarrier {
|
||||
trait PrinterSupport<'ast>: pprust::PpAnn {
|
||||
/// Provides a uniform interface for re-extracting a reference to a
|
||||
/// `Session` from a value that now owns it.
|
||||
fn sess<'a>(&'a self) -> &'a Session;
|
||||
}
|
||||
|
||||
trait AstMapCarrier {
|
||||
/// Provides a uniform interface for re-extracting a reference to an
|
||||
/// `ast_map::Map` from a value that now owns it.
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map>;
|
||||
}
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>>;
|
||||
|
||||
trait PrinterSupport : SessionCarrier + AstMapCarrier {
|
||||
/// Produces the pretty-print annotation object.
|
||||
///
|
||||
/// Usually implemented via `self as &pprust::PpAnn`.
|
||||
///
|
||||
/// (Rust does not yet support upcasting from a trait object to
|
||||
/// an object for one of its super-traits.)
|
||||
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn;
|
||||
}
|
||||
|
||||
struct NoAnn {
|
||||
sess: Session,
|
||||
ast_map: Option<ast_map::Map>,
|
||||
}
|
||||
|
||||
impl PrinterSupport for NoAnn {
|
||||
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self as &pprust::PpAnn }
|
||||
}
|
||||
|
||||
impl SessionCarrier for NoAnn {
|
||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
||||
struct NoAnn<'ast> {
|
||||
sess: Session,
|
||||
ast_map: Option<ast_map::Map<'ast>>
|
||||
}
|
||||
|
||||
impl AstMapCarrier for NoAnn {
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map> {
|
||||
impl<'ast> PrinterSupport<'ast> for NoAnn<'ast> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
||||
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
|
||||
self.ast_map.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl pprust::PpAnn for NoAnn {}
|
||||
impl<'ast> pprust::PpAnn for NoAnn<'ast> {}
|
||||
|
||||
struct IdentifiedAnnotation {
|
||||
struct IdentifiedAnnotation<'ast> {
|
||||
sess: Session,
|
||||
ast_map: Option<ast_map::Map>,
|
||||
ast_map: Option<ast_map::Map<'ast>>,
|
||||
}
|
||||
|
||||
impl PrinterSupport for IdentifiedAnnotation {
|
||||
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self as &pprust::PpAnn }
|
||||
}
|
||||
|
||||
impl SessionCarrier for IdentifiedAnnotation {
|
||||
impl<'ast> PrinterSupport<'ast> for IdentifiedAnnotation<'ast> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
||||
}
|
||||
|
||||
impl AstMapCarrier for IdentifiedAnnotation {
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map> {
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
|
||||
self.ast_map.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl pprust::PpAnn for IdentifiedAnnotation {
|
||||
impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
|
||||
fn pre(&self,
|
||||
s: &mut pprust::State,
|
||||
node: pprust::AnnNode) -> io::IoResult<()> {
|
||||
|
|
@ -222,26 +203,20 @@ impl pprust::PpAnn for IdentifiedAnnotation {
|
|||
}
|
||||
}
|
||||
|
||||
struct HygieneAnnotation {
|
||||
struct HygieneAnnotation<'ast> {
|
||||
sess: Session,
|
||||
ast_map: Option<ast_map::Map>,
|
||||
ast_map: Option<ast_map::Map<'ast>>,
|
||||
}
|
||||
|
||||
impl PrinterSupport for HygieneAnnotation {
|
||||
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self as &pprust::PpAnn }
|
||||
}
|
||||
|
||||
impl SessionCarrier for HygieneAnnotation {
|
||||
impl<'ast> PrinterSupport<'ast> for HygieneAnnotation<'ast> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { &self.sess }
|
||||
}
|
||||
|
||||
impl AstMapCarrier for HygieneAnnotation {
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map> {
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'ast>> {
|
||||
self.ast_map.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl pprust::PpAnn for HygieneAnnotation {
|
||||
impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
|
||||
fn post(&self,
|
||||
s: &mut pprust::State,
|
||||
node: pprust::AnnNode) -> io::IoResult<()> {
|
||||
|
|
@ -266,16 +241,10 @@ struct TypedAnnotation<'tcx> {
|
|||
analysis: CrateAnalysis<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> PrinterSupport for TypedAnnotation<'tcx> {
|
||||
fn pp_ann<'a>(&'a self) -> &'a pprust::PpAnn { self as &pprust::PpAnn }
|
||||
}
|
||||
|
||||
impl<'tcx> SessionCarrier for TypedAnnotation<'tcx> {
|
||||
impl<'tcx> PrinterSupport<'tcx> for TypedAnnotation<'tcx> {
|
||||
fn sess<'a>(&'a self) -> &'a Session { &self.analysis.ty_cx.sess }
|
||||
}
|
||||
|
||||
impl<'tcx> AstMapCarrier for TypedAnnotation<'tcx> {
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map> {
|
||||
fn ast_map<'a>(&'a self) -> Option<&'a ast_map::Map<'tcx>> {
|
||||
Some(&self.analysis.ty_cx.map)
|
||||
}
|
||||
}
|
||||
|
|
@ -347,12 +316,12 @@ impl FromStr for UserIdentifiedItem {
|
|||
}
|
||||
}
|
||||
|
||||
enum NodesMatchingUII<'a> {
|
||||
enum NodesMatchingUII<'a, 'ast: 'a> {
|
||||
NodesMatchingDirect(option::Item<ast::NodeId>),
|
||||
NodesMatchingSuffix(ast_map::NodesMatchingSuffix<'a, String>),
|
||||
NodesMatchingSuffix(ast_map::NodesMatchingSuffix<'a, 'ast, String>),
|
||||
}
|
||||
|
||||
impl<'a> Iterator<ast::NodeId> for NodesMatchingUII<'a> {
|
||||
impl<'a, 'ast> Iterator<ast::NodeId> for NodesMatchingUII<'a, 'ast> {
|
||||
fn next(&mut self) -> Option<ast::NodeId> {
|
||||
match self {
|
||||
&NodesMatchingDirect(ref mut iter) => iter.next(),
|
||||
|
|
@ -369,7 +338,8 @@ impl UserIdentifiedItem {
|
|||
}
|
||||
}
|
||||
|
||||
fn all_matching_node_ids<'a>(&'a self, map: &'a ast_map::Map) -> NodesMatchingUII<'a> {
|
||||
fn all_matching_node_ids<'a, 'ast>(&'a self, map: &'a ast_map::Map<'ast>)
|
||||
-> NodesMatchingUII<'a, 'ast> {
|
||||
match *self {
|
||||
ItemViaNode(node_id) =>
|
||||
NodesMatchingDirect(Some(node_id).move_iter()),
|
||||
|
|
@ -443,15 +413,24 @@ pub fn pretty_print_input(sess: Session,
|
|||
let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(), input);
|
||||
|
||||
let is_expanded = needs_expansion(&ppm);
|
||||
let (krate, ast_map) = if needs_ast_map(&ppm, &opt_uii) {
|
||||
let k = driver::phase_2_configure_and_expand(&sess, krate, id.as_slice(), None);
|
||||
let (krate, ast_map) = match k {
|
||||
let compute_ast_map = needs_ast_map(&ppm, &opt_uii);
|
||||
let krate = if compute_ast_map {
|
||||
match driver::phase_2_configure_and_expand(&sess, krate, id.as_slice(), None) {
|
||||
None => return,
|
||||
Some(p) => p,
|
||||
};
|
||||
(krate, Some(ast_map))
|
||||
Some(k) => k
|
||||
}
|
||||
} else {
|
||||
(krate, None)
|
||||
krate
|
||||
};
|
||||
|
||||
let mut forest = ast_map::Forest::new(krate);
|
||||
let type_arena = TypedArena::new();
|
||||
|
||||
let (krate, ast_map) = if compute_ast_map {
|
||||
let map = driver::assign_node_ids_and_map(&sess, &mut forest);
|
||||
(map.krate(), Some(map))
|
||||
} else {
|
||||
(forest.krate(), None)
|
||||
};
|
||||
|
||||
let src_name = driver::source_name(input);
|
||||
|
|
@ -476,12 +455,12 @@ pub fn pretty_print_input(sess: Session,
|
|||
match (ppm, opt_uii) {
|
||||
(PpmSource(s), None) =>
|
||||
s.call_with_pp_support(
|
||||
sess, &krate, ast_map, id, out, |annotation, out| {
|
||||
sess, ast_map, &type_arena, id, out, |annotation, out| {
|
||||
debug!("pretty printing source code {}", s);
|
||||
let sess = annotation.sess();
|
||||
pprust::print_crate(sess.codemap(),
|
||||
sess.diagnostic(),
|
||||
&krate,
|
||||
krate,
|
||||
src_name.to_string(),
|
||||
&mut rdr,
|
||||
out,
|
||||
|
|
@ -491,7 +470,7 @@ pub fn pretty_print_input(sess: Session,
|
|||
|
||||
(PpmSource(s), Some(uii)) =>
|
||||
s.call_with_pp_support(
|
||||
sess, &krate, ast_map, id, (out,uii), |annotation, (out,uii)| {
|
||||
sess, ast_map, &type_arena, id, (out,uii), |annotation, (out,uii)| {
|
||||
debug!("pretty printing source code {}", s);
|
||||
let sess = annotation.sess();
|
||||
let ast_map = annotation.ast_map()
|
||||
|
|
@ -533,9 +512,8 @@ pub fn pretty_print_input(sess: Session,
|
|||
match code {
|
||||
Some(code) => {
|
||||
let variants = gather_flowgraph_variants(&sess);
|
||||
let type_arena = TypedArena::new();
|
||||
let analysis = driver::phase_3_run_analysis_passes(sess, &krate,
|
||||
ast_map, &type_arena, id);
|
||||
let analysis = driver::phase_3_run_analysis_passes(sess, ast_map,
|
||||
&type_arena, id);
|
||||
print_flowgraph(variants, analysis, code, out)
|
||||
}
|
||||
None => {
|
||||
|
|
|
|||
|
|
@ -263,7 +263,6 @@ pub fn build_session_(sopts: config::Options,
|
|||
}
|
||||
|
||||
// Seems out of place, but it uses session, so I'm putting it here
|
||||
pub fn expect<T:Clone>(sess: &Session, opt: Option<T>, msg: || -> String)
|
||||
-> T {
|
||||
pub fn expect<T>(sess: &Session, opt: Option<T>, msg: || -> String) -> T {
|
||||
diagnostic::expect(sess.diagnostic(), opt, msg)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use driver::session::Session;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
|
||||
struct NodeIdAssigner<'a> {
|
||||
sess: &'a Session
|
||||
}
|
||||
|
||||
impl<'a> ast_map::FoldOps for NodeIdAssigner<'a> {
|
||||
fn new_id(&self, old_id: ast::NodeId) -> ast::NodeId {
|
||||
assert_eq!(old_id, ast::DUMMY_NODE_ID);
|
||||
self.sess.next_node_id()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn assign_node_ids_and_map(sess: &Session, krate: ast::Crate) -> (ast::Crate, ast_map::Map) {
|
||||
ast_map::map_crate(krate, NodeIdAssigner { sess: sess })
|
||||
}
|
||||
|
|
@ -10,9 +10,8 @@
|
|||
|
||||
use syntax::fold::Folder;
|
||||
use syntax::{ast, fold, attr};
|
||||
use syntax::codemap;
|
||||
|
||||
use std::gc::{Gc, GC};
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax::ptr::P;
|
||||
|
||||
/// A folder that strips out items that do not belong in the current
|
||||
/// configuration.
|
||||
|
|
@ -28,22 +27,22 @@ pub fn strip_unconfigured_items(krate: ast::Crate) -> ast::Crate {
|
|||
}
|
||||
|
||||
impl<'a> fold::Folder for Context<'a> {
|
||||
fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
|
||||
fn fold_mod(&mut self, module: ast::Mod) -> ast::Mod {
|
||||
fold_mod(self, module)
|
||||
}
|
||||
fn fold_block(&mut self, block: ast::P<ast::Block>) -> ast::P<ast::Block> {
|
||||
fn fold_block(&mut self, block: P<ast::Block>) -> P<ast::Block> {
|
||||
fold_block(self, block)
|
||||
}
|
||||
fn fold_foreign_mod(&mut self, foreign_mod: &ast::ForeignMod) -> ast::ForeignMod {
|
||||
fn fold_foreign_mod(&mut self, foreign_mod: ast::ForeignMod) -> ast::ForeignMod {
|
||||
fold_foreign_mod(self, foreign_mod)
|
||||
}
|
||||
fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ {
|
||||
fn fold_item_underscore(&mut self, item: ast::Item_) -> ast::Item_ {
|
||||
fold_item_underscore(self, item)
|
||||
}
|
||||
fn fold_expr(&mut self, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
|
||||
fn fold_expr(&mut self, expr: P<ast::Expr>) -> P<ast::Expr> {
|
||||
fold_expr(self, expr)
|
||||
}
|
||||
fn fold_mac(&mut self, mac: &ast::Mac) -> ast::Mac {
|
||||
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
|
||||
fold::noop_fold_mac(mac, self)
|
||||
}
|
||||
}
|
||||
|
|
@ -57,34 +56,32 @@ pub fn strip_items(krate: ast::Crate,
|
|||
ctxt.fold_crate(krate)
|
||||
}
|
||||
|
||||
fn filter_view_item<'r>(cx: &mut Context, view_item: &'r ast::ViewItem)
|
||||
-> Option<&'r ast::ViewItem> {
|
||||
if view_item_in_cfg(cx, view_item) {
|
||||
fn filter_view_item(cx: &mut Context, view_item: ast::ViewItem) -> Option<ast::ViewItem> {
|
||||
if view_item_in_cfg(cx, &view_item) {
|
||||
Some(view_item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
|
||||
let filtered_items: Vec<&Gc<ast::Item>> = m.items.iter()
|
||||
.filter(|a| item_in_cfg(cx, &***a))
|
||||
.collect();
|
||||
let flattened_items = filtered_items.move_iter()
|
||||
.flat_map(|&x| cx.fold_item(x).move_iter())
|
||||
.collect();
|
||||
let filtered_view_items = m.view_items.iter().filter_map(|a| {
|
||||
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
|
||||
}).collect();
|
||||
fn fold_mod(cx: &mut Context, ast::Mod {inner, view_items, items}: ast::Mod) -> ast::Mod {
|
||||
ast::Mod {
|
||||
inner: m.inner,
|
||||
view_items: filtered_view_items,
|
||||
items: flattened_items
|
||||
inner: inner,
|
||||
view_items: view_items.move_iter().filter_map(|a| {
|
||||
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
|
||||
}).collect(),
|
||||
items: items.move_iter().filter_map(|a| {
|
||||
if item_in_cfg(cx, &*a) {
|
||||
Some(cx.fold_item(a))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).flat_map(|x| x.move_iter()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn filter_foreign_item(cx: &mut Context, item: Gc<ast::ForeignItem>)
|
||||
-> Option<Gc<ast::ForeignItem>> {
|
||||
fn filter_foreign_item(cx: &mut Context, item: P<ast::ForeignItem>)
|
||||
-> Option<P<ast::ForeignItem>> {
|
||||
if foreign_item_in_cfg(cx, &*item) {
|
||||
Some(item)
|
||||
} else {
|
||||
|
|
@ -92,134 +89,135 @@ fn filter_foreign_item(cx: &mut Context, item: Gc<ast::ForeignItem>)
|
|||
}
|
||||
}
|
||||
|
||||
fn fold_foreign_mod(cx: &mut Context, nm: &ast::ForeignMod) -> ast::ForeignMod {
|
||||
let filtered_items = nm.items
|
||||
.iter()
|
||||
.filter_map(|a| filter_foreign_item(cx, *a))
|
||||
.collect();
|
||||
let filtered_view_items = nm.view_items.iter().filter_map(|a| {
|
||||
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
|
||||
}).collect();
|
||||
fn fold_foreign_mod(cx: &mut Context, ast::ForeignMod {abi, view_items, items}: ast::ForeignMod)
|
||||
-> ast::ForeignMod {
|
||||
ast::ForeignMod {
|
||||
abi: nm.abi,
|
||||
view_items: filtered_view_items,
|
||||
items: filtered_items
|
||||
abi: abi,
|
||||
view_items: view_items.move_iter().filter_map(|a| {
|
||||
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
|
||||
}).collect(),
|
||||
items: items.move_iter()
|
||||
.filter_map(|a| filter_foreign_item(cx, a))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
|
||||
let item = match *item {
|
||||
ast::ItemImpl(ref a, ref b, c, ref impl_items) => {
|
||||
let impl_items = impl_items.iter()
|
||||
.filter(|ii| {
|
||||
impl_item_in_cfg(cx, &**ii)
|
||||
})
|
||||
.map(|x| *x)
|
||||
fn fold_item_underscore(cx: &mut Context, item: ast::Item_) -> ast::Item_ {
|
||||
let item = match item {
|
||||
ast::ItemImpl(a, b, c, impl_items) => {
|
||||
let impl_items = impl_items.move_iter()
|
||||
.filter(|ii| impl_item_in_cfg(cx, ii))
|
||||
.collect();
|
||||
ast::ItemImpl((*a).clone(), (*b).clone(), c, impl_items)
|
||||
ast::ItemImpl(a, b, c, impl_items)
|
||||
}
|
||||
ast::ItemTrait(ref a, ref b, ref c, ref methods) => {
|
||||
let methods = methods.iter()
|
||||
.filter(|m| trait_method_in_cfg(cx, *m) )
|
||||
.map(|x| (*x).clone())
|
||||
ast::ItemTrait(a, b, c, methods) => {
|
||||
let methods = methods.move_iter()
|
||||
.filter(|m| trait_method_in_cfg(cx, m))
|
||||
.collect();
|
||||
ast::ItemTrait((*a).clone(), (*b).clone(), (*c).clone(), methods)
|
||||
ast::ItemTrait(a, b, c, methods)
|
||||
}
|
||||
ast::ItemStruct(ref def, ref generics) => {
|
||||
ast::ItemStruct(fold_struct(cx, &**def), generics.clone())
|
||||
ast::ItemStruct(def, generics) => {
|
||||
ast::ItemStruct(fold_struct(cx, def), generics)
|
||||
}
|
||||
ast::ItemEnum(ref def, ref generics) => {
|
||||
let mut variants = def.variants.iter().map(|c| c.clone()).
|
||||
filter_map(|v| {
|
||||
ast::ItemEnum(def, generics) => {
|
||||
let mut variants = def.variants.move_iter().filter_map(|v| {
|
||||
if !(cx.in_cfg)(v.node.attrs.as_slice()) {
|
||||
None
|
||||
} else {
|
||||
Some(match v.node.kind {
|
||||
ast::TupleVariantKind(..) => v,
|
||||
ast::StructVariantKind(ref def) => {
|
||||
let def = fold_struct(cx, &**def);
|
||||
box(GC) codemap::Spanned {
|
||||
node: ast::Variant_ {
|
||||
kind: ast::StructVariantKind(def.clone()),
|
||||
..v.node.clone()
|
||||
},
|
||||
..*v
|
||||
Some(v.map(|Spanned {node: ast::Variant_ {id, name, attrs, kind,
|
||||
disr_expr, vis}, span}| {
|
||||
Spanned {
|
||||
node: ast::Variant_ {
|
||||
id: id,
|
||||
name: name,
|
||||
attrs: attrs,
|
||||
kind: match kind {
|
||||
ast::TupleVariantKind(..) => kind,
|
||||
ast::StructVariantKind(def) => {
|
||||
ast::StructVariantKind(fold_struct(cx, def))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
disr_expr: disr_expr,
|
||||
vis: vis
|
||||
},
|
||||
span: span
|
||||
}
|
||||
}))
|
||||
}
|
||||
});
|
||||
ast::ItemEnum(ast::EnumDef {
|
||||
variants: variants.collect(),
|
||||
}, generics.clone())
|
||||
}, generics)
|
||||
}
|
||||
ref item => item.clone(),
|
||||
item => item,
|
||||
};
|
||||
|
||||
fold::noop_fold_item_underscore(&item, cx)
|
||||
fold::noop_fold_item_underscore(item, cx)
|
||||
}
|
||||
|
||||
fn fold_struct(cx: &mut Context, def: &ast::StructDef) -> Gc<ast::StructDef> {
|
||||
let mut fields = def.fields.iter().map(|c| c.clone()).filter(|m| {
|
||||
(cx.in_cfg)(m.node.attrs.as_slice())
|
||||
});
|
||||
box(GC) ast::StructDef {
|
||||
fields: fields.collect(),
|
||||
ctor_id: def.ctor_id,
|
||||
super_struct: def.super_struct.clone(),
|
||||
is_virtual: def.is_virtual,
|
||||
}
|
||||
}
|
||||
|
||||
fn retain_stmt(cx: &mut Context, stmt: Gc<ast::Stmt>) -> bool {
|
||||
match stmt.node {
|
||||
ast::StmtDecl(decl, _) => {
|
||||
match decl.node {
|
||||
ast::DeclItem(ref item) => {
|
||||
item_in_cfg(cx, &**item)
|
||||
}
|
||||
_ => true
|
||||
fn fold_struct(cx: &mut Context, def: P<ast::StructDef>) -> P<ast::StructDef> {
|
||||
def.map(|ast::StructDef {fields, ctor_id, super_struct, is_virtual}| {
|
||||
ast::StructDef {
|
||||
fields: fields.move_iter().filter(|m| {
|
||||
(cx.in_cfg)(m.node.attrs.as_slice())
|
||||
}).collect(),
|
||||
ctor_id: ctor_id,
|
||||
super_struct: super_struct,
|
||||
is_virtual: is_virtual,
|
||||
}
|
||||
}
|
||||
_ => true
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
|
||||
let resulting_stmts: Vec<&Gc<ast::Stmt>> =
|
||||
b.stmts.iter().filter(|&a| retain_stmt(cx, *a)).collect();
|
||||
let resulting_stmts = resulting_stmts.move_iter()
|
||||
.flat_map(|stmt| cx.fold_stmt(&**stmt).move_iter())
|
||||
.collect();
|
||||
let filtered_view_items = b.view_items.iter().filter_map(|a| {
|
||||
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
|
||||
}).collect();
|
||||
ast::P(ast::Block {
|
||||
view_items: filtered_view_items,
|
||||
stmts: resulting_stmts,
|
||||
expr: b.expr.map(|x| cx.fold_expr(x)),
|
||||
id: b.id,
|
||||
rules: b.rules,
|
||||
span: b.span,
|
||||
})
|
||||
}
|
||||
|
||||
fn fold_expr(cx: &mut Context, expr: Gc<ast::Expr>) -> Gc<ast::Expr> {
|
||||
let expr = match expr.node {
|
||||
ast::ExprMatch(ref m, ref arms) => {
|
||||
let arms = arms.iter()
|
||||
.filter(|a| (cx.in_cfg)(a.attrs.as_slice()))
|
||||
.map(|a| a.clone())
|
||||
.collect();
|
||||
box(GC) ast::Expr {
|
||||
id: expr.id,
|
||||
span: expr.span.clone(),
|
||||
node: ast::ExprMatch(m.clone(), arms),
|
||||
fn retain_stmt(cx: &mut Context, stmt: &ast::Stmt) -> bool {
|
||||
match stmt.node {
|
||||
ast::StmtDecl(ref decl, _) => {
|
||||
match decl.node {
|
||||
ast::DeclItem(ref item) => {
|
||||
item_in_cfg(cx, &**item)
|
||||
}
|
||||
_ => true
|
||||
}
|
||||
}
|
||||
_ => expr.clone()
|
||||
};
|
||||
fold::noop_fold_expr(expr, cx)
|
||||
_ => true
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_block(cx: &mut Context, b: P<ast::Block>) -> P<ast::Block> {
|
||||
b.map(|ast::Block {id, view_items, stmts, expr, rules, span}| {
|
||||
let resulting_stmts: Vec<P<ast::Stmt>> =
|
||||
stmts.move_iter().filter(|a| retain_stmt(cx, &**a)).collect();
|
||||
let resulting_stmts = resulting_stmts.move_iter()
|
||||
.flat_map(|stmt| cx.fold_stmt(stmt).move_iter())
|
||||
.collect();
|
||||
let filtered_view_items = view_items.move_iter().filter_map(|a| {
|
||||
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
|
||||
}).collect();
|
||||
ast::Block {
|
||||
id: id,
|
||||
view_items: filtered_view_items,
|
||||
stmts: resulting_stmts,
|
||||
expr: expr.map(|x| cx.fold_expr(x)),
|
||||
rules: rules,
|
||||
span: span,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn fold_expr(cx: &mut Context, expr: P<ast::Expr>) -> P<ast::Expr> {
|
||||
expr.map(|ast::Expr {id, span, node}| {
|
||||
fold::noop_fold_expr(ast::Expr {
|
||||
id: id,
|
||||
node: match node {
|
||||
ast::ExprMatch(m, arms) => {
|
||||
ast::ExprMatch(m, arms.move_iter()
|
||||
.filter(|a| (cx.in_cfg)(a.attrs.as_slice()))
|
||||
.collect())
|
||||
}
|
||||
_ => node
|
||||
},
|
||||
span: span
|
||||
}, cx)
|
||||
})
|
||||
}
|
||||
|
||||
fn item_in_cfg(cx: &mut Context, item: &ast::Item) -> bool {
|
||||
|
|
@ -237,19 +235,19 @@ fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool {
|
|||
fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool {
|
||||
match *meth {
|
||||
ast::RequiredMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
|
||||
ast::ProvidedMethod(meth) => (cx.in_cfg)(meth.attrs.as_slice())
|
||||
ast::ProvidedMethod(ref meth) => (cx.in_cfg)(meth.attrs.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_item_in_cfg(cx: &mut Context, impl_item: &ast::ImplItem) -> bool {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(meth) => (cx.in_cfg)(meth.attrs.as_slice()),
|
||||
ast::MethodImplItem(ref meth) => (cx.in_cfg)(meth.attrs.as_slice()),
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if an item should be translated in the current crate
|
||||
// configuration based on the item's attributes
|
||||
fn in_cfg(cfg: &[Gc<ast::MetaItem>], attrs: &[ast::Attribute]) -> bool {
|
||||
attr::test_cfg(cfg, attrs.iter().map(|x| *x))
|
||||
fn in_cfg(cfg: &[P<ast::MetaItem>], attrs: &[ast::Attribute]) -> bool {
|
||||
attr::test_cfg(cfg, attrs.iter())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ use syntax::parse::token;
|
|||
use driver::session::Session;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::slice;
|
||||
|
||||
/// This is a list of all known features since the beginning of time. This list
|
||||
/// can never shrink, it may only be expanded (in order to prevent old programs
|
||||
|
|
@ -220,7 +221,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
ast::ItemStruct(struct_definition, _) => {
|
||||
ast::ItemStruct(ref struct_definition, _) => {
|
||||
if attr::contains_name(i.attrs.as_slice(), "simd") {
|
||||
self.gate_feature("simd", i.span,
|
||||
"SIMD types are experimental and possibly buggy");
|
||||
|
|
@ -310,7 +311,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
|
|||
|
||||
fn visit_ty(&mut self, t: &ast::Ty) {
|
||||
match t.node {
|
||||
ast::TyClosure(closure) if closure.onceness == ast::Once => {
|
||||
ast::TyClosure(ref closure) if closure.onceness == ast::Once => {
|
||||
self.gate_feature("once_fns", t.span,
|
||||
"once functions are \
|
||||
experimental and likely to be removed");
|
||||
|
|
@ -352,7 +353,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
|
|||
fn visit_generics(&mut self, generics: &ast::Generics) {
|
||||
for type_parameter in generics.ty_params.iter() {
|
||||
match type_parameter.default {
|
||||
Some(ty) => {
|
||||
Some(ref ty) => {
|
||||
self.gate_feature("default_type_params", ty.span,
|
||||
"default type parameters are \
|
||||
experimental and possibly buggy");
|
||||
|
|
@ -364,7 +365,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
|
|||
}
|
||||
|
||||
fn visit_attribute(&mut self, attr: &ast::Attribute) {
|
||||
if attr::contains_name([*attr], "lang") {
|
||||
if attr::contains_name(slice::ref_slice(attr), "lang") {
|
||||
self.gate_feature("lang_items",
|
||||
attr.span,
|
||||
"language items are subject to change");
|
||||
|
|
@ -420,7 +421,7 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
|
|||
expected #![feature(...)]");
|
||||
}
|
||||
Some(list) => {
|
||||
for &mi in list.iter() {
|
||||
for mi in list.iter() {
|
||||
let name = match mi.node {
|
||||
ast::MetaWord(ref word) => (*word).clone(),
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ use syntax::owned_slice::OwnedSlice;
|
|||
use syntax::parse::token::InternedString;
|
||||
use syntax::parse::token::special_idents;
|
||||
use syntax::parse::token;
|
||||
use syntax::ptr::P;
|
||||
use syntax::util::small_vector::SmallVector;
|
||||
|
||||
use std::mem;
|
||||
use std::gc::{Gc, GC};
|
||||
|
||||
pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
|
||||
-> ast::Crate {
|
||||
|
|
@ -149,7 +149,6 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
|
|||
if !no_prelude(krate.attrs.as_slice()) {
|
||||
// only add `use std::prelude::*;` if there wasn't a
|
||||
// `#![no_implicit_prelude]` at the crate level.
|
||||
|
||||
// fold_mod() will insert glob path.
|
||||
let globs_attr = attr::mk_attr_inner(attr::mk_attr_id(),
|
||||
attr::mk_list_item(
|
||||
|
|
@ -161,23 +160,23 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
|
|||
attr::mark_used(&globs_attr);
|
||||
krate.attrs.push(globs_attr);
|
||||
|
||||
krate.module = self.fold_mod(&krate.module);
|
||||
krate.module = self.fold_mod(krate.module);
|
||||
}
|
||||
krate
|
||||
}
|
||||
|
||||
fn fold_item(&mut self, item: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
|
||||
fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
|
||||
if !no_prelude(item.attrs.as_slice()) {
|
||||
// only recur if there wasn't `#![no_implicit_prelude]`
|
||||
// on this item, i.e. this means that the prelude is not
|
||||
// implicitly imported though the whole subtree
|
||||
fold::noop_fold_item(&*item, self)
|
||||
fold::noop_fold_item(item, self)
|
||||
} else {
|
||||
SmallVector::one(item)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
|
||||
fn fold_mod(&mut self, ast::Mod {inner, view_items, items}: ast::Mod) -> ast::Mod {
|
||||
let prelude_path = ast::Path {
|
||||
span: DUMMY_SP,
|
||||
global: false,
|
||||
|
|
@ -194,44 +193,41 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
|
|||
}),
|
||||
};
|
||||
|
||||
let vp = box(GC) codemap::dummy_spanned(ast::ViewPathGlob(prelude_path,
|
||||
ast::DUMMY_NODE_ID));
|
||||
let vi2 = ast::ViewItem {
|
||||
node: ast::ViewItemUse(vp),
|
||||
attrs: vec!(ast::Attribute {
|
||||
span: DUMMY_SP,
|
||||
node: ast::Attribute_ {
|
||||
id: attr::mk_attr_id(),
|
||||
style: ast::AttrOuter,
|
||||
value: box(GC) ast::MetaItem {
|
||||
span: DUMMY_SP,
|
||||
node: ast::MetaWord(token::get_name(
|
||||
special_idents::prelude_import.name)),
|
||||
},
|
||||
is_sugared_doc: false,
|
||||
},
|
||||
}),
|
||||
vis: ast::Inherited,
|
||||
span: DUMMY_SP,
|
||||
};
|
||||
|
||||
let (crates, uses) = module.view_items.partitioned(|x| {
|
||||
let (crates, uses) = view_items.partitioned(|x| {
|
||||
match x.node {
|
||||
ast::ViewItemExternCrate(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
});
|
||||
|
||||
// add vi2 after any `extern crate` but before any `use`
|
||||
// add prelude after any `extern crate` but before any `use`
|
||||
let mut view_items = crates;
|
||||
view_items.push(vi2);
|
||||
let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path, ast::DUMMY_NODE_ID)));
|
||||
view_items.push(ast::ViewItem {
|
||||
node: ast::ViewItemUse(vp),
|
||||
attrs: vec![ast::Attribute {
|
||||
span: DUMMY_SP,
|
||||
node: ast::Attribute_ {
|
||||
id: attr::mk_attr_id(),
|
||||
style: ast::AttrOuter,
|
||||
value: P(ast::MetaItem {
|
||||
span: DUMMY_SP,
|
||||
node: ast::MetaWord(token::get_name(
|
||||
special_idents::prelude_import.name)),
|
||||
}),
|
||||
is_sugared_doc: false,
|
||||
},
|
||||
}],
|
||||
vis: ast::Inherited,
|
||||
span: DUMMY_SP,
|
||||
});
|
||||
view_items.push_all_move(uses);
|
||||
|
||||
let new_module = ast::Mod {
|
||||
fold::noop_fold_mod(ast::Mod {
|
||||
inner: inner,
|
||||
view_items: view_items,
|
||||
..(*module).clone()
|
||||
};
|
||||
fold::noop_fold_mod(&new_module, self)
|
||||
items: items
|
||||
}, self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@
|
|||
use driver::session::Session;
|
||||
use front::config;
|
||||
|
||||
use std::gc::{Gc, GC};
|
||||
use std::slice;
|
||||
use std::mem;
|
||||
use std::vec;
|
||||
use syntax::{ast, ast_util};
|
||||
use syntax::ast_util::*;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::attr;
|
||||
|
|
@ -28,13 +28,13 @@ use syntax::codemap;
|
|||
use syntax::ext::base::ExtCtxt;
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::ext::expand::ExpansionConfig;
|
||||
use syntax::fold::Folder;
|
||||
use syntax::fold::{Folder, MoveMap};
|
||||
use syntax::fold;
|
||||
use syntax::owned_slice::OwnedSlice;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax::parse::token;
|
||||
use syntax::print::pprust;
|
||||
use syntax::{ast, ast_util};
|
||||
use syntax::ptr::P;
|
||||
use syntax::util::small_vector::SmallVector;
|
||||
|
||||
struct Test {
|
||||
|
|
@ -105,12 +105,12 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
|||
folded
|
||||
}
|
||||
|
||||
fn fold_item(&mut self, i: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
|
||||
fn fold_item(&mut self, i: P<ast::Item>) -> SmallVector<P<ast::Item>> {
|
||||
self.cx.path.push(i.ident);
|
||||
debug!("current path: {}",
|
||||
ast_util::path_name_i(self.cx.path.as_slice()));
|
||||
|
||||
if is_test_fn(&self.cx, i) || is_bench_fn(&self.cx, i) {
|
||||
if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) {
|
||||
match i.node {
|
||||
ast::ItemFn(_, ast::UnsafeFn, _, _, _) => {
|
||||
let sess = self.cx.sess;
|
||||
|
|
@ -123,9 +123,9 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
|||
let test = Test {
|
||||
span: i.span,
|
||||
path: self.cx.path.clone(),
|
||||
bench: is_bench_fn(&self.cx, i),
|
||||
ignore: is_ignored(&self.cx, i),
|
||||
should_fail: should_fail(i)
|
||||
bench: is_bench_fn(&self.cx, &*i),
|
||||
ignore: is_ignored(&self.cx, &*i),
|
||||
should_fail: should_fail(&*i)
|
||||
};
|
||||
self.cx.testfns.push(test);
|
||||
self.tests.push(i.ident);
|
||||
|
|
@ -138,14 +138,14 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
|||
// We don't want to recurse into anything other than mods, since
|
||||
// mods or tests inside of functions will break things
|
||||
let res = match i.node {
|
||||
ast::ItemMod(..) => fold::noop_fold_item(&*i, self),
|
||||
ast::ItemMod(..) => fold::noop_fold_item(i, self),
|
||||
_ => SmallVector::one(i),
|
||||
};
|
||||
self.cx.path.pop();
|
||||
res
|
||||
}
|
||||
|
||||
fn fold_mod(&mut self, m: &ast::Mod) -> ast::Mod {
|
||||
fn fold_mod(&mut self, m: ast::Mod) -> ast::Mod {
|
||||
let tests = mem::replace(&mut self.tests, Vec::new());
|
||||
let tested_submods = mem::replace(&mut self.tested_submods, Vec::new());
|
||||
let mut mod_folded = fold::noop_fold_mod(m, self);
|
||||
|
|
@ -155,22 +155,25 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
|||
// Remove any #[main] from the AST so it doesn't clash with
|
||||
// the one we're going to add. Only if compiling an executable.
|
||||
|
||||
fn nomain(item: Gc<ast::Item>) -> Gc<ast::Item> {
|
||||
box(GC) ast::Item {
|
||||
attrs: item.attrs.iter().filter_map(|attr| {
|
||||
if !attr.check_name("main") {
|
||||
Some(*attr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect(),
|
||||
.. (*item).clone()
|
||||
}
|
||||
}
|
||||
mod_folded.items = mem::replace(&mut mod_folded.items, vec![]).move_map(|item| {
|
||||
item.map(|ast::Item {id, ident, attrs, node, vis, span}| {
|
||||
ast::Item {
|
||||
id: id,
|
||||
ident: ident,
|
||||
attrs: attrs.move_iter().filter_map(|attr| {
|
||||
if !attr.check_name("main") {
|
||||
Some(attr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect(),
|
||||
node: node,
|
||||
vis: vis,
|
||||
span: span
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
for i in mod_folded.items.mut_iter() {
|
||||
*i = nomain(*i);
|
||||
}
|
||||
if !tests.is_empty() || !tested_submods.is_empty() {
|
||||
let (it, sym) = mk_reexport_mod(&mut self.cx, tests, tested_submods);
|
||||
mod_folded.items.push(it);
|
||||
|
|
@ -188,7 +191,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
|||
}
|
||||
|
||||
fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
|
||||
tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (Gc<ast::Item>, ast::Ident) {
|
||||
tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (P<ast::Item>, ast::Ident) {
|
||||
let mut view_items = Vec::new();
|
||||
let super_ = token::str_to_ident("super");
|
||||
|
||||
|
|
@ -208,14 +211,14 @@ fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
|
|||
};
|
||||
|
||||
let sym = token::gensym_ident("__test_reexports");
|
||||
let it = box(GC) ast::Item {
|
||||
let it = P(ast::Item {
|
||||
ident: sym.clone(),
|
||||
attrs: Vec::new(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ItemMod(reexport_mod),
|
||||
vis: ast::Public,
|
||||
span: DUMMY_SP,
|
||||
};
|
||||
});
|
||||
|
||||
(it, sym)
|
||||
}
|
||||
|
|
@ -266,10 +269,10 @@ fn strip_test_functions(krate: ast::Crate) -> ast::Crate {
|
|||
})
|
||||
}
|
||||
|
||||
fn is_test_fn(cx: &TestCtxt, i: Gc<ast::Item>) -> bool {
|
||||
fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
|
||||
let has_test_attr = attr::contains_name(i.attrs.as_slice(), "test");
|
||||
|
||||
fn has_test_signature(i: Gc<ast::Item>) -> bool {
|
||||
fn has_test_signature(i: &ast::Item) -> bool {
|
||||
match &i.node {
|
||||
&ast::ItemFn(ref decl, _, _, ref generics, _) => {
|
||||
let no_output = match decl.output.node {
|
||||
|
|
@ -295,10 +298,10 @@ fn is_test_fn(cx: &TestCtxt, i: Gc<ast::Item>) -> bool {
|
|||
return has_test_attr && has_test_signature(i);
|
||||
}
|
||||
|
||||
fn is_bench_fn(cx: &TestCtxt, i: Gc<ast::Item>) -> bool {
|
||||
fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
|
||||
let has_bench_attr = attr::contains_name(i.attrs.as_slice(), "bench");
|
||||
|
||||
fn has_test_signature(i: Gc<ast::Item>) -> bool {
|
||||
fn has_test_signature(i: &ast::Item) -> bool {
|
||||
match i.node {
|
||||
ast::ItemFn(ref decl, _, _, ref generics, _) => {
|
||||
let input_cnt = decl.inputs.len();
|
||||
|
|
@ -325,19 +328,19 @@ fn is_bench_fn(cx: &TestCtxt, i: Gc<ast::Item>) -> bool {
|
|||
return has_bench_attr && has_test_signature(i);
|
||||
}
|
||||
|
||||
fn is_ignored(cx: &TestCtxt, i: Gc<ast::Item>) -> bool {
|
||||
fn is_ignored(cx: &TestCtxt, i: &ast::Item) -> bool {
|
||||
i.attrs.iter().any(|attr| {
|
||||
// check ignore(cfg(foo, bar))
|
||||
attr.check_name("ignore") && match attr.meta_item_list() {
|
||||
Some(ref cfgs) => {
|
||||
attr::test_cfg(cx.config.as_slice(), cfgs.iter().map(|x| *x))
|
||||
attr::test_cfg(cx.config.as_slice(), cfgs.iter())
|
||||
}
|
||||
None => true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn should_fail(i: Gc<ast::Item>) -> bool {
|
||||
fn should_fail(i: &ast::Item) -> bool {
|
||||
attr::contains_name(i.attrs.as_slice(), "should_fail")
|
||||
}
|
||||
|
||||
|
|
@ -362,9 +365,9 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
|
|||
let id_test = token::str_to_ident("test");
|
||||
let (vi, vis) = if cx.is_test_crate {
|
||||
(ast::ViewItemUse(
|
||||
box(GC) nospan(ast::ViewPathSimple(id_test,
|
||||
path_node(vec!(id_test)),
|
||||
ast::DUMMY_NODE_ID))),
|
||||
P(nospan(ast::ViewPathSimple(id_test,
|
||||
path_node(vec!(id_test)),
|
||||
ast::DUMMY_NODE_ID)))),
|
||||
ast::Public)
|
||||
} else {
|
||||
(ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
|
||||
|
|
@ -378,7 +381,7 @@ fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
|
|||
}
|
||||
}
|
||||
|
||||
fn mk_test_module(cx: &mut TestCtxt) -> (Gc<ast::Item>, Option<ast::ViewItem>) {
|
||||
fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
|
||||
// Link to test crate
|
||||
let view_items = vec!(mk_std(cx));
|
||||
|
||||
|
|
@ -421,7 +424,7 @@ fn mk_test_module(cx: &mut TestCtxt) -> (Gc<ast::Item>, Option<ast::ViewItem>) {
|
|||
ast::DUMMY_NODE_ID));
|
||||
|
||||
ast::ViewItem {
|
||||
node: ast::ViewItemUse(box(GC) use_path),
|
||||
node: ast::ViewItemUse(P(use_path)),
|
||||
attrs: vec![],
|
||||
vis: ast::Inherited,
|
||||
span: DUMMY_SP
|
||||
|
|
@ -430,7 +433,7 @@ fn mk_test_module(cx: &mut TestCtxt) -> (Gc<ast::Item>, Option<ast::ViewItem>) {
|
|||
|
||||
debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&item));
|
||||
|
||||
(box(GC) item, reexport)
|
||||
(P(item), reexport)
|
||||
}
|
||||
|
||||
fn nospan<T>(t: T) -> codemap::Spanned<T> {
|
||||
|
|
@ -449,7 +452,7 @@ fn path_node(ids: Vec<ast::Ident> ) -> ast::Path {
|
|||
}
|
||||
}
|
||||
|
||||
fn mk_tests(cx: &TestCtxt) -> Gc<ast::Item> {
|
||||
fn mk_tests(cx: &TestCtxt) -> P<ast::Item> {
|
||||
// The vector of test_descs for this crate
|
||||
let test_descs = mk_test_descs(cx);
|
||||
|
||||
|
|
@ -483,24 +486,24 @@ fn is_test_crate(krate: &ast::Crate) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn mk_test_descs(cx: &TestCtxt) -> Gc<ast::Expr> {
|
||||
fn mk_test_descs(cx: &TestCtxt) -> P<ast::Expr> {
|
||||
debug!("building test vector from {} tests", cx.testfns.len());
|
||||
|
||||
box(GC) ast::Expr {
|
||||
P(ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprAddrOf(ast::MutImmutable,
|
||||
box(GC) ast::Expr {
|
||||
P(ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprVec(cx.testfns.iter().map(|test| {
|
||||
mk_test_desc_and_fn_rec(cx, test)
|
||||
}).collect()),
|
||||
span: DUMMY_SP,
|
||||
}),
|
||||
}).collect()),
|
||||
span: DUMMY_SP,
|
||||
})),
|
||||
span: DUMMY_SP,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> Gc<ast::Expr> {
|
||||
fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
|
||||
// FIXME #15962: should be using quote_expr, but that stringifies
|
||||
// __test_reexports, causing it to be reinterned, losing the
|
||||
// gensym information.
|
||||
|
|
|
|||
|
|
@ -119,7 +119,6 @@ pub mod front {
|
|||
pub mod config;
|
||||
pub mod test;
|
||||
pub mod std_inject;
|
||||
pub mod assign_node_ids_and_map;
|
||||
pub mod feature_gate;
|
||||
pub mod show_span;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ use lint::{Context, LintPass, LintArray};
|
|||
|
||||
use std::cmp;
|
||||
use std::collections::HashMap;
|
||||
use std::slice;
|
||||
use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
|
||||
use std::gc::Gc;
|
||||
use syntax::abi;
|
||||
use syntax::ast_map;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
|
|
@ -45,6 +45,7 @@ use syntax::attr;
|
|||
use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
use syntax::{ast, ast_util, visit};
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
declare_lint!(WHILE_TRUE, Warn,
|
||||
|
|
@ -59,9 +60,9 @@ impl LintPass for WhileTrue {
|
|||
|
||||
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
|
||||
match e.node {
|
||||
ast::ExprWhile(cond, _, _) => {
|
||||
ast::ExprWhile(ref cond, _, _) => {
|
||||
match cond.node {
|
||||
ast::ExprLit(lit) => {
|
||||
ast::ExprLit(ref lit) => {
|
||||
match lit.node {
|
||||
ast::LitBool(true) => {
|
||||
cx.span_lint(WHILE_TRUE, e.span,
|
||||
|
|
@ -91,9 +92,9 @@ impl LintPass for UnusedCasts {
|
|||
|
||||
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
|
||||
match e.node {
|
||||
ast::ExprCast(expr, ty) => {
|
||||
let t_t = ast_ty_to_ty(cx, &infer::new_infer_ctxt(cx.tcx), &*ty);
|
||||
if ty::get(ty::expr_ty(cx.tcx, &*expr)).sty == ty::get(t_t).sty {
|
||||
ast::ExprCast(ref expr, ref ty) => {
|
||||
let t_t = ast_ty_to_ty(cx, &infer::new_infer_ctxt(cx.tcx), &**ty);
|
||||
if ty::get(ty::expr_ty(cx.tcx, &**expr)).sty == ty::get(t_t).sty {
|
||||
cx.span_lint(UNNECESSARY_TYPECAST, ty.span, "unnecessary type cast");
|
||||
}
|
||||
}
|
||||
|
|
@ -131,9 +132,9 @@ impl LintPass for TypeLimits {
|
|||
|
||||
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
|
||||
match e.node {
|
||||
ast::ExprUnary(ast::UnNeg, expr) => {
|
||||
ast::ExprUnary(ast::UnNeg, ref expr) => {
|
||||
match expr.node {
|
||||
ast::ExprLit(lit) => {
|
||||
ast::ExprLit(ref lit) => {
|
||||
match lit.node {
|
||||
ast::LitInt(_, ast::UnsignedIntLit(_)) => {
|
||||
cx.span_lint(UNSIGNED_NEGATE, e.span,
|
||||
|
|
@ -144,7 +145,7 @@ impl LintPass for TypeLimits {
|
|||
}
|
||||
},
|
||||
_ => {
|
||||
let t = ty::expr_ty(cx.tcx, &*expr);
|
||||
let t = ty::expr_ty(cx.tcx, &**expr);
|
||||
match ty::get(t).sty {
|
||||
ty::ty_uint(_) => {
|
||||
cx.span_lint(UNSIGNED_NEGATE, e.span,
|
||||
|
|
@ -160,16 +161,16 @@ impl LintPass for TypeLimits {
|
|||
self.negated_expr_id = expr.id;
|
||||
}
|
||||
},
|
||||
ast::ExprParen(expr) if self.negated_expr_id == e.id => {
|
||||
ast::ExprParen(ref expr) if self.negated_expr_id == e.id => {
|
||||
self.negated_expr_id = expr.id;
|
||||
},
|
||||
ast::ExprBinary(binop, l, r) => {
|
||||
if is_comparison(binop) && !check_limits(cx.tcx, binop, &*l, &*r) {
|
||||
ast::ExprBinary(binop, ref l, ref r) => {
|
||||
if is_comparison(binop) && !check_limits(cx.tcx, binop, &**l, &**r) {
|
||||
cx.span_lint(TYPE_LIMITS, e.span,
|
||||
"comparison is useless due to type limits");
|
||||
}
|
||||
},
|
||||
ast::ExprLit(lit) => {
|
||||
ast::ExprLit(ref lit) => {
|
||||
match ty::get(ty::expr_ty(cx.tcx, e)).sty {
|
||||
ty::ty_int(t) => {
|
||||
match lit.node {
|
||||
|
|
@ -292,7 +293,7 @@ impl LintPass for TypeLimits {
|
|||
ty::ty_int(int_ty) => {
|
||||
let (min, max) = int_ty_range(int_ty);
|
||||
let lit_val: i64 = match lit.node {
|
||||
ast::ExprLit(li) => match li.node {
|
||||
ast::ExprLit(ref li) => match li.node {
|
||||
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
|
||||
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => v as i64,
|
||||
ast::LitInt(v, ast::SignedIntLit(_, ast::Minus)) |
|
||||
|
|
@ -306,7 +307,7 @@ impl LintPass for TypeLimits {
|
|||
ty::ty_uint(uint_ty) => {
|
||||
let (min, max): (u64, u64) = uint_ty_range(uint_ty);
|
||||
let lit_val: u64 = match lit.node {
|
||||
ast::ExprLit(li) => match li.node {
|
||||
ast::ExprLit(ref li) => match li.node {
|
||||
ast::LitInt(v, _) => v,
|
||||
_ => return true
|
||||
},
|
||||
|
|
@ -400,8 +401,8 @@ impl LintPass for CTypes {
|
|||
ast::ItemForeignMod(ref nmod) if nmod.abi != abi::RustIntrinsic => {
|
||||
for ni in nmod.items.iter() {
|
||||
match ni.node {
|
||||
ast::ForeignItemFn(decl, _) => check_foreign_fn(cx, &*decl),
|
||||
ast::ForeignItemStatic(t, _) => check_ty(cx, &*t)
|
||||
ast::ForeignItemFn(ref decl, _) => check_foreign_fn(cx, &**decl),
|
||||
ast::ForeignItemStatic(ref t, _) => check_ty(cx, &**t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -477,7 +478,7 @@ impl LintPass for HeapMemory {
|
|||
|
||||
// If it's a struct, we also have to check the fields' types
|
||||
match it.node {
|
||||
ast::ItemStruct(struct_def, _) => {
|
||||
ast::ItemStruct(ref struct_def, _) => {
|
||||
for struct_field in struct_def.fields.iter() {
|
||||
self.check_heap_type(cx, struct_field.span,
|
||||
ty::node_id_to_type(cx.tcx, struct_field.node.id));
|
||||
|
|
@ -658,7 +659,7 @@ impl LintPass for PathStatement {
|
|||
|
||||
fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
|
||||
match s.node {
|
||||
ast::StmtSemi(expr, _) => {
|
||||
ast::StmtSemi(ref expr, _) => {
|
||||
match expr.node {
|
||||
ast::ExprPath(_) => cx.span_lint(PATH_STATEMENT, s.span,
|
||||
"path statement with no effect"),
|
||||
|
|
@ -685,10 +686,10 @@ impl LintPass for UnusedResult {
|
|||
|
||||
fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
|
||||
let expr = match s.node {
|
||||
ast::StmtSemi(expr, _) => expr,
|
||||
ast::StmtSemi(ref expr, _) => &**expr,
|
||||
_ => return
|
||||
};
|
||||
let t = ty::expr_ty(cx.tcx, &*expr);
|
||||
let t = ty::expr_ty(cx.tcx, expr);
|
||||
match ty::get(t).sty {
|
||||
ty::ty_nil | ty::ty_bot | ty::ty_bool => return,
|
||||
_ => {}
|
||||
|
|
@ -698,7 +699,7 @@ impl LintPass for UnusedResult {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
let t = ty::expr_ty(cx.tcx, &*expr);
|
||||
let t = ty::expr_ty(cx.tcx, expr);
|
||||
let mut warned = false;
|
||||
match ty::get(t).sty {
|
||||
ty::ty_struct(did, _) |
|
||||
|
|
@ -1080,29 +1081,29 @@ impl LintPass for UnnecessaryParens {
|
|||
|
||||
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
|
||||
let (value, msg, struct_lit_needs_parens) = match e.node {
|
||||
ast::ExprIf(cond, _, _) => (cond, "`if` condition", true),
|
||||
ast::ExprWhile(cond, _, _) => (cond, "`while` condition", true),
|
||||
ast::ExprMatch(head, _) => (head, "`match` head expression", true),
|
||||
ast::ExprRet(Some(value)) => (value, "`return` value", false),
|
||||
ast::ExprAssign(_, value) => (value, "assigned value", false),
|
||||
ast::ExprAssignOp(_, _, value) => (value, "assigned value", false),
|
||||
ast::ExprIf(ref cond, _, _) => (cond, "`if` condition", true),
|
||||
ast::ExprWhile(ref cond, _, _) => (cond, "`while` condition", true),
|
||||
ast::ExprMatch(ref head, _) => (head, "`match` head expression", true),
|
||||
ast::ExprRet(Some(ref value)) => (value, "`return` value", false),
|
||||
ast::ExprAssign(_, ref value) => (value, "assigned value", false),
|
||||
ast::ExprAssignOp(_, _, ref value) => (value, "assigned value", false),
|
||||
_ => return
|
||||
};
|
||||
self.check_unnecessary_parens_core(cx, &*value, msg, struct_lit_needs_parens);
|
||||
self.check_unnecessary_parens_core(cx, &**value, msg, struct_lit_needs_parens);
|
||||
}
|
||||
|
||||
fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
|
||||
let (value, msg) = match s.node {
|
||||
ast::StmtDecl(decl, _) => match decl.node {
|
||||
ast::DeclLocal(local) => match local.init {
|
||||
Some(value) => (value, "assigned value"),
|
||||
ast::StmtDecl(ref decl, _) => match decl.node {
|
||||
ast::DeclLocal(ref local) => match local.init {
|
||||
Some(ref value) => (value, "assigned value"),
|
||||
None => return
|
||||
},
|
||||
_ => return
|
||||
},
|
||||
_ => return
|
||||
};
|
||||
self.check_unnecessary_parens_core(cx, &*value, msg, false);
|
||||
self.check_unnecessary_parens_core(cx, &**value, msg, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1157,12 +1158,12 @@ declare_lint!(pub UNUSED_MUT, Warn,
|
|||
pub struct UnusedMut;
|
||||
|
||||
impl UnusedMut {
|
||||
fn check_unused_mut_pat(&self, cx: &Context, pats: &[Gc<ast::Pat>]) {
|
||||
fn check_unused_mut_pat(&self, cx: &Context, pats: &[P<ast::Pat>]) {
|
||||
// collect all mutable pattern and group their NodeIDs by their Identifier to
|
||||
// avoid false warnings in match arms with multiple patterns
|
||||
let mut mutables = HashMap::new();
|
||||
for &p in pats.iter() {
|
||||
pat_util::pat_bindings(&cx.tcx.def_map, &*p, |mode, id, _, path1| {
|
||||
for p in pats.iter() {
|
||||
pat_util::pat_bindings(&cx.tcx.def_map, &**p, |mode, id, _, path1| {
|
||||
let ident = path1.node;
|
||||
match mode {
|
||||
ast::BindByValue(ast::MutMutable) => {
|
||||
|
|
@ -1205,10 +1206,10 @@ impl LintPass for UnusedMut {
|
|||
|
||||
fn check_stmt(&mut self, cx: &Context, s: &ast::Stmt) {
|
||||
match s.node {
|
||||
ast::StmtDecl(d, _) => {
|
||||
ast::StmtDecl(ref d, _) => {
|
||||
match d.node {
|
||||
ast::DeclLocal(l) => {
|
||||
self.check_unused_mut_pat(cx, &[l.pat]);
|
||||
ast::DeclLocal(ref l) => {
|
||||
self.check_unused_mut_pat(cx, slice::ref_slice(&l.pat));
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -1221,7 +1222,7 @@ impl LintPass for UnusedMut {
|
|||
_: visit::FnKind, decl: &ast::FnDecl,
|
||||
_: &ast::Block, _: Span, _: ast::NodeId) {
|
||||
for a in decl.inputs.iter() {
|
||||
self.check_unused_mut_pat(cx, &[a.pat]);
|
||||
self.check_unused_mut_pat(cx, slice::ref_slice(&a.pat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ pub fn gather_attrs(attrs: &[ast::Attribute])
|
|||
|
||||
attr::mark_used(attr);
|
||||
|
||||
let meta = attr.node.value;
|
||||
let meta = &attr.node.value;
|
||||
let metas = match meta.node {
|
||||
ast::MetaList(_, ref metas) => metas,
|
||||
_ => {
|
||||
|
|
@ -709,8 +709,8 @@ impl LintPass for GatherNodeLevels {
|
|||
///
|
||||
/// Consumes the `lint_store` field of the `Session`.
|
||||
pub fn check_crate(tcx: &ty::ctxt,
|
||||
krate: &ast::Crate,
|
||||
exported_items: &ExportedItems) {
|
||||
let krate = tcx.map.krate();
|
||||
let mut cx = Context::new(tcx, krate, exported_items);
|
||||
|
||||
// Visit the whole crate.
|
||||
|
|
|
|||
|
|
@ -97,18 +97,18 @@ pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId) -> Vec<ast_map::PathElem>
|
|||
path.as_slice())
|
||||
}
|
||||
|
||||
pub enum found_ast {
|
||||
found(ast::InlinedItem),
|
||||
found_parent(ast::DefId, ast::InlinedItem),
|
||||
pub enum found_ast<'ast> {
|
||||
found(&'ast ast::InlinedItem),
|
||||
found_parent(ast::DefId, &'ast ast::InlinedItem),
|
||||
not_found,
|
||||
}
|
||||
|
||||
// Finds the AST for this item in the crate metadata, if any. If the item was
|
||||
// not marked for inlining, then the AST will not be present and hence none
|
||||
// will be returned.
|
||||
pub fn maybe_get_item_ast(tcx: &ty::ctxt, def: ast::DefId,
|
||||
decode_inlined_item: decoder::DecodeInlinedItem)
|
||||
-> found_ast {
|
||||
pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId,
|
||||
decode_inlined_item: decoder::DecodeInlinedItem)
|
||||
-> found_ast<'tcx> {
|
||||
let cstore = &tcx.sess.cstore;
|
||||
let cdata = cstore.get_crate_data(def.krate);
|
||||
decoder::maybe_get_item_ast(&*cdata, tcx, def.node, decode_inlined_item)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ use middle::ty;
|
|||
use middle::typeck;
|
||||
use middle::astencode::vtable_decoder_helpers;
|
||||
|
||||
use std::gc::Gc;
|
||||
use std::hash::Hash;
|
||||
use std::hash;
|
||||
use std::io::extensions::u64_from_be_bytes;
|
||||
|
|
@ -48,6 +47,7 @@ use syntax::parse::token;
|
|||
use syntax::print::pprust;
|
||||
use syntax::ast;
|
||||
use syntax::codemap;
|
||||
use syntax::ptr::P;
|
||||
|
||||
pub type Cmd<'a> = &'a crate_metadata;
|
||||
|
||||
|
|
@ -612,27 +612,28 @@ pub fn get_item_path(cdata: Cmd, id: ast::NodeId) -> Vec<ast_map::PathElem> {
|
|||
item_path(lookup_item(id, cdata.data()))
|
||||
}
|
||||
|
||||
pub type DecodeInlinedItem<'a> = |cdata: Cmd,
|
||||
tcx: &ty::ctxt,
|
||||
path: Vec<ast_map::PathElem>,
|
||||
par_doc: rbml::Doc|: 'a
|
||||
-> Result<ast::InlinedItem, Vec<ast_map::PathElem> >;
|
||||
pub type DecodeInlinedItem<'a> = <'tcx> |cdata: Cmd,
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
path: Vec<ast_map::PathElem>,
|
||||
par_doc: rbml::Doc|: 'a
|
||||
-> Result<&'tcx ast::InlinedItem,
|
||||
Vec<ast_map::PathElem>>;
|
||||
|
||||
pub fn maybe_get_item_ast(cdata: Cmd, tcx: &ty::ctxt, id: ast::NodeId,
|
||||
decode_inlined_item: DecodeInlinedItem)
|
||||
-> csearch::found_ast {
|
||||
pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeId,
|
||||
decode_inlined_item: DecodeInlinedItem)
|
||||
-> csearch::found_ast<'tcx> {
|
||||
debug!("Looking up item: {}", id);
|
||||
let item_doc = lookup_item(id, cdata.data());
|
||||
let path = Vec::from_slice(item_path(item_doc).init());
|
||||
match decode_inlined_item(cdata, tcx, path, item_doc) {
|
||||
Ok(ref ii) => csearch::found(*ii),
|
||||
Ok(ii) => csearch::found(ii),
|
||||
Err(path) => {
|
||||
match item_parent_item(item_doc) {
|
||||
Some(did) => {
|
||||
let did = translate_def_id(cdata, did);
|
||||
let parent_item = lookup_item(did.node, cdata.data());
|
||||
match decode_inlined_item(cdata, tcx, path, parent_item) {
|
||||
Ok(ref ii) => csearch::found_parent(did, *ii),
|
||||
Ok(ii) => csearch::found_parent(did, ii),
|
||||
Err(_) => csearch::not_found
|
||||
}
|
||||
}
|
||||
|
|
@ -1003,8 +1004,8 @@ pub fn get_struct_fields(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId)
|
|||
result
|
||||
}
|
||||
|
||||
fn get_meta_items(md: rbml::Doc) -> Vec<Gc<ast::MetaItem>> {
|
||||
let mut items: Vec<Gc<ast::MetaItem>> = Vec::new();
|
||||
fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
|
||||
let mut items: Vec<P<ast::MetaItem>> = Vec::new();
|
||||
reader::tagged_docs(md, tag_meta_item_word, |meta_item_doc| {
|
||||
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
|
||||
let n = token::intern_and_get_ident(nd.as_str_slice());
|
||||
|
|
@ -1043,7 +1044,7 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
|
|||
// Currently it's only possible to have a single meta item on
|
||||
// an attribute
|
||||
assert_eq!(meta_items.len(), 1u);
|
||||
let meta_item = *meta_items.get(0);
|
||||
let meta_item = meta_items.move_iter().nth(0).unwrap();
|
||||
attrs.push(
|
||||
codemap::Spanned {
|
||||
node: ast::Attribute_ {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ use util::nodemap::{NodeMap, NodeSet};
|
|||
|
||||
use serialize::Encodable;
|
||||
use std::cell::RefCell;
|
||||
use std::gc::Gc;
|
||||
use std::hash::Hash;
|
||||
use std::hash;
|
||||
use std::mem;
|
||||
|
|
@ -46,6 +45,7 @@ use syntax::attr::AttrMetaMethods;
|
|||
use syntax::diagnostic::SpanHandler;
|
||||
use syntax::parse::token::special_idents;
|
||||
use syntax::parse::token;
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::visit;
|
||||
use syntax;
|
||||
|
|
@ -55,16 +55,11 @@ use rbml::io::SeekableMemWriter;
|
|||
/// A borrowed version of `ast::InlinedItem`.
|
||||
pub enum InlinedItemRef<'a> {
|
||||
IIItemRef(&'a ast::Item),
|
||||
IITraitItemRef(ast::DefId, InlinedTraitItemRef<'a>),
|
||||
IITraitItemRef(ast::DefId, &'a ast::TraitItem),
|
||||
IIImplItemRef(ast::DefId, &'a ast::ImplItem),
|
||||
IIForeignRef(&'a ast::ForeignItem)
|
||||
}
|
||||
|
||||
/// A borrowed version of `ast::InlinedTraitItem`.
|
||||
pub enum InlinedTraitItemRef<'a> {
|
||||
ProvidedInlinedTraitItemRef(&'a Method),
|
||||
RequiredInlinedTraitItemRef(&'a Method),
|
||||
}
|
||||
|
||||
pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
|
||||
|
||||
pub type EncodeInlinedItem<'a> = |ecx: &EncodeContext,
|
||||
|
|
@ -507,7 +502,7 @@ fn encode_reexported_static_methods(ecx: &EncodeContext,
|
|||
/// * For enums, iterates through the node IDs of the variants.
|
||||
///
|
||||
/// * For newtype structs, iterates through the node ID of the constructor.
|
||||
fn each_auxiliary_node_id(item: Gc<Item>, callback: |NodeId| -> bool) -> bool {
|
||||
fn each_auxiliary_node_id(item: &Item, callback: |NodeId| -> bool) -> bool {
|
||||
let mut continue_ = true;
|
||||
match item.node {
|
||||
ItemEnum(ref enum_def, _) => {
|
||||
|
|
@ -518,7 +513,7 @@ fn each_auxiliary_node_id(item: Gc<Item>, callback: |NodeId| -> bool) -> bool {
|
|||
}
|
||||
}
|
||||
}
|
||||
ItemStruct(struct_def, _) => {
|
||||
ItemStruct(ref struct_def, _) => {
|
||||
// If this is a newtype struct, return the constructor.
|
||||
match struct_def.ctor_id {
|
||||
Some(ctor_id) if struct_def.fields.len() > 0 &&
|
||||
|
|
@ -587,7 +582,7 @@ fn encode_info_for_mod(ecx: &EncodeContext,
|
|||
rbml_w.wr_str(def_to_string(local_def(item.id)).as_slice());
|
||||
rbml_w.end_tag();
|
||||
|
||||
each_auxiliary_node_id(*item, |auxiliary_node_id| {
|
||||
each_auxiliary_node_id(&**item, |auxiliary_node_id| {
|
||||
rbml_w.start_tag(tag_mod_child);
|
||||
rbml_w.wr_str(def_to_string(local_def(
|
||||
auxiliary_node_id)).as_slice());
|
||||
|
|
@ -858,7 +853,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
|
|||
impl_path: PathElems,
|
||||
is_default_impl: bool,
|
||||
parent_id: NodeId,
|
||||
ast_method_opt: Option<Gc<Method>>) {
|
||||
ast_item_opt: Option<&ImplItem>) {
|
||||
|
||||
debug!("encode_info_for_method: {:?} {}", m.def_id,
|
||||
token::get_ident(m.ident));
|
||||
|
|
@ -877,26 +872,20 @@ fn encode_info_for_method(ecx: &EncodeContext,
|
|||
|
||||
let elem = ast_map::PathName(m.ident.name);
|
||||
encode_path(rbml_w, impl_path.chain(Some(elem).move_iter()));
|
||||
match ast_method_opt {
|
||||
Some(ast_method) => {
|
||||
encode_attributes(rbml_w, ast_method.attrs.as_slice())
|
||||
match ast_item_opt {
|
||||
Some(&ast::MethodImplItem(ref ast_method)) => {
|
||||
encode_attributes(rbml_w, ast_method.attrs.as_slice());
|
||||
let any_types = !pty.generics.types.is_empty();
|
||||
if any_types || is_default_impl || should_inline(ast_method.attrs.as_slice()) {
|
||||
encode_inlined_item(ecx, rbml_w, IIImplItemRef(local_def(parent_id),
|
||||
ast_item_opt.unwrap()));
|
||||
}
|
||||
if !any_types {
|
||||
encode_symbol(ecx, rbml_w, m.def_id.node);
|
||||
}
|
||||
encode_method_argument_names(rbml_w, ast_method.pe_fn_decl());
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
|
||||
for &ast_method in ast_method_opt.iter() {
|
||||
let any_types = !pty.generics.types.is_empty();
|
||||
if any_types || is_default_impl || should_inline(ast_method.attrs.as_slice()) {
|
||||
encode_inlined_item(ecx,
|
||||
rbml_w,
|
||||
IITraitItemRef(local_def(parent_id),
|
||||
RequiredInlinedTraitItemRef(
|
||||
&*ast_method)));
|
||||
}
|
||||
if !any_types {
|
||||
encode_symbol(ecx, rbml_w, m.def_id.node);
|
||||
}
|
||||
encode_method_argument_names(rbml_w, &*ast_method.pe_fn_decl());
|
||||
None => {}
|
||||
}
|
||||
|
||||
rbml_w.end_tag();
|
||||
|
|
@ -1127,7 +1116,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
(*enum_definition).variants.as_slice(),
|
||||
index);
|
||||
}
|
||||
ItemStruct(struct_def, _) => {
|
||||
ItemStruct(ref struct_def, _) => {
|
||||
let fields = ty::lookup_struct_fields(tcx, def_id);
|
||||
|
||||
/* First, encode the fields
|
||||
|
|
@ -1178,7 +1167,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
None => {}
|
||||
}
|
||||
}
|
||||
ItemImpl(_, ref opt_trait, ty, ref ast_items) => {
|
||||
ItemImpl(_, ref opt_trait, ref ty, ref ast_items) => {
|
||||
// We need to encode information about the default methods we
|
||||
// have inherited, so we drive this based on the impl structure.
|
||||
let impl_items = tcx.impl_items.borrow();
|
||||
|
|
@ -1228,7 +1217,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
let num_implemented_methods = ast_items.len();
|
||||
for (i, &trait_item_def_id) in items.iter().enumerate() {
|
||||
let ast_item = if i < num_implemented_methods {
|
||||
Some(*ast_items.get(i))
|
||||
Some(ast_items.get(i))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
@ -1238,29 +1227,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
pos: rbml_w.writer.tell().unwrap(),
|
||||
});
|
||||
|
||||
let trait_item_type =
|
||||
let ty::MethodTraitItem(method_type) =
|
||||
ty::impl_or_trait_item(tcx, trait_item_def_id.def_id());
|
||||
match (trait_item_type, ast_item) {
|
||||
(ty::MethodTraitItem(method_type),
|
||||
Some(ast::MethodImplItem(ast_method))) => {
|
||||
encode_info_for_method(ecx,
|
||||
rbml_w,
|
||||
&*method_type,
|
||||
path.clone(),
|
||||
false,
|
||||
item.id,
|
||||
Some(ast_method))
|
||||
}
|
||||
(ty::MethodTraitItem(method_type), None) => {
|
||||
encode_info_for_method(ecx,
|
||||
rbml_w,
|
||||
&*method_type,
|
||||
path.clone(),
|
||||
false,
|
||||
item.id,
|
||||
None)
|
||||
}
|
||||
}
|
||||
encode_info_for_method(ecx, rbml_w, &*method_type, path.clone(),
|
||||
false, item.id, ast_item)
|
||||
}
|
||||
}
|
||||
ItemTrait(_, _, _, ref ms) => {
|
||||
|
|
@ -1345,15 +1315,16 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
}
|
||||
}
|
||||
|
||||
match ms.get(i) {
|
||||
&RequiredMethod(ref tm) => {
|
||||
let trait_item = ms.get(i);
|
||||
match *trait_item {
|
||||
RequiredMethod(ref tm) => {
|
||||
encode_attributes(rbml_w, tm.attrs.as_slice());
|
||||
encode_item_sort(rbml_w, 'r');
|
||||
encode_parent_sort(rbml_w, 't');
|
||||
encode_method_argument_names(rbml_w, &*tm.decl);
|
||||
}
|
||||
|
||||
&ProvidedMethod(m) => {
|
||||
ProvidedMethod(ref m) => {
|
||||
encode_attributes(rbml_w, m.attrs.as_slice());
|
||||
// If this is a static method, we've already
|
||||
// encoded this.
|
||||
|
|
@ -1366,14 +1337,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
}
|
||||
encode_item_sort(rbml_w, 'p');
|
||||
encode_parent_sort(rbml_w, 't');
|
||||
encode_inlined_item(
|
||||
ecx,
|
||||
rbml_w,
|
||||
IITraitItemRef(
|
||||
def_id,
|
||||
ProvidedInlinedTraitItemRef(&*m)));
|
||||
encode_method_argument_names(rbml_w,
|
||||
&*m.pe_fn_decl());
|
||||
encode_inlined_item(ecx, rbml_w,
|
||||
IITraitItemRef(def_id, trait_item));
|
||||
encode_method_argument_names(rbml_w, &*m.pe_fn_decl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1571,7 +1537,7 @@ fn write_i64(writer: &mut SeekableMemWriter, &n: &i64) {
|
|||
wr.write_be_u32(n as u32);
|
||||
}
|
||||
|
||||
fn encode_meta_item(rbml_w: &mut Encoder, mi: Gc<MetaItem>) {
|
||||
fn encode_meta_item(rbml_w: &mut Encoder, mi: &MetaItem) {
|
||||
match mi.node {
|
||||
MetaWord(ref name) => {
|
||||
rbml_w.start_tag(tag_meta_item_word);
|
||||
|
|
@ -1601,7 +1567,7 @@ fn encode_meta_item(rbml_w: &mut Encoder, mi: Gc<MetaItem>) {
|
|||
rbml_w.writer.write(name.get().as_bytes());
|
||||
rbml_w.end_tag();
|
||||
for inner_item in items.iter() {
|
||||
encode_meta_item(rbml_w, *inner_item);
|
||||
encode_meta_item(rbml_w, &**inner_item);
|
||||
}
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
|
|
@ -1613,7 +1579,7 @@ fn encode_attributes(rbml_w: &mut Encoder, attrs: &[Attribute]) {
|
|||
for attr in attrs.iter() {
|
||||
rbml_w.start_tag(tag_attribute);
|
||||
rbml_w.wr_tagged_u8(tag_attribute_is_sugared_doc, attr.node.is_sugared_doc as u8);
|
||||
encode_meta_item(rbml_w, attr.node.value);
|
||||
encode_meta_item(rbml_w, &*attr.node.value);
|
||||
rbml_w.end_tag();
|
||||
}
|
||||
rbml_w.end_tag();
|
||||
|
|
@ -1852,12 +1818,12 @@ fn encode_misc_info(ecx: &EncodeContext,
|
|||
rbml_w: &mut Encoder) {
|
||||
rbml_w.start_tag(tag_misc_info);
|
||||
rbml_w.start_tag(tag_misc_info_crate_items);
|
||||
for &item in krate.module.items.iter() {
|
||||
for item in krate.module.items.iter() {
|
||||
rbml_w.start_tag(tag_mod_child);
|
||||
rbml_w.wr_str(def_to_string(local_def(item.id)).as_slice());
|
||||
rbml_w.end_tag();
|
||||
|
||||
each_auxiliary_node_id(item, |auxiliary_node_id| {
|
||||
each_auxiliary_node_id(&**item, |auxiliary_node_id| {
|
||||
rbml_w.start_tag(tag_mod_child);
|
||||
rbml_w.wr_str(def_to_string(local_def(
|
||||
auxiliary_node_id)).as_slice());
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -44,7 +44,7 @@ impl Variant {
|
|||
}
|
||||
|
||||
pub struct DataflowLabeller<'a, 'tcx: 'a> {
|
||||
pub inner: cfg_dot::LabelledCFG<'a>,
|
||||
pub inner: cfg_dot::LabelledCFG<'a, 'tcx>,
|
||||
pub variants: Vec<Variant>,
|
||||
pub borrowck_ctxt: &'a BorrowckCtxt<'a, 'tcx>,
|
||||
pub analysis_data: &'a borrowck::AnalysisData<'a, 'tcx>,
|
||||
|
|
|
|||
|
|
@ -22,9 +22,7 @@ use middle::mem_categorization as mc;
|
|||
use middle::ty;
|
||||
use util::ppaux::{note_and_explain_region, Repr, UserString};
|
||||
|
||||
use std::cell::{Cell};
|
||||
use std::rc::Rc;
|
||||
use std::gc::{Gc, GC};
|
||||
use std::string::String;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
|
|
@ -71,34 +69,33 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: &ty::ctxt,
|
||||
krate: &ast::Crate) {
|
||||
pub fn check_crate(tcx: &ty::ctxt) {
|
||||
let mut bccx = BorrowckCtxt {
|
||||
tcx: tcx,
|
||||
stats: box(GC) BorrowStats {
|
||||
loaned_paths_same: Cell::new(0),
|
||||
loaned_paths_imm: Cell::new(0),
|
||||
stable_paths: Cell::new(0),
|
||||
guaranteed_paths: Cell::new(0),
|
||||
stats: BorrowStats {
|
||||
loaned_paths_same: 0,
|
||||
loaned_paths_imm: 0,
|
||||
stable_paths: 0,
|
||||
guaranteed_paths: 0
|
||||
}
|
||||
};
|
||||
|
||||
visit::walk_crate(&mut bccx, krate);
|
||||
visit::walk_crate(&mut bccx, tcx.map.krate());
|
||||
|
||||
if tcx.sess.borrowck_stats() {
|
||||
println!("--- borrowck stats ---");
|
||||
println!("paths requiring guarantees: {}",
|
||||
bccx.stats.guaranteed_paths.get());
|
||||
bccx.stats.guaranteed_paths);
|
||||
println!("paths requiring loans : {}",
|
||||
make_stat(&bccx, bccx.stats.loaned_paths_same.get()));
|
||||
make_stat(&bccx, bccx.stats.loaned_paths_same));
|
||||
println!("paths requiring imm loans : {}",
|
||||
make_stat(&bccx, bccx.stats.loaned_paths_imm.get()));
|
||||
make_stat(&bccx, bccx.stats.loaned_paths_imm));
|
||||
println!("stable paths : {}",
|
||||
make_stat(&bccx, bccx.stats.stable_paths.get()));
|
||||
make_stat(&bccx, bccx.stats.stable_paths));
|
||||
}
|
||||
|
||||
fn make_stat(bccx: &BorrowckCtxt, stat: uint) -> String {
|
||||
let total = bccx.stats.guaranteed_paths.get() as f64;
|
||||
let total = bccx.stats.guaranteed_paths as f64;
|
||||
let perc = if total == 0.0 { 0.0 } else { stat as f64 * 100.0 / total };
|
||||
format!("{} ({:.0f}%)", stat, perc)
|
||||
}
|
||||
|
|
@ -110,8 +107,8 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
|
|||
// loan step is intended for things that have a data
|
||||
// flow dependent conditions.
|
||||
match item.node {
|
||||
ast::ItemStatic(_, _, ex) => {
|
||||
gather_loans::gather_loans_in_static_initializer(this, &*ex);
|
||||
ast::ItemStatic(_, _, ref ex) => {
|
||||
gather_loans::gather_loans_in_static_initializer(this, &**ex);
|
||||
}
|
||||
_ => {
|
||||
visit::walk_item(this, item);
|
||||
|
|
@ -206,11 +203,11 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
|
|||
|
||||
let mut bccx = BorrowckCtxt {
|
||||
tcx: tcx,
|
||||
stats: box(GC) BorrowStats {
|
||||
loaned_paths_same: Cell::new(0),
|
||||
loaned_paths_imm: Cell::new(0),
|
||||
stable_paths: Cell::new(0),
|
||||
guaranteed_paths: Cell::new(0),
|
||||
stats: BorrowStats {
|
||||
loaned_paths_same: 0,
|
||||
loaned_paths_imm: 0,
|
||||
stable_paths: 0,
|
||||
guaranteed_paths: 0
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -234,14 +231,14 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
|
|||
tcx: &'a ty::ctxt<'tcx>,
|
||||
|
||||
// Statistics:
|
||||
stats: Gc<BorrowStats>,
|
||||
stats: BorrowStats
|
||||
}
|
||||
|
||||
pub struct BorrowStats {
|
||||
loaned_paths_same: Cell<uint>,
|
||||
loaned_paths_imm: Cell<uint>,
|
||||
stable_paths: Cell<uint>,
|
||||
guaranteed_paths: Cell<uint>,
|
||||
struct BorrowStats {
|
||||
loaned_paths_same: uint,
|
||||
loaned_paths_imm: uint,
|
||||
stable_paths: uint,
|
||||
guaranteed_paths: uint
|
||||
}
|
||||
|
||||
pub type BckResult<T> = Result<T, BckError>;
|
||||
|
|
@ -290,9 +287,9 @@ pub fn closure_to_block(closure_id: ast::NodeId,
|
|||
tcx: &ty::ctxt) -> ast::NodeId {
|
||||
match tcx.map.get(closure_id) {
|
||||
ast_map::NodeExpr(expr) => match expr.node {
|
||||
ast::ExprProc(_, block) |
|
||||
ast::ExprFnBlock(_, _, block) |
|
||||
ast::ExprUnboxedFn(_, _, _, block) => { block.id }
|
||||
ast::ExprProc(_, ref block) |
|
||||
ast::ExprFnBlock(_, _, ref block) |
|
||||
ast::ExprUnboxedFn(_, _, _, ref block) => { block.id }
|
||||
_ => fail!("encountered non-closure id: {}", closure_id)
|
||||
},
|
||||
_ => fail!("encountered non-expr id: {}", closure_id)
|
||||
|
|
|
|||
|
|
@ -15,10 +15,9 @@ use middle::typeck;
|
|||
use middle::ty;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::ptr::P;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
struct CFGBuilder<'a, 'tcx: 'a> {
|
||||
tcx: &'a ty::ctxt<'tcx>,
|
||||
exit_map: NodeMap<CFGIndex>,
|
||||
|
|
@ -69,15 +68,15 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
fn block(&mut self, blk: &ast::Block, pred: CFGIndex) -> CFGIndex {
|
||||
let mut stmts_exit = pred;
|
||||
for stmt in blk.stmts.iter() {
|
||||
stmts_exit = self.stmt(stmt.clone(), stmts_exit);
|
||||
stmts_exit = self.stmt(&**stmt, stmts_exit);
|
||||
}
|
||||
|
||||
let expr_exit = self.opt_expr(blk.expr.clone(), stmts_exit);
|
||||
let expr_exit = self.opt_expr(&blk.expr, stmts_exit);
|
||||
|
||||
self.add_node(blk.id, [expr_exit])
|
||||
}
|
||||
|
||||
fn stmt(&mut self, stmt: Gc<ast::Stmt>, pred: CFGIndex) -> CFGIndex {
|
||||
fn stmt(&mut self, stmt: &ast::Stmt, pred: CFGIndex) -> CFGIndex {
|
||||
match stmt.node {
|
||||
ast::StmtDecl(ref decl, id) => {
|
||||
let exit = self.decl(&**decl, pred);
|
||||
|
|
@ -85,7 +84,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ast::StmtExpr(ref expr, id) | ast::StmtSemi(ref expr, id) => {
|
||||
let exit = self.expr(expr.clone(), pred);
|
||||
let exit = self.expr(&**expr, pred);
|
||||
self.add_node(id, [exit])
|
||||
}
|
||||
|
||||
|
|
@ -98,7 +97,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
fn decl(&mut self, decl: &ast::Decl, pred: CFGIndex) -> CFGIndex {
|
||||
match decl.node {
|
||||
ast::DeclLocal(ref local) => {
|
||||
let init_exit = self.opt_expr(local.init.clone(), pred);
|
||||
let init_exit = self.opt_expr(&local.init, pred);
|
||||
self.pat(&*local.pat, init_exit)
|
||||
}
|
||||
|
||||
|
|
@ -127,24 +126,20 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
|
||||
ast::PatEnum(_, Some(ref subpats)) |
|
||||
ast::PatTup(ref subpats) => {
|
||||
let pats_exit =
|
||||
self.pats_all(subpats.iter().map(|p| p.clone()), pred);
|
||||
let pats_exit = self.pats_all(subpats.iter(), pred);
|
||||
self.add_node(pat.id, [pats_exit])
|
||||
}
|
||||
|
||||
ast::PatStruct(_, ref subpats, _) => {
|
||||
let pats_exit =
|
||||
self.pats_all(subpats.iter().map(|f| f.pat.clone()), pred);
|
||||
self.pats_all(subpats.iter().map(|f| &f.pat), pred);
|
||||
self.add_node(pat.id, [pats_exit])
|
||||
}
|
||||
|
||||
ast::PatVec(ref pre, ref vec, ref post) => {
|
||||
let pre_exit =
|
||||
self.pats_all(pre.iter().map(|p| *p), pred);
|
||||
let vec_exit =
|
||||
self.pats_all(vec.iter().map(|p| *p), pre_exit);
|
||||
let post_exit =
|
||||
self.pats_all(post.iter().map(|p| *p), vec_exit);
|
||||
let pre_exit = self.pats_all(pre.iter(), pred);
|
||||
let vec_exit = self.pats_all(vec.iter(), pre_exit);
|
||||
let post_exit = self.pats_all(post.iter(), vec_exit);
|
||||
self.add_node(pat.id, [post_exit])
|
||||
}
|
||||
|
||||
|
|
@ -154,16 +149,16 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn pats_all<I: Iterator<Gc<ast::Pat>>>(&mut self,
|
||||
pats: I,
|
||||
pred: CFGIndex) -> CFGIndex {
|
||||
fn pats_all<'a, I: Iterator<&'a P<ast::Pat>>>(&mut self,
|
||||
pats: I,
|
||||
pred: CFGIndex) -> CFGIndex {
|
||||
//! Handles case where all of the patterns must match.
|
||||
let mut pats = pats;
|
||||
pats.fold(pred, |pred, pat| self.pat(&*pat, pred))
|
||||
pats.fold(pred, |pred, pat| self.pat(&**pat, pred))
|
||||
}
|
||||
|
||||
fn pats_any(&mut self,
|
||||
pats: &[Gc<ast::Pat>],
|
||||
pats: &[P<ast::Pat>],
|
||||
pred: CFGIndex) -> CFGIndex {
|
||||
//! Handles case where just one of the patterns must match.
|
||||
|
||||
|
|
@ -171,15 +166,15 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
self.pat(&*pats[0], pred)
|
||||
} else {
|
||||
let collect = self.add_dummy_node([]);
|
||||
for &pat in pats.iter() {
|
||||
let pat_exit = self.pat(&*pat, pred);
|
||||
for pat in pats.iter() {
|
||||
let pat_exit = self.pat(&**pat, pred);
|
||||
self.add_contained_edge(pat_exit, collect);
|
||||
}
|
||||
collect
|
||||
}
|
||||
}
|
||||
|
||||
fn expr(&mut self, expr: Gc<ast::Expr>, pred: CFGIndex) -> CFGIndex {
|
||||
fn expr(&mut self, expr: &ast::Expr, pred: CFGIndex) -> CFGIndex {
|
||||
match expr.node {
|
||||
ast::ExprBlock(ref blk) => {
|
||||
let blk_exit = self.block(&**blk, pred);
|
||||
|
|
@ -201,7 +196,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
// v 3 v 4
|
||||
// [..expr..]
|
||||
//
|
||||
let cond_exit = self.expr(cond.clone(), pred); // 1
|
||||
let cond_exit = self.expr(&**cond, pred); // 1
|
||||
let then_exit = self.block(&**then, cond_exit); // 2
|
||||
self.add_node(expr.id, [cond_exit, then_exit]) // 3,4
|
||||
}
|
||||
|
|
@ -221,9 +216,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
// v 4 v 5
|
||||
// [..expr..]
|
||||
//
|
||||
let cond_exit = self.expr(cond.clone(), pred); // 1
|
||||
let cond_exit = self.expr(&**cond, pred); // 1
|
||||
let then_exit = self.block(&**then, cond_exit); // 2
|
||||
let else_exit = self.expr(otherwise.clone(), cond_exit); // 3
|
||||
let else_exit = self.expr(&**otherwise, cond_exit); // 3
|
||||
self.add_node(expr.id, [then_exit, else_exit]) // 4, 5
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +242,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
|
||||
// Is the condition considered part of the loop?
|
||||
let loopback = self.add_dummy_node([pred]); // 1
|
||||
let cond_exit = self.expr(cond.clone(), loopback); // 2
|
||||
let cond_exit = self.expr(&**cond, loopback); // 2
|
||||
let expr_exit = self.add_node(expr.id, [cond_exit]); // 3
|
||||
self.loop_scopes.push(LoopScope {
|
||||
loop_id: expr.id,
|
||||
|
|
@ -283,7 +278,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
// Note that `break` and `continue` statements
|
||||
// may cause additional edges.
|
||||
|
||||
let head = self.expr(head.clone(), pred); // 1
|
||||
let head = self.expr(&**head, pred); // 1
|
||||
let loopback = self.add_dummy_node([head]); // 2
|
||||
let cond = self.add_dummy_node([loopback]); // 3
|
||||
let expr_exit = self.add_node(expr.id, [cond]); // 4
|
||||
|
|
@ -353,7 +348,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
// v 6 v v
|
||||
// [.....expr.....]
|
||||
//
|
||||
let discr_exit = self.expr(discr.clone(), pred); // 1
|
||||
let discr_exit = self.expr(&**discr, pred); // 1
|
||||
|
||||
let expr_exit = self.add_node(expr.id, []);
|
||||
let mut cond_exit = discr_exit;
|
||||
|
|
@ -361,10 +356,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
cond_exit = self.add_dummy_node([cond_exit]); // 2
|
||||
let pats_exit = self.pats_any(arm.pats.as_slice(),
|
||||
cond_exit); // 3
|
||||
let guard_exit = self.opt_expr(arm.guard,
|
||||
let guard_exit = self.opt_expr(&arm.guard,
|
||||
pats_exit); // 4
|
||||
let body_exit = self.expr(arm.body.clone(),
|
||||
guard_exit); // 5
|
||||
let body_exit = self.expr(&*arm.body, guard_exit); // 5
|
||||
self.add_contained_edge(body_exit, expr_exit); // 6
|
||||
}
|
||||
expr_exit
|
||||
|
|
@ -385,13 +379,13 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
// v 3 v 4
|
||||
// [..exit..]
|
||||
//
|
||||
let l_exit = self.expr(l.clone(), pred); // 1
|
||||
let r_exit = self.expr(r.clone(), l_exit); // 2
|
||||
let l_exit = self.expr(&**l, pred); // 1
|
||||
let r_exit = self.expr(&**r, l_exit); // 2
|
||||
self.add_node(expr.id, [l_exit, r_exit]) // 3,4
|
||||
}
|
||||
|
||||
ast::ExprRet(ref v) => {
|
||||
let v_exit = self.opt_expr(v.clone(), pred);
|
||||
let v_exit = self.opt_expr(v, pred);
|
||||
let b = self.add_node(expr.id, [v_exit]);
|
||||
self.add_returning_edge(expr, b);
|
||||
self.add_node(ast::DUMMY_NODE_ID, [])
|
||||
|
|
@ -414,62 +408,60 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ast::ExprVec(ref elems) => {
|
||||
self.straightline(expr, pred, elems.as_slice())
|
||||
self.straightline(expr, pred, elems.iter().map(|e| &**e))
|
||||
}
|
||||
|
||||
ast::ExprCall(ref func, ref args) => {
|
||||
self.call(expr, pred, func.clone(), args.as_slice())
|
||||
self.call(expr, pred, &**func, args.iter().map(|e| &**e))
|
||||
}
|
||||
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
self.call(expr, pred, *args.get(0), args.slice_from(1))
|
||||
self.call(expr, pred, &**args.get(0), args.slice_from(1).iter().map(|e| &**e))
|
||||
}
|
||||
|
||||
ast::ExprIndex(ref l, ref r) |
|
||||
ast::ExprBinary(_, ref l, ref r) if self.is_method_call(&*expr) => {
|
||||
self.call(expr, pred, l.clone(), [r.clone()])
|
||||
ast::ExprBinary(_, ref l, ref r) if self.is_method_call(expr) => {
|
||||
self.call(expr, pred, &**l, Some(&**r).move_iter())
|
||||
}
|
||||
|
||||
ast::ExprUnary(_, ref e) if self.is_method_call(&*expr) => {
|
||||
self.call(expr, pred, e.clone(), [])
|
||||
ast::ExprUnary(_, ref e) if self.is_method_call(expr) => {
|
||||
self.call(expr, pred, &**e, None::<ast::Expr>.iter())
|
||||
}
|
||||
|
||||
ast::ExprTup(ref exprs) => {
|
||||
self.straightline(expr, pred, exprs.as_slice())
|
||||
self.straightline(expr, pred, exprs.iter().map(|e| &**e))
|
||||
}
|
||||
|
||||
ast::ExprStruct(_, ref fields, base) => {
|
||||
ast::ExprStruct(_, ref fields, ref base) => {
|
||||
let base_exit = self.opt_expr(base, pred);
|
||||
let field_exprs: Vec<Gc<ast::Expr>> =
|
||||
fields.iter().map(|f| f.expr).collect();
|
||||
self.straightline(expr, base_exit, field_exprs.as_slice())
|
||||
self.straightline(expr, base_exit, fields.iter().map(|f| &*f.expr))
|
||||
}
|
||||
|
||||
ast::ExprRepeat(elem, count) => {
|
||||
self.straightline(expr, pred, [elem, count])
|
||||
ast::ExprRepeat(ref elem, ref count) => {
|
||||
self.straightline(expr, pred, [elem, count].iter().map(|&e| &**e))
|
||||
}
|
||||
|
||||
ast::ExprAssign(l, r) |
|
||||
ast::ExprAssignOp(_, l, r) => {
|
||||
self.straightline(expr, pred, [r, l])
|
||||
ast::ExprAssign(ref l, ref r) |
|
||||
ast::ExprAssignOp(_, ref l, ref r) => {
|
||||
self.straightline(expr, pred, [r, l].iter().map(|&e| &**e))
|
||||
}
|
||||
|
||||
ast::ExprIndex(l, r) |
|
||||
ast::ExprBinary(_, l, r) => { // NB: && and || handled earlier
|
||||
self.straightline(expr, pred, [l, r])
|
||||
ast::ExprIndex(ref l, ref r) |
|
||||
ast::ExprBinary(_, ref l, ref r) => { // NB: && and || handled earlier
|
||||
self.straightline(expr, pred, [l, r].iter().map(|&e| &**e))
|
||||
}
|
||||
|
||||
ast::ExprBox(p, e) => {
|
||||
self.straightline(expr, pred, [p, e])
|
||||
ast::ExprBox(ref p, ref e) => {
|
||||
self.straightline(expr, pred, [p, e].iter().map(|&e| &**e))
|
||||
}
|
||||
|
||||
ast::ExprAddrOf(_, e) |
|
||||
ast::ExprCast(e, _) |
|
||||
ast::ExprUnary(_, e) |
|
||||
ast::ExprParen(e) |
|
||||
ast::ExprField(e, _, _) |
|
||||
ast::ExprTupField(e, _, _) => {
|
||||
self.straightline(expr, pred, [e])
|
||||
ast::ExprAddrOf(_, ref e) |
|
||||
ast::ExprCast(ref e, _) |
|
||||
ast::ExprUnary(_, ref e) |
|
||||
ast::ExprParen(ref e) |
|
||||
ast::ExprField(ref e, _, _) |
|
||||
ast::ExprTupField(ref e, _, _) => {
|
||||
self.straightline(expr, pred, Some(&**e).move_iter())
|
||||
}
|
||||
|
||||
ast::ExprInlineAsm(ref inline_asm) => {
|
||||
|
|
@ -477,13 +469,13 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
let outputs = inline_asm.outputs.iter();
|
||||
let post_inputs = self.exprs(inputs.map(|a| {
|
||||
debug!("cfg::construct InlineAsm id:{} input:{:?}", expr.id, a);
|
||||
let &(_, expr) = a;
|
||||
expr
|
||||
let &(_, ref expr) = a;
|
||||
&**expr
|
||||
}), pred);
|
||||
let post_outputs = self.exprs(outputs.map(|a| {
|
||||
debug!("cfg::construct InlineAsm id:{} output:{:?}", expr.id, a);
|
||||
let &(_, expr, _) = a;
|
||||
expr
|
||||
let &(_, ref expr, _) = a;
|
||||
&**expr
|
||||
}), post_inputs);
|
||||
self.add_node(expr.id, [post_outputs])
|
||||
}
|
||||
|
|
@ -494,16 +486,16 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
ast::ExprUnboxedFn(..) |
|
||||
ast::ExprLit(..) |
|
||||
ast::ExprPath(..) => {
|
||||
self.straightline(expr, pred, [])
|
||||
self.straightline(expr, pred, None::<ast::Expr>.iter())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn call(&mut self,
|
||||
call_expr: Gc<ast::Expr>,
|
||||
fn call<'a, I: Iterator<&'a ast::Expr>>(&mut self,
|
||||
call_expr: &ast::Expr,
|
||||
pred: CFGIndex,
|
||||
func_or_rcvr: Gc<ast::Expr>,
|
||||
args: &[Gc<ast::Expr>]) -> CFGIndex {
|
||||
func_or_rcvr: &ast::Expr,
|
||||
args: I) -> CFGIndex {
|
||||
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
|
||||
let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
|
||||
|
||||
|
|
@ -516,28 +508,27 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn exprs<I:Iterator<Gc<ast::Expr>>>(&mut self,
|
||||
mut exprs: I,
|
||||
pred: CFGIndex) -> CFGIndex {
|
||||
fn exprs<'a, I: Iterator<&'a ast::Expr>>(&mut self,
|
||||
mut exprs: I,
|
||||
pred: CFGIndex) -> CFGIndex {
|
||||
//! Constructs graph for `exprs` evaluated in order
|
||||
exprs.fold(pred, |p, e| self.expr(e, p))
|
||||
}
|
||||
|
||||
fn opt_expr(&mut self,
|
||||
opt_expr: Option<Gc<ast::Expr>>,
|
||||
opt_expr: &Option<P<ast::Expr>>,
|
||||
pred: CFGIndex) -> CFGIndex {
|
||||
//! Constructs graph for `opt_expr` evaluated, if Some
|
||||
|
||||
opt_expr.iter().fold(pred, |p, &e| self.expr(e, p))
|
||||
opt_expr.iter().fold(pred, |p, e| self.expr(&**e, p))
|
||||
}
|
||||
|
||||
fn straightline(&mut self,
|
||||
expr: Gc<ast::Expr>,
|
||||
fn straightline<'a, I: Iterator<&'a ast::Expr>>(&mut self,
|
||||
expr: &ast::Expr,
|
||||
pred: CFGIndex,
|
||||
subexprs: &[Gc<ast::Expr>]) -> CFGIndex {
|
||||
subexprs: I) -> CFGIndex {
|
||||
//! Handles case of an expression that evaluates `subexprs` in order
|
||||
|
||||
let subexprs_exit = self.exprs(subexprs.iter().map(|&e|e), pred);
|
||||
let subexprs_exit = self.exprs(subexprs, pred);
|
||||
self.add_node(expr.id, [subexprs_exit])
|
||||
}
|
||||
|
||||
|
|
@ -566,7 +557,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn add_exiting_edge(&mut self,
|
||||
from_expr: Gc<ast::Expr>,
|
||||
from_expr: &ast::Expr,
|
||||
from_index: CFGIndex,
|
||||
to_loop: LoopScope,
|
||||
to_index: CFGIndex) {
|
||||
|
|
@ -581,7 +572,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn add_returning_edge(&mut self,
|
||||
_from_expr: Gc<ast::Expr>,
|
||||
_from_expr: &ast::Expr,
|
||||
from_index: CFGIndex) {
|
||||
let mut data = CFGEdgeData {
|
||||
exiting_scopes: vec!(),
|
||||
|
|
@ -593,7 +584,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn find_scope(&self,
|
||||
expr: Gc<ast::Expr>,
|
||||
expr: &ast::Expr,
|
||||
label: Option<ast::Ident>) -> LoopScope {
|
||||
match label {
|
||||
None => {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ use middle::cfg;
|
|||
pub type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode);
|
||||
pub type Edge<'a> = &'a cfg::CFGEdge;
|
||||
|
||||
pub struct LabelledCFG<'a>{
|
||||
pub ast_map: &'a ast_map::Map,
|
||||
pub struct LabelledCFG<'a, 'ast: 'a> {
|
||||
pub ast_map: &'a ast_map::Map<'ast>,
|
||||
pub cfg: &'a cfg::CFG,
|
||||
pub name: String,
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ fn replace_newline_with_backslash_l(s: String) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a> {
|
||||
impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
|
||||
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(self.name.as_slice()) }
|
||||
|
||||
fn node_id(&'a self, &(i,_): &Node<'a>) -> dot::Id<'a> {
|
||||
|
|
@ -110,7 +110,7 @@ impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a>
|
||||
impl<'a, 'ast> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast>
|
||||
{
|
||||
fn nodes(&self) -> dot::Nodes<'a, Node<'a>> { self.cfg.nodes() }
|
||||
fn edges(&self) -> dot::Edges<'a, Edge<'a>> { self.cfg.edges() }
|
||||
|
|
|
|||
|
|
@ -53,15 +53,16 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(krate: &Crate, tcx: &ty::ctxt) {
|
||||
visit::walk_crate(&mut CheckCrateVisitor { tcx: tcx, in_const: false }, krate);
|
||||
pub fn check_crate(tcx: &ty::ctxt) {
|
||||
visit::walk_crate(&mut CheckCrateVisitor { tcx: tcx, in_const: false },
|
||||
tcx.map.krate());
|
||||
tcx.sess.abort_if_errors();
|
||||
}
|
||||
|
||||
fn check_item(v: &mut CheckCrateVisitor, it: &Item) {
|
||||
match it.node {
|
||||
ItemStatic(_, _, ex) => {
|
||||
v.inside_const(|v| v.visit_expr(&*ex));
|
||||
ItemStatic(_, _, ref ex) => {
|
||||
v.inside_const(|v| v.visit_expr(&**ex));
|
||||
check_item_recursion(&v.tcx.sess, &v.tcx.map, &v.tcx.def_map, it);
|
||||
}
|
||||
ItemEnum(ref enum_definition, _) => {
|
||||
|
|
@ -78,9 +79,9 @@ fn check_item(v: &mut CheckCrateVisitor, it: &Item) {
|
|||
fn check_pat(v: &mut CheckCrateVisitor, p: &Pat) {
|
||||
fn is_str(e: &Expr) -> bool {
|
||||
match e.node {
|
||||
ExprBox(_, expr) => {
|
||||
ExprBox(_, ref expr) => {
|
||||
match expr.node {
|
||||
ExprLit(lit) => ast_util::lit_is_str(lit),
|
||||
ExprLit(ref lit) => ast_util::lit_is_str(&**lit),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -106,7 +107,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
span_err!(v.tcx.sess, e.span, E0010, "cannot do allocations in constant expressions");
|
||||
return;
|
||||
}
|
||||
ExprLit(lit) if ast_util::lit_is_str(lit) => {}
|
||||
ExprLit(ref lit) if ast_util::lit_is_str(&**lit) => {}
|
||||
ExprBinary(..) | ExprUnary(..) => {
|
||||
let method_call = typeck::MethodCall::expr(e.id);
|
||||
if v.tcx.method_map.borrow().contains_key(&method_call) {
|
||||
|
|
@ -149,7 +150,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
}
|
||||
}
|
||||
}
|
||||
ExprCall(callee, _) => {
|
||||
ExprCall(ref callee, _) => {
|
||||
match v.tcx.def_map.borrow().find(&callee.id) {
|
||||
Some(&DefStruct(..)) => {} // OK.
|
||||
Some(&DefVariant(..)) => {} // OK.
|
||||
|
|
@ -194,7 +195,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
ExprTup(..) |
|
||||
ExprRepeat(..) |
|
||||
ExprStruct(..) => { }
|
||||
ExprAddrOf(_, inner) => {
|
||||
ExprAddrOf(_, ref inner) => {
|
||||
match inner.node {
|
||||
// Mutable slices are allowed.
|
||||
ExprVec(_) => {}
|
||||
|
|
@ -214,12 +215,13 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
|
|||
visit::walk_expr(v, e);
|
||||
}
|
||||
|
||||
struct CheckItemRecursionVisitor<'a> {
|
||||
struct CheckItemRecursionVisitor<'a, 'ast: 'a> {
|
||||
root_it: &'a Item,
|
||||
sess: &'a Session,
|
||||
ast_map: &'a ast_map::Map,
|
||||
ast_map: &'a ast_map::Map<'ast>,
|
||||
def_map: &'a resolve::DefMap,
|
||||
idstack: Vec<NodeId> }
|
||||
idstack: Vec<NodeId>
|
||||
}
|
||||
|
||||
// Make sure a const item doesn't recursively refer to itself
|
||||
// FIXME: Should use the dependency graph when it's available (#1356)
|
||||
|
|
@ -238,7 +240,7 @@ pub fn check_item_recursion<'a>(sess: &'a Session,
|
|||
visitor.visit_item(it);
|
||||
}
|
||||
|
||||
impl<'a, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a> {
|
||||
impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> {
|
||||
fn visit_item(&mut self, it: &Item) {
|
||||
if self.idstack.iter().any(|x| x == &(it.id)) {
|
||||
self.sess.span_fatal(self.root_it.span, "recursive constant");
|
||||
|
|
|
|||
|
|
@ -19,19 +19,26 @@ use middle::pat_util::*;
|
|||
use middle::ty::*;
|
||||
use middle::ty;
|
||||
use std::fmt;
|
||||
use std::gc::{Gc, GC};
|
||||
use std::iter::AdditiveIterator;
|
||||
use std::iter::range_inclusive;
|
||||
use std::slice;
|
||||
use syntax::ast::*;
|
||||
use syntax::ast_util::walk_pat;
|
||||
use syntax::codemap::{Span, Spanned, DUMMY_SP};
|
||||
use syntax::fold::{Folder, noop_fold_pat};
|
||||
use syntax::print::pprust::pat_to_string;
|
||||
use syntax::parse::token;
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit::{mod, Visitor, FnKind};
|
||||
use util::ppaux::ty_to_string;
|
||||
|
||||
struct Matrix(Vec<Vec<Gc<Pat>>>);
|
||||
static DUMMY_WILD_PAT: Pat = Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
node: PatWild(PatWildSingle),
|
||||
span: DUMMY_SP
|
||||
};
|
||||
|
||||
struct Matrix<'a>(Vec<Vec<&'a Pat>>);
|
||||
|
||||
/// Pretty-printer for matrices of patterns, example:
|
||||
/// ++++++++++++++++++++++++++
|
||||
|
|
@ -45,7 +52,7 @@ struct Matrix(Vec<Vec<Gc<Pat>>>);
|
|||
/// ++++++++++++++++++++++++++
|
||||
/// + _ + [_, _, ..tail] +
|
||||
/// ++++++++++++++++++++++++++
|
||||
impl fmt::Show for Matrix {
|
||||
impl<'a> fmt::Show for Matrix<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "\n"));
|
||||
|
||||
|
|
@ -80,8 +87,8 @@ impl fmt::Show for Matrix {
|
|||
}
|
||||
}
|
||||
|
||||
impl FromIterator<Vec<Gc<Pat>>> for Matrix {
|
||||
fn from_iter<T: Iterator<Vec<Gc<Pat>>>>(mut iterator: T) -> Matrix {
|
||||
impl<'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> {
|
||||
fn from_iter<T: Iterator<Vec<&'a Pat>>>(mut iterator: T) -> Matrix<'a> {
|
||||
Matrix(iterator.collect())
|
||||
}
|
||||
}
|
||||
|
|
@ -110,7 +117,7 @@ pub enum Constructor {
|
|||
#[deriving(Clone, PartialEq)]
|
||||
enum Usefulness {
|
||||
Useful,
|
||||
UsefulWithWitness(Vec<Gc<Pat>>),
|
||||
UsefulWithWitness(Vec<P<Pat>>),
|
||||
NotUseful
|
||||
}
|
||||
|
||||
|
|
@ -132,16 +139,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: &ty::ctxt, krate: &Crate) {
|
||||
let mut cx = MatchCheckCtxt { tcx: tcx };
|
||||
visit::walk_crate(&mut cx, krate);
|
||||
pub fn check_crate(tcx: &ty::ctxt) {
|
||||
visit::walk_crate(&mut MatchCheckCtxt { tcx: tcx }, tcx.map.krate());
|
||||
tcx.sess.abort_if_errors();
|
||||
}
|
||||
|
||||
fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) {
|
||||
visit::walk_expr(cx, ex);
|
||||
match ex.node {
|
||||
ExprMatch(scrut, ref arms) => {
|
||||
ExprMatch(ref scrut, ref arms) => {
|
||||
// First, check legality of move bindings.
|
||||
for arm in arms.iter() {
|
||||
check_legality_of_move_bindings(cx,
|
||||
|
|
@ -156,28 +162,26 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) {
|
|||
// assigning or borrowing anything mutably.
|
||||
for arm in arms.iter() {
|
||||
match arm.guard {
|
||||
Some(guard) => check_for_mutation_in_guard(cx, &*guard),
|
||||
Some(ref guard) => check_for_mutation_in_guard(cx, &**guard),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
let mut static_inliner = StaticInliner::new(cx.tcx);
|
||||
let inlined_arms = arms
|
||||
.iter()
|
||||
.map(|arm| Arm {
|
||||
pats: arm.pats.iter().map(|pat| {
|
||||
static_inliner.fold_pat(*pat)
|
||||
}).collect(),
|
||||
..arm.clone()
|
||||
})
|
||||
.collect::<Vec<Arm>>();
|
||||
let inlined_arms = arms.iter().map(|arm| {
|
||||
(arm.pats.iter().map(|pat| {
|
||||
static_inliner.fold_pat((*pat).clone())
|
||||
}).collect(), arm.guard.as_ref().map(|e| &**e))
|
||||
}).collect::<Vec<(Vec<P<Pat>>, Option<&Expr>)>>();
|
||||
|
||||
if static_inliner.failed {
|
||||
return;
|
||||
}
|
||||
|
||||
// Third, check if there are any references to NaN that we should warn about.
|
||||
check_for_static_nan(cx, inlined_arms.as_slice());
|
||||
for &(ref pats, _) in inlined_arms.iter() {
|
||||
check_for_static_nan(cx, pats.as_slice());
|
||||
}
|
||||
|
||||
// Fourth, check for unreachable arms.
|
||||
check_arms(cx, inlined_arms.as_slice());
|
||||
|
|
@ -198,28 +202,25 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) {
|
|||
}
|
||||
|
||||
let matrix: Matrix = inlined_arms
|
||||
.move_iter()
|
||||
.filter(|arm| arm.guard.is_none())
|
||||
.flat_map(|arm| arm.pats.move_iter())
|
||||
.map(|pat| vec![pat])
|
||||
.iter()
|
||||
.filter(|&&(_, guard)| guard.is_none())
|
||||
.flat_map(|arm| arm.ref0().iter())
|
||||
.map(|pat| vec![&**pat])
|
||||
.collect();
|
||||
check_exhaustive(cx, ex.span, &matrix);
|
||||
},
|
||||
ExprForLoop(ref pat, _, _, _) => {
|
||||
let mut static_inliner = StaticInliner::new(cx.tcx);
|
||||
match is_refutable(cx, static_inliner.fold_pat(*pat)) {
|
||||
Some(uncovered_pat) => {
|
||||
cx.tcx.sess.span_err(
|
||||
pat.span,
|
||||
format!("refutable pattern in `for` loop binding: \
|
||||
`{}` not covered",
|
||||
pat_to_string(&*uncovered_pat)).as_slice());
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
is_refutable(cx, &*static_inliner.fold_pat((*pat).clone()), |uncovered_pat| {
|
||||
cx.tcx.sess.span_err(
|
||||
pat.span,
|
||||
format!("refutable pattern in `for` loop binding: \
|
||||
`{}` not covered",
|
||||
pat_to_string(uncovered_pat)).as_slice());
|
||||
});
|
||||
|
||||
// Check legality of move bindings.
|
||||
check_legality_of_move_bindings(cx, false, [ *pat ]);
|
||||
check_legality_of_move_bindings(cx, false, slice::ref_slice(pat));
|
||||
check_legality_of_bindings_in_at_patterns(cx, &**pat);
|
||||
}
|
||||
_ => ()
|
||||
|
|
@ -234,36 +235,34 @@ fn is_expr_const_nan(tcx: &ty::ctxt, expr: &Expr) -> bool {
|
|||
}
|
||||
|
||||
// Check that we do not match against a static NaN (#6804)
|
||||
fn check_for_static_nan(cx: &MatchCheckCtxt, arms: &[Arm]) {
|
||||
for arm in arms.iter() {
|
||||
for &pat in arm.pats.iter() {
|
||||
walk_pat(&*pat, |p| {
|
||||
match p.node {
|
||||
PatLit(expr) if is_expr_const_nan(cx.tcx, &*expr) => {
|
||||
span_warn!(cx.tcx.sess, p.span, E0003,
|
||||
"unmatchable NaN in pattern, \
|
||||
use the is_nan method in a guard instead");
|
||||
}
|
||||
_ => ()
|
||||
fn check_for_static_nan(cx: &MatchCheckCtxt, pats: &[P<Pat>]) {
|
||||
for pat in pats.iter() {
|
||||
walk_pat(&**pat, |p| {
|
||||
match p.node {
|
||||
PatLit(ref expr) if is_expr_const_nan(cx.tcx, &**expr) => {
|
||||
span_warn!(cx.tcx.sess, p.span, E0003,
|
||||
"unmatchable NaN in pattern, \
|
||||
use the is_nan method in a guard instead");
|
||||
}
|
||||
true
|
||||
});
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Check for unreachable patterns
|
||||
fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) {
|
||||
let mut seen = Matrix(vec!());
|
||||
for arm in arms.iter() {
|
||||
for &pat in arm.pats.iter() {
|
||||
let v = vec![pat];
|
||||
fn check_arms(cx: &MatchCheckCtxt, arms: &[(Vec<P<Pat>>, Option<&Expr>)]) {
|
||||
let mut seen = Matrix(vec![]);
|
||||
for &(ref pats, guard) in arms.iter() {
|
||||
for pat in pats.iter() {
|
||||
let v = vec![&**pat];
|
||||
match is_useful(cx, &seen, v.as_slice(), LeaveOutWitness) {
|
||||
NotUseful => span_err!(cx.tcx.sess, pat.span, E0001, "unreachable pattern"),
|
||||
Useful => (),
|
||||
UsefulWithWitness(_) => unreachable!()
|
||||
}
|
||||
if arm.guard.is_none() {
|
||||
if guard.is_none() {
|
||||
let Matrix(mut rows) = seen;
|
||||
rows.push(v);
|
||||
seen = Matrix(rows);
|
||||
|
|
@ -272,17 +271,24 @@ fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) {
|
|||
}
|
||||
}
|
||||
|
||||
fn raw_pat<'a>(p: &'a Pat) -> &'a Pat {
|
||||
match p.node {
|
||||
PatIdent(_, _, Some(ref s)) => raw_pat(&**s),
|
||||
_ => p
|
||||
}
|
||||
}
|
||||
|
||||
fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix) {
|
||||
match is_useful(cx, matrix, [wild()], ConstructWitness) {
|
||||
match is_useful(cx, matrix, &[&DUMMY_WILD_PAT], ConstructWitness) {
|
||||
UsefulWithWitness(pats) => {
|
||||
let witness = match pats.as_slice() {
|
||||
[witness] => witness,
|
||||
[] => wild(),
|
||||
[ref witness] => &**witness,
|
||||
[] => &DUMMY_WILD_PAT,
|
||||
_ => unreachable!()
|
||||
};
|
||||
span_err!(cx.tcx.sess, sp, E0004,
|
||||
"non-exhaustive patterns: `{}` not covered",
|
||||
pat_to_string(&*witness)
|
||||
pat_to_string(witness)
|
||||
);
|
||||
}
|
||||
NotUseful => {
|
||||
|
|
@ -292,17 +298,17 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, matrix: &Matrix) {
|
|||
}
|
||||
}
|
||||
|
||||
fn const_val_to_expr(value: &const_val) -> Gc<Expr> {
|
||||
fn const_val_to_expr(value: &const_val) -> P<Expr> {
|
||||
let node = match value {
|
||||
&const_bool(b) => LitBool(b),
|
||||
&const_nil => LitNil,
|
||||
_ => unreachable!()
|
||||
};
|
||||
box (GC) Expr {
|
||||
P(Expr {
|
||||
id: 0,
|
||||
node: ExprLit(box(GC) Spanned { node: node, span: DUMMY_SP }),
|
||||
node: ExprLit(P(Spanned { node: node, span: DUMMY_SP })),
|
||||
span: DUMMY_SP
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub struct StaticInliner<'a, 'tcx: 'a> {
|
||||
|
|
@ -320,16 +326,18 @@ impl<'a, 'tcx> StaticInliner<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
|
||||
fn fold_pat(&mut self, pat: Gc<Pat>) -> Gc<Pat> {
|
||||
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
|
||||
match pat.node {
|
||||
PatIdent(..) | PatEnum(..) => {
|
||||
let def = self.tcx.def_map.borrow().find_copy(&pat.id);
|
||||
match def {
|
||||
Some(DefStatic(did, _)) => match lookup_const_by_id(self.tcx, did) {
|
||||
Some(const_expr) => box (GC) Pat {
|
||||
span: pat.span,
|
||||
..(*const_expr_to_pat(self.tcx, const_expr)).clone()
|
||||
},
|
||||
Some(const_expr) => {
|
||||
const_expr_to_pat(self.tcx, const_expr).map(|mut new_pat| {
|
||||
new_pat.span = pat.span;
|
||||
new_pat
|
||||
})
|
||||
}
|
||||
None => {
|
||||
self.failed = true;
|
||||
span_err!(self.tcx.sess, pat.span, E0158,
|
||||
|
|
@ -359,9 +367,11 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
|
|||
/// left_ty: struct X { a: (bool, &'static str), b: uint}
|
||||
/// pats: [(false, "foo"), 42] => X { a: (false, "foo"), b: 42 }
|
||||
fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
|
||||
pats: Vec<Gc<Pat>>, left_ty: ty::t) -> Gc<Pat> {
|
||||
pats: Vec<&Pat>, left_ty: ty::t) -> P<Pat> {
|
||||
let pats_len = pats.len();
|
||||
let mut pats = pats.move_iter().map(|p| P((*p).clone()));
|
||||
let pat = match ty::get(left_ty).sty {
|
||||
ty::ty_tup(_) => PatTup(pats),
|
||||
ty::ty_tup(_) => PatTup(pats.collect()),
|
||||
|
||||
ty::ty_enum(cid, _) | ty::ty_struct(cid, _) => {
|
||||
let (vid, is_structure) = match ctor {
|
||||
|
|
@ -374,16 +384,16 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
|
|||
if is_structure {
|
||||
let fields = ty::lookup_struct_fields(cx.tcx, vid);
|
||||
let field_pats: Vec<FieldPat> = fields.move_iter()
|
||||
.zip(pats.iter())
|
||||
.filter(|&(_, pat)| pat.node != PatWild(PatWildSingle))
|
||||
.zip(pats)
|
||||
.filter(|&(_, ref pat)| pat.node != PatWild(PatWildSingle))
|
||||
.map(|(field, pat)| FieldPat {
|
||||
ident: Ident::new(field.name),
|
||||
pat: pat.clone()
|
||||
pat: pat
|
||||
}).collect();
|
||||
let has_more_fields = field_pats.len() < pats.len();
|
||||
let has_more_fields = field_pats.len() < pats_len;
|
||||
PatStruct(def_to_path(cx.tcx, vid), field_pats, has_more_fields)
|
||||
} else {
|
||||
PatEnum(def_to_path(cx.tcx, vid), Some(pats))
|
||||
PatEnum(def_to_path(cx.tcx, vid), Some(pats.collect()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -391,35 +401,35 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
|
|||
match ty::get(ty).sty {
|
||||
ty::ty_vec(_, Some(n)) => match ctor {
|
||||
&Single => {
|
||||
assert_eq!(pats.len(), n);
|
||||
PatVec(pats, None, vec!())
|
||||
assert_eq!(pats_len, n);
|
||||
PatVec(pats.collect(), None, vec!())
|
||||
},
|
||||
_ => unreachable!()
|
||||
},
|
||||
ty::ty_vec(_, None) => match ctor {
|
||||
&Slice(n) => {
|
||||
assert_eq!(pats.len(), n);
|
||||
PatVec(pats, None, vec!())
|
||||
assert_eq!(pats_len, n);
|
||||
PatVec(pats.collect(), None, vec!())
|
||||
},
|
||||
_ => unreachable!()
|
||||
},
|
||||
ty::ty_str => PatWild(PatWildSingle),
|
||||
|
||||
_ => {
|
||||
assert_eq!(pats.len(), 1);
|
||||
PatRegion(pats.get(0).clone())
|
||||
assert_eq!(pats_len, 1);
|
||||
PatRegion(pats.nth(0).unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_box(_) => {
|
||||
assert_eq!(pats.len(), 1);
|
||||
PatBox(pats.get(0).clone())
|
||||
assert_eq!(pats_len, 1);
|
||||
PatBox(pats.nth(0).unwrap())
|
||||
}
|
||||
|
||||
ty::ty_vec(_, Some(len)) => {
|
||||
assert_eq!(pats.len(), len);
|
||||
PatVec(pats, None, vec!())
|
||||
assert_eq!(pats_len, len);
|
||||
PatVec(pats.collect(), None, vec![])
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
|
@ -430,11 +440,11 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
|
|||
}
|
||||
};
|
||||
|
||||
box (GC) Pat {
|
||||
P(Pat {
|
||||
id: 0,
|
||||
node: pat,
|
||||
span: DUMMY_SP
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn missing_constructor(cx: &MatchCheckCtxt, &Matrix(ref rows): &Matrix,
|
||||
|
|
@ -492,7 +502,7 @@ fn all_constructors(cx: &MatchCheckCtxt, left_ty: ty::t,
|
|||
// So it assumes that v is non-empty.
|
||||
fn is_useful(cx: &MatchCheckCtxt,
|
||||
matrix: &Matrix,
|
||||
v: &[Gc<Pat>],
|
||||
v: &[&Pat],
|
||||
witness: WitnessPreference)
|
||||
-> Usefulness {
|
||||
let &Matrix(ref rows) = matrix;
|
||||
|
|
@ -506,12 +516,12 @@ fn is_useful(cx: &MatchCheckCtxt,
|
|||
if rows.get(0).len() == 0u {
|
||||
return NotUseful;
|
||||
}
|
||||
let real_pat = match rows.iter().find(|r| r.get(0).id != 0) {
|
||||
let real_pat = match rows.iter().find(|r| r.get(0).id != DUMMY_NODE_ID) {
|
||||
Some(r) => raw_pat(*r.get(0)),
|
||||
None if v.len() == 0 => return NotUseful,
|
||||
None => v[0]
|
||||
};
|
||||
let left_ty = if real_pat.id == 0 {
|
||||
let left_ty = if real_pat.id == DUMMY_NODE_ID {
|
||||
ty::mk_nil()
|
||||
} else {
|
||||
ty::pat_ty(cx.tcx, &*real_pat)
|
||||
|
|
@ -530,14 +540,13 @@ fn is_useful(cx: &MatchCheckCtxt,
|
|||
match is_useful_specialized(cx, matrix, v, c.clone(), left_ty, witness) {
|
||||
UsefulWithWitness(pats) => UsefulWithWitness({
|
||||
let arity = constructor_arity(cx, &c, left_ty);
|
||||
let subpats = {
|
||||
let mut result = {
|
||||
let pat_slice = pats.as_slice();
|
||||
Vec::from_fn(arity, |i| {
|
||||
pat_slice.get(i).map(|p| p.clone())
|
||||
.unwrap_or_else(|| wild())
|
||||
})
|
||||
let subpats = Vec::from_fn(arity, |i| {
|
||||
pat_slice.get(i).map_or(&DUMMY_WILD_PAT, |p| &**p)
|
||||
});
|
||||
vec![construct_witness(cx, &c, subpats, left_ty)]
|
||||
};
|
||||
let mut result = vec!(construct_witness(cx, &c, subpats, left_ty));
|
||||
result.extend(pats.move_iter().skip(arity));
|
||||
result
|
||||
}),
|
||||
|
|
@ -547,13 +556,21 @@ fn is_useful(cx: &MatchCheckCtxt,
|
|||
},
|
||||
|
||||
Some(constructor) => {
|
||||
let matrix = rows.iter().filter_map(|r| default(cx, r.as_slice())).collect();
|
||||
let matrix = rows.iter().filter_map(|r| {
|
||||
if pat_is_binding_or_wild(&cx.tcx.def_map, raw_pat(r[0])) {
|
||||
Some(Vec::from_slice(r.tail()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect();
|
||||
match is_useful(cx, &matrix, v.tail(), witness) {
|
||||
UsefulWithWitness(pats) => {
|
||||
let arity = constructor_arity(cx, &constructor, left_ty);
|
||||
let wild_pats = Vec::from_elem(arity, wild());
|
||||
let wild_pats = Vec::from_elem(arity, &DUMMY_WILD_PAT);
|
||||
let enum_pat = construct_witness(cx, &constructor, wild_pats, left_ty);
|
||||
UsefulWithWitness(vec!(enum_pat).append(pats.as_slice()))
|
||||
let mut new_pats = vec![enum_pat];
|
||||
new_pats.extend(pats.move_iter());
|
||||
UsefulWithWitness(new_pats)
|
||||
},
|
||||
result => result
|
||||
}
|
||||
|
|
@ -566,8 +583,9 @@ fn is_useful(cx: &MatchCheckCtxt,
|
|||
}
|
||||
}
|
||||
|
||||
fn is_useful_specialized(cx: &MatchCheckCtxt, &Matrix(ref m): &Matrix, v: &[Gc<Pat>],
|
||||
ctor: Constructor, lty: ty::t, witness: WitnessPreference) -> Usefulness {
|
||||
fn is_useful_specialized(cx: &MatchCheckCtxt, &Matrix(ref m): &Matrix,
|
||||
v: &[&Pat], ctor: Constructor, lty: ty::t,
|
||||
witness: WitnessPreference) -> Usefulness {
|
||||
let arity = constructor_arity(cx, &ctor, lty);
|
||||
let matrix = Matrix(m.iter().filter_map(|r| {
|
||||
specialize(cx, r.as_slice(), &ctor, 0u, arity)
|
||||
|
|
@ -587,7 +605,7 @@ fn is_useful_specialized(cx: &MatchCheckCtxt, &Matrix(ref m): &Matrix, v: &[Gc<P
|
|||
///
|
||||
/// On the other hand, a wild pattern and an identifier pattern cannot be
|
||||
/// specialized in any way.
|
||||
fn pat_constructors(cx: &MatchCheckCtxt, p: Gc<Pat>,
|
||||
fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
|
||||
left_ty: ty::t, max_slice_length: uint) -> Vec<Constructor> {
|
||||
let pat = raw_pat(p);
|
||||
match pat.node {
|
||||
|
|
@ -613,10 +631,10 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: Gc<Pat>,
|
|||
Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
|
||||
_ => vec!(Single)
|
||||
},
|
||||
PatLit(expr) =>
|
||||
vec!(ConstantValue(eval_const_expr(cx.tcx, &*expr))),
|
||||
PatRange(lo, hi) =>
|
||||
vec!(ConstantRange(eval_const_expr(cx.tcx, &*lo), eval_const_expr(cx.tcx, &*hi))),
|
||||
PatLit(ref expr) =>
|
||||
vec!(ConstantValue(eval_const_expr(cx.tcx, &**expr))),
|
||||
PatRange(ref lo, ref hi) =>
|
||||
vec!(ConstantRange(eval_const_expr(cx.tcx, &**lo), eval_const_expr(cx.tcx, &**hi))),
|
||||
PatVec(ref before, ref slice, ref after) =>
|
||||
match ty::get(left_ty).sty {
|
||||
ty::ty_vec(_, Some(_)) => vec!(Single),
|
||||
|
|
@ -691,14 +709,15 @@ fn range_covered_by_constructor(ctor: &Constructor,
|
|||
/// different patterns.
|
||||
/// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
|
||||
/// fields filled with wild patterns.
|
||||
pub fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
|
||||
constructor: &Constructor, col: uint, arity: uint) -> Option<Vec<Gc<Pat>>> {
|
||||
pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
|
||||
constructor: &Constructor, col: uint, arity: uint) -> Option<Vec<&'a Pat>> {
|
||||
let &Pat {
|
||||
id: pat_id, node: ref node, span: pat_span
|
||||
} = &(*raw_pat(r[col]));
|
||||
let head: Option<Vec<Gc<Pat>>> = match node {
|
||||
} = raw_pat(r[col]);
|
||||
let head: Option<Vec<&Pat>> = match node {
|
||||
|
||||
&PatWild(_) =>
|
||||
Some(Vec::from_elem(arity, wild())),
|
||||
Some(Vec::from_elem(arity, &DUMMY_WILD_PAT)),
|
||||
|
||||
&PatIdent(_, _, _) => {
|
||||
let opt_def = cx.tcx.def_map.borrow().find_copy(&pat_id);
|
||||
|
|
@ -710,7 +729,7 @@ pub fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
|
|||
} else {
|
||||
None
|
||||
},
|
||||
_ => Some(Vec::from_elem(arity, wild()))
|
||||
_ => Some(Vec::from_elem(arity, &DUMMY_WILD_PAT))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -722,8 +741,8 @@ pub fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
|
|||
DefVariant(_, id, _) if *constructor != Variant(id) => None,
|
||||
DefVariant(..) | DefFn(..) | DefStruct(..) => {
|
||||
Some(match args {
|
||||
&Some(ref args) => args.clone(),
|
||||
&None => Vec::from_elem(arity, wild())
|
||||
&Some(ref args) => args.iter().map(|p| &**p).collect(),
|
||||
&None => Vec::from_elem(arity, &DUMMY_WILD_PAT)
|
||||
})
|
||||
}
|
||||
_ => None
|
||||
|
|
@ -757,8 +776,8 @@ pub fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
|
|||
let struct_fields = ty::lookup_struct_fields(cx.tcx, variant_id);
|
||||
let args = struct_fields.iter().map(|sf| {
|
||||
match pattern_fields.iter().find(|f| f.ident.name == sf.name) {
|
||||
Some(f) => f.pat,
|
||||
_ => wild()
|
||||
Some(ref f) => &*f.pat,
|
||||
_ => &DUMMY_WILD_PAT
|
||||
}
|
||||
}).collect();
|
||||
args
|
||||
|
|
@ -766,15 +785,15 @@ pub fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
|
|||
}
|
||||
|
||||
&PatTup(ref args) =>
|
||||
Some(args.clone()),
|
||||
Some(args.iter().map(|p| &**p).collect()),
|
||||
|
||||
&PatBox(ref inner) | &PatRegion(ref inner) =>
|
||||
Some(vec!(inner.clone())),
|
||||
Some(vec![&**inner]),
|
||||
|
||||
&PatLit(ref expr) => {
|
||||
let expr_value = eval_const_expr(cx.tcx, &**expr);
|
||||
match range_covered_by_constructor(constructor, &expr_value, &expr_value) {
|
||||
Some(true) => Some(vec!()),
|
||||
Some(true) => Some(vec![]),
|
||||
Some(false) => None,
|
||||
None => {
|
||||
cx.tcx.sess.span_err(pat_span, "mismatched types between arms");
|
||||
|
|
@ -787,7 +806,7 @@ pub fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
|
|||
let from_value = eval_const_expr(cx.tcx, &**from);
|
||||
let to_value = eval_const_expr(cx.tcx, &**to);
|
||||
match range_covered_by_constructor(constructor, &from_value, &to_value) {
|
||||
Some(true) => Some(vec!()),
|
||||
Some(true) => Some(vec![]),
|
||||
Some(false) => None,
|
||||
None => {
|
||||
cx.tcx.sess.span_err(pat_span, "mismatched types between arms");
|
||||
|
|
@ -800,28 +819,28 @@ pub fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
|
|||
match *constructor {
|
||||
// Fixed-length vectors.
|
||||
Single => {
|
||||
let mut pats = before.clone();
|
||||
pats.grow_fn(arity - before.len() - after.len(), |_| wild());
|
||||
pats.push_all(after.as_slice());
|
||||
let mut pats: Vec<&Pat> = before.iter().map(|p| &**p).collect();
|
||||
pats.grow_fn(arity - before.len() - after.len(), |_| &DUMMY_WILD_PAT);
|
||||
pats.extend(after.iter().map(|p| &**p));
|
||||
Some(pats)
|
||||
},
|
||||
Slice(length) if before.len() + after.len() <= length && slice.is_some() => {
|
||||
let mut pats = before.clone();
|
||||
pats.grow_fn(arity - before.len() - after.len(), |_| wild());
|
||||
pats.push_all(after.as_slice());
|
||||
let mut pats: Vec<&Pat> = before.iter().map(|p| &**p).collect();
|
||||
pats.grow_fn(arity - before.len() - after.len(), |_| &DUMMY_WILD_PAT);
|
||||
pats.extend(after.iter().map(|p| &**p));
|
||||
Some(pats)
|
||||
},
|
||||
Slice(length) if before.len() + after.len() == length => {
|
||||
let mut pats = before.clone();
|
||||
pats.push_all(after.as_slice());
|
||||
let mut pats: Vec<&Pat> = before.iter().map(|p| &**p).collect();
|
||||
pats.extend(after.iter().map(|p| &**p));
|
||||
Some(pats)
|
||||
},
|
||||
SliceWithSubslice(prefix, suffix)
|
||||
if before.len() == prefix
|
||||
&& after.len() == suffix
|
||||
&& slice.is_some() => {
|
||||
let mut pats = before.clone();
|
||||
pats.push_all(after.as_slice());
|
||||
let mut pats: Vec<&Pat> = before.iter().map(|p| &**p).collect();
|
||||
pats.extend(after.iter().map(|p| &**p));
|
||||
Some(pats)
|
||||
}
|
||||
_ => None
|
||||
|
|
@ -836,14 +855,6 @@ pub fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
|
|||
head.map(|head| head.append(r.slice_to(col)).append(r.slice_from(col + 1)))
|
||||
}
|
||||
|
||||
fn default(cx: &MatchCheckCtxt, r: &[Gc<Pat>]) -> Option<Vec<Gc<Pat>>> {
|
||||
if pat_is_binding_or_wild(&cx.tcx.def_map, &*raw_pat(r[0])) {
|
||||
Some(Vec::from_slice(r.tail()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {
|
||||
visit::walk_local(cx, loc);
|
||||
|
||||
|
|
@ -853,18 +864,15 @@ fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {
|
|||
};
|
||||
|
||||
let mut static_inliner = StaticInliner::new(cx.tcx);
|
||||
match is_refutable(cx, static_inliner.fold_pat(loc.pat)) {
|
||||
Some(pat) => {
|
||||
span_err!(cx.tcx.sess, loc.pat.span, E0005,
|
||||
"refutable pattern in {} binding: `{}` not covered",
|
||||
name, pat_to_string(&*pat)
|
||||
);
|
||||
},
|
||||
None => ()
|
||||
}
|
||||
is_refutable(cx, &*static_inliner.fold_pat(loc.pat.clone()), |pat| {
|
||||
span_err!(cx.tcx.sess, loc.pat.span, E0005,
|
||||
"refutable pattern in {} binding: `{}` not covered",
|
||||
name, pat_to_string(pat)
|
||||
);
|
||||
});
|
||||
|
||||
// Check legality of move bindings and `@` patterns.
|
||||
check_legality_of_move_bindings(cx, false, [ loc.pat ]);
|
||||
check_legality_of_move_bindings(cx, false, slice::ref_slice(&loc.pat));
|
||||
check_legality_of_bindings_in_at_patterns(cx, &*loc.pat);
|
||||
}
|
||||
|
||||
|
|
@ -875,26 +883,23 @@ fn check_fn(cx: &mut MatchCheckCtxt,
|
|||
sp: Span) {
|
||||
visit::walk_fn(cx, kind, decl, body, sp);
|
||||
for input in decl.inputs.iter() {
|
||||
match is_refutable(cx, input.pat) {
|
||||
Some(pat) => {
|
||||
span_err!(cx.tcx.sess, input.pat.span, E0006,
|
||||
"refutable pattern in function argument: `{}` not covered",
|
||||
pat_to_string(&*pat)
|
||||
);
|
||||
},
|
||||
None => ()
|
||||
}
|
||||
check_legality_of_move_bindings(cx, false, [input.pat]);
|
||||
is_refutable(cx, &*input.pat, |pat| {
|
||||
span_err!(cx.tcx.sess, input.pat.span, E0006,
|
||||
"refutable pattern in function argument: `{}` not covered",
|
||||
pat_to_string(pat)
|
||||
);
|
||||
});
|
||||
check_legality_of_move_bindings(cx, false, slice::ref_slice(&input.pat));
|
||||
check_legality_of_bindings_in_at_patterns(cx, &*input.pat);
|
||||
}
|
||||
}
|
||||
|
||||
fn is_refutable(cx: &MatchCheckCtxt, pat: Gc<Pat>) -> Option<Gc<Pat>> {
|
||||
fn is_refutable<A>(cx: &MatchCheckCtxt, pat: &Pat, refutable: |&Pat| -> A) -> Option<A> {
|
||||
let pats = Matrix(vec!(vec!(pat)));
|
||||
match is_useful(cx, &pats, [wild()], ConstructWitness) {
|
||||
match is_useful(cx, &pats, [&DUMMY_WILD_PAT], ConstructWitness) {
|
||||
UsefulWithWitness(pats) => {
|
||||
assert_eq!(pats.len(), 1);
|
||||
Some(pats.get(0).clone())
|
||||
Some(refutable(&*pats[0]))
|
||||
},
|
||||
NotUseful => None,
|
||||
Useful => unreachable!()
|
||||
|
|
@ -904,7 +909,7 @@ fn is_refutable(cx: &MatchCheckCtxt, pat: Gc<Pat>) -> Option<Gc<Pat>> {
|
|||
// Legality of move bindings checking
|
||||
fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
|
||||
has_guard: bool,
|
||||
pats: &[Gc<Pat>]) {
|
||||
pats: &[P<Pat>]) {
|
||||
let tcx = cx.tcx;
|
||||
let def_map = &tcx.def_map;
|
||||
let mut by_ref_span = None;
|
||||
|
|
@ -920,7 +925,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
|
|||
})
|
||||
}
|
||||
|
||||
let check_move: |&Pat, Option<Gc<Pat>>| = |p, sub| {
|
||||
let check_move: |&Pat, Option<&Pat>| = |p, sub| {
|
||||
// check legality of moving out of the enum
|
||||
|
||||
// x @ Foo(..) is legal, but x @ Foo(y) isn't.
|
||||
|
|
@ -939,10 +944,10 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
|
|||
walk_pat(&**pat, |p| {
|
||||
if pat_is_binding(def_map, &*p) {
|
||||
match p.node {
|
||||
PatIdent(BindByValue(_), _, sub) => {
|
||||
PatIdent(BindByValue(_), _, ref sub) => {
|
||||
let pat_ty = ty::node_id_to_type(tcx, p.id);
|
||||
if ty::type_moves_by_default(tcx, pat_ty) {
|
||||
check_move(p, sub);
|
||||
check_move(p, sub.as_ref().map(|p| &**p));
|
||||
}
|
||||
}
|
||||
PatIdent(BindByRef(_), _, _) => {
|
||||
|
|
|
|||
|
|
@ -56,8 +56,9 @@ struct CheckStaticVisitor<'a, 'tcx: 'a> {
|
|||
in_const: bool
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: &ty::ctxt, krate: &ast::Crate) {
|
||||
visit::walk_crate(&mut CheckStaticVisitor { tcx: tcx, in_const: false }, krate)
|
||||
pub fn check_crate(tcx: &ty::ctxt) {
|
||||
visit::walk_crate(&mut CheckStaticVisitor { tcx: tcx, in_const: false },
|
||||
tcx.map.krate())
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@ use util::nodemap::{DefIdMap};
|
|||
|
||||
use syntax::ast::*;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::visit;
|
||||
use syntax::{ast, ast_map, ast_util};
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::gc::{Gc, GC};
|
||||
|
||||
//
|
||||
// This pass classifies expressions by their constant-ness.
|
||||
|
|
@ -83,7 +83,7 @@ pub fn join_all<It: Iterator<constness>>(mut cs: It) -> constness {
|
|||
cs.fold(integral_const, |a, b| join(a, b))
|
||||
}
|
||||
|
||||
pub fn lookup_const(tcx: &ty::ctxt, e: &Expr) -> Option<Gc<Expr>> {
|
||||
fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
|
||||
let opt_def = tcx.def_map.borrow().find_copy(&e.id);
|
||||
match opt_def {
|
||||
Some(def::DefStatic(def_id, false)) => {
|
||||
|
|
@ -96,83 +96,90 @@ pub fn lookup_const(tcx: &ty::ctxt, e: &Expr) -> Option<Gc<Expr>> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn lookup_variant_by_id(tcx: &ty::ctxt,
|
||||
fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
|
||||
enum_def: ast::DefId,
|
||||
variant_def: ast::DefId)
|
||||
-> Option<Gc<Expr>> {
|
||||
fn variant_expr(variants: &[ast::P<ast::Variant>],
|
||||
id: ast::NodeId) -> Option<Gc<Expr>> {
|
||||
-> Option<&'a Expr> {
|
||||
fn variant_expr<'a>(variants: &'a [P<ast::Variant>], id: ast::NodeId)
|
||||
-> Option<&'a Expr> {
|
||||
for variant in variants.iter() {
|
||||
if variant.node.id == id {
|
||||
return variant.node.disr_expr;
|
||||
return variant.node.disr_expr.as_ref().map(|e| &**e);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
if ast_util::is_local(enum_def) {
|
||||
{
|
||||
match tcx.map.find(enum_def.node) {
|
||||
None => None,
|
||||
Some(ast_map::NodeItem(it)) => match it.node {
|
||||
ItemEnum(ast::EnumDef { variants: ref variants }, _) => {
|
||||
variant_expr(variants.as_slice(), variant_def.node)
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
Some(_) => None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match tcx.extern_const_variants.borrow().find(&variant_def) {
|
||||
Some(&e) => return e,
|
||||
None => {}
|
||||
}
|
||||
let e = match csearch::maybe_get_item_ast(tcx, enum_def,
|
||||
|a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
|
||||
csearch::found(ast::IIItem(item)) => match item.node {
|
||||
match tcx.map.find(enum_def.node) {
|
||||
None => None,
|
||||
Some(ast_map::NodeItem(it)) => match it.node {
|
||||
ItemEnum(ast::EnumDef { variants: ref variants }, _) => {
|
||||
variant_expr(variants.as_slice(), variant_def.node)
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
_ => None
|
||||
};
|
||||
tcx.extern_const_variants.borrow_mut().insert(variant_def, e);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup_const_by_id(tcx: &ty::ctxt, def_id: ast::DefId)
|
||||
-> Option<Gc<Expr>> {
|
||||
if ast_util::is_local(def_id) {
|
||||
{
|
||||
match tcx.map.find(def_id.node) {
|
||||
None => None,
|
||||
Some(ast_map::NodeItem(it)) => match it.node {
|
||||
ItemStatic(_, ast::MutImmutable, const_expr) => {
|
||||
Some(const_expr)
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
Some(_) => None
|
||||
}
|
||||
Some(_) => None
|
||||
}
|
||||
} else {
|
||||
match tcx.extern_const_statics.borrow().find(&def_id) {
|
||||
Some(&e) => return e,
|
||||
match tcx.extern_const_variants.borrow().find(&variant_def) {
|
||||
Some(&ast::DUMMY_NODE_ID) => return None,
|
||||
Some(&expr_id) => {
|
||||
return Some(tcx.map.expect_expr(expr_id));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
let e = match csearch::maybe_get_item_ast(tcx, def_id,
|
||||
let expr_id = match csearch::maybe_get_item_ast(tcx, enum_def,
|
||||
|a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
|
||||
csearch::found(ast::IIItem(item)) => match item.node {
|
||||
ItemStatic(_, ast::MutImmutable, const_expr) => Some(const_expr),
|
||||
csearch::found(&ast::IIItem(ref item)) => match item.node {
|
||||
ItemEnum(ast::EnumDef { variants: ref variants }, _) => {
|
||||
// NOTE this doesn't do the right thing, it compares inlined
|
||||
// NodeId's to the original variant_def's NodeId, but they
|
||||
// come from different crates, so they will likely never match.
|
||||
variant_expr(variants.as_slice(), variant_def.node).map(|e| e.id)
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
_ => None
|
||||
};
|
||||
tcx.extern_const_statics.borrow_mut().insert(def_id, e);
|
||||
return e;
|
||||
tcx.extern_const_variants.borrow_mut().insert(variant_def,
|
||||
expr_id.unwrap_or(ast::DUMMY_NODE_ID));
|
||||
expr_id.map(|id| tcx.map.expect_expr(id))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup_const_by_id<'a>(tcx: &'a ty::ctxt, def_id: ast::DefId)
|
||||
-> Option<&'a Expr> {
|
||||
if ast_util::is_local(def_id) {
|
||||
match tcx.map.find(def_id.node) {
|
||||
None => None,
|
||||
Some(ast_map::NodeItem(it)) => match it.node {
|
||||
ItemStatic(_, ast::MutImmutable, ref const_expr) => {
|
||||
Some(&**const_expr)
|
||||
}
|
||||
_ => None
|
||||
},
|
||||
Some(_) => None
|
||||
}
|
||||
} else {
|
||||
match tcx.extern_const_statics.borrow().find(&def_id) {
|
||||
Some(&ast::DUMMY_NODE_ID) => return None,
|
||||
Some(&expr_id) => {
|
||||
return Some(tcx.map.expect_expr(expr_id));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
let expr_id = match csearch::maybe_get_item_ast(tcx, def_id,
|
||||
|a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
|
||||
csearch::found(&ast::IIItem(ref item)) => match item.node {
|
||||
ItemStatic(_, ast::MutImmutable, ref const_expr) => Some(const_expr.id),
|
||||
_ => None
|
||||
},
|
||||
_ => None
|
||||
};
|
||||
tcx.extern_const_statics.borrow_mut().insert(def_id,
|
||||
expr_id.unwrap_or(ast::DUMMY_NODE_ID));
|
||||
expr_id.map(|id| tcx.map.expect_expr(id))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -271,8 +278,8 @@ impl<'a, 'tcx> ConstEvalVisitor<'a, 'tcx> {
|
|||
impl<'a, 'tcx, 'v> Visitor<'v> for ConstEvalVisitor<'a, 'tcx> {
|
||||
fn visit_ty(&mut self, t: &Ty) {
|
||||
match t.node {
|
||||
TyFixedLengthVec(_, expr) => {
|
||||
check::check_const_in_type(self.tcx, &*expr, ty::mk_uint());
|
||||
TyFixedLengthVec(_, ref expr) => {
|
||||
check::check_const_in_type(self.tcx, &**expr, ty::mk_uint());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -285,13 +292,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstEvalVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn process_crate(krate: &ast::Crate,
|
||||
tcx: &ty::ctxt) {
|
||||
let mut v = ConstEvalVisitor {
|
||||
pub fn process_crate(tcx: &ty::ctxt) {
|
||||
visit::walk_crate(&mut ConstEvalVisitor {
|
||||
tcx: tcx,
|
||||
ccache: DefIdMap::new(),
|
||||
};
|
||||
visit::walk_crate(&mut v, krate);
|
||||
}, tcx.map.krate());
|
||||
tcx.sess.abort_if_errors();
|
||||
}
|
||||
|
||||
|
|
@ -309,12 +314,12 @@ pub enum const_val {
|
|||
const_nil
|
||||
}
|
||||
|
||||
pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: Gc<Expr>) -> Gc<Pat> {
|
||||
pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P<Pat> {
|
||||
let pat = match expr.node {
|
||||
ExprTup(ref exprs) =>
|
||||
PatTup(exprs.iter().map(|&expr| const_expr_to_pat(tcx, expr)).collect()),
|
||||
PatTup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr)).collect()),
|
||||
|
||||
ExprCall(callee, ref args) => {
|
||||
ExprCall(ref callee, ref args) => {
|
||||
let def = tcx.def_map.borrow().get_copy(&callee.id);
|
||||
tcx.def_map.borrow_mut().find_or_insert(expr.id, def);
|
||||
let path = match def {
|
||||
|
|
@ -322,20 +327,20 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: Gc<Expr>) -> Gc<Pat> {
|
|||
def::DefVariant(_, variant_did, _) => def_to_path(tcx, variant_did),
|
||||
_ => unreachable!()
|
||||
};
|
||||
let pats = args.iter().map(|&expr| const_expr_to_pat(tcx, expr)).collect();
|
||||
let pats = args.iter().map(|expr| const_expr_to_pat(tcx, &**expr)).collect();
|
||||
PatEnum(path, Some(pats))
|
||||
}
|
||||
|
||||
ExprStruct(ref path, ref fields, None) => {
|
||||
let field_pats = fields.iter().map(|field| FieldPat {
|
||||
ident: field.ident.node,
|
||||
pat: const_expr_to_pat(tcx, field.expr)
|
||||
pat: const_expr_to_pat(tcx, &*field.expr)
|
||||
}).collect();
|
||||
PatStruct(path.clone(), field_pats, false)
|
||||
}
|
||||
|
||||
ExprVec(ref exprs) => {
|
||||
let pats = exprs.iter().map(|&expr| const_expr_to_pat(tcx, expr)).collect();
|
||||
let pats = exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr)).collect();
|
||||
PatVec(pats, None, vec![])
|
||||
}
|
||||
|
||||
|
|
@ -347,7 +352,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: Gc<Expr>) -> Gc<Pat> {
|
|||
Some(def::DefVariant(..)) =>
|
||||
PatEnum(path.clone(), None),
|
||||
_ => {
|
||||
match lookup_const(tcx, &*expr) {
|
||||
match lookup_const(tcx, expr) {
|
||||
Some(actual) => return const_expr_to_pat(tcx, actual),
|
||||
_ => unreachable!()
|
||||
}
|
||||
|
|
@ -355,9 +360,9 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: Gc<Expr>) -> Gc<Pat> {
|
|||
}
|
||||
}
|
||||
|
||||
_ => PatLit(expr)
|
||||
_ => PatLit(P(expr.clone()))
|
||||
};
|
||||
box (GC) Pat { id: expr.id, node: pat, span: expr.span }
|
||||
P(Pat { id: expr.id, node: pat, span: expr.span })
|
||||
}
|
||||
|
||||
pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val {
|
||||
|
|
|
|||
|
|
@ -219,12 +219,12 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
ast_map::NodeTraitItem(trait_method) => {
|
||||
visit::walk_trait_item(self, &*trait_method);
|
||||
visit::walk_trait_item(self, trait_method);
|
||||
}
|
||||
ast_map::NodeImplItem(impl_item) => {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(method) => {
|
||||
visit::walk_block(self, &*method.pe_body());
|
||||
ast::MethodImplItem(ref method) => {
|
||||
visit::walk_block(self, method.pe_body());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -338,7 +338,7 @@ impl<'v> Visitor<'v> for LifeSeeder {
|
|||
ast::ItemImpl(_, Some(ref _trait_ref), _, ref impl_items) => {
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(method) => {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
self.worklist.push(method.id);
|
||||
}
|
||||
}
|
||||
|
|
@ -422,7 +422,7 @@ fn should_warn(item: &ast::Item) -> bool {
|
|||
|
||||
fn get_struct_ctor_id(item: &ast::Item) -> Option<ast::NodeId> {
|
||||
match item.node {
|
||||
ast::ItemStruct(struct_def, _) => struct_def.ctor_id,
|
||||
ast::ItemStruct(ref struct_def, _) => struct_def.ctor_id,
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
|
@ -551,8 +551,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
|||
|
||||
pub fn check_crate(tcx: &ty::ctxt,
|
||||
exported_items: &privacy::ExportedItems,
|
||||
reachable_symbols: &NodeSet,
|
||||
krate: &ast::Crate) {
|
||||
reachable_symbols: &NodeSet) {
|
||||
let krate = tcx.map.krate();
|
||||
let live_symbols = find_live(tcx, exported_items,
|
||||
reachable_symbols, krate);
|
||||
let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols };
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
|
|||
|
||||
fn check_str_index(&mut self, e: &ast::Expr) {
|
||||
let base_type = match e.node {
|
||||
ast::ExprIndex(base, _) => ty::node_id_to_type(self.tcx, base.id),
|
||||
ast::ExprIndex(ref base, _) => ty::node_id_to_type(self.tcx, base.id),
|
||||
_ => return
|
||||
};
|
||||
debug!("effect: checking index with base type {}",
|
||||
|
|
@ -153,7 +153,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
|||
"invocation of unsafe method")
|
||||
}
|
||||
}
|
||||
ast::ExprCall(base, _) => {
|
||||
ast::ExprCall(ref base, _) => {
|
||||
let base_type = ty::node_id_to_type(self.tcx, base.id);
|
||||
debug!("effect: call case, base type is {}",
|
||||
ppaux::ty_to_string(self.tcx, base_type));
|
||||
|
|
@ -161,7 +161,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
|||
self.require_unsafe(expr.span, "call to unsafe function")
|
||||
}
|
||||
}
|
||||
ast::ExprUnary(ast::UnDeref, base) => {
|
||||
ast::ExprUnary(ast::UnDeref, ref base) => {
|
||||
let base_type = ty::node_id_to_type(self.tcx, base.id);
|
||||
debug!("effect: unary case, base type is {}",
|
||||
ppaux::ty_to_string(self.tcx, base_type));
|
||||
|
|
@ -197,11 +197,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: &ty::ctxt, krate: &ast::Crate) {
|
||||
pub fn check_crate(tcx: &ty::ctxt) {
|
||||
let mut visitor = EffectCheckVisitor {
|
||||
tcx: tcx,
|
||||
unsafe_context: SafeContext,
|
||||
};
|
||||
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
visit::walk_crate(&mut visitor, tcx.map.krate());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
use driver::config;
|
||||
use driver::session::Session;
|
||||
use syntax::ast::{Crate, Name, NodeId, Item, ItemFn};
|
||||
use syntax::ast::{Name, NodeId, Item, ItemFn};
|
||||
use syntax::ast_map;
|
||||
use syntax::attr;
|
||||
use syntax::codemap::Span;
|
||||
|
|
@ -19,10 +19,10 @@ use syntax::parse::token;
|
|||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
struct EntryContext<'a> {
|
||||
struct EntryContext<'a, 'ast: 'a> {
|
||||
session: &'a Session,
|
||||
|
||||
ast_map: &'a ast_map::Map,
|
||||
ast_map: &'a ast_map::Map<'ast>,
|
||||
|
||||
// The interned Name for "main".
|
||||
main_name: Name,
|
||||
|
|
@ -41,13 +41,13 @@ struct EntryContext<'a> {
|
|||
non_main_fns: Vec<(NodeId, Span)> ,
|
||||
}
|
||||
|
||||
impl<'a, 'v> Visitor<'v> for EntryContext<'a> {
|
||||
impl<'a, 'ast, 'v> Visitor<'v> for EntryContext<'a, 'ast> {
|
||||
fn visit_item(&mut self, item: &Item) {
|
||||
find_item(item, self);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_entry_point(session: &Session, krate: &Crate, ast_map: &ast_map::Map) {
|
||||
pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
|
||||
let any_exe = session.crate_types.borrow().iter().any(|ty| {
|
||||
*ty == config::CrateTypeExecutable
|
||||
});
|
||||
|
|
@ -57,7 +57,7 @@ pub fn find_entry_point(session: &Session, krate: &Crate, ast_map: &ast_map::Map
|
|||
}
|
||||
|
||||
// If the user wants no main function at all, then stop here.
|
||||
if attr::contains_name(krate.attrs.as_slice(), "no_main") {
|
||||
if attr::contains_name(ast_map.krate().attrs.as_slice(), "no_main") {
|
||||
session.entry_type.set(Some(config::EntryNone));
|
||||
return
|
||||
}
|
||||
|
|
@ -72,7 +72,7 @@ pub fn find_entry_point(session: &Session, krate: &Crate, ast_map: &ast_map::Map
|
|||
non_main_fns: Vec::new(),
|
||||
};
|
||||
|
||||
visit::walk_crate(&mut ctxt, krate);
|
||||
visit::walk_crate(&mut ctxt, ast_map.krate());
|
||||
|
||||
configure_main(&mut ctxt);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ use middle::typeck::{MethodStatic, MethodStaticUnboxedClosure};
|
|||
use middle::typeck;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use std::gc::Gc;
|
||||
use syntax::ast;
|
||||
use syntax::ptr::P;
|
||||
use syntax::codemap::Span;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -242,7 +242,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
ty::ReScope(body.id), // Args live only as long as the fn body.
|
||||
arg_ty);
|
||||
|
||||
self.walk_pat(arg_cmt, arg.pat.clone());
|
||||
self.walk_pat(arg_cmt, &*arg.pat);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
self.delegate.consume(consume_id, consume_span, cmt, mode);
|
||||
}
|
||||
|
||||
fn consume_exprs(&mut self, exprs: &Vec<Gc<ast::Expr>>) {
|
||||
fn consume_exprs(&mut self, exprs: &Vec<P<ast::Expr>>) {
|
||||
for expr in exprs.iter() {
|
||||
self.consume_expr(&**expr);
|
||||
}
|
||||
|
|
@ -315,7 +315,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
ast::ExprPath(..) => { }
|
||||
|
||||
ast::ExprUnary(ast::UnDeref, ref base) => { // *base
|
||||
if !self.walk_overloaded_operator(expr, &**base, []) {
|
||||
if !self.walk_overloaded_operator(expr, &**base, None) {
|
||||
self.select_from_expr(&**base);
|
||||
}
|
||||
}
|
||||
|
|
@ -328,8 +328,8 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
self.select_from_expr(&**base);
|
||||
}
|
||||
|
||||
ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
|
||||
if !self.walk_overloaded_operator(expr, &**lhs, [rhs.clone()]) {
|
||||
ast::ExprIndex(ref lhs, ref rhs) => { // lhs[rhs]
|
||||
if !self.walk_overloaded_operator(expr, &**lhs, Some(&**rhs)) {
|
||||
self.select_from_expr(&**lhs);
|
||||
self.consume_expr(&**rhs);
|
||||
}
|
||||
|
|
@ -345,7 +345,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
}
|
||||
|
||||
ast::ExprStruct(_, ref fields, ref opt_with) => {
|
||||
self.walk_struct_expr(expr, fields, opt_with.clone());
|
||||
self.walk_struct_expr(expr, fields, opt_with);
|
||||
}
|
||||
|
||||
ast::ExprTup(ref exprs) => {
|
||||
|
|
@ -423,19 +423,19 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
pat.span,
|
||||
ty::ReScope(blk.id),
|
||||
pattern_type);
|
||||
self.walk_pat(pat_cmt, pat.clone());
|
||||
self.walk_pat(pat_cmt, &**pat);
|
||||
|
||||
self.walk_block(&**blk);
|
||||
}
|
||||
|
||||
ast::ExprUnary(_, ref lhs) => {
|
||||
if !self.walk_overloaded_operator(expr, &**lhs, []) {
|
||||
if !self.walk_overloaded_operator(expr, &**lhs, None) {
|
||||
self.consume_expr(&**lhs);
|
||||
}
|
||||
}
|
||||
|
||||
ast::ExprBinary(_, ref lhs, ref rhs) => {
|
||||
if !self.walk_overloaded_operator(expr, &**lhs, [rhs.clone()]) {
|
||||
if !self.walk_overloaded_operator(expr, &**lhs, Some(&**rhs)) {
|
||||
self.consume_expr(&**lhs);
|
||||
self.consume_expr(&**rhs);
|
||||
}
|
||||
|
|
@ -554,7 +554,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
ast::StmtDecl(ref decl, _) => {
|
||||
match decl.node {
|
||||
ast::DeclLocal(ref local) => {
|
||||
self.walk_local(local.clone());
|
||||
self.walk_local(&**local);
|
||||
}
|
||||
|
||||
ast::DeclItem(_) => {
|
||||
|
|
@ -575,7 +575,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
}
|
||||
}
|
||||
|
||||
fn walk_local(&mut self, local: Gc<ast::Local>) {
|
||||
fn walk_local(&mut self, local: &ast::Local) {
|
||||
match local.init {
|
||||
None => {
|
||||
let delegate = &mut self.delegate;
|
||||
|
|
@ -592,7 +592,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
// `walk_pat`:
|
||||
self.walk_expr(&**expr);
|
||||
let init_cmt = return_if_err!(self.mc.cat_expr(&**expr));
|
||||
self.walk_pat(init_cmt, local.pat);
|
||||
self.walk_pat(init_cmt, &*local.pat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -617,14 +617,14 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
fn walk_struct_expr(&mut self,
|
||||
_expr: &ast::Expr,
|
||||
fields: &Vec<ast::Field>,
|
||||
opt_with: Option<Gc<ast::Expr>>) {
|
||||
opt_with: &Option<P<ast::Expr>>) {
|
||||
// Consume the expressions supplying values for each field.
|
||||
for field in fields.iter() {
|
||||
self.consume_expr(&*field.expr);
|
||||
}
|
||||
|
||||
let with_expr = match opt_with {
|
||||
Some(ref w) => { w.clone() }
|
||||
let with_expr = match *opt_with {
|
||||
Some(ref w) => &**w,
|
||||
None => { return; }
|
||||
};
|
||||
|
||||
|
|
@ -773,7 +773,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
fn walk_overloaded_operator(&mut self,
|
||||
expr: &ast::Expr,
|
||||
receiver: &ast::Expr,
|
||||
args: &[Gc<ast::Expr>])
|
||||
rhs: Option<&ast::Expr>)
|
||||
-> bool
|
||||
{
|
||||
if !self.typer.is_method_call(expr.id) {
|
||||
|
|
@ -789,15 +789,15 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
let r = ty::ReScope(expr.id);
|
||||
let bk = ty::ImmBorrow;
|
||||
|
||||
for arg in args.iter() {
|
||||
self.borrow_expr(&**arg, r, bk, OverloadedOperator);
|
||||
for &arg in rhs.iter() {
|
||||
self.borrow_expr(arg, r, bk, OverloadedOperator);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn walk_arm(&mut self, discr_cmt: mc::cmt, arm: &ast::Arm) {
|
||||
for &pat in arm.pats.iter() {
|
||||
self.walk_pat(discr_cmt.clone(), pat);
|
||||
for pat in arm.pats.iter() {
|
||||
self.walk_pat(discr_cmt.clone(), &**pat);
|
||||
}
|
||||
|
||||
for guard in arm.guard.iter() {
|
||||
|
|
@ -807,7 +807,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
self.consume_expr(&*arm.body);
|
||||
}
|
||||
|
||||
fn walk_pat(&mut self, cmt_discr: mc::cmt, pat: Gc<ast::Pat>) {
|
||||
fn walk_pat(&mut self, cmt_discr: mc::cmt, pat: &ast::Pat) {
|
||||
debug!("walk_pat cmt_discr={} pat={}", cmt_discr.repr(self.tcx()),
|
||||
pat.repr(self.tcx()));
|
||||
let mc = &self.mc;
|
||||
|
|
@ -859,14 +859,14 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> {
|
|||
}
|
||||
} else {
|
||||
match pat.node {
|
||||
ast::PatVec(_, Some(slice_pat), _) => {
|
||||
ast::PatVec(_, Some(ref slice_pat), _) => {
|
||||
// The `slice_pat` here creates a slice into
|
||||
// the original vector. This is effectively a
|
||||
// borrow of the elements of the vector being
|
||||
// matched.
|
||||
|
||||
let (slice_cmt, slice_mutbl, slice_r) = {
|
||||
match mc.cat_slice_pattern(cmt_pat, &*slice_pat) {
|
||||
match mc.cat_slice_pattern(cmt_pat, &**slice_pat) {
|
||||
Ok(v) => v,
|
||||
Err(()) => {
|
||||
tcx.sess.span_bug(slice_pat.span,
|
||||
|
|
|
|||
|
|
@ -148,11 +148,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: &ctxt, krate: &ast::Crate) {
|
||||
let mut visitor = IntrinsicCheckingVisitor {
|
||||
tcx: tcx,
|
||||
};
|
||||
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
pub fn check_crate(tcx: &ctxt) {
|
||||
visit::walk_crate(&mut IntrinsicCheckingVisitor { tcx: tcx },
|
||||
tcx.map.krate());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,14 +83,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: &ty::ctxt,
|
||||
krate: &Crate) {
|
||||
pub fn check_crate(tcx: &ty::ctxt) {
|
||||
let mut ctx = Context {
|
||||
tcx: tcx,
|
||||
struct_and_enum_bounds_checked: HashSet::new(),
|
||||
parameter_environments: Vec::new(),
|
||||
};
|
||||
visit::walk_crate(&mut ctx, krate);
|
||||
visit::walk_crate(&mut ctx, tcx.map.krate());
|
||||
tcx.sess.abort_if_errors();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ use lint;
|
|||
use util::nodemap::NodeMap;
|
||||
|
||||
use std::fmt;
|
||||
use std::gc::Gc;
|
||||
use std::io;
|
||||
use std::mem::transmute;
|
||||
use std::rc::Rc;
|
||||
|
|
@ -122,16 +121,16 @@ use syntax::codemap::{BytePos, original_sp, Span};
|
|||
use syntax::parse::token::special_idents;
|
||||
use syntax::parse::token;
|
||||
use syntax::print::pprust::{expr_to_string, block_to_string};
|
||||
use syntax::ptr::P;
|
||||
use syntax::{visit, ast_util};
|
||||
use syntax::visit::{Visitor, FnKind};
|
||||
|
||||
/// For use with `propagate_through_loop`.
|
||||
#[deriving(PartialEq, Eq)]
|
||||
enum LoopKind {
|
||||
enum LoopKind<'a> {
|
||||
/// An endless `loop` loop.
|
||||
LoopLoop,
|
||||
/// A `while` loop, with the given expression as condition.
|
||||
WhileLoop(Gc<Expr>),
|
||||
WhileLoop(&'a Expr),
|
||||
/// A `for` loop.
|
||||
ForLoop,
|
||||
}
|
||||
|
|
@ -189,9 +188,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> {
|
|||
fn visit_arm(&mut self, a: &Arm) { visit_arm(self, a); }
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: &ty::ctxt,
|
||||
krate: &Crate) {
|
||||
visit::walk_crate(&mut IrMaps::new(tcx), krate);
|
||||
pub fn check_crate(tcx: &ty::ctxt) {
|
||||
visit::walk_crate(&mut IrMaps::new(tcx), tcx.map.krate());
|
||||
tcx.sess.abort_if_errors();
|
||||
}
|
||||
|
||||
|
|
@ -617,25 +615,25 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn arm_pats_bindings(&mut self,
|
||||
pats: &[Gc<Pat>],
|
||||
pat: Option<&Pat>,
|
||||
f: |&mut Liveness<'a, 'tcx>, LiveNode, Variable, Span, NodeId|) {
|
||||
// only consider the first pattern; any later patterns must have
|
||||
// the same bindings, and we also consider the first pattern to be
|
||||
// the "authoritative" set of ids
|
||||
if !pats.is_empty() {
|
||||
self.pat_bindings(&*pats[0], f)
|
||||
match pat {
|
||||
Some(pat) => {
|
||||
self.pat_bindings(pat, f);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn define_bindings_in_pat(&mut self, pat: Gc<Pat>, succ: LiveNode)
|
||||
fn define_bindings_in_pat(&mut self, pat: &Pat, succ: LiveNode)
|
||||
-> LiveNode {
|
||||
self.define_bindings_in_arm_pats([pat], succ)
|
||||
self.define_bindings_in_arm_pats(Some(pat), succ)
|
||||
}
|
||||
|
||||
fn define_bindings_in_arm_pats(&mut self, pats: &[Gc<Pat>], succ: LiveNode)
|
||||
fn define_bindings_in_arm_pats(&mut self, pat: Option<&Pat>, succ: LiveNode)
|
||||
-> LiveNode {
|
||||
let mut succ = succ;
|
||||
self.arm_pats_bindings(pats, |this, ln, var, _sp, _id| {
|
||||
self.arm_pats_bindings(pat, |this, ln, var, _sp, _id| {
|
||||
this.init_from_succ(ln, succ);
|
||||
this.define(ln, var);
|
||||
succ = ln;
|
||||
|
|
@ -882,7 +880,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
|
||||
fn propagate_through_block(&mut self, blk: &Block, succ: LiveNode)
|
||||
-> LiveNode {
|
||||
let succ = self.propagate_through_opt_expr(blk.expr, succ);
|
||||
let succ = self.propagate_through_opt_expr(blk.expr.as_ref().map(|e| &**e), succ);
|
||||
blk.stmts.iter().rev().fold(succ, |succ, stmt| {
|
||||
self.propagate_through_stmt(&**stmt, succ)
|
||||
})
|
||||
|
|
@ -931,11 +929,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
// initialization, which is mildly more complex than checking
|
||||
// once at the func header but otherwise equivalent.
|
||||
|
||||
let succ = self.propagate_through_opt_expr(local.init, succ);
|
||||
self.define_bindings_in_pat(local.pat, succ)
|
||||
let succ = self.propagate_through_opt_expr(local.init.as_ref().map(|e| &**e), succ);
|
||||
self.define_bindings_in_pat(&*local.pat, succ)
|
||||
}
|
||||
|
||||
fn propagate_through_exprs(&mut self, exprs: &[Gc<Expr>], succ: LiveNode)
|
||||
fn propagate_through_exprs(&mut self, exprs: &[P<Expr>], succ: LiveNode)
|
||||
-> LiveNode {
|
||||
exprs.iter().rev().fold(succ, |succ, expr| {
|
||||
self.propagate_through_expr(&**expr, succ)
|
||||
|
|
@ -943,7 +941,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn propagate_through_opt_expr(&mut self,
|
||||
opt_expr: Option<Gc<Expr>>,
|
||||
opt_expr: Option<&Expr>,
|
||||
succ: LiveNode)
|
||||
-> LiveNode {
|
||||
opt_expr.iter().fold(succ, |succ, expr| {
|
||||
|
|
@ -1014,7 +1012,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
// v v
|
||||
// ( succ )
|
||||
//
|
||||
let else_ln = self.propagate_through_opt_expr(els.clone(), succ);
|
||||
let else_ln = self.propagate_through_opt_expr(els.as_ref().map(|e| &**e), succ);
|
||||
let then_ln = self.propagate_through_block(&**then, succ);
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
self.init_from_succ(ln, else_ln);
|
||||
|
|
@ -1023,10 +1021,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ExprWhile(ref cond, ref blk, _) => {
|
||||
self.propagate_through_loop(expr,
|
||||
WhileLoop(cond.clone()),
|
||||
&**blk,
|
||||
succ)
|
||||
self.propagate_through_loop(expr, WhileLoop(&**cond), &**blk, succ)
|
||||
}
|
||||
|
||||
ExprForLoop(_, ref head, ref blk, _) => {
|
||||
|
|
@ -1062,9 +1057,12 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
let body_succ =
|
||||
self.propagate_through_expr(&*arm.body, succ);
|
||||
let guard_succ =
|
||||
self.propagate_through_opt_expr(arm.guard, body_succ);
|
||||
self.propagate_through_opt_expr(arm.guard.as_ref().map(|e| &**e), body_succ);
|
||||
// only consider the first pattern; any later patterns must have
|
||||
// the same bindings, and we also consider the first pattern to be
|
||||
// the "authoritative" set of ids
|
||||
let arm_succ =
|
||||
self.define_bindings_in_arm_pats(arm.pats.as_slice(),
|
||||
self.define_bindings_in_arm_pats(arm.pats.as_slice().head().map(|p| &**p),
|
||||
guard_succ);
|
||||
self.merge_from_succ(ln, arm_succ, first_merge);
|
||||
first_merge = false;
|
||||
|
|
@ -1072,10 +1070,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
self.propagate_through_expr(&**e, ln)
|
||||
}
|
||||
|
||||
ExprRet(o_e) => {
|
||||
ExprRet(ref o_e) => {
|
||||
// ignore succ and subst exit_ln:
|
||||
let exit_ln = self.s.exit_ln;
|
||||
self.propagate_through_opt_expr(o_e, exit_ln)
|
||||
self.propagate_through_opt_expr(o_e.as_ref().map(|e| &**e), exit_ln)
|
||||
}
|
||||
|
||||
ExprBreak(opt_label) => {
|
||||
|
|
@ -1134,7 +1132,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ExprStruct(_, ref fields, ref with_expr) => {
|
||||
let succ = self.propagate_through_opt_expr(with_expr.clone(), succ);
|
||||
let succ = self.propagate_through_opt_expr(with_expr.as_ref().map(|e| &**e), succ);
|
||||
fields.iter().rev().fold(succ, |succ, field| {
|
||||
self.propagate_through_expr(&*field.expr, succ)
|
||||
})
|
||||
|
|
@ -1182,7 +1180,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
ExprIndex(ref l, ref r) |
|
||||
ExprBinary(_, ref l, ref r) |
|
||||
ExprBox(ref l, ref r) => {
|
||||
self.propagate_through_exprs([l.clone(), r.clone()], succ)
|
||||
let r_succ = self.propagate_through_expr(&**r, succ);
|
||||
self.propagate_through_expr(&**l, r_succ)
|
||||
}
|
||||
|
||||
ExprAddrOf(_, ref e) |
|
||||
|
|
@ -1342,12 +1341,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
let mut first_merge = true;
|
||||
let ln = self.live_node(expr.id, expr.span);
|
||||
self.init_empty(ln, succ);
|
||||
if kind != LoopLoop {
|
||||
// If this is not a `loop` loop, then it's possible we bypass
|
||||
// the body altogether. Otherwise, the only way is via a `break`
|
||||
// in the loop body.
|
||||
self.merge_from_succ(ln, succ, first_merge);
|
||||
first_merge = false;
|
||||
match kind {
|
||||
LoopLoop => {}
|
||||
_ => {
|
||||
// If this is not a `loop` loop, then it's possible we bypass
|
||||
// the body altogether. Otherwise, the only way is via a `break`
|
||||
// in the loop body.
|
||||
self.merge_from_succ(ln, succ, first_merge);
|
||||
first_merge = false;
|
||||
}
|
||||
}
|
||||
debug!("propagate_through_loop: using id for loop body {} {}",
|
||||
expr.id, block_to_string(body));
|
||||
|
|
@ -1413,7 +1415,10 @@ fn check_local(this: &mut Liveness, local: &Local) {
|
|||
}
|
||||
|
||||
fn check_arm(this: &mut Liveness, arm: &Arm) {
|
||||
this.arm_pats_bindings(arm.pats.as_slice(), |this, ln, var, sp, id| {
|
||||
// only consider the first pattern; any later patterns must have
|
||||
// the same bindings, and we also consider the first pattern to be
|
||||
// the "authoritative" set of ids
|
||||
this.arm_pats_bindings(arm.pats.as_slice().head().map(|p| &**p), |this, ln, var, sp, id| {
|
||||
this.warn_about_unused(sp, id, ln, var);
|
||||
});
|
||||
visit::walk_arm(this, arm);
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
|||
}
|
||||
|
||||
ast::ExprPath(_) => {
|
||||
let def = self.tcx().def_map.borrow().get_copy(&expr.id);
|
||||
let def = *self.tcx().def_map.borrow().get(&expr.id);
|
||||
self.cat_def(expr.id, expr.span, expr_ty, def)
|
||||
}
|
||||
|
||||
|
|
@ -1154,7 +1154,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
|||
if_ok!(self.cat_pattern(subcmt, &**subpat, op));
|
||||
}
|
||||
|
||||
ast::PatVec(ref before, slice, ref after) => {
|
||||
ast::PatVec(ref before, ref slice, ref after) => {
|
||||
let elt_cmt = self.cat_index(pat, self.deref_vec(pat, cmt));
|
||||
for before_pat in before.iter() {
|
||||
if_ok!(self.cat_pattern(elt_cmt.clone(), &**before_pat,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ use middle::resolve;
|
|||
use middle::ty;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::gc::{Gc, GC};
|
||||
use syntax::ast::*;
|
||||
use syntax::ast_util::{walk_pat};
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
|
|
@ -115,17 +114,6 @@ pub fn simple_identifier<'a>(pat: &'a Pat) -> Option<&'a Ident> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn wild() -> Gc<Pat> {
|
||||
box (GC) Pat { id: 0, node: PatWild(PatWildSingle), span: DUMMY_SP }
|
||||
}
|
||||
|
||||
pub fn raw_pat(p: Gc<Pat>) -> Gc<Pat> {
|
||||
match p.node {
|
||||
PatIdent(_, _, Some(s)) => { raw_pat(s) }
|
||||
_ => { p }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn def_to_path(tcx: &ty::ctxt, id: DefId) -> Path {
|
||||
ty::with_path(tcx, id, |mut path| Path {
|
||||
global: false,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
//! outside their scopes. This pass will also generate a set of exported items
|
||||
//! which are available for use externally when compiled as a library.
|
||||
|
||||
use std::gc::Gc;
|
||||
use std::mem::replace;
|
||||
|
||||
use metadata::csearch;
|
||||
|
|
@ -263,7 +262,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
|||
if public_ty || public_trait {
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(method) => {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
let meth_public =
|
||||
match method.pe_explicit_self().node {
|
||||
ast::SelfStatic => public_ty,
|
||||
|
|
@ -457,11 +456,10 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
|||
// invocation.
|
||||
// FIXME(#10573) is this the right behavior? Why not consider
|
||||
// where the method was defined?
|
||||
Some(ast_map::NodeImplItem(ref ii)) => {
|
||||
match **ii {
|
||||
ast::MethodImplItem(m) => {
|
||||
let imp = self.tcx
|
||||
.map
|
||||
Some(ast_map::NodeImplItem(ii)) => {
|
||||
match *ii {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
let imp = self.tcx.map
|
||||
.get_parent_did(closest_private_id);
|
||||
match ty::impl_trait_ref(self.tcx, imp) {
|
||||
Some(..) => return Allowable,
|
||||
|
|
@ -1108,7 +1106,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
|||
impls");
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(m) => {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
check_inherited(m.span, m.pe_vis(), "");
|
||||
}
|
||||
}
|
||||
|
|
@ -1169,7 +1167,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
|||
tcx.sess.span_err(sp, "visibility has no effect inside functions");
|
||||
}
|
||||
}
|
||||
let check_struct = |def: &Gc<ast::StructDef>| {
|
||||
let check_struct = |def: &ast::StructDef| {
|
||||
for f in def.fields.iter() {
|
||||
match f.node.kind {
|
||||
ast::NamedField(_, p) => check_inherited(tcx, f.span, p),
|
||||
|
|
@ -1182,7 +1180,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
|||
ast::ItemImpl(_, _, _, ref impl_items) => {
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(m) => {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
check_inherited(tcx, m.span, m.pe_vis());
|
||||
}
|
||||
}
|
||||
|
|
@ -1198,13 +1196,13 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
|||
check_inherited(tcx, v.span, v.node.vis);
|
||||
|
||||
match v.node.kind {
|
||||
ast::StructVariantKind(ref s) => check_struct(s),
|
||||
ast::StructVariantKind(ref s) => check_struct(&**s),
|
||||
ast::TupleVariantKind(..) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast::ItemStruct(ref def, _) => check_struct(def),
|
||||
ast::ItemStruct(ref def, _) => check_struct(&**def),
|
||||
|
||||
ast::ItemTrait(_, _, _, ref methods) => {
|
||||
for m in methods.iter() {
|
||||
|
|
@ -1305,7 +1303,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
|||
// (i.e. we could just return here to not check them at
|
||||
// all, or some worse estimation of whether an impl is
|
||||
// publicly visible.
|
||||
ast::ItemImpl(ref g, ref trait_ref, self_, ref impl_items) => {
|
||||
ast::ItemImpl(ref g, ref trait_ref, ref self_, ref impl_items) => {
|
||||
// `impl [... for] Private` is never visible.
|
||||
let self_contains_private;
|
||||
// impl [... for] Public<...>, but not `impl [... for]
|
||||
|
|
@ -1320,7 +1318,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
|||
at_outer_type: true,
|
||||
outer_type_is_public_path: false,
|
||||
};
|
||||
visitor.visit_ty(&*self_);
|
||||
visitor.visit_ty(&**self_);
|
||||
self_contains_private = visitor.contains_private;
|
||||
self_is_public_path = visitor.outer_type_is_public_path;
|
||||
}
|
||||
|
|
@ -1349,7 +1347,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
|||
impl_items.iter()
|
||||
.any(|impl_item| {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(m) => {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
self.exported_items.contains(&m.id)
|
||||
}
|
||||
}
|
||||
|
|
@ -1365,8 +1363,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
|||
None => {
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(method) => {
|
||||
visit::walk_method_helper(self, &*method)
|
||||
ast::MethodImplItem(ref method) => {
|
||||
visit::walk_method_helper(self, &**method)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1393,13 +1391,13 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
|||
let mut found_pub_static = false;
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(method) => {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
if method.pe_explicit_self().node ==
|
||||
ast::SelfStatic &&
|
||||
self.exported_items
|
||||
.contains(&method.id) {
|
||||
found_pub_static = true;
|
||||
visit::walk_method_helper(self, &*method);
|
||||
visit::walk_method_helper(self, &**method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1487,8 +1485,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
|||
pub fn check_crate(tcx: &ty::ctxt,
|
||||
exp_map2: &resolve::ExportMap2,
|
||||
external_exports: resolve::ExternalExports,
|
||||
last_private_map: resolve::LastPrivateMap,
|
||||
krate: &ast::Crate) -> (ExportedItems, PublicItems) {
|
||||
last_private_map: resolve::LastPrivateMap)
|
||||
-> (ExportedItems, PublicItems) {
|
||||
let krate = tcx.map.krate();
|
||||
|
||||
// Figure out who everyone's parent is
|
||||
let mut visitor = ParentVisitor {
|
||||
parents: NodeMap::new(),
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
|||
}
|
||||
Some(ast_map::NodeImplItem(impl_item)) => {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(method) => {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
if generics_require_inlining(method.pe_generics()) ||
|
||||
attributes_specify_inlining(
|
||||
method.attrs.as_slice()) {
|
||||
|
|
@ -333,10 +333,10 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
|||
}
|
||||
ast_map::NodeImplItem(impl_item) => {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(method) => {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
let did = self.tcx.map.get_parent_did(search_item);
|
||||
if method_might_be_inlined(self.tcx, &*method, did) {
|
||||
visit::walk_block(self, &*method.pe_body())
|
||||
if method_might_be_inlined(self.tcx, &**method, did) {
|
||||
visit::walk_block(self, method.pe_body())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ use util::common::can_reach;
|
|||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::gc::Gc;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::{ast, visit};
|
||||
use syntax::visit::{Visitor, FnKind};
|
||||
use syntax::ast::{Block, Item, FnDecl, NodeId, Arm, Pat, Stmt, Expr, Local};
|
||||
use syntax::ast_util::{stmt_id};
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit::{Visitor, FnKind};
|
||||
|
||||
/**
|
||||
The region maps encode information about region relationships.
|
||||
|
|
@ -422,7 +422,7 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &ast::Arm) {
|
|||
visitor.region_maps.mark_as_terminating_scope(arm.body.id);
|
||||
|
||||
match arm.guard {
|
||||
Some(expr) => {
|
||||
Some(ref expr) => {
|
||||
visitor.region_maps.mark_as_terminating_scope(expr.id);
|
||||
}
|
||||
None => { }
|
||||
|
|
@ -471,28 +471,28 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
|
|||
// scopes, meaning that temporaries cannot outlive them.
|
||||
// This ensures fixed size stacks.
|
||||
|
||||
ast::ExprBinary(ast::BiAnd, _, r) |
|
||||
ast::ExprBinary(ast::BiOr, _, r) => {
|
||||
ast::ExprBinary(ast::BiAnd, _, ref r) |
|
||||
ast::ExprBinary(ast::BiOr, _, ref r) => {
|
||||
// For shortcircuiting operators, mark the RHS as a terminating
|
||||
// scope since it only executes conditionally.
|
||||
visitor.region_maps.mark_as_terminating_scope(r.id);
|
||||
}
|
||||
|
||||
ast::ExprIf(_, then, Some(otherwise)) => {
|
||||
ast::ExprIf(_, ref then, Some(ref otherwise)) => {
|
||||
visitor.region_maps.mark_as_terminating_scope(then.id);
|
||||
visitor.region_maps.mark_as_terminating_scope(otherwise.id);
|
||||
}
|
||||
|
||||
ast::ExprIf(expr, then, None) => {
|
||||
ast::ExprIf(ref expr, ref then, None) => {
|
||||
visitor.region_maps.mark_as_terminating_scope(expr.id);
|
||||
visitor.region_maps.mark_as_terminating_scope(then.id);
|
||||
}
|
||||
|
||||
ast::ExprLoop(body, _) => {
|
||||
ast::ExprLoop(ref body, _) => {
|
||||
visitor.region_maps.mark_as_terminating_scope(body.id);
|
||||
}
|
||||
|
||||
ast::ExprWhile(expr, body, _) => {
|
||||
ast::ExprWhile(ref expr, ref body, _) => {
|
||||
visitor.region_maps.mark_as_terminating_scope(expr.id);
|
||||
visitor.region_maps.mark_as_terminating_scope(body.id);
|
||||
}
|
||||
|
|
@ -776,7 +776,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
|
|||
ast::ExprTupField(ref subexpr, _, _) |
|
||||
ast::ExprIndex(ref subexpr, _) |
|
||||
ast::ExprParen(ref subexpr) => {
|
||||
let subexpr: &'a Gc<Expr> = subexpr; // FIXME(#11586)
|
||||
let subexpr: &'a P<Expr> = subexpr; // FIXME(#11586)
|
||||
expr = &**subexpr;
|
||||
}
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ use syntax::ast::{Ident, ImplItem, Item, ItemEnum, ItemFn, ItemForeignMod};
|
|||
use syntax::ast::{ItemImpl, ItemMac, ItemMod, ItemStatic, ItemStruct};
|
||||
use syntax::ast::{ItemTrait, ItemTy, LOCAL_CRATE, Local, Method};
|
||||
use syntax::ast::{MethodImplItem, Mod, Name, NamedField, NodeId};
|
||||
use syntax::ast::{P, Pat, PatEnum, PatIdent, PatLit};
|
||||
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
|
||||
use syntax::ast::{PatRange, PatStruct, Path, PathListIdent, PathListMod};
|
||||
use syntax::ast::{PrimTy, Public, SelfExplicit, SelfStatic};
|
||||
use syntax::ast::{RegionTyParamBound, StmtDecl, StructField};
|
||||
|
|
@ -43,8 +43,7 @@ use syntax::ast::{UnboxedFnTyParamBound, UnnamedField, UnsafeFn, Variant};
|
|||
use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse, ViewPathGlob};
|
||||
use syntax::ast::{ViewPathList, ViewPathSimple, Visibility};
|
||||
use syntax::ast;
|
||||
use syntax::ast_util::{PostExpansionMethod, local_def};
|
||||
use syntax::ast_util::{trait_item_to_ty_method, walk_pat};
|
||||
use syntax::ast_util::{PostExpansionMethod, local_def, walk_pat};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::ext::mtwt;
|
||||
use syntax::parse::token::special_names;
|
||||
|
|
@ -52,6 +51,7 @@ use syntax::parse::token::special_idents;
|
|||
use syntax::parse::token;
|
||||
use syntax::codemap::{Span, DUMMY_SP, Pos};
|
||||
use syntax::owned_slice::OwnedSlice;
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
|
|
@ -1164,7 +1164,7 @@ impl<'a> Resolver<'a> {
|
|||
// Check each statement.
|
||||
for statement in block.stmts.iter() {
|
||||
match statement.node {
|
||||
StmtDecl(declaration, _) => {
|
||||
StmtDecl(ref declaration, _) => {
|
||||
match declaration.node {
|
||||
DeclItem(_) => {
|
||||
return true;
|
||||
|
|
@ -1277,7 +1277,7 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
|
||||
// These items live in both the type and value namespaces.
|
||||
ItemStruct(struct_def, _) => {
|
||||
ItemStruct(ref struct_def, _) => {
|
||||
// Adding to both Type and Value namespaces or just Type?
|
||||
let (forbid, ctor_id) = match struct_def.ctor_id {
|
||||
Some(ctor_id) => (ForbidDuplicateTypesAndValues, Some(ctor_id)),
|
||||
|
|
@ -1309,7 +1309,7 @@ impl<'a> Resolver<'a> {
|
|||
parent
|
||||
}
|
||||
|
||||
ItemImpl(_, None, ty, ref impl_items) => {
|
||||
ItemImpl(_, None, ref ty, ref impl_items) => {
|
||||
// If this implements an anonymous trait, then add all the
|
||||
// methods within to a new module, if the type was defined
|
||||
// within this module.
|
||||
|
|
@ -1364,7 +1364,7 @@ impl<'a> Resolver<'a> {
|
|||
// For each implementation item...
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
MethodImplItem(method) => {
|
||||
MethodImplItem(ref method) => {
|
||||
// Add the method to the module.
|
||||
let ident = method.pe_ident();
|
||||
let method_name_bindings =
|
||||
|
|
@ -1430,37 +1430,42 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
// Add the names of all the methods to the trait info.
|
||||
for method in methods.iter() {
|
||||
let ty_m = trait_item_to_ty_method(method);
|
||||
|
||||
let ident = ty_m.ident;
|
||||
let (m_id, m_ident, m_fn_style, m_self, m_span) = match *method {
|
||||
ast::RequiredMethod(ref m) => {
|
||||
(m.id, m.ident, m.fn_style, &m.explicit_self, m.span)
|
||||
}
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
(m.id, m.pe_ident(), m.pe_fn_style(), m.pe_explicit_self(), m.span)
|
||||
}
|
||||
};
|
||||
|
||||
// Add it as a name in the trait module.
|
||||
let (def, static_flag) = match ty_m.explicit_self.node {
|
||||
let (def, static_flag) = match m_self.node {
|
||||
SelfStatic => {
|
||||
// Static methods become `def_static_method`s.
|
||||
(DefStaticMethod(local_def(ty_m.id),
|
||||
(DefStaticMethod(local_def(m_id),
|
||||
FromTrait(local_def(item.id)),
|
||||
ty_m.fn_style),
|
||||
m_fn_style),
|
||||
StaticMethodTraitItemKind)
|
||||
}
|
||||
_ => {
|
||||
// Non-static methods become `def_method`s.
|
||||
(DefMethod(local_def(ty_m.id),
|
||||
(DefMethod(local_def(m_id),
|
||||
Some(local_def(item.id))),
|
||||
NonstaticMethodTraitItemKind)
|
||||
}
|
||||
};
|
||||
|
||||
let method_name_bindings =
|
||||
self.add_child(ident,
|
||||
self.add_child(m_ident,
|
||||
module_parent.clone(),
|
||||
ForbidDuplicateValues,
|
||||
ty_m.span);
|
||||
method_name_bindings.define_value(def, ty_m.span, true);
|
||||
m_span);
|
||||
method_name_bindings.define_value(def, m_span, true);
|
||||
|
||||
self.trait_item_map
|
||||
.borrow_mut()
|
||||
.insert((ident.name, def_id), static_flag);
|
||||
.insert((m_ident.name, def_id), static_flag);
|
||||
}
|
||||
|
||||
name_bindings.define_type(DefTrait(def_id), sp, is_public);
|
||||
|
|
@ -4068,7 +4073,7 @@ impl<'a> Resolver<'a> {
|
|||
ItemStruct(ref struct_def, ref generics) => {
|
||||
self.resolve_struct(item.id,
|
||||
generics,
|
||||
struct_def.super_struct,
|
||||
&struct_def.super_struct,
|
||||
struct_def.fields.as_slice());
|
||||
}
|
||||
|
||||
|
|
@ -4100,15 +4105,15 @@ impl<'a> Resolver<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
ItemFn(fn_decl, _, _, ref generics, block) => {
|
||||
ItemFn(ref fn_decl, _, _, ref generics, ref block) => {
|
||||
self.resolve_function(ItemRibKind,
|
||||
Some(fn_decl),
|
||||
Some(&**fn_decl),
|
||||
HasTypeParameters
|
||||
(generics,
|
||||
FnSpace,
|
||||
item.id,
|
||||
ItemRibKind),
|
||||
block);
|
||||
&**block);
|
||||
}
|
||||
|
||||
ItemStatic(..) => {
|
||||
|
|
@ -4179,9 +4184,9 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
fn resolve_function(&mut self,
|
||||
rib_kind: RibKind,
|
||||
optional_declaration: Option<P<FnDecl>>,
|
||||
optional_declaration: Option<&FnDecl>,
|
||||
type_parameters: TypeParameters,
|
||||
block: P<Block>) {
|
||||
block: &Block) {
|
||||
// Create a value rib for the function.
|
||||
let function_value_rib = Rib::new(rib_kind);
|
||||
self.value_ribs.borrow_mut().push(function_value_rib);
|
||||
|
|
@ -4357,7 +4362,7 @@ impl<'a> Resolver<'a> {
|
|||
fn resolve_struct(&mut self,
|
||||
id: NodeId,
|
||||
generics: &Generics,
|
||||
super_struct: Option<P<Ty>>,
|
||||
super_struct: &Option<P<Ty>>,
|
||||
fields: &[StructField]) {
|
||||
// If applicable, create a rib for the type parameters.
|
||||
self.with_type_parameter_rib(HasTypeParameters(generics,
|
||||
|
|
@ -4370,8 +4375,8 @@ impl<'a> Resolver<'a> {
|
|||
this.resolve_where_clause(&generics.where_clause);
|
||||
|
||||
// Resolve the super struct.
|
||||
match super_struct {
|
||||
Some(t) => match t.node {
|
||||
match *super_struct {
|
||||
Some(ref t) => match t.node {
|
||||
TyPath(ref path, None, path_id) => {
|
||||
match this.resolve_path(id, path, TypeNS, true) {
|
||||
Some((DefTy(def_id), lp)) if this.structs.contains_key(&def_id) => {
|
||||
|
|
@ -4489,7 +4494,7 @@ impl<'a> Resolver<'a> {
|
|||
this.with_current_self_type(self_type, |this| {
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
MethodImplItem(method) => {
|
||||
MethodImplItem(ref method) => {
|
||||
// If this is a trait impl, ensure the method
|
||||
// exists in trait
|
||||
this.check_trait_item(method.pe_ident(),
|
||||
|
|
@ -4500,7 +4505,7 @@ impl<'a> Resolver<'a> {
|
|||
this.resolve_method(
|
||||
MethodRibKind(id,
|
||||
ProvidedMethod(method.id)),
|
||||
&*method);
|
||||
&**method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4738,7 +4743,7 @@ impl<'a> Resolver<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
TyClosure(c) | TyProc(c) => {
|
||||
TyClosure(ref c) | TyProc(ref c) => {
|
||||
self.resolve_type_parameter_bounds(ty.id, &c.bounds,
|
||||
TraitBoundingTypeParameter);
|
||||
visit::walk_ty(self, ty);
|
||||
|
|
@ -4775,7 +4780,7 @@ impl<'a> Resolver<'a> {
|
|||
let renamed = mtwt::resolve(ident);
|
||||
|
||||
match self.resolve_bare_identifier_pattern(ident, pattern.span) {
|
||||
FoundStructOrEnumVariant(def, lp)
|
||||
FoundStructOrEnumVariant(ref def, lp)
|
||||
if mode == RefutableMode => {
|
||||
debug!("(resolving pattern) resolving `{}` to \
|
||||
struct or enum variant",
|
||||
|
|
@ -4785,7 +4790,7 @@ impl<'a> Resolver<'a> {
|
|||
pattern,
|
||||
binding_mode,
|
||||
"an enum variant");
|
||||
self.record_def(pattern.id, (def, lp));
|
||||
self.record_def(pattern.id, (def.clone(), lp));
|
||||
}
|
||||
FoundStructOrEnumVariant(..) => {
|
||||
self.resolve_error(
|
||||
|
|
@ -4795,7 +4800,7 @@ impl<'a> Resolver<'a> {
|
|||
scope",
|
||||
token::get_name(renamed)).as_slice());
|
||||
}
|
||||
FoundConst(def, lp) if mode == RefutableMode => {
|
||||
FoundConst(ref def, lp) if mode == RefutableMode => {
|
||||
debug!("(resolving pattern) resolving `{}` to \
|
||||
constant",
|
||||
token::get_name(renamed));
|
||||
|
|
@ -4804,7 +4809,7 @@ impl<'a> Resolver<'a> {
|
|||
pattern,
|
||||
binding_mode,
|
||||
"a constant");
|
||||
self.record_def(pattern.id, (def, lp));
|
||||
self.record_def(pattern.id, (def.clone(), lp));
|
||||
}
|
||||
FoundConst(..) => {
|
||||
self.resolve_error(pattern.span,
|
||||
|
|
@ -5024,7 +5029,7 @@ impl<'a> Resolver<'a> {
|
|||
if path.segments.len() > 1 {
|
||||
let def = self.resolve_module_relative_path(path, namespace);
|
||||
match (def, unqualified_def) {
|
||||
(Some((d, _)), Some((ud, _))) if d == ud => {
|
||||
(Some((ref d, _)), Some((ref ud, _))) if *d == *ud => {
|
||||
self.session
|
||||
.add_lint(lint::builtin::UNNECESSARY_QUALIFICATION,
|
||||
id,
|
||||
|
|
@ -5386,8 +5391,8 @@ impl<'a> Resolver<'a> {
|
|||
-> Option<(Path, NodeId, FallbackChecks)> {
|
||||
match t.node {
|
||||
TyPath(ref path, _, node_id) => Some((path.clone(), node_id, allow)),
|
||||
TyPtr(mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
|
||||
TyRptr(_, mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
|
||||
TyPtr(ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, OnlyTraitAndStatics),
|
||||
TyRptr(_, ref mut_ty) => extract_path_and_node_id(&*mut_ty.ty, allow),
|
||||
// This doesn't handle the remaining `Ty` variants as they are not
|
||||
// that commonly the self_type, it might be interesting to provide
|
||||
// support for those in future.
|
||||
|
|
@ -5647,12 +5652,12 @@ impl<'a> Resolver<'a> {
|
|||
visit::walk_expr(self, expr);
|
||||
}
|
||||
|
||||
ExprFnBlock(_, fn_decl, block) |
|
||||
ExprProc(fn_decl, block) |
|
||||
ExprUnboxedFn(_, _, fn_decl, block) => {
|
||||
ExprFnBlock(_, ref fn_decl, ref block) |
|
||||
ExprProc(ref fn_decl, ref block) |
|
||||
ExprUnboxedFn(_, _, ref fn_decl, ref block) => {
|
||||
self.resolve_function(FunctionRibKind(expr.id, block.id),
|
||||
Some(fn_decl), NoTypeParameters,
|
||||
block);
|
||||
Some(&**fn_decl), NoTypeParameters,
|
||||
&**block);
|
||||
}
|
||||
|
||||
ExprStruct(ref path, _, _) => {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ use middle::ty;
|
|||
use middle::typeck;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::gc::Gc;
|
||||
use std::io;
|
||||
use std::io::File;
|
||||
use std::io::fs;
|
||||
|
|
@ -54,6 +53,7 @@ use syntax::owned_slice::OwnedSlice;
|
|||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::print::pprust::{path_to_string,ty_to_string};
|
||||
use syntax::ptr::P;
|
||||
|
||||
use middle::save::span_utils::SpanUtils;
|
||||
use middle::save::recorder::Recorder;
|
||||
|
|
@ -289,9 +289,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
NodeItem(item) => {
|
||||
scope_id = item.id;
|
||||
match item.node {
|
||||
ast::ItemImpl(_, _, ty, _) => {
|
||||
ast::ItemImpl(_, _, ref ty, _) => {
|
||||
let mut result = String::from_str("<");
|
||||
result.push_str(ty_to_string(&*ty).as_slice());
|
||||
result.push_str(ty_to_string(&**ty).as_slice());
|
||||
|
||||
match ty::trait_of_item(&self.analysis.ty_cx,
|
||||
ast_util::local_def(method.id)) {
|
||||
|
|
@ -466,9 +466,9 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
|
||||
fn process_fn(&mut self,
|
||||
item: &ast::Item,
|
||||
decl: ast::P<ast::FnDecl>,
|
||||
decl: &ast::FnDecl,
|
||||
ty_params: &ast::Generics,
|
||||
body: ast::P<ast::Block>) {
|
||||
body: &ast::Block) {
|
||||
let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
|
||||
|
||||
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Fn);
|
||||
|
|
@ -494,7 +494,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
|
||||
fn process_static(&mut self,
|
||||
item: &ast::Item,
|
||||
typ: ast::P<ast::Ty>,
|
||||
typ: &ast::Ty,
|
||||
mt: ast::Mutability,
|
||||
expr: &ast::Expr)
|
||||
{
|
||||
|
|
@ -611,7 +611,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
item: &ast::Item,
|
||||
type_parameters: &ast::Generics,
|
||||
trait_ref: &Option<ast::TraitRef>,
|
||||
typ: ast::P<ast::Ty>,
|
||||
typ: &ast::Ty,
|
||||
impl_items: &Vec<ast::ImplItem>) {
|
||||
match typ.node {
|
||||
ast::TyPath(ref path, _, id) => {
|
||||
|
|
@ -643,8 +643,8 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
self.process_generic_params(type_parameters, item.span, "", item.id);
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(method) => {
|
||||
visit::walk_method_helper(self, &*method)
|
||||
ast::MethodImplItem(ref method) => {
|
||||
visit::walk_method_helper(self, &**method)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -833,7 +833,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
ex: &ast::Expr,
|
||||
path: &ast::Path,
|
||||
fields: &Vec<ast::Field>,
|
||||
base: &Option<Gc<ast::Expr>>) {
|
||||
base: &Option<P<ast::Expr>>) {
|
||||
if generated_code(path.span) {
|
||||
return
|
||||
}
|
||||
|
|
@ -883,7 +883,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
|
||||
fn process_method_call(&mut self,
|
||||
ex: &ast::Expr,
|
||||
args: &Vec<Gc<ast::Expr>>) {
|
||||
args: &Vec<P<ast::Expr>>) {
|
||||
let method_map = self.analysis.ty_cx.method_map.borrow();
|
||||
let method_callee = method_map.get(&typeck::MethodCall::expr(ex.id));
|
||||
let (def_id, decl_id) = match method_callee.origin {
|
||||
|
|
@ -1010,7 +1010,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
|
|||
self.collected_paths.push((p.id, path, immut, recorder::VarRef));
|
||||
match *optional_subpattern {
|
||||
None => {}
|
||||
Some(subpattern) => self.visit_pat(&*subpattern),
|
||||
Some(ref subpattern) => self.visit_pat(&**subpattern)
|
||||
}
|
||||
}
|
||||
_ => visit::walk_pat(self, p)
|
||||
|
|
@ -1025,28 +1025,28 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
}
|
||||
|
||||
match item.node {
|
||||
ast::ItemFn(decl, _, _, ref ty_params, body) =>
|
||||
self.process_fn(item, decl, ty_params, body),
|
||||
ast::ItemStatic(typ, mt, expr) =>
|
||||
self.process_static(item, typ, mt, &*expr),
|
||||
ast::ItemStruct(def, ref ty_params) => self.process_struct(item, &*def, ty_params),
|
||||
ast::ItemFn(ref decl, _, _, ref ty_params, ref body) =>
|
||||
self.process_fn(item, &**decl, ty_params, &**body),
|
||||
ast::ItemStatic(ref typ, mt, ref expr) =>
|
||||
self.process_static(item, &**typ, mt, &**expr),
|
||||
ast::ItemStruct(ref def, ref ty_params) => self.process_struct(item, &**def, ty_params),
|
||||
ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
|
||||
ast::ItemImpl(ref ty_params,
|
||||
ref trait_ref,
|
||||
typ,
|
||||
ref typ,
|
||||
ref impl_items) => {
|
||||
self.process_impl(item,
|
||||
ty_params,
|
||||
trait_ref,
|
||||
typ,
|
||||
&**typ,
|
||||
impl_items)
|
||||
}
|
||||
ast::ItemTrait(ref generics, _, ref trait_refs, ref methods) =>
|
||||
self.process_trait(item, generics, trait_refs, methods),
|
||||
ast::ItemMod(ref m) => self.process_mod(item, m),
|
||||
ast::ItemTy(ty, ref ty_params) => {
|
||||
ast::ItemTy(ref ty, ref ty_params) => {
|
||||
let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
|
||||
let value = ty_to_string(&*ty);
|
||||
let value = ty_to_string(&**ty);
|
||||
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type);
|
||||
self.fmt.typedef_str(item.span,
|
||||
sub_span,
|
||||
|
|
@ -1054,7 +1054,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
qualname.as_slice(),
|
||||
value.as_slice());
|
||||
|
||||
self.visit_ty(&*ty);
|
||||
self.visit_ty(&**ty);
|
||||
self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
|
||||
},
|
||||
ast::ItemMac(_) => (),
|
||||
|
|
@ -1073,8 +1073,8 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
}
|
||||
}
|
||||
match param.default {
|
||||
Some(ty) => self.visit_ty(&*ty),
|
||||
None => (),
|
||||
Some(ref ty) => self.visit_ty(&**ty),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1139,7 +1139,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
qualname,
|
||||
method_type.id);
|
||||
}
|
||||
ast::ProvidedMethod(method) => self.process_method(&*method),
|
||||
ast::ProvidedMethod(ref method) => self.process_method(&**method)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1269,7 +1269,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
}
|
||||
|
||||
match ex.node {
|
||||
ast::ExprCall(_f, ref _args) => {
|
||||
ast::ExprCall(ref _f, ref _args) => {
|
||||
// Don't need to do anything for function calls,
|
||||
// because just walking the callee path does what we want.
|
||||
visit::walk_expr(self, ex);
|
||||
|
|
@ -1278,14 +1278,14 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
ast::ExprStruct(ref path, ref fields, ref base) =>
|
||||
self.process_struct_lit(ex, path, fields, base),
|
||||
ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args),
|
||||
ast::ExprField(sub_ex, ident, _) => {
|
||||
ast::ExprField(ref sub_ex, ident, _) => {
|
||||
if generated_code(sub_ex.span) {
|
||||
return
|
||||
}
|
||||
|
||||
self.visit_expr(&*sub_ex);
|
||||
self.visit_expr(&**sub_ex);
|
||||
|
||||
let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex);
|
||||
let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &**sub_ex);
|
||||
let t_box = ty::get(t);
|
||||
match t_box.sty {
|
||||
ty::ty_struct(def_id, _) => {
|
||||
|
|
@ -1306,14 +1306,14 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
"Expected struct type, but not ty_struct"),
|
||||
}
|
||||
},
|
||||
ast::ExprTupField(sub_ex, idx, _) => {
|
||||
ast::ExprTupField(ref sub_ex, idx, _) => {
|
||||
if generated_code(sub_ex.span) {
|
||||
return
|
||||
}
|
||||
|
||||
self.visit_expr(&*sub_ex);
|
||||
self.visit_expr(&**sub_ex);
|
||||
|
||||
let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex);
|
||||
let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &**sub_ex);
|
||||
let t_box = ty::get(t);
|
||||
match t_box.sty {
|
||||
ty::ty_struct(def_id, _) => {
|
||||
|
|
@ -1334,7 +1334,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
"Expected struct type, but not ty_struct"),
|
||||
}
|
||||
},
|
||||
ast::ExprFnBlock(_, decl, body) => {
|
||||
ast::ExprFnBlock(_, ref decl, ref body) => {
|
||||
if generated_code(body.span) {
|
||||
return
|
||||
}
|
||||
|
|
@ -1349,7 +1349,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
self.visit_ty(&*decl.output);
|
||||
|
||||
// walk the body
|
||||
self.nest(ex.id, |v| v.visit_block(&*body));
|
||||
self.nest(ex.id, |v| v.visit_block(&**body));
|
||||
},
|
||||
_ => {
|
||||
visit::walk_expr(self, ex)
|
||||
|
|
|
|||
|
|
@ -218,24 +218,20 @@ use util::ppaux::{Repr, vec_map_to_string};
|
|||
|
||||
use std;
|
||||
use std::collections::HashMap;
|
||||
use std::gc::{Gc};
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::ast::Ident;
|
||||
use syntax::ast::{DUMMY_NODE_ID, Ident};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::fold::Folder;
|
||||
use syntax::ptr::P;
|
||||
|
||||
struct ConstantExpr<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>, Gc<ast::Expr>);
|
||||
struct ConstantExpr<'a>(&'a ast::Expr);
|
||||
|
||||
impl<'a, 'tcx> Eq for ConstantExpr<'a, 'tcx> {
|
||||
fn assert_receiver_is_total_eq(&self) {}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> PartialEq for ConstantExpr<'a, 'tcx> {
|
||||
fn eq(&self, other: &ConstantExpr<'a, 'tcx>) -> bool {
|
||||
let &ConstantExpr(tcx, expr) = self;
|
||||
let &ConstantExpr(_, other_expr) = other;
|
||||
match const_eval::compare_lit_exprs(tcx, &*expr, &*other_expr) {
|
||||
impl<'a> ConstantExpr<'a> {
|
||||
fn eq(self, other: ConstantExpr<'a>, tcx: &ty::ctxt) -> bool {
|
||||
let ConstantExpr(expr) = self;
|
||||
let ConstantExpr(other_expr) = other;
|
||||
match const_eval::compare_lit_exprs(tcx, expr, other_expr) {
|
||||
Some(val1) => val1 == 0,
|
||||
None => fail!("compare_list_exprs: type mismatch"),
|
||||
}
|
||||
|
|
@ -243,30 +239,44 @@ impl<'a, 'tcx> PartialEq for ConstantExpr<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// An option identifying a branch (either a literal, an enum variant or a range)
|
||||
#[deriving(Eq, PartialEq)]
|
||||
enum Opt<'blk, 'tcx: 'blk> {
|
||||
ConstantValue(ConstantExpr<'blk, 'tcx>),
|
||||
ConstantRange(ConstantExpr<'blk, 'tcx>, ConstantExpr<'blk, 'tcx>),
|
||||
enum Opt<'a> {
|
||||
ConstantValue(ConstantExpr<'a>),
|
||||
ConstantRange(ConstantExpr<'a>, ConstantExpr<'a>),
|
||||
Variant(ty::Disr, Rc<adt::Repr>, ast::DefId),
|
||||
SliceLengthEqual(uint),
|
||||
SliceLengthGreaterOrEqual(/* prefix length */ uint, /* suffix length */ uint),
|
||||
}
|
||||
|
||||
impl<'blk, 'tcx> Opt<'blk, 'tcx> {
|
||||
fn trans(&self, mut bcx: Block<'blk, 'tcx>) -> OptResult<'blk, 'tcx> {
|
||||
impl<'a> Opt<'a> {
|
||||
fn eq(&self, other: &Opt<'a>, tcx: &ty::ctxt) -> bool {
|
||||
match (self, other) {
|
||||
(&ConstantValue(a), &ConstantValue(b)) => a.eq(b, tcx),
|
||||
(&ConstantRange(a1, a2), &ConstantRange(b1, b2)) => {
|
||||
a1.eq(b1, tcx) && a2.eq(b2, tcx)
|
||||
}
|
||||
(&Variant(a_disr, ref a_repr, a_def), &Variant(b_disr, ref b_repr, b_def)) => {
|
||||
a_disr == b_disr && *a_repr == *b_repr && a_def == b_def
|
||||
}
|
||||
(&SliceLengthEqual(a), &SliceLengthEqual(b)) => a == b,
|
||||
(&SliceLengthGreaterOrEqual(a1, a2), &SliceLengthGreaterOrEqual(b1, b2)) => {
|
||||
a1 == b1 && a2 == b2
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn trans<'blk, 'tcx>(&self, mut bcx: Block<'blk, 'tcx>) -> OptResult<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("match::trans_opt");
|
||||
let ccx = bcx.ccx();
|
||||
match *self {
|
||||
ConstantValue(ConstantExpr(_, lit_expr)) => {
|
||||
ConstantValue(ConstantExpr(lit_expr)) => {
|
||||
let lit_ty = ty::node_id_to_type(bcx.tcx(), lit_expr.id);
|
||||
let (llval, _, _) = consts::const_expr(ccx, &*lit_expr, true);
|
||||
let lit_datum = immediate_rvalue(llval, lit_ty);
|
||||
let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx));
|
||||
SingleResult(Result::new(bcx, lit_datum.val))
|
||||
}
|
||||
ConstantRange(
|
||||
ConstantExpr(_, ref l1),
|
||||
ConstantExpr(_, ref l2)) => {
|
||||
ConstantRange(ConstantExpr(ref l1), ConstantExpr(ref l2)) => {
|
||||
let (l1, _, _) = consts::const_expr(ccx, &**l1, true);
|
||||
let (l2, _, _) = consts::const_expr(ccx, &**l2, true);
|
||||
RangeResult(Result::new(bcx, l1), Result::new(bcx, l2))
|
||||
|
|
@ -325,9 +335,9 @@ pub struct BindingInfo {
|
|||
|
||||
type BindingsMap = HashMap<Ident, BindingInfo>;
|
||||
|
||||
struct ArmData<'a, 'blk, 'tcx: 'blk> {
|
||||
struct ArmData<'p, 'blk, 'tcx: 'blk> {
|
||||
bodycx: Block<'blk, 'tcx>,
|
||||
arm: &'a ast::Arm,
|
||||
arm: &'p ast::Arm,
|
||||
bindings_map: BindingsMap
|
||||
}
|
||||
|
||||
|
|
@ -337,13 +347,13 @@ struct ArmData<'a, 'blk, 'tcx: 'blk> {
|
|||
* As we proceed `bound_ptrs` are filled with pointers to values to be bound,
|
||||
* these pointers are stored in llmatch variables just before executing `data` arm.
|
||||
*/
|
||||
struct Match<'a, 'blk: 'a, 'tcx: 'blk> {
|
||||
pats: Vec<Gc<ast::Pat>>,
|
||||
data: &'a ArmData<'a, 'blk, 'tcx>,
|
||||
struct Match<'a, 'p: 'a, 'blk: 'a, 'tcx: 'blk> {
|
||||
pats: Vec<&'p ast::Pat>,
|
||||
data: &'a ArmData<'p, 'blk, 'tcx>,
|
||||
bound_ptrs: Vec<(Ident, ValueRef)>
|
||||
}
|
||||
|
||||
impl<'a, 'blk, 'tcx> Repr for Match<'a, 'blk, 'tcx> {
|
||||
impl<'a, 'p, 'blk, 'tcx> Repr for Match<'a, 'p, 'blk, 'tcx> {
|
||||
fn repr(&self, tcx: &ty::ctxt) -> String {
|
||||
if tcx.sess.verbose() {
|
||||
// for many programs, this just take too long to serialize
|
||||
|
|
@ -364,11 +374,11 @@ fn has_nested_bindings(m: &[Match], col: uint) -> bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
fn expand_nested_bindings<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
m: &'a [Match<'a, 'blk, 'tcx>],
|
||||
col: uint,
|
||||
val: ValueRef)
|
||||
-> Vec<Match<'a, 'blk, 'tcx>> {
|
||||
fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
m: &[Match<'a, 'p, 'blk, 'tcx>],
|
||||
col: uint,
|
||||
val: ValueRef)
|
||||
-> Vec<Match<'a, 'p, 'blk, 'tcx>> {
|
||||
debug!("expand_nested_bindings(bcx={}, m={}, col={}, val={})",
|
||||
bcx.to_str(),
|
||||
m.repr(bcx.tcx()),
|
||||
|
|
@ -381,9 +391,9 @@ fn expand_nested_bindings<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
let mut pat = *br.pats.get(col);
|
||||
loop {
|
||||
pat = match pat.node {
|
||||
ast::PatIdent(_, ref path, Some(inner)) => {
|
||||
ast::PatIdent(_, ref path, Some(ref inner)) => {
|
||||
bound_ptrs.push((path.node, val));
|
||||
inner.clone()
|
||||
&**inner
|
||||
},
|
||||
_ => break
|
||||
}
|
||||
|
|
@ -399,15 +409,15 @@ fn expand_nested_bindings<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
}).collect()
|
||||
}
|
||||
|
||||
type EnterPatterns<'a> = |&[Gc<ast::Pat>]|: 'a -> Option<Vec<Gc<ast::Pat>>>;
|
||||
type EnterPatterns<'a> = <'p> |&[&'p ast::Pat]|: 'a -> Option<Vec<&'p ast::Pat>>;
|
||||
|
||||
fn enter_match<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
dm: &DefMap,
|
||||
m: &'a [Match<'a, 'blk, 'tcx>],
|
||||
col: uint,
|
||||
val: ValueRef,
|
||||
e: EnterPatterns)
|
||||
-> Vec<Match<'a, 'blk, 'tcx>> {
|
||||
fn enter_match<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
dm: &DefMap,
|
||||
m: &[Match<'a, 'p, 'blk, 'tcx>],
|
||||
col: uint,
|
||||
val: ValueRef,
|
||||
e: EnterPatterns)
|
||||
-> Vec<Match<'a, 'p, 'blk, 'tcx>> {
|
||||
debug!("enter_match(bcx={}, m={}, col={}, val={})",
|
||||
bcx.to_str(),
|
||||
m.repr(bcx.tcx()),
|
||||
|
|
@ -425,7 +435,7 @@ fn enter_match<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
bound_ptrs.push((path.node, val));
|
||||
}
|
||||
}
|
||||
ast::PatVec(ref before, Some(slice), ref after) => {
|
||||
ast::PatVec(ref before, Some(ref slice), ref after) => {
|
||||
match slice.node {
|
||||
ast::PatIdent(_, ref path, None) => {
|
||||
let subslice_val = bind_subslice_pat(
|
||||
|
|
@ -438,7 +448,6 @@ fn enter_match<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Match {
|
||||
pats: pats,
|
||||
data: br.data,
|
||||
|
|
@ -448,12 +457,12 @@ fn enter_match<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
}).collect()
|
||||
}
|
||||
|
||||
fn enter_default<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
dm: &DefMap,
|
||||
m: &'a [Match<'a, 'blk, 'tcx>],
|
||||
col: uint,
|
||||
val: ValueRef)
|
||||
-> Vec<Match<'a, 'blk, 'tcx>> {
|
||||
fn enter_default<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
dm: &DefMap,
|
||||
m: &[Match<'a, 'p, 'blk, 'tcx>],
|
||||
col: uint,
|
||||
val: ValueRef)
|
||||
-> Vec<Match<'a, 'p, 'blk, 'tcx>> {
|
||||
debug!("enter_default(bcx={}, m={}, col={}, val={})",
|
||||
bcx.to_str(),
|
||||
m.repr(bcx.tcx()),
|
||||
|
|
@ -499,16 +508,16 @@ fn enter_default<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
/// takes the complete row of patterns rather than just the first one.
|
||||
/// Also, most of the enter_() family functions have been unified with
|
||||
/// the check_match specialization step.
|
||||
fn enter_opt<'a, 'blk, 'tcx>(
|
||||
fn enter_opt<'a, 'p, 'blk, 'tcx>(
|
||||
bcx: Block<'blk, 'tcx>,
|
||||
_: ast::NodeId,
|
||||
dm: &DefMap,
|
||||
m: &'a [Match<'a, 'blk, 'tcx>],
|
||||
m: &[Match<'a, 'p, 'blk, 'tcx>],
|
||||
opt: &Opt,
|
||||
col: uint,
|
||||
variant_size: uint,
|
||||
val: ValueRef)
|
||||
-> Vec<Match<'a, 'blk, 'tcx>> {
|
||||
-> Vec<Match<'a, 'p, 'blk, 'tcx>> {
|
||||
debug!("enter_opt(bcx={}, m={}, opt={:?}, col={}, val={})",
|
||||
bcx.to_str(),
|
||||
m.repr(bcx.tcx()),
|
||||
|
|
@ -518,10 +527,10 @@ fn enter_opt<'a, 'blk, 'tcx>(
|
|||
let _indenter = indenter();
|
||||
|
||||
let ctor = match opt {
|
||||
&ConstantValue(ConstantExpr(_, expr)) => check_match::ConstantValue(
|
||||
&ConstantValue(ConstantExpr(expr)) => check_match::ConstantValue(
|
||||
const_eval::eval_const_expr(bcx.tcx(), &*expr)
|
||||
),
|
||||
&ConstantRange(ConstantExpr(_, lo), ConstantExpr(_, hi)) => check_match::ConstantRange(
|
||||
&ConstantRange(ConstantExpr(lo), ConstantExpr(hi)) => check_match::ConstantRange(
|
||||
const_eval::eval_const_expr(bcx.tcx(), &*lo),
|
||||
const_eval::eval_const_expr(bcx.tcx(), &*hi)
|
||||
),
|
||||
|
|
@ -542,51 +551,41 @@ fn enter_opt<'a, 'blk, 'tcx>(
|
|||
// Returns the options in one column of matches. An option is something that
|
||||
// needs to be conditionally matched at runtime; for example, the discriminant
|
||||
// on a set of enum variants or a literal.
|
||||
fn get_branches<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
m: &[Match], col: uint)
|
||||
-> Vec<Opt<'blk, 'tcx>> {
|
||||
let ccx = bcx.ccx();
|
||||
fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
m: &[Match<'a, 'p, 'blk, 'tcx>], col: uint)
|
||||
-> Vec<Opt<'p>> {
|
||||
let tcx = bcx.tcx();
|
||||
|
||||
fn add_to_set<'blk, 'tcx>(set: &mut Vec<Opt<'blk, 'tcx>>, opt: Opt<'blk, 'tcx>) {
|
||||
if !set.contains(&opt) {
|
||||
set.push(opt);
|
||||
}
|
||||
}
|
||||
|
||||
let mut found = Vec::new();
|
||||
let mut found: Vec<Opt> = vec![];
|
||||
for (i, br) in m.iter().enumerate() {
|
||||
let cur = *br.pats.get(col);
|
||||
match cur.node {
|
||||
ast::PatLit(l) => {
|
||||
add_to_set(&mut found, ConstantValue(ConstantExpr(ccx.tcx(), l)));
|
||||
}
|
||||
let opt = match cur.node {
|
||||
ast::PatLit(ref l) => ConstantValue(ConstantExpr(&**l)),
|
||||
ast::PatIdent(..) | ast::PatEnum(..) | ast::PatStruct(..) => {
|
||||
// This is either an enum variant or a variable binding.
|
||||
let opt_def = ccx.tcx().def_map.borrow().find_copy(&cur.id);
|
||||
let opt_def = tcx.def_map.borrow().find_copy(&cur.id);
|
||||
match opt_def {
|
||||
Some(def::DefVariant(enum_id, var_id, _)) => {
|
||||
let variant = ty::enum_variant_with_id(ccx.tcx(), enum_id, var_id);
|
||||
add_to_set(&mut found, Variant(
|
||||
variant.disr_val,
|
||||
adt::represent_node(bcx, cur.id), var_id
|
||||
));
|
||||
let variant = ty::enum_variant_with_id(tcx, enum_id, var_id);
|
||||
Variant(variant.disr_val, adt::represent_node(bcx, cur.id), var_id)
|
||||
}
|
||||
_ => {}
|
||||
_ => continue
|
||||
}
|
||||
}
|
||||
ast::PatRange(l1, l2) => {
|
||||
add_to_set(&mut found, ConstantRange(
|
||||
ConstantExpr(ccx.tcx(), l1),
|
||||
ConstantExpr(ccx.tcx(), l2)
|
||||
));
|
||||
ast::PatRange(ref l1, ref l2) => {
|
||||
ConstantRange(ConstantExpr(&**l1), ConstantExpr(&**l2))
|
||||
}
|
||||
ast::PatVec(ref before, None, ref after) => {
|
||||
add_to_set(&mut found, SliceLengthEqual(before.len() + after.len()));
|
||||
SliceLengthEqual(before.len() + after.len())
|
||||
}
|
||||
ast::PatVec(ref before, Some(_), ref after) => {
|
||||
add_to_set(&mut found, SliceLengthGreaterOrEqual(before.len(), after.len()));
|
||||
SliceLengthGreaterOrEqual(before.len(), after.len())
|
||||
}
|
||||
_ => {}
|
||||
_ => continue
|
||||
};
|
||||
|
||||
if !found.iter().any(|x| x.eq(&opt, tcx)) {
|
||||
found.push(opt);
|
||||
}
|
||||
}
|
||||
found
|
||||
|
|
@ -870,14 +869,14 @@ fn insert_lllocals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
bcx
|
||||
}
|
||||
|
||||
fn compile_guard<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
guard_expr: &ast::Expr,
|
||||
data: &ArmData,
|
||||
m: &'a [Match<'a, 'blk, 'tcx>],
|
||||
vals: &[ValueRef],
|
||||
chk: &FailureHandler,
|
||||
has_genuine_default: bool)
|
||||
-> Block<'blk, 'tcx> {
|
||||
fn compile_guard<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
guard_expr: &ast::Expr,
|
||||
data: &ArmData,
|
||||
m: &[Match<'a, 'p, 'blk, 'tcx>],
|
||||
vals: &[ValueRef],
|
||||
chk: &FailureHandler,
|
||||
has_genuine_default: bool)
|
||||
-> Block<'blk, 'tcx> {
|
||||
debug!("compile_guard(bcx={}, guard_expr={}, m={}, vals={})",
|
||||
bcx.to_str(),
|
||||
bcx.expr_to_string(guard_expr),
|
||||
|
|
@ -918,11 +917,11 @@ fn compile_guard<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
})
|
||||
}
|
||||
|
||||
fn compile_submatch<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
m: &'a [Match<'a, 'blk, 'tcx>],
|
||||
vals: &[ValueRef],
|
||||
chk: &FailureHandler,
|
||||
has_genuine_default: bool) {
|
||||
fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
m: &[Match<'a, 'p, 'blk, 'tcx>],
|
||||
vals: &[ValueRef],
|
||||
chk: &FailureHandler,
|
||||
has_genuine_default: bool) {
|
||||
debug!("compile_submatch(bcx={}, m={}, vals={})",
|
||||
bcx.to_str(),
|
||||
m.repr(bcx.tcx()),
|
||||
|
|
@ -978,13 +977,13 @@ fn compile_submatch<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
fn compile_submatch_continue<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
m: &'a [Match<'a, 'blk, 'tcx>],
|
||||
vals: &[ValueRef],
|
||||
chk: &FailureHandler,
|
||||
col: uint,
|
||||
val: ValueRef,
|
||||
has_genuine_default: bool) {
|
||||
fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
m: &[Match<'a, 'p, 'blk, 'tcx>],
|
||||
vals: &[ValueRef],
|
||||
chk: &FailureHandler,
|
||||
col: uint,
|
||||
val: ValueRef,
|
||||
has_genuine_default: bool) {
|
||||
let fcx = bcx.fcx;
|
||||
let tcx = bcx.tcx();
|
||||
let dm = &tcx.def_map;
|
||||
|
|
@ -994,9 +993,11 @@ fn compile_submatch_continue<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
|
||||
// Find a real id (we're adding placeholder wildcard patterns, but
|
||||
// each column is guaranteed to have at least one real pattern)
|
||||
let pat_id = m.iter().map(|br| br.pats.get(col).id).find(|&id| id != 0).unwrap_or(0);
|
||||
let pat_id = m.iter().map(|br| br.pats.get(col).id)
|
||||
.find(|&id| id != DUMMY_NODE_ID)
|
||||
.unwrap_or(DUMMY_NODE_ID);
|
||||
|
||||
let left_ty = if pat_id == 0 {
|
||||
let left_ty = if pat_id == DUMMY_NODE_ID {
|
||||
ty::mk_nil()
|
||||
} else {
|
||||
node_id_type(bcx, pat_id)
|
||||
|
|
@ -1264,7 +1265,7 @@ impl euv::Delegate for ReassignmentChecker {
|
|||
}
|
||||
}
|
||||
|
||||
fn create_bindings_map(bcx: Block, pat: Gc<ast::Pat>,
|
||||
fn create_bindings_map(bcx: Block, pat: &ast::Pat,
|
||||
discr: &ast::Expr, body: &ast::Expr) -> BindingsMap {
|
||||
// Create the bindings map, which is a mapping from each binding name
|
||||
// to an alloca() that will be the value for that local variable.
|
||||
|
|
@ -1345,14 +1346,17 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
|
|||
let arm_datas: Vec<ArmData> = arms.iter().map(|arm| ArmData {
|
||||
bodycx: fcx.new_id_block("case_body", arm.body.id),
|
||||
arm: arm,
|
||||
bindings_map: create_bindings_map(bcx, *arm.pats.get(0), discr_expr, &*arm.body)
|
||||
bindings_map: create_bindings_map(bcx, &**arm.pats.get(0), discr_expr, &*arm.body)
|
||||
}).collect();
|
||||
|
||||
let mut static_inliner = StaticInliner::new(scope_cx.tcx());
|
||||
let arm_pats: Vec<Vec<P<ast::Pat>>> = arm_datas.iter().map(|arm_data| {
|
||||
arm_data.arm.pats.iter().map(|p| static_inliner.fold_pat((*p).clone())).collect()
|
||||
}).collect();
|
||||
let mut matches = Vec::new();
|
||||
for arm_data in arm_datas.iter() {
|
||||
matches.extend(arm_data.arm.pats.iter().map(|&p| Match {
|
||||
pats: vec![static_inliner.fold_pat(p)],
|
||||
for (arm_data, pats) in arm_datas.iter().zip(arm_pats.iter()) {
|
||||
matches.extend(pats.iter().map(|p| Match {
|
||||
pats: vec![&**p],
|
||||
data: arm_data,
|
||||
bound_ptrs: Vec::new(),
|
||||
}));
|
||||
|
|
@ -1404,11 +1408,25 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
let _icx = push_ctxt("match::store_local");
|
||||
let mut bcx = bcx;
|
||||
let tcx = bcx.tcx();
|
||||
let pat = local.pat;
|
||||
let opt_init_expr = local.init;
|
||||
let pat = &*local.pat;
|
||||
|
||||
return match opt_init_expr {
|
||||
Some(init_expr) => {
|
||||
fn create_dummy_locals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
pat: &ast::Pat)
|
||||
-> Block<'blk, 'tcx> {
|
||||
// create dummy memory for the variables if we have no
|
||||
// value to store into them immediately
|
||||
let tcx = bcx.tcx();
|
||||
pat_bindings(&tcx.def_map, pat, |_, p_id, _, path1| {
|
||||
let scope = cleanup::var_scope(tcx, p_id);
|
||||
bcx = mk_binding_alloca(
|
||||
bcx, p_id, &path1.node, BindLocal, scope, (),
|
||||
|(), bcx, llval, ty| { zero_mem(bcx, llval, ty); bcx });
|
||||
});
|
||||
bcx
|
||||
}
|
||||
|
||||
match local.init {
|
||||
Some(ref init_expr) => {
|
||||
// Optimize the "let x = expr" case. This just writes
|
||||
// the result of evaluating `expr` directly into the alloca
|
||||
// for `x`. Often the general path results in similar or the
|
||||
|
|
@ -1424,7 +1442,7 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
let var_scope = cleanup::var_scope(tcx, local.id);
|
||||
return mk_binding_alloca(
|
||||
bcx, pat.id, ident, BindLocal, var_scope, (),
|
||||
|(), bcx, v, _| expr::trans_into(bcx, &*init_expr,
|
||||
|(), bcx, v, _| expr::trans_into(bcx, &**init_expr,
|
||||
expr::SaveIn(v)));
|
||||
}
|
||||
|
||||
|
|
@ -1433,8 +1451,8 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
|
||||
// General path.
|
||||
let init_datum =
|
||||
unpack_datum!(bcx, expr::trans_to_lvalue(bcx, &*init_expr, "let"));
|
||||
if ty::type_is_bot(expr_ty(bcx, &*init_expr)) {
|
||||
unpack_datum!(bcx, expr::trans_to_lvalue(bcx, &**init_expr, "let"));
|
||||
if ty::type_is_bot(expr_ty(bcx, &**init_expr)) {
|
||||
create_dummy_locals(bcx, pat)
|
||||
} else {
|
||||
if bcx.sess().asm_comments() {
|
||||
|
|
@ -1447,26 +1465,11 @@ pub fn store_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
None => {
|
||||
create_dummy_locals(bcx, pat)
|
||||
}
|
||||
};
|
||||
|
||||
fn create_dummy_locals<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
pat: Gc<ast::Pat>)
|
||||
-> Block<'blk, 'tcx> {
|
||||
// create dummy memory for the variables if we have no
|
||||
// value to store into them immediately
|
||||
let tcx = bcx.tcx();
|
||||
pat_bindings(&tcx.def_map, &*pat, |_, p_id, _, path1| {
|
||||
let scope = cleanup::var_scope(tcx, p_id);
|
||||
bcx = mk_binding_alloca(
|
||||
bcx, p_id, &path1.node, BindLocal, scope, (),
|
||||
|(), bcx, llval, ty| { zero_mem(bcx, llval, ty); bcx });
|
||||
});
|
||||
bcx
|
||||
}
|
||||
}
|
||||
|
||||
pub fn store_arg<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
pat: Gc<ast::Pat>,
|
||||
pat: &ast::Pat,
|
||||
arg: Datum<Rvalue>,
|
||||
arg_scope: cleanup::ScopeId)
|
||||
-> Block<'blk, 'tcx> {
|
||||
|
|
@ -1520,7 +1523,7 @@ pub fn store_arg<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
/// Generates code for the pattern binding in a `for` loop like
|
||||
/// `for <pat> in <expr> { ... }`.
|
||||
pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
pat: Gc<ast::Pat>,
|
||||
pat: &ast::Pat,
|
||||
llvalue: ValueRef,
|
||||
body_scope: cleanup::ScopeId)
|
||||
-> Block<'blk, 'tcx> {
|
||||
|
|
@ -1573,7 +1576,7 @@ fn mk_binding_alloca<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
|
|||
}
|
||||
|
||||
fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
pat: Gc<ast::Pat>,
|
||||
pat: &ast::Pat,
|
||||
val: ValueRef,
|
||||
binding_mode: IrrefutablePatternBindingMode,
|
||||
cleanup_scope: cleanup::ScopeId)
|
||||
|
|
@ -1611,7 +1614,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
let tcx = bcx.tcx();
|
||||
let ccx = bcx.ccx();
|
||||
match pat.node {
|
||||
ast::PatIdent(pat_binding_mode, ref path1, inner) => {
|
||||
ast::PatIdent(pat_binding_mode, ref path1, ref inner) => {
|
||||
if pat_is_binding(&tcx.def_map, &*pat) {
|
||||
// Allocate the stack slot where the value of this
|
||||
// binding will live and place it into the appropriate
|
||||
|
|
@ -1637,8 +1640,8 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
});
|
||||
}
|
||||
|
||||
for &inner_pat in inner.iter() {
|
||||
bcx = bind_irrefutable_pat(bcx, inner_pat, val,
|
||||
for inner_pat in inner.iter() {
|
||||
bcx = bind_irrefutable_pat(bcx, &**inner_pat, val,
|
||||
binding_mode, cleanup_scope);
|
||||
}
|
||||
}
|
||||
|
|
@ -1655,9 +1658,9 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
vinfo.disr_val,
|
||||
val);
|
||||
for sub_pat in sub_pats.iter() {
|
||||
for (i, argval) in args.vals.iter().enumerate() {
|
||||
bcx = bind_irrefutable_pat(bcx, *sub_pat.get(i),
|
||||
*argval, binding_mode,
|
||||
for (i, &argval) in args.vals.iter().enumerate() {
|
||||
bcx = bind_irrefutable_pat(bcx, &**sub_pat.get(i),
|
||||
argval, binding_mode,
|
||||
cleanup_scope);
|
||||
}
|
||||
}
|
||||
|
|
@ -1674,7 +1677,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
for (i, elem) in elems.iter().enumerate() {
|
||||
let fldptr = adt::trans_field_ptr(bcx, &*repr,
|
||||
val, 0, i);
|
||||
bcx = bind_irrefutable_pat(bcx, *elem,
|
||||
bcx = bind_irrefutable_pat(bcx, &**elem,
|
||||
fldptr, binding_mode,
|
||||
cleanup_scope);
|
||||
}
|
||||
|
|
@ -1695,7 +1698,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
let ix = ty::field_idx_strict(tcx, f.ident.name, field_tys);
|
||||
let fldptr = adt::trans_field_ptr(bcx, &*pat_repr, val,
|
||||
discr, ix);
|
||||
bcx = bind_irrefutable_pat(bcx, f.pat, fldptr,
|
||||
bcx = bind_irrefutable_pat(bcx, &*f.pat, fldptr,
|
||||
binding_mode, cleanup_scope);
|
||||
}
|
||||
})
|
||||
|
|
@ -1704,17 +1707,17 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
let repr = adt::represent_node(bcx, pat.id);
|
||||
for (i, elem) in elems.iter().enumerate() {
|
||||
let fldptr = adt::trans_field_ptr(bcx, &*repr, val, 0, i);
|
||||
bcx = bind_irrefutable_pat(bcx, *elem, fldptr,
|
||||
bcx = bind_irrefutable_pat(bcx, &**elem, fldptr,
|
||||
binding_mode, cleanup_scope);
|
||||
}
|
||||
}
|
||||
ast::PatBox(inner) => {
|
||||
ast::PatBox(ref inner) => {
|
||||
let llbox = Load(bcx, val);
|
||||
bcx = bind_irrefutable_pat(bcx, inner, llbox, binding_mode, cleanup_scope);
|
||||
bcx = bind_irrefutable_pat(bcx, &**inner, llbox, binding_mode, cleanup_scope);
|
||||
}
|
||||
ast::PatRegion(inner) => {
|
||||
ast::PatRegion(ref inner) => {
|
||||
let loaded_val = Load(bcx, val);
|
||||
bcx = bind_irrefutable_pat(bcx, inner, loaded_val, binding_mode, cleanup_scope);
|
||||
bcx = bind_irrefutable_pat(bcx, &**inner, loaded_val, binding_mode, cleanup_scope);
|
||||
}
|
||||
ast::PatVec(ref before, ref slice, ref after) => {
|
||||
let pat_ty = node_id_type(bcx, pat.id);
|
||||
|
|
@ -1733,8 +1736,8 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
.chain(slice.iter())
|
||||
.chain(after.iter())
|
||||
.zip(extracted.vals.move_iter())
|
||||
.fold(bcx, |bcx, (&inner, elem)|
|
||||
bind_irrefutable_pat(bcx, inner, elem, binding_mode, cleanup_scope)
|
||||
.fold(bcx, |bcx, (inner, elem)|
|
||||
bind_irrefutable_pat(bcx, &**inner, elem, binding_mode, cleanup_scope)
|
||||
);
|
||||
}
|
||||
ast::PatMac(..) => {
|
||||
|
|
|
|||
|
|
@ -67,10 +67,10 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
|
|||
let in_datum = unpack_datum!(bcx, expr::trans(bcx, &**input));
|
||||
unpack_result!(bcx, {
|
||||
callee::trans_arg_datum(bcx,
|
||||
expr_ty(bcx, &**input),
|
||||
in_datum,
|
||||
cleanup::CustomScope(temp_scope),
|
||||
callee::DontAutorefArg)
|
||||
expr_ty(bcx, &**input),
|
||||
in_datum,
|
||||
cleanup::CustomScope(temp_scope),
|
||||
callee::DontAutorefArg)
|
||||
})
|
||||
}).collect::<Vec<_>>().append(ext_inputs.as_slice());
|
||||
|
||||
|
|
|
|||
|
|
@ -1356,7 +1356,7 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
|
|||
match tcx.map.find(id) {
|
||||
Some(ast_map::NodeItem(i)) => {
|
||||
match i.node {
|
||||
ast::ItemFn(_, _, _, _, blk) => {
|
||||
ast::ItemFn(_, _, _, _, ref blk) => {
|
||||
let mut explicit = CheckForNestedReturnsVisitor::explicit();
|
||||
let mut implicit = CheckForNestedReturnsVisitor::implicit();
|
||||
visit::walk_item(&mut explicit, &*i);
|
||||
|
|
@ -1368,12 +1368,12 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
|
|||
}
|
||||
Some(ast_map::NodeTraitItem(trait_method)) => {
|
||||
match *trait_method {
|
||||
ast::ProvidedMethod(m) => {
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
match m.node {
|
||||
ast::MethDecl(_, _, _, _, _, _, blk, _) => {
|
||||
ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
|
||||
let mut explicit = CheckForNestedReturnsVisitor::explicit();
|
||||
let mut implicit = CheckForNestedReturnsVisitor::implicit();
|
||||
visit::walk_method_helper(&mut explicit, &*m);
|
||||
visit::walk_method_helper(&mut explicit, &**m);
|
||||
visit::walk_expr_opt(&mut implicit, &blk.expr);
|
||||
explicit.found || implicit.found
|
||||
}
|
||||
|
|
@ -1386,11 +1386,11 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
|
|||
}
|
||||
}
|
||||
}
|
||||
Some(ast_map::NodeImplItem(ref ii)) => {
|
||||
match **ii {
|
||||
Some(ast_map::NodeImplItem(ii)) => {
|
||||
match *ii {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
match m.node {
|
||||
ast::MethDecl(_, _, _, _, _, _, blk, _) => {
|
||||
ast::MethDecl(_, _, _, _, _, _, ref blk, _) => {
|
||||
let mut explicit = CheckForNestedReturnsVisitor::explicit();
|
||||
let mut implicit = CheckForNestedReturnsVisitor::implicit();
|
||||
visit::walk_method_helper(&mut explicit, &**m);
|
||||
|
|
@ -1404,12 +1404,12 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
|
|||
}
|
||||
Some(ast_map::NodeExpr(e)) => {
|
||||
match e.node {
|
||||
ast::ExprFnBlock(_, _, blk) |
|
||||
ast::ExprProc(_, blk) |
|
||||
ast::ExprUnboxedFn(_, _, _, blk) => {
|
||||
ast::ExprFnBlock(_, _, ref blk) |
|
||||
ast::ExprProc(_, ref blk) |
|
||||
ast::ExprUnboxedFn(_, _, _, ref blk) => {
|
||||
let mut explicit = CheckForNestedReturnsVisitor::explicit();
|
||||
let mut implicit = CheckForNestedReturnsVisitor::implicit();
|
||||
visit::walk_expr(&mut explicit, &*e);
|
||||
visit::walk_expr(&mut explicit, e);
|
||||
visit::walk_expr_opt(&mut implicit, &blk.expr);
|
||||
explicit.found || implicit.found
|
||||
}
|
||||
|
|
@ -1649,7 +1649,7 @@ fn copy_args_to_allocas<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>,
|
|||
// This alloca should be optimized away by LLVM's mem-to-reg pass in
|
||||
// the event it's not truly needed.
|
||||
|
||||
bcx = _match::store_arg(bcx, args[i].pat, arg_datum, arg_scope_id);
|
||||
bcx = _match::store_arg(bcx, &*args[i].pat, arg_datum, arg_scope_id);
|
||||
|
||||
if fcx.ccx.sess().opts.debuginfo == FullDebugInfo {
|
||||
debuginfo::create_argument_metadata(bcx, &args[i]);
|
||||
|
|
@ -1701,7 +1701,7 @@ fn copy_unboxed_closure_args_to_allocas<'blk, 'tcx>(
|
|||
tuple_element_datum.to_rvalue_datum(bcx,
|
||||
"arg"));
|
||||
bcx = _match::store_arg(bcx,
|
||||
args[j].pat,
|
||||
&*args[j].pat,
|
||||
tuple_element_datum,
|
||||
arg_scope_id);
|
||||
|
||||
|
|
@ -2008,7 +2008,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
if !type_is_zero_size(ccx, result_ty) {
|
||||
match args {
|
||||
callee::ArgExprs(exprs) => {
|
||||
let fields = exprs.iter().map(|x| *x).enumerate().collect::<Vec<_>>();
|
||||
let fields = exprs.iter().map(|x| &**x).enumerate().collect::<Vec<_>>();
|
||||
bcx = expr::trans_adt(bcx, result_ty, disr, fields.as_slice(),
|
||||
None, expr::SaveIn(llresult));
|
||||
}
|
||||
|
|
@ -2792,15 +2792,15 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
|||
ccx.sess().bug("unexpected variant: required trait method in \
|
||||
get_item_val()");
|
||||
}
|
||||
ast::ProvidedMethod(m) => {
|
||||
register_method(ccx, id, &*m)
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
register_method(ccx, id, &**m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ast_map::NodeImplItem(ii) => {
|
||||
match *ii {
|
||||
ast::MethodImplItem(m) => register_method(ccx, id, &*m),
|
||||
ast::MethodImplItem(ref m) => register_method(ccx, id, &**m),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3042,9 +3042,10 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn trans_crate(krate: ast::Crate,
|
||||
analysis: CrateAnalysis) -> (ty::ctxt, CrateTranslation) {
|
||||
pub fn trans_crate<'tcx>(analysis: CrateAnalysis<'tcx>)
|
||||
-> (ty::ctxt<'tcx>, CrateTranslation) {
|
||||
let CrateAnalysis { ty_cx: tcx, exp_map2, reachable, name, .. } = analysis;
|
||||
let krate = tcx.map.krate();
|
||||
|
||||
// Before we touch LLVM, make sure that multithreading is enabled.
|
||||
unsafe {
|
||||
|
|
@ -3064,7 +3065,7 @@ pub fn trans_crate(krate: ast::Crate,
|
|||
}
|
||||
}
|
||||
|
||||
let link_meta = link::build_link_meta(&tcx.sess, &krate, name);
|
||||
let link_meta = link::build_link_meta(&tcx.sess, krate, name);
|
||||
|
||||
let codegen_units = tcx.sess.opts.cg.codegen_units;
|
||||
let shared_ccx = SharedCrateContext::new(link_meta.crate_name.as_slice(),
|
||||
|
|
@ -3096,7 +3097,7 @@ pub fn trans_crate(krate: ast::Crate,
|
|||
}
|
||||
|
||||
// Translate the metadata.
|
||||
let metadata = write_metadata(&shared_ccx, &krate);
|
||||
let metadata = write_metadata(&shared_ccx, krate);
|
||||
|
||||
if shared_ccx.sess().trans_stats() {
|
||||
let stats = shared_ccx.stats();
|
||||
|
|
|
|||
|
|
@ -53,10 +53,10 @@ use middle::typeck::MethodCall;
|
|||
use util::ppaux::Repr;
|
||||
use util::ppaux::ty_to_string;
|
||||
|
||||
use std::gc::Gc;
|
||||
use syntax::abi as synabi;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::ptr::P;
|
||||
|
||||
pub struct MethodData {
|
||||
pub llfn: ValueRef,
|
||||
|
|
@ -902,7 +902,7 @@ pub fn trans_call_inner<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
pub enum CallArgs<'a> {
|
||||
// Supply value of arguments as a list of expressions that must be
|
||||
// translated. This is used in the common case of `foo(bar, qux)`.
|
||||
ArgExprs(&'a [Gc<ast::Expr>]),
|
||||
ArgExprs(&'a [P<ast::Expr>]),
|
||||
|
||||
// Supply value of arguments as a list of LLVM value refs; frequently
|
||||
// used with lang items and so forth, when the argument is an internal
|
||||
|
|
@ -916,12 +916,12 @@ pub enum CallArgs<'a> {
|
|||
|
||||
// Supply value of arguments as a list of expressions that must be
|
||||
// translated, for overloaded call operators.
|
||||
ArgOverloadedCall(&'a [Gc<ast::Expr>]),
|
||||
ArgOverloadedCall(Vec<&'a ast::Expr>),
|
||||
}
|
||||
|
||||
fn trans_args_under_call_abi<'blk, 'tcx>(
|
||||
mut bcx: Block<'blk, 'tcx>,
|
||||
arg_exprs: &[Gc<ast::Expr>],
|
||||
arg_exprs: &[P<ast::Expr>],
|
||||
fn_ty: ty::t,
|
||||
llargs: &mut Vec<ValueRef>,
|
||||
arg_cleanup_scope: cleanup::ScopeId,
|
||||
|
|
@ -941,13 +941,13 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
|
|||
}
|
||||
|
||||
// Now untuple the rest of the arguments.
|
||||
let tuple_expr = arg_exprs[1];
|
||||
let tuple_expr = &arg_exprs[1];
|
||||
let tuple_type = node_id_type(bcx, tuple_expr.id);
|
||||
|
||||
match ty::get(tuple_type).sty {
|
||||
ty::ty_tup(ref field_types) => {
|
||||
let tuple_datum = unpack_datum!(bcx,
|
||||
expr::trans(bcx, &*tuple_expr));
|
||||
expr::trans(bcx, &**tuple_expr));
|
||||
let tuple_lvalue_datum =
|
||||
unpack_datum!(bcx,
|
||||
tuple_datum.to_lvalue_datum(bcx,
|
||||
|
|
@ -982,7 +982,7 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
|
|||
|
||||
fn trans_overloaded_call_args<'blk, 'tcx>(
|
||||
mut bcx: Block<'blk, 'tcx>,
|
||||
arg_exprs: &[Gc<ast::Expr>],
|
||||
arg_exprs: Vec<&ast::Expr>,
|
||||
fn_ty: ty::t,
|
||||
llargs: &mut Vec<ValueRef>,
|
||||
arg_cleanup_scope: cleanup::ScopeId,
|
||||
|
|
@ -991,7 +991,7 @@ fn trans_overloaded_call_args<'blk, 'tcx>(
|
|||
// Translate the `self` argument first.
|
||||
let arg_tys = ty::ty_fn_args(fn_ty);
|
||||
if !ignore_self {
|
||||
let arg_datum = unpack_datum!(bcx, expr::trans(bcx, &*arg_exprs[0]));
|
||||
let arg_datum = unpack_datum!(bcx, expr::trans(bcx, arg_exprs[0]));
|
||||
llargs.push(unpack_result!(bcx, {
|
||||
trans_arg_datum(bcx,
|
||||
*arg_tys.get(0),
|
||||
|
|
@ -1007,7 +1007,7 @@ fn trans_overloaded_call_args<'blk, 'tcx>(
|
|||
ty::ty_tup(ref field_types) => {
|
||||
for (i, &field_type) in field_types.iter().enumerate() {
|
||||
let arg_datum =
|
||||
unpack_datum!(bcx, expr::trans(bcx, &*arg_exprs[i + 1]));
|
||||
unpack_datum!(bcx, expr::trans(bcx, arg_exprs[i + 1]));
|
||||
llargs.push(unpack_result!(bcx, {
|
||||
trans_arg_datum(bcx,
|
||||
field_type,
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
|
|||
|
||||
pub fn def(&self, nid: ast::NodeId) -> def::Def {
|
||||
match self.tcx().def_map.borrow().find(&nid) {
|
||||
Some(&v) => v,
|
||||
Some(v) => v.clone(),
|
||||
None => {
|
||||
self.tcx().sess.bug(format!(
|
||||
"no def associated with node id {:?}", nid).as_slice());
|
||||
|
|
|
|||
|
|
@ -33,12 +33,12 @@ use middle::ty;
|
|||
use util::ppaux::{Repr, ty_to_string};
|
||||
|
||||
use std::c_str::ToCStr;
|
||||
use std::gc::Gc;
|
||||
use std::vec;
|
||||
use libc::c_uint;
|
||||
use syntax::{ast, ast_util};
|
||||
use syntax::ptr::P;
|
||||
|
||||
pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
|
||||
pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
|
||||
-> ValueRef {
|
||||
let _icx = push_ctxt("trans_lit");
|
||||
debug!("const_lit: {}", lit);
|
||||
|
|
@ -102,7 +102,7 @@ fn first_two<R, S, T>((a, b, _): (R, S, T)) -> (R, S) {
|
|||
}
|
||||
|
||||
fn const_vec(cx: &CrateContext, e: &ast::Expr,
|
||||
es: &[Gc<ast::Expr>], is_local: bool) -> (ValueRef, Type, bool) {
|
||||
es: &[P<ast::Expr>], is_local: bool) -> (ValueRef, Type, bool) {
|
||||
let vec_ty = ty::expr_ty(cx.tcx(), e);
|
||||
let unit_ty = ty::sequence_element_type(cx.tcx(), vec_ty);
|
||||
let llunitty = type_of::type_of(cx, unit_ty);
|
||||
|
|
@ -321,7 +321,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
|
|||
// if it's assigned to a static.
|
||||
fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
is_local: bool) -> (ValueRef, bool) {
|
||||
let map_list = |exprs: &[Gc<ast::Expr>]| {
|
||||
let map_list = |exprs: &[P<ast::Expr>]| {
|
||||
exprs.iter().map(|e| first_two(const_expr(cx, &**e, is_local)))
|
||||
.fold((Vec::new(), true),
|
||||
|(l, all_inlineable), (val, inlineable)| {
|
||||
|
|
@ -332,7 +332,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
let _icx = push_ctxt("const_expr");
|
||||
return match e.node {
|
||||
ast::ExprLit(ref lit) => {
|
||||
(consts::const_lit(cx, e, (**lit).clone()), true)
|
||||
(consts::const_lit(cx, e, &**lit), true)
|
||||
}
|
||||
ast::ExprBinary(b, ref e1, ref e2) => {
|
||||
let (te1, _, _) = const_expr(cx, &**e1, is_local);
|
||||
|
|
@ -653,7 +653,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
|||
}
|
||||
}
|
||||
}
|
||||
ast::ExprCall(callee, ref args) => {
|
||||
ast::ExprCall(ref callee, ref args) => {
|
||||
let opt_def = cx.tcx().def_map.borrow().find_copy(&callee.id);
|
||||
match opt_def {
|
||||
Some(def::DefStruct(_)) => {
|
||||
|
|
|
|||
|
|
@ -39,8 +39,6 @@ use syntax::parse::token::InternedString;
|
|||
use syntax::parse::token;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
use std::gc::Gc;
|
||||
|
||||
pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
|
||||
s: &ast::Stmt)
|
||||
-> Block<'blk, 'tcx> {
|
||||
|
|
@ -61,7 +59,7 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
|
|||
ast::StmtExpr(ref e, _) | ast::StmtSemi(ref e, _) => {
|
||||
bcx = trans_stmt_semi(bcx, &**e);
|
||||
}
|
||||
ast::StmtDecl(d, _) => {
|
||||
ast::StmtDecl(ref d, _) => {
|
||||
match d.node {
|
||||
ast::DeclLocal(ref local) => {
|
||||
bcx = init_local(bcx, &**local);
|
||||
|
|
@ -132,8 +130,8 @@ pub fn trans_block<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
if_id: ast::NodeId,
|
||||
cond: &ast::Expr,
|
||||
thn: ast::P<ast::Block>,
|
||||
els: Option<Gc<ast::Expr>>,
|
||||
thn: &ast::Block,
|
||||
els: Option<&ast::Expr>,
|
||||
dest: expr::Dest)
|
||||
-> Block<'blk, 'tcx> {
|
||||
debug!("trans_if(bcx={}, if_id={}, cond={}, thn={:?}, dest={})",
|
||||
|
|
@ -251,7 +249,7 @@ pub fn trans_while<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
/// Translates a `for` loop.
|
||||
pub fn trans_for<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
loop_info: NodeInfo,
|
||||
pat: Gc<ast::Pat>,
|
||||
pat: &ast::Pat,
|
||||
head: &ast::Expr,
|
||||
body: &ast::Block)
|
||||
-> Block<'blk, 'tcx> {
|
||||
|
|
@ -453,7 +451,7 @@ pub fn trans_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
}
|
||||
|
||||
pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
e: Option<Gc<ast::Expr>>)
|
||||
e: Option<&ast::Expr>)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("trans_ret");
|
||||
let fcx = bcx.fcx;
|
||||
|
|
|
|||
|
|
@ -207,7 +207,6 @@ use std::c_str::{CString, ToCStr};
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::gc::Gc;
|
||||
use std::ptr;
|
||||
use std::rc::{Rc, Weak};
|
||||
use syntax::util::interner::Interner;
|
||||
|
|
@ -1129,8 +1128,8 @@ pub fn create_function_debug_context(cx: &CrateContext,
|
|||
}
|
||||
|
||||
match item.node {
|
||||
ast::ItemFn(fn_decl, _, _, ref generics, top_level_block) => {
|
||||
(item.ident, fn_decl, generics, top_level_block, item.span, true)
|
||||
ast::ItemFn(ref fn_decl, _, _, ref generics, ref top_level_block) => {
|
||||
(item.ident, &**fn_decl, generics, &**top_level_block, item.span, true)
|
||||
}
|
||||
_ => {
|
||||
cx.sess().span_bug(item.span,
|
||||
|
|
@ -1158,16 +1157,16 @@ pub fn create_function_debug_context(cx: &CrateContext,
|
|||
}
|
||||
ast_map::NodeExpr(ref expr) => {
|
||||
match expr.node {
|
||||
ast::ExprFnBlock(_, fn_decl, top_level_block) |
|
||||
ast::ExprProc(fn_decl, top_level_block) |
|
||||
ast::ExprUnboxedFn(_, _, fn_decl, top_level_block) => {
|
||||
ast::ExprFnBlock(_, ref fn_decl, ref top_level_block) |
|
||||
ast::ExprProc(ref fn_decl, ref top_level_block) |
|
||||
ast::ExprUnboxedFn(_, _, ref fn_decl, ref top_level_block) => {
|
||||
let name = format!("fn{}", token::gensym("fn"));
|
||||
let name = token::str_to_ident(name.as_slice());
|
||||
(name, fn_decl,
|
||||
(name, &**fn_decl,
|
||||
// This is not quite right. It should actually inherit
|
||||
// the generics of the enclosing function.
|
||||
&empty_generics,
|
||||
top_level_block,
|
||||
&**top_level_block,
|
||||
expr.span,
|
||||
// Don't try to lookup the item path:
|
||||
false)
|
||||
|
|
@ -1287,9 +1286,8 @@ pub fn create_function_debug_context(cx: &CrateContext,
|
|||
source_locations_enabled: Cell::new(false),
|
||||
};
|
||||
|
||||
let arg_pats = fn_decl.inputs.iter().map(|arg_ref| arg_ref.pat).collect::<Vec<_>>();
|
||||
populate_scope_map(cx,
|
||||
arg_pats.as_slice(),
|
||||
fn_decl.inputs.as_slice(),
|
||||
&*top_level_block,
|
||||
fn_metadata,
|
||||
&mut *fn_debug_context.scope_map.borrow_mut());
|
||||
|
|
@ -3169,7 +3167,7 @@ fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId)
|
|||
// introducing *artificial* lexical scope descriptors where necessary. These
|
||||
// artificial scopes allow GDB to correctly handle name shadowing.
|
||||
fn populate_scope_map(cx: &CrateContext,
|
||||
arg_pats: &[Gc<ast::Pat>],
|
||||
args: &[ast::Arg],
|
||||
fn_entry_block: &ast::Block,
|
||||
fn_metadata: DISubprogram,
|
||||
scope_map: &mut HashMap<ast::NodeId, DIScope>) {
|
||||
|
|
@ -3185,8 +3183,8 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
|
||||
// Push argument identifiers onto the stack so arguments integrate nicely
|
||||
// with variable shadowing.
|
||||
for &arg_pat in arg_pats.iter() {
|
||||
pat_util::pat_bindings(def_map, &*arg_pat, |_, _, _, path1| {
|
||||
for arg in args.iter() {
|
||||
pat_util::pat_bindings(def_map, &*arg.pat, |_, _, _, path1| {
|
||||
scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
|
||||
ident: Some(path1.node) });
|
||||
})
|
||||
|
|
@ -3272,10 +3270,10 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
scope_stack: &mut Vec<ScopeStackEntry> ,
|
||||
scope_map: &mut HashMap<ast::NodeId, DIScope>) {
|
||||
match *decl {
|
||||
codemap::Spanned { node: ast::DeclLocal(local), .. } => {
|
||||
codemap::Spanned { node: ast::DeclLocal(ref local), .. } => {
|
||||
scope_map.insert(local.id, scope_stack.last().unwrap().scope_metadata);
|
||||
|
||||
walk_pattern(cx, local.pat, scope_stack, scope_map);
|
||||
walk_pattern(cx, &*local.pat, scope_stack, scope_map);
|
||||
|
||||
for exp in local.init.iter() {
|
||||
walk_expr(cx, &**exp, scope_stack, scope_map);
|
||||
|
|
@ -3286,7 +3284,7 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
}
|
||||
|
||||
fn walk_pattern(cx: &CrateContext,
|
||||
pat: Gc<ast::Pat>,
|
||||
pat: &ast::Pat,
|
||||
scope_stack: &mut Vec<ScopeStackEntry> ,
|
||||
scope_map: &mut HashMap<ast::NodeId, DIScope>) {
|
||||
|
||||
|
|
@ -3367,8 +3365,8 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
|
||||
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
|
||||
|
||||
for &sub_pat in sub_pat_opt.iter() {
|
||||
walk_pattern(cx, sub_pat, scope_stack, scope_map);
|
||||
for sub_pat in sub_pat_opt.iter() {
|
||||
walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3379,9 +3377,9 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
ast::PatEnum(_, ref sub_pats_opt) => {
|
||||
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
|
||||
|
||||
for ref sub_pats in sub_pats_opt.iter() {
|
||||
for &p in sub_pats.iter() {
|
||||
walk_pattern(cx, p, scope_stack, scope_map);
|
||||
for sub_pats in sub_pats_opt.iter() {
|
||||
for p in sub_pats.iter() {
|
||||
walk_pattern(cx, &**p, scope_stack, scope_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3389,8 +3387,8 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
ast::PatStruct(_, ref field_pats, _) => {
|
||||
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
|
||||
|
||||
for &ast::FieldPat { pat: sub_pat, .. } in field_pats.iter() {
|
||||
walk_pattern(cx, sub_pat, scope_stack, scope_map);
|
||||
for &ast::FieldPat { pat: ref sub_pat, .. } in field_pats.iter() {
|
||||
walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3398,13 +3396,13 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
|
||||
|
||||
for sub_pat in sub_pats.iter() {
|
||||
walk_pattern(cx, sub_pat.clone(), scope_stack, scope_map);
|
||||
walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
|
||||
}
|
||||
}
|
||||
|
||||
ast::PatBox(ref sub_pat) | ast::PatRegion(ref sub_pat) => {
|
||||
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
|
||||
walk_pattern(cx, sub_pat.clone(), scope_stack, scope_map);
|
||||
walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
ast::PatLit(ref exp) => {
|
||||
|
|
@ -3421,16 +3419,16 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
ast::PatVec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => {
|
||||
scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
|
||||
|
||||
for &sub_pat in front_sub_pats.iter() {
|
||||
walk_pattern(cx, sub_pat, scope_stack, scope_map);
|
||||
for sub_pat in front_sub_pats.iter() {
|
||||
walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
for &sub_pat in middle_sub_pats.iter() {
|
||||
walk_pattern(cx, sub_pat, scope_stack, scope_map);
|
||||
for sub_pat in middle_sub_pats.iter() {
|
||||
walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
for &sub_pat in back_sub_pats.iter() {
|
||||
walk_pattern(cx, sub_pat, scope_stack, scope_map);
|
||||
for sub_pat in back_sub_pats.iter() {
|
||||
walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3466,8 +3464,8 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
walk_expr(cx, &**sub_expr, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
ast::ExprRet(exp_opt) => match exp_opt {
|
||||
Some(sub_exp) => walk_expr(cx, &*sub_exp, scope_stack, scope_map),
|
||||
ast::ExprRet(ref exp_opt) => match *exp_opt {
|
||||
Some(ref sub_exp) => walk_expr(cx, &**sub_exp, scope_stack, scope_map),
|
||||
None => ()
|
||||
},
|
||||
|
||||
|
|
@ -3538,7 +3536,7 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
.unwrap()
|
||||
.scope_metadata);
|
||||
walk_pattern(cx,
|
||||
*pattern,
|
||||
&**pattern,
|
||||
scope_stack,
|
||||
scope_map);
|
||||
walk_block(cx, &**body, scope_stack, scope_map);
|
||||
|
|
@ -3570,7 +3568,7 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
scope_map,
|
||||
|cx, scope_stack, scope_map| {
|
||||
for &ast::Arg { pat: ref pattern, .. } in decl.inputs.iter() {
|
||||
walk_pattern(cx, pattern.clone(), scope_stack, scope_map);
|
||||
walk_pattern(cx, &**pattern, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
walk_block(cx, &**block, scope_stack, scope_map);
|
||||
|
|
@ -3607,8 +3605,8 @@ fn populate_scope_map(cx: &CrateContext,
|
|||
scope_stack,
|
||||
scope_map,
|
||||
|cx, scope_stack, scope_map| {
|
||||
for &pat in arm_ref.pats.iter() {
|
||||
walk_pattern(cx, pat, scope_stack, scope_map);
|
||||
for pat in arm_ref.pats.iter() {
|
||||
walk_pattern(cx, &**pat, scope_stack, scope_map);
|
||||
}
|
||||
|
||||
for guard_exp in arm_ref.guard.iter() {
|
||||
|
|
|
|||
|
|
@ -77,8 +77,7 @@ use middle::trans::type_::Type;
|
|||
use syntax::ast;
|
||||
use syntax::codemap;
|
||||
use syntax::print::pprust::{expr_to_string};
|
||||
|
||||
use std::gc::Gc;
|
||||
use syntax::ptr::P;
|
||||
|
||||
// Destinations
|
||||
|
||||
|
|
@ -597,7 +596,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
}
|
||||
|
||||
}
|
||||
ast::ExprLit(ref lit) => trans_immediate_lit(bcx, expr, (**lit).clone()),
|
||||
ast::ExprLit(ref lit) => trans_immediate_lit(bcx, expr, &**lit),
|
||||
ast::ExprBinary(op, ref lhs, ref rhs) => {
|
||||
trans_binary(bcx, expr, op, &**lhs, &**rhs)
|
||||
}
|
||||
|
|
@ -882,8 +881,8 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
ast::ExprAgain(label_opt) => {
|
||||
controlflow::trans_cont(bcx, expr.id, label_opt)
|
||||
}
|
||||
ast::ExprRet(ex) => {
|
||||
controlflow::trans_ret(bcx, ex)
|
||||
ast::ExprRet(ref ex) => {
|
||||
controlflow::trans_ret(bcx, ex.as_ref().map(|e| &**e))
|
||||
}
|
||||
ast::ExprWhile(ref cond, ref body, _) => {
|
||||
controlflow::trans_while(bcx, expr.id, &**cond, &**body)
|
||||
|
|
@ -891,7 +890,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
ast::ExprForLoop(ref pat, ref head, ref body, _) => {
|
||||
controlflow::trans_for(bcx,
|
||||
expr_info(expr),
|
||||
*pat,
|
||||
&**pat,
|
||||
&**head,
|
||||
&**body)
|
||||
}
|
||||
|
|
@ -928,7 +927,7 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
}
|
||||
}
|
||||
ast::ExprAssignOp(op, ref dst, ref src) => {
|
||||
trans_assign_op(bcx, expr, op, &**dst, src.clone())
|
||||
trans_assign_op(bcx, expr, op, &**dst, &**src)
|
||||
}
|
||||
ast::ExprInlineAsm(ref a) => {
|
||||
asm::trans_inline_asm(bcx, a)
|
||||
|
|
@ -958,8 +957,8 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
ast::ExprPath(_) => {
|
||||
trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest)
|
||||
}
|
||||
ast::ExprIf(ref cond, ref thn, els) => {
|
||||
controlflow::trans_if(bcx, expr.id, &**cond, thn.clone(), els, dest)
|
||||
ast::ExprIf(ref cond, ref thn, ref els) => {
|
||||
controlflow::trans_if(bcx, expr.id, &**cond, &**thn, els.as_ref().map(|e| &**e), dest)
|
||||
}
|
||||
ast::ExprMatch(ref discr, ref arms) => {
|
||||
_match::trans_match(bcx, expr, &**discr, arms.as_slice(), dest)
|
||||
|
|
@ -967,20 +966,20 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
ast::ExprBlock(ref blk) => {
|
||||
controlflow::trans_block(bcx, &**blk, dest)
|
||||
}
|
||||
ast::ExprStruct(_, ref fields, base) => {
|
||||
ast::ExprStruct(_, ref fields, ref base) => {
|
||||
trans_struct(bcx,
|
||||
fields.as_slice(),
|
||||
base,
|
||||
base.as_ref().map(|e| &**e),
|
||||
expr.span,
|
||||
expr.id,
|
||||
dest)
|
||||
}
|
||||
ast::ExprTup(ref args) => {
|
||||
let numbered_fields: Vec<(uint, Gc<ast::Expr>)> =
|
||||
args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect();
|
||||
let numbered_fields: Vec<(uint, &ast::Expr)> =
|
||||
args.iter().enumerate().map(|(i, arg)| (i, &**arg)).collect();
|
||||
trans_adt(bcx, expr_ty(bcx, expr), 0, numbered_fields.as_slice(), None, dest)
|
||||
}
|
||||
ast::ExprLit(lit) => {
|
||||
ast::ExprLit(ref lit) => {
|
||||
match lit.node {
|
||||
ast::LitStr(ref s, _) => {
|
||||
tvec::trans_lit_str(bcx, expr, (*s).clone(), dest)
|
||||
|
|
@ -1005,14 +1004,14 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
expr_to_string(expr), expr_ty.repr(tcx));
|
||||
closure::trans_expr_fn(bcx, store, &**decl, &**body, expr.id, dest)
|
||||
}
|
||||
ast::ExprUnboxedFn(_, _, decl, body) => {
|
||||
closure::trans_unboxed_closure(bcx, &*decl, &*body, expr.id, dest)
|
||||
ast::ExprUnboxedFn(_, _, ref decl, ref body) => {
|
||||
closure::trans_unboxed_closure(bcx, &**decl, &**body, expr.id, dest)
|
||||
}
|
||||
ast::ExprCall(ref f, ref args) => {
|
||||
if bcx.tcx().is_method_call(expr.id) {
|
||||
trans_overloaded_call(bcx,
|
||||
expr,
|
||||
*f,
|
||||
&**f,
|
||||
args.as_slice(),
|
||||
Some(dest))
|
||||
} else {
|
||||
|
|
@ -1061,7 +1060,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
}
|
||||
}
|
||||
ast::ExprAssignOp(op, ref dst, ref src) => {
|
||||
trans_assign_op(bcx, expr, op, &**dst, src.clone())
|
||||
trans_assign_op(bcx, expr, op, &**dst, &**src)
|
||||
}
|
||||
_ => {
|
||||
bcx.tcx().sess.span_bug(
|
||||
|
|
@ -1263,7 +1262,7 @@ pub fn with_field_tys<R>(tcx: &ty::ctxt,
|
|||
|
||||
fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
fields: &[ast::Field],
|
||||
base: Option<Gc<ast::Expr>>,
|
||||
base: Option<&ast::Expr>,
|
||||
expr_span: codemap::Span,
|
||||
id: ast::NodeId,
|
||||
dest: Dest) -> Block<'blk, 'tcx> {
|
||||
|
|
@ -1281,7 +1280,7 @@ fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
match opt_pos {
|
||||
Some(i) => {
|
||||
*need_base.get_mut(i) = false;
|
||||
(i, field.expr)
|
||||
(i, &*field.expr)
|
||||
}
|
||||
None => {
|
||||
tcx.sess.span_bug(field.span,
|
||||
|
|
@ -1320,11 +1319,12 @@ fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
* Note that `fields` may be empty; the base expression must always be
|
||||
* evaluated for side-effects.
|
||||
*/
|
||||
pub struct StructBaseInfo {
|
||||
pub struct StructBaseInfo<'a> {
|
||||
/// The base expression; will be evaluated after all explicit fields.
|
||||
expr: Gc<ast::Expr>,
|
||||
expr: &'a ast::Expr,
|
||||
/// The indices of fields to copy paired with their types.
|
||||
fields: Vec<(uint, ty::t)> }
|
||||
fields: Vec<(uint, ty::t)>
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ADT instance:
|
||||
|
|
@ -1339,7 +1339,7 @@ pub struct StructBaseInfo {
|
|||
pub fn trans_adt<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
ty: ty::t,
|
||||
discr: ty::Disr,
|
||||
fields: &[(uint, Gc<ast::Expr>)],
|
||||
fields: &[(uint, &ast::Expr)],
|
||||
optbase: Option<StructBaseInfo>,
|
||||
dest: Dest) -> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("trans_adt");
|
||||
|
|
@ -1407,7 +1407,7 @@ pub fn trans_adt<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
|
||||
fn trans_immediate_lit<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
expr: &ast::Expr,
|
||||
lit: ast::Lit)
|
||||
lit: &ast::Lit)
|
||||
-> DatumBlock<'blk, 'tcx, Expr> {
|
||||
// must not be a string constant, that is a RvalueDpsExpr
|
||||
let _icx = push_ctxt("trans_immediate_lit");
|
||||
|
|
@ -1750,12 +1750,12 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
dest)
|
||||
}
|
||||
|
||||
fn trans_overloaded_call<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
expr: &ast::Expr,
|
||||
callee: Gc<ast::Expr>,
|
||||
args: &[Gc<ast::Expr>],
|
||||
dest: Option<Dest>)
|
||||
-> Block<'blk, 'tcx> {
|
||||
fn trans_overloaded_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||
expr: &ast::Expr,
|
||||
callee: &'a ast::Expr,
|
||||
args: &'a [P<ast::Expr>],
|
||||
dest: Option<Dest>)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let method_call = MethodCall::expr(expr.id);
|
||||
let method_type = bcx.tcx()
|
||||
.method_map
|
||||
|
|
@ -1763,7 +1763,7 @@ fn trans_overloaded_call<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
.get(&method_call)
|
||||
.ty;
|
||||
let mut all_args = vec!(callee);
|
||||
all_args.push_all(args);
|
||||
all_args.extend(args.iter().map(|e| &**e));
|
||||
unpack_result!(bcx,
|
||||
callee::trans_call_inner(bcx,
|
||||
Some(expr_info(expr)),
|
||||
|
|
@ -1776,8 +1776,7 @@ fn trans_overloaded_call<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||
None,
|
||||
arg_cleanup_scope)
|
||||
},
|
||||
callee::ArgOverloadedCall(
|
||||
all_args.as_slice()),
|
||||
callee::ArgOverloadedCall(all_args),
|
||||
dest));
|
||||
bcx
|
||||
}
|
||||
|
|
@ -1957,7 +1956,7 @@ fn trans_assign_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
expr: &ast::Expr,
|
||||
op: ast::BinOp,
|
||||
dst: &ast::Expr,
|
||||
src: Gc<ast::Expr>)
|
||||
src: &ast::Expr)
|
||||
-> Block<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("trans_assign_op");
|
||||
let mut bcx = bcx;
|
||||
|
|
|
|||
|
|
@ -47,12 +47,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
|
|||
ccx.external().borrow_mut().insert(fn_id, None);
|
||||
return None;
|
||||
}
|
||||
csearch::found(ast::IIItem(item)) => {
|
||||
csearch::found(&ast::IIItem(ref item)) => {
|
||||
ccx.external().borrow_mut().insert(fn_id, Some(item.id));
|
||||
ccx.external_srcs().borrow_mut().insert(item.id, fn_id);
|
||||
|
||||
ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
|
||||
trans_item(ccx, &*item);
|
||||
trans_item(ccx, &**item);
|
||||
|
||||
let linkage = match item.node {
|
||||
ast::ItemFn(_, _, _, ref generics, _) => {
|
||||
|
|
@ -104,12 +104,12 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
|
|||
|
||||
local_def(item.id)
|
||||
}
|
||||
csearch::found(ast::IIForeign(item)) => {
|
||||
csearch::found(&ast::IIForeign(ref item)) => {
|
||||
ccx.external().borrow_mut().insert(fn_id, Some(item.id));
|
||||
ccx.external_srcs().borrow_mut().insert(item.id, fn_id);
|
||||
local_def(item.id)
|
||||
}
|
||||
csearch::found_parent(parent_id, ast::IIItem(item)) => {
|
||||
csearch::found_parent(parent_id, &ast::IIItem(ref item)) => {
|
||||
ccx.external().borrow_mut().insert(parent_id, Some(item.id));
|
||||
ccx.external_srcs().borrow_mut().insert(item.id, parent_id);
|
||||
|
||||
|
|
@ -135,32 +135,37 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
|
|||
_ => ccx.sess().bug("maybe_instantiate_inline: item has a \
|
||||
non-enum, non-struct parent")
|
||||
}
|
||||
trans_item(ccx, &*item);
|
||||
trans_item(ccx, &**item);
|
||||
local_def(my_id)
|
||||
}
|
||||
csearch::found_parent(_, _) => {
|
||||
ccx.sess().bug("maybe_get_item_ast returned a found_parent \
|
||||
with a non-item parent");
|
||||
}
|
||||
csearch::found(ast::IITraitItem(impl_did, impl_item)) => {
|
||||
match impl_item {
|
||||
ast::ProvidedInlinedTraitItem(mth) |
|
||||
ast::RequiredInlinedTraitItem(mth) => {
|
||||
csearch::found(&ast::IITraitItem(_, ref trait_item)) => {
|
||||
match *trait_item {
|
||||
ast::RequiredMethod(_) => ccx.sess().bug("found RequiredMethod IITraitItem"),
|
||||
ast::ProvidedMethod(ref mth) => {
|
||||
ccx.external().borrow_mut().insert(fn_id, Some(mth.id));
|
||||
ccx.external_srcs().borrow_mut().insert(mth.id, fn_id);
|
||||
|
||||
ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
match impl_item {
|
||||
ast::ProvidedInlinedTraitItem(mth) => {
|
||||
// If this is a default method, we can't look up the
|
||||
// impl type. But we aren't going to translate anyways, so
|
||||
// don't.
|
||||
local_def(mth.id)
|
||||
}
|
||||
ast::RequiredInlinedTraitItem(mth) => {
|
||||
}
|
||||
}
|
||||
csearch::found(&ast::IIImplItem(impl_did, ref impl_item)) => {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(ref mth) => {
|
||||
ccx.external().borrow_mut().insert(fn_id, Some(mth.id));
|
||||
ccx.external_srcs().borrow_mut().insert(mth.id, fn_id);
|
||||
|
||||
ccx.stats().n_inlines.set(ccx.stats().n_inlines.get() + 1);
|
||||
|
||||
let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
|
||||
let unparameterized = impl_tpt.generics.types.is_empty() &&
|
||||
mth.pe_generics().ty_params.is_empty();
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ pub fn trans_impl(ccx: &CrateContext,
|
|||
let mut v = TransItemVisitor{ ccx: ccx };
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(method) => {
|
||||
visit::walk_method_helper(&mut v, &*method);
|
||||
ast::MethodImplItem(ref method) => {
|
||||
visit::walk_method_helper(&mut v, &**method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -75,14 +75,14 @@ pub fn trans_impl(ccx: &CrateContext,
|
|||
}
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(method) => {
|
||||
ast::MethodImplItem(ref method) => {
|
||||
if method.pe_generics().ty_params.len() == 0u {
|
||||
let trans_everywhere = attr::requests_inline(method.attrs.as_slice());
|
||||
for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) {
|
||||
let llfn = get_item_val(ccx, method.id);
|
||||
trans_fn(ccx,
|
||||
&*method.pe_fn_decl(),
|
||||
&*method.pe_body(),
|
||||
method.pe_fn_decl(),
|
||||
method.pe_body(),
|
||||
llfn,
|
||||
¶m_substs::empty(),
|
||||
method.id,
|
||||
|
|
@ -96,7 +96,7 @@ pub fn trans_impl(ccx: &CrateContext,
|
|||
let mut v = TransItemVisitor {
|
||||
ccx: ccx,
|
||||
};
|
||||
visit::walk_method_helper(&mut v, &*method);
|
||||
visit::walk_method_helper(&mut v, &**method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,13 +221,13 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
|||
}
|
||||
ast_map::NodeImplItem(ii) => {
|
||||
match *ii {
|
||||
ast::MethodImplItem(mth) => {
|
||||
ast::MethodImplItem(ref mth) => {
|
||||
let d = mk_lldecl(abi::Rust);
|
||||
let needs_body = setup_lldecl(d, mth.attrs.as_slice());
|
||||
if needs_body {
|
||||
trans_fn(ccx,
|
||||
&*mth.pe_fn_decl(),
|
||||
&*mth.pe_body(),
|
||||
mth.pe_fn_decl(),
|
||||
mth.pe_body(),
|
||||
d,
|
||||
&psubsts,
|
||||
mth.id,
|
||||
|
|
@ -239,11 +239,11 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
|||
}
|
||||
ast_map::NodeTraitItem(method) => {
|
||||
match *method {
|
||||
ast::ProvidedMethod(mth) => {
|
||||
ast::ProvidedMethod(ref mth) => {
|
||||
let d = mk_lldecl(abi::Rust);
|
||||
let needs_body = setup_lldecl(d, mth.attrs.as_slice());
|
||||
if needs_body {
|
||||
trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d,
|
||||
trans_fn(ccx, mth.pe_fn_decl(), mth.pe_body(), d,
|
||||
&psubsts, mth.id, []);
|
||||
}
|
||||
d
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
|
||||
// Handle the "..." case (returns a slice since strings are always unsized):
|
||||
match content_expr.node {
|
||||
ast::ExprLit(lit) => {
|
||||
ast::ExprLit(ref lit) => {
|
||||
match lit.node {
|
||||
ast::LitStr(ref s, _) => {
|
||||
let scratch = rvalue_scratch_datum(bcx, vec_ty, "");
|
||||
|
|
@ -255,7 +255,7 @@ pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
bcx.expr_to_string(vstore_expr));
|
||||
|
||||
match content_expr.node {
|
||||
ast::ExprLit(lit) => {
|
||||
ast::ExprLit(ref lit) => {
|
||||
match lit.node {
|
||||
ast::LitStr(ref s, _) => {
|
||||
match dest {
|
||||
|
|
@ -363,7 +363,7 @@ pub fn elements_required(bcx: Block, content_expr: &ast::Expr) -> uint {
|
|||
//! Figure out the number of elements we need to store this content
|
||||
|
||||
match content_expr.node {
|
||||
ast::ExprLit(lit) => {
|
||||
ast::ExprLit(ref lit) => {
|
||||
match lit.node {
|
||||
ast::LitStr(ref s, _) => s.get().len(),
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ use std::cmp;
|
|||
use std::fmt::Show;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, sip, Writer};
|
||||
use std::gc::Gc;
|
||||
use std::iter::AdditiveIterator;
|
||||
use std::mem;
|
||||
use std::ops;
|
||||
|
|
@ -459,7 +458,7 @@ pub struct ctxt<'tcx> {
|
|||
pub trait_refs: RefCell<NodeMap<Rc<TraitRef>>>,
|
||||
pub trait_defs: RefCell<DefIdMap<Rc<TraitDef>>>,
|
||||
|
||||
pub map: ast_map::Map,
|
||||
pub map: ast_map::Map<'tcx>,
|
||||
pub intrinsic_defs: RefCell<DefIdMap<t>>,
|
||||
pub freevars: RefCell<freevars::freevar_map>,
|
||||
pub tcache: type_cache,
|
||||
|
|
@ -533,8 +532,8 @@ pub struct ctxt<'tcx> {
|
|||
|
||||
/// These two caches are used by const_eval when decoding external statics
|
||||
/// and variants that are found.
|
||||
pub extern_const_statics: RefCell<DefIdMap<Option<Gc<ast::Expr>>>>,
|
||||
pub extern_const_variants: RefCell<DefIdMap<Option<Gc<ast::Expr>>>>,
|
||||
pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
|
||||
pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
|
||||
|
||||
pub method_map: typeck::MethodMap,
|
||||
pub vtable_map: typeck::vtable_map,
|
||||
|
|
@ -1382,7 +1381,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
|
|||
type_arena: &'tcx TypedArena<t_box_>,
|
||||
dm: resolve::DefMap,
|
||||
named_region_map: resolve_lifetime::NamedRegionMap,
|
||||
map: ast_map::Map,
|
||||
map: ast_map::Map<'tcx>,
|
||||
freevars: freevars::freevar_map,
|
||||
capture_modes: freevars::CaptureModeMap,
|
||||
region_maps: middle::region::RegionMaps,
|
||||
|
|
@ -3619,7 +3618,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
|
|||
RvalueDpsExpr
|
||||
}
|
||||
|
||||
ast::ExprLit(lit) if lit_is_str(lit) => {
|
||||
ast::ExprLit(ref lit) if lit_is_str(&**lit) => {
|
||||
RvalueDpsExpr
|
||||
}
|
||||
|
||||
|
|
@ -3668,7 +3667,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
|
|||
RvalueDatumExpr
|
||||
}
|
||||
|
||||
ast::ExprBox(place, _) => {
|
||||
ast::ExprBox(ref place, _) => {
|
||||
// Special case `Box<T>`/`Gc<T>` for now:
|
||||
let definition = match tcx.def_map.borrow().find(&place.id) {
|
||||
Some(&def) => def,
|
||||
|
|
@ -3959,16 +3958,15 @@ pub fn provided_trait_methods(cx: &ctxt, id: ast::DefId) -> Vec<Rc<Method>> {
|
|||
Some(ast_map::NodeItem(item)) => {
|
||||
match item.node {
|
||||
ItemTrait(_, _, _, ref ms) => {
|
||||
let (_, p) = ast_util::split_trait_methods(ms.as_slice());
|
||||
p.iter()
|
||||
.map(|m| {
|
||||
match impl_or_trait_item(
|
||||
cx,
|
||||
ast_util::local_def(m.id)) {
|
||||
MethodTraitItem(m) => m,
|
||||
ms.iter().filter_map(|m| match *m {
|
||||
ast::RequiredMethod(_) => None,
|
||||
ast::ProvidedMethod(ref m) => {
|
||||
match impl_or_trait_item(cx,
|
||||
ast_util::local_def(m.id)) {
|
||||
MethodTraitItem(m) => Some(m),
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}).collect()
|
||||
}
|
||||
_ => {
|
||||
cx.sess.bug(format!("provided_trait_methods: `{}` is \
|
||||
|
|
@ -4289,11 +4287,11 @@ pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> Rc<Vec<Rc<VariantInfo>>> {
|
|||
expr, since check_enum_variants also updates the enum_var_cache
|
||||
*/
|
||||
match cx.map.get(id.node) {
|
||||
ast_map::NodeItem(item) => {
|
||||
ast_map::NodeItem(ref item) => {
|
||||
match item.node {
|
||||
ast::ItemEnum(ref enum_definition, _) => {
|
||||
let mut last_discriminant: Option<Disr> = None;
|
||||
Rc::new(enum_definition.variants.iter().map(|&variant| {
|
||||
Rc::new(enum_definition.variants.iter().map(|variant| {
|
||||
|
||||
let mut discriminant = match last_discriminant {
|
||||
Some(val) => val + 1,
|
||||
|
|
@ -4324,7 +4322,7 @@ pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> Rc<Vec<Rc<VariantInfo>>> {
|
|||
};
|
||||
|
||||
last_discriminant = Some(discriminant);
|
||||
Rc::new(VariantInfo::from_ast_variant(cx, &*variant,
|
||||
Rc::new(VariantInfo::from_ast_variant(cx, &**variant,
|
||||
discriminant))
|
||||
}).collect())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -451,13 +451,10 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||
for inner_ast_type in path.segments
|
||||
.iter()
|
||||
.flat_map(|s| s.types.iter()) {
|
||||
let mt = ast::MutTy {
|
||||
ty: *inner_ast_type,
|
||||
mutbl: ast::MutImmutable,
|
||||
};
|
||||
return Some(mk_pointer(this,
|
||||
rscope,
|
||||
&mt,
|
||||
ast::MutImmutable,
|
||||
&**inner_ast_type,
|
||||
Uniq,
|
||||
|typ| ty::mk_uniq(this.tcx(), typ)));
|
||||
}
|
||||
|
|
@ -478,13 +475,10 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||
for inner_ast_type in path.segments
|
||||
.iter()
|
||||
.flat_map(|s| s.types.iter()) {
|
||||
let mt = ast::MutTy {
|
||||
ty: *inner_ast_type,
|
||||
mutbl: ast::MutImmutable,
|
||||
};
|
||||
return Some(mk_pointer(this,
|
||||
rscope,
|
||||
&mt,
|
||||
ast::MutImmutable,
|
||||
&**inner_ast_type,
|
||||
Box,
|
||||
|typ| {
|
||||
match ty::get(typ).sty {
|
||||
|
|
@ -578,14 +572,15 @@ pub fn trait_ref_for_unboxed_function<'tcx, AC: AstConv<'tcx>,
|
|||
fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
a_seq_ty: &ast::MutTy,
|
||||
a_seq_mutbl: ast::Mutability,
|
||||
a_seq_ty: &ast::Ty,
|
||||
ptr_ty: PointerTy,
|
||||
constr: |ty::t| -> ty::t)
|
||||
-> ty::t {
|
||||
let tcx = this.tcx();
|
||||
debug!("mk_pointer(ptr_ty={})", ptr_ty);
|
||||
|
||||
match a_seq_ty.ty.node {
|
||||
match a_seq_ty.node {
|
||||
ast::TyVec(ref ty) => {
|
||||
let ty = ast_ty_to_ty(this, rscope, &**ty);
|
||||
return constr(ty::mk_vec(tcx, ty, None));
|
||||
|
|
@ -610,11 +605,11 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||
RPtr(r) => {
|
||||
return ty::mk_rptr(this.tcx(),
|
||||
r,
|
||||
ty::mt {mutbl: a_seq_ty.mutbl, ty: tr});
|
||||
ty::mt {mutbl: a_seq_mutbl, ty: tr});
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_err(
|
||||
a_seq_ty.ty.span,
|
||||
a_seq_ty.span,
|
||||
"~trait or &trait are the only supported \
|
||||
forms of casting-to-trait");
|
||||
return ty::mk_err();
|
||||
|
|
@ -671,7 +666,7 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||
return ty::mk_uniq(tcx, tr);
|
||||
}
|
||||
RPtr(r) => {
|
||||
return ty::mk_rptr(tcx, r, ty::mt{mutbl: a_seq_ty.mutbl, ty: tr});
|
||||
return ty::mk_rptr(tcx, r, ty::mt{mutbl: a_seq_mutbl, ty: tr});
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_err(
|
||||
|
|
@ -688,7 +683,7 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||
_ => {}
|
||||
}
|
||||
|
||||
constr(ast_ty_to_ty(this, rscope, &*a_seq_ty.ty))
|
||||
constr(ast_ty_to_ty(this, rscope, a_seq_ty))
|
||||
}
|
||||
|
||||
// Parses the programmer's textual representation of a type into our
|
||||
|
|
@ -716,17 +711,16 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||
match ast_ty.node {
|
||||
ast::TyNil => ty::mk_nil(),
|
||||
ast::TyBot => ty::mk_bot(),
|
||||
ast::TyBox(ty) => {
|
||||
let mt = ast::MutTy { ty: ty, mutbl: ast::MutImmutable };
|
||||
mk_pointer(this, rscope, &mt, Box, |ty| ty::mk_box(tcx, ty))
|
||||
ast::TyBox(ref ty) => {
|
||||
mk_pointer(this, rscope, ast::MutImmutable, &**ty, Box,
|
||||
|ty| ty::mk_box(tcx, ty))
|
||||
}
|
||||
ast::TyUniq(ty) => {
|
||||
let mt = ast::MutTy { ty: ty, mutbl: ast::MutImmutable };
|
||||
mk_pointer(this, rscope, &mt, Uniq,
|
||||
ast::TyUniq(ref ty) => {
|
||||
mk_pointer(this, rscope, ast::MutImmutable, &**ty, Uniq,
|
||||
|ty| ty::mk_uniq(tcx, ty))
|
||||
}
|
||||
ast::TyVec(ty) => {
|
||||
ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &*ty), None)
|
||||
ast::TyVec(ref ty) => {
|
||||
ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty), None)
|
||||
}
|
||||
ast::TyPtr(ref mt) => {
|
||||
ty::mk_ptr(tcx, ty::mt {
|
||||
|
|
@ -737,7 +731,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||
ast::TyRptr(ref region, ref mt) => {
|
||||
let r = opt_ast_region_to_region(this, rscope, ast_ty.span, region);
|
||||
debug!("ty_rptr r={}", r.repr(this.tcx()));
|
||||
mk_pointer(this, rscope, mt, RPtr(r),
|
||||
mk_pointer(this, rscope, mt.mutbl, &*mt.ty, RPtr(r),
|
||||
|ty| ty::mk_rptr(tcx, r, ty::mt {ty: ty, mutbl: mt.mutbl}))
|
||||
}
|
||||
ast::TyTup(ref fields) => {
|
||||
|
|
@ -870,15 +864,15 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||
}
|
||||
}
|
||||
}
|
||||
ast::TyFixedLengthVec(ty, e) => {
|
||||
match const_eval::eval_const_expr_partial(tcx, &*e) {
|
||||
ast::TyFixedLengthVec(ref ty, ref e) => {
|
||||
match const_eval::eval_const_expr_partial(tcx, &**e) {
|
||||
Ok(ref r) => {
|
||||
match *r {
|
||||
const_eval::const_int(i) =>
|
||||
ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &*ty),
|
||||
ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty),
|
||||
Some(i as uint)),
|
||||
const_eval::const_uint(i) =>
|
||||
ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &*ty),
|
||||
ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty),
|
||||
Some(i as uint)),
|
||||
_ => {
|
||||
tcx.sess.span_fatal(
|
||||
|
|
@ -895,7 +889,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||
}
|
||||
}
|
||||
}
|
||||
ast::TyTypeof(_e) => {
|
||||
ast::TyTypeof(ref _e) => {
|
||||
tcx.sess.span_bug(ast_ty.span, "typeof is reserved but unimplemented");
|
||||
}
|
||||
ast::TyInfer => {
|
||||
|
|
@ -925,7 +919,7 @@ pub fn ty_of_arg<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(this: &AC, rscope: &R
|
|||
|
||||
struct SelfInfo<'a> {
|
||||
untransformed_self_ty: ty::t,
|
||||
explicit_self: ast::ExplicitSelf,
|
||||
explicit_self: &'a ast::ExplicitSelf,
|
||||
}
|
||||
|
||||
pub fn ty_of_method<'tcx, AC: AstConv<'tcx>>(
|
||||
|
|
@ -933,7 +927,7 @@ pub fn ty_of_method<'tcx, AC: AstConv<'tcx>>(
|
|||
id: ast::NodeId,
|
||||
fn_style: ast::FnStyle,
|
||||
untransformed_self_ty: ty::t,
|
||||
explicit_self: ast::ExplicitSelf,
|
||||
explicit_self: &ast::ExplicitSelf,
|
||||
decl: &ast::FnDecl,
|
||||
abi: abi::Abi)
|
||||
-> (ty::BareFnTy, ty::ExplicitSelfCategory) {
|
||||
|
|
@ -1087,8 +1081,8 @@ fn determine_explicit_self_category<'tcx, AC: AstConv<'tcx>,
|
|||
lifetime);
|
||||
ty::ByReferenceExplicitSelfCategory(region, mutability)
|
||||
}
|
||||
ast::SelfExplicit(ast_type, _) => {
|
||||
let explicit_type = ast_ty_to_ty(this, rscope, &*ast_type);
|
||||
ast::SelfExplicit(ref ast_type, _) => {
|
||||
let explicit_type = ast_ty_to_ty(this, rscope, &**ast_type);
|
||||
|
||||
{
|
||||
let inference_context = infer::new_infer_ctxt(this.tcx());
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ use middle::typeck::require_same_types;
|
|||
use util::ppaux;
|
||||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::gc::Gc;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::parse::token;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
|
||||
pub fn check_match(fcx: &FnCtxt,
|
||||
expr: &ast::Expr,
|
||||
|
|
@ -66,17 +66,17 @@ pub fn check_match(fcx: &FnCtxt,
|
|||
let mut guard_err = false;
|
||||
let mut guard_bot = false;
|
||||
match arm.guard {
|
||||
Some(ref e) => {
|
||||
check_expr_has_type(fcx, &**e, ty::mk_bool());
|
||||
let e_ty = fcx.expr_ty(&**e);
|
||||
if ty::type_is_error(e_ty) {
|
||||
guard_err = true;
|
||||
}
|
||||
else if ty::type_is_bot(e_ty) {
|
||||
guard_bot = true;
|
||||
}
|
||||
},
|
||||
None => ()
|
||||
Some(ref e) => {
|
||||
check_expr_has_type(fcx, &**e, ty::mk_bool());
|
||||
let e_ty = fcx.expr_ty(&**e);
|
||||
if ty::type_is_error(e_ty) {
|
||||
guard_err = true;
|
||||
}
|
||||
else if ty::type_is_bot(e_ty) {
|
||||
guard_bot = true;
|
||||
}
|
||||
},
|
||||
None => ()
|
||||
}
|
||||
check_expr(fcx, &*arm.body);
|
||||
let bty = fcx.node_ty(arm.body.id);
|
||||
|
|
@ -113,7 +113,7 @@ pub struct pat_ctxt<'a, 'tcx: 'a> {
|
|||
}
|
||||
|
||||
pub fn check_pat_variant(pcx: &pat_ctxt, pat: &ast::Pat, path: &ast::Path,
|
||||
subpats: &Option<Vec<Gc<ast::Pat>>>, expected: ty::t) {
|
||||
subpats: &Option<Vec<P<ast::Pat>>>, expected: ty::t) {
|
||||
|
||||
// Typecheck the path.
|
||||
let fcx = pcx.fcx;
|
||||
|
|
@ -457,7 +457,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
|
|||
demand::suptype(fcx, pat.span, expected, const_pty.ty);
|
||||
fcx.write_ty(pat.id, const_pty.ty);
|
||||
}
|
||||
ast::PatIdent(bm, ref path1, sub) if pat_is_binding(&tcx.def_map, pat) => {
|
||||
ast::PatIdent(bm, ref path1, ref sub) if pat_is_binding(&tcx.def_map, pat) => {
|
||||
let typ = fcx.local_ty(pat.span, pat.id);
|
||||
|
||||
match bm {
|
||||
|
|
@ -491,9 +491,9 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
|
|||
ppaux::ty_to_string(tcx, expected),
|
||||
pat.id);
|
||||
|
||||
match sub {
|
||||
Some(ref p) => check_pat(pcx, &**p, expected),
|
||||
_ => ()
|
||||
match *sub {
|
||||
Some(ref p) => check_pat(pcx, &**p, expected),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
// it's not a binding, it's an enum in disguise:
|
||||
|
|
@ -624,14 +624,14 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
|
|||
ast::PatRegion(ref inner) => {
|
||||
check_pointer_pat(pcx, Borrowed, &**inner, pat.id, pat.span, expected);
|
||||
}
|
||||
ast::PatVec(ref before, slice, ref after) => {
|
||||
ast::PatVec(ref before, ref slice, ref after) => {
|
||||
let default_region_var =
|
||||
fcx.infcx().next_region_var(
|
||||
infer::PatternRegion(pat.span));
|
||||
|
||||
let check_err = |found: String| {
|
||||
for &elt in before.iter() {
|
||||
check_pat(pcx, &*elt, ty::mk_err());
|
||||
for elt in before.iter() {
|
||||
check_pat(pcx, &**elt, ty::mk_err());
|
||||
}
|
||||
for elt in slice.iter() {
|
||||
check_pat(pcx, &**elt, ty::mk_err());
|
||||
|
|
@ -690,7 +690,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
|
|||
};
|
||||
|
||||
let min_len = before.len() + after.len();
|
||||
fixed.and_then(|count| match slice {
|
||||
fixed.and_then(|count| match *slice {
|
||||
Some(_) if count < min_len =>
|
||||
Some(format!("a fixed vector pattern of size at least {}", min_len)),
|
||||
|
||||
|
|
@ -703,7 +703,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
|
|||
for elt in before.iter() {
|
||||
check_pat(pcx, &**elt, elt_type);
|
||||
}
|
||||
match slice {
|
||||
match *slice {
|
||||
Some(ref slice_pat) => {
|
||||
let slice_ty = ty::mk_slice(tcx,
|
||||
region_var,
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ use std::cell::{Cell, RefCell};
|
|||
use std::collections::HashMap;
|
||||
use std::mem::replace;
|
||||
use std::rc::Rc;
|
||||
use std::gc::Gc;
|
||||
use std::slice;
|
||||
use syntax::abi;
|
||||
use syntax::ast::{ProvidedMethod, RequiredMethod};
|
||||
use syntax::ast;
|
||||
|
|
@ -137,6 +137,7 @@ use syntax::codemap;
|
|||
use syntax::owned_slice::OwnedSlice;
|
||||
use syntax::parse::token;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax;
|
||||
|
|
@ -401,7 +402,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckItemSizedTypesVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
|
||||
pub fn check_item_types(ccx: &CrateCtxt) {
|
||||
let krate = ccx.tcx.map.krate();
|
||||
|
||||
let mut visit = CheckTypeWellFormedVisitor { ccx: ccx };
|
||||
visit::walk_crate(&mut visit, krate);
|
||||
|
||||
|
|
@ -624,7 +627,7 @@ fn span_for_field(tcx: &ty::ctxt, field: &ty::field_ty, struct_id: ast::DefId) -
|
|||
};
|
||||
|
||||
match item.node {
|
||||
ast::ItemStruct(struct_def, _) => {
|
||||
ast::ItemStruct(ref struct_def, _) => {
|
||||
match struct_def.fields.iter().find(|f| match f.node.kind {
|
||||
ast::NamedField(ident, _) => ident.name == field.name,
|
||||
_ => false,
|
||||
|
|
@ -818,8 +821,8 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(m) => {
|
||||
check_method_body(ccx, &impl_pty.generics, &*m);
|
||||
ast::MethodImplItem(ref m) => {
|
||||
check_method_body(ccx, &impl_pty.generics, &**m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -841,14 +844,14 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
}
|
||||
ast::ItemTrait(_, _, _, ref trait_methods) => {
|
||||
let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
|
||||
for trait_method in (*trait_methods).iter() {
|
||||
for trait_method in trait_methods.iter() {
|
||||
match *trait_method {
|
||||
RequiredMethod(..) => {
|
||||
// Nothing to do, since required methods don't have
|
||||
// bodies to check.
|
||||
}
|
||||
ProvidedMethod(m) => {
|
||||
check_method_body(ccx, &trait_def.generics, &*m);
|
||||
ProvidedMethod(ref m) => {
|
||||
check_method_body(ccx, &trait_def.generics, &**m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -930,7 +933,7 @@ fn check_impl_items_against_trait(ccx: &CrateCtxt,
|
|||
// and compatible with trait signature
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
ast::MethodImplItem(impl_method) => {
|
||||
ast::MethodImplItem(ref impl_method) => {
|
||||
let impl_method_def_id = local_def(impl_method.id);
|
||||
let impl_item_ty = ty::impl_or_trait_item(ccx.tcx,
|
||||
impl_method_def_id);
|
||||
|
|
@ -983,7 +986,7 @@ fn check_impl_items_against_trait(ccx: &CrateCtxt,
|
|||
let is_implemented =
|
||||
impl_items.iter().any(|ii| {
|
||||
match *ii {
|
||||
ast::MethodImplItem(m) => {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
m.pe_ident().name == trait_method.ident.name
|
||||
}
|
||||
}
|
||||
|
|
@ -1968,9 +1971,9 @@ pub fn autoderef<T>(fcx: &FnCtxt, sp: Span, base_ty: ty::t,
|
|||
/// Attempts to resolve a call expression as an overloaded call.
|
||||
fn try_overloaded_call(fcx: &FnCtxt,
|
||||
call_expression: &ast::Expr,
|
||||
callee: Gc<ast::Expr>,
|
||||
callee: &ast::Expr,
|
||||
callee_type: ty::t,
|
||||
args: &[Gc<ast::Expr>])
|
||||
args: &[P<ast::Expr>])
|
||||
-> bool {
|
||||
// Bail out if the callee is a bare function or a closure. We check those
|
||||
// manually.
|
||||
|
|
@ -2072,9 +2075,9 @@ fn try_overloaded_deref(fcx: &FnCtxt,
|
|||
fn try_overloaded_index(fcx: &FnCtxt,
|
||||
method_call: Option<MethodCall>,
|
||||
expr: &ast::Expr,
|
||||
base_expr: Gc<ast::Expr>,
|
||||
base_expr: &ast::Expr,
|
||||
base_ty: ty::t,
|
||||
index_expr: Gc<ast::Expr>,
|
||||
index_expr: &P<ast::Expr>,
|
||||
lvalue_pref: LvaluePreference)
|
||||
-> Option<ty::mt> {
|
||||
// Try `IndexMut` first, if preferred.
|
||||
|
|
@ -2119,7 +2122,7 @@ fn try_overloaded_index(fcx: &FnCtxt,
|
|||
expr.span,
|
||||
method_type,
|
||||
expr,
|
||||
[base_expr, index_expr],
|
||||
slice::ref_slice(index_expr),
|
||||
DoDerefArgs,
|
||||
DontTupleArguments);
|
||||
|
||||
|
|
@ -2145,7 +2148,7 @@ fn try_overloaded_index(fcx: &FnCtxt,
|
|||
/// The return type of this function represents the concrete element type
|
||||
/// `A` in the type `Iterator<A>` that the method returns.
|
||||
fn lookup_method_for_for_loop(fcx: &FnCtxt,
|
||||
iterator_expr: Gc<ast::Expr>,
|
||||
iterator_expr: &ast::Expr,
|
||||
loop_id: ast::NodeId)
|
||||
-> ty::t {
|
||||
let trait_did = match fcx.tcx().lang_items.require(IteratorItem) {
|
||||
|
|
@ -2188,8 +2191,8 @@ fn lookup_method_for_for_loop(fcx: &FnCtxt,
|
|||
let return_type = check_method_argument_types(fcx,
|
||||
iterator_expr.span,
|
||||
method_type,
|
||||
&*iterator_expr,
|
||||
[iterator_expr],
|
||||
iterator_expr,
|
||||
&[],
|
||||
DontDerefArgs,
|
||||
DontTupleArguments);
|
||||
|
||||
|
|
@ -2224,23 +2227,17 @@ fn check_method_argument_types(fcx: &FnCtxt,
|
|||
sp: Span,
|
||||
method_fn_ty: ty::t,
|
||||
callee_expr: &ast::Expr,
|
||||
args: &[Gc<ast::Expr>],
|
||||
args_no_rcvr: &[P<ast::Expr>],
|
||||
deref_args: DerefArgs,
|
||||
tuple_arguments: TupleArgumentsFlag)
|
||||
-> ty::t {
|
||||
// HACK(eddyb) ignore provided self (it has special typeck rules).
|
||||
let args = if tuple_arguments == DontTupleArguments {
|
||||
args.slice_from(1)
|
||||
} else {
|
||||
args
|
||||
};
|
||||
if ty::type_is_error(method_fn_ty) {
|
||||
let err_inputs = err_args(args.len());
|
||||
let err_inputs = err_args(args_no_rcvr.len());
|
||||
check_argument_types(fcx,
|
||||
sp,
|
||||
err_inputs.as_slice(),
|
||||
callee_expr,
|
||||
args,
|
||||
args_no_rcvr,
|
||||
deref_args,
|
||||
false,
|
||||
tuple_arguments);
|
||||
|
|
@ -2253,7 +2250,7 @@ fn check_method_argument_types(fcx: &FnCtxt,
|
|||
sp,
|
||||
fty.sig.inputs.slice_from(1),
|
||||
callee_expr,
|
||||
args,
|
||||
args_no_rcvr,
|
||||
deref_args,
|
||||
fty.sig.variadic,
|
||||
tuple_arguments);
|
||||
|
|
@ -2271,7 +2268,7 @@ fn check_argument_types(fcx: &FnCtxt,
|
|||
sp: Span,
|
||||
fn_inputs: &[ty::t],
|
||||
callee_expr: &ast::Expr,
|
||||
args: &[Gc<ast::Expr>],
|
||||
args: &[P<ast::Expr>],
|
||||
deref_args: DerefArgs,
|
||||
variadic: bool,
|
||||
tuple_arguments: TupleArgumentsFlag) {
|
||||
|
|
@ -2665,7 +2662,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
fn check_call(fcx: &FnCtxt,
|
||||
call_expr: &ast::Expr,
|
||||
f: &ast::Expr,
|
||||
args: &[Gc<ast::Expr>]) {
|
||||
args: &[P<ast::Expr>]) {
|
||||
// Store the type of `f` as the type of the callee
|
||||
let fn_ty = fcx.expr_ty(f);
|
||||
|
||||
|
|
@ -2716,9 +2713,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
fn check_method_call(fcx: &FnCtxt,
|
||||
expr: &ast::Expr,
|
||||
method_name: ast::SpannedIdent,
|
||||
args: &[Gc<ast::Expr>],
|
||||
tps: &[ast::P<ast::Ty>]) {
|
||||
let rcvr = args[0].clone();
|
||||
args: &[P<ast::Expr>],
|
||||
tps: &[P<ast::Ty>]) {
|
||||
let rcvr = &*args[0];
|
||||
// We can't know if we need &mut self before we look up the method,
|
||||
// so treat the receiver as mutable just in case - only explicit
|
||||
// overloaded dereferences care about the distinction.
|
||||
|
|
@ -2779,7 +2776,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
method_name.span,
|
||||
fn_ty,
|
||||
expr,
|
||||
args,
|
||||
args.slice_from(1),
|
||||
DontDerefArgs,
|
||||
DontTupleArguments);
|
||||
|
||||
|
|
@ -2791,7 +2788,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
fn check_then_else(fcx: &FnCtxt,
|
||||
cond_expr: &ast::Expr,
|
||||
then_blk: &ast::Block,
|
||||
opt_else_expr: Option<Gc<ast::Expr>>,
|
||||
opt_else_expr: Option<&ast::Expr>,
|
||||
id: ast::NodeId,
|
||||
sp: Span,
|
||||
expected: Expectation) {
|
||||
|
|
@ -2852,22 +2849,31 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
fcx.write_ty(id, if_ty);
|
||||
}
|
||||
|
||||
fn lookup_op_method(fcx: &FnCtxt,
|
||||
op_ex: &ast::Expr,
|
||||
self_t: ty::t,
|
||||
opname: ast::Name,
|
||||
trait_did: Option<ast::DefId>,
|
||||
args: &[Gc<ast::Expr>],
|
||||
autoderef_receiver: AutoderefReceiverFlag,
|
||||
unbound_method: ||) -> ty::t {
|
||||
fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
op_ex: &ast::Expr,
|
||||
lhs_ty: ty::t,
|
||||
opname: ast::Name,
|
||||
trait_did: Option<ast::DefId>,
|
||||
lhs: &'a ast::Expr,
|
||||
rhs: Option<&P<ast::Expr>>,
|
||||
autoderef_receiver: AutoderefReceiverFlag,
|
||||
unbound_method: ||) -> ty::t {
|
||||
let method = match trait_did {
|
||||
Some(trait_did) => {
|
||||
method::lookup_in_trait(fcx, op_ex.span, Some(&*args[0]), opname,
|
||||
trait_did, self_t, [], autoderef_receiver,
|
||||
method::lookup_in_trait(fcx, op_ex.span, Some(lhs), opname,
|
||||
trait_did, lhs_ty, &[], autoderef_receiver,
|
||||
IgnoreStaticMethods)
|
||||
}
|
||||
None => None
|
||||
};
|
||||
let args = match rhs {
|
||||
Some(rhs) => slice::ref_slice(rhs),
|
||||
None => {
|
||||
// Work around the lack of coercion.
|
||||
let empty: &[_] = &[];
|
||||
empty
|
||||
}
|
||||
};
|
||||
match method {
|
||||
Some(method) => {
|
||||
let method_ty = method.ty;
|
||||
|
|
@ -2903,8 +2909,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
fn check_binop(fcx: &FnCtxt,
|
||||
expr: &ast::Expr,
|
||||
op: ast::BinOp,
|
||||
lhs: Gc<ast::Expr>,
|
||||
rhs: Gc<ast::Expr>,
|
||||
lhs: &ast::Expr,
|
||||
rhs: &P<ast::Expr>,
|
||||
is_binop_assignment: IsBinopAssignment) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
|
||||
|
|
@ -2920,7 +2926,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
|
||||
if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) {
|
||||
// Shift is a special case: rhs must be uint, no matter what lhs is
|
||||
check_expr_has_type(fcx, &*rhs, ty::mk_uint());
|
||||
check_expr_has_type(fcx, &**rhs, ty::mk_uint());
|
||||
fcx.write_ty(expr.id, lhs_t);
|
||||
return;
|
||||
}
|
||||
|
|
@ -2928,7 +2934,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
if ty::is_binopable(tcx, lhs_t, op) {
|
||||
let tvar = fcx.infcx().next_ty_var();
|
||||
demand::suptype(fcx, expr.span, tvar, lhs_t);
|
||||
check_expr_has_type(fcx, &*rhs, tvar);
|
||||
check_expr_has_type(fcx, &**rhs, tvar);
|
||||
|
||||
let result_t = match op {
|
||||
ast::BiEq | ast::BiNe | ast::BiLt | ast::BiLe | ast::BiGe |
|
||||
|
|
@ -2993,7 +2999,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
},
|
||||
lhs_t,
|
||||
None);
|
||||
check_expr(fcx, &*rhs);
|
||||
check_expr(fcx, &**rhs);
|
||||
ty::mk_err()
|
||||
};
|
||||
|
||||
|
|
@ -3005,10 +3011,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
|
||||
fn check_user_binop(fcx: &FnCtxt,
|
||||
ex: &ast::Expr,
|
||||
lhs_expr: Gc<ast::Expr>,
|
||||
lhs_expr: &ast::Expr,
|
||||
lhs_resolved_t: ty::t,
|
||||
op: ast::BinOp,
|
||||
rhs: Gc<ast::Expr>) -> ty::t {
|
||||
rhs: &P<ast::Expr>) -> ty::t {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
let lang = &tcx.lang_items;
|
||||
let (name, trait_did) = match op {
|
||||
|
|
@ -3029,12 +3035,12 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
ast::BiEq => ("eq", lang.eq_trait()),
|
||||
ast::BiNe => ("ne", lang.eq_trait()),
|
||||
ast::BiAnd | ast::BiOr => {
|
||||
check_expr(fcx, &*rhs);
|
||||
check_expr(fcx, &**rhs);
|
||||
return ty::mk_err();
|
||||
}
|
||||
};
|
||||
lookup_op_method(fcx, ex, lhs_resolved_t, token::intern(name),
|
||||
trait_did, [lhs_expr, rhs], DontAutoderefReceiver, || {
|
||||
trait_did, lhs_expr, Some(rhs), DontAutoderefReceiver, || {
|
||||
fcx.type_error_message(ex.span, |actual| {
|
||||
format!("binary operation `{}` cannot be applied to type `{}`",
|
||||
ast_util::binop_to_string(op),
|
||||
|
|
@ -3048,10 +3054,10 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
mname: &str,
|
||||
trait_did: Option<ast::DefId>,
|
||||
ex: &ast::Expr,
|
||||
rhs_expr: Gc<ast::Expr>,
|
||||
rhs_expr: &ast::Expr,
|
||||
rhs_t: ty::t) -> ty::t {
|
||||
lookup_op_method(fcx, ex, rhs_t, token::intern(mname),
|
||||
trait_did, [rhs_expr], DontAutoderefReceiver, || {
|
||||
trait_did, rhs_expr, None, DontAutoderefReceiver, || {
|
||||
fcx.type_error_message(ex.span, |actual| {
|
||||
format!("cannot apply unary operator `{}` to type `{}`",
|
||||
op_str, actual)
|
||||
|
|
@ -3063,7 +3069,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
expr: &ast::Expr,
|
||||
kind: ast::UnboxedClosureKind,
|
||||
decl: &ast::FnDecl,
|
||||
body: ast::P<ast::Block>) {
|
||||
body: &ast::Block) {
|
||||
let mut fn_ty = astconv::ty_of_closure(
|
||||
fcx,
|
||||
expr.id,
|
||||
|
|
@ -3131,7 +3137,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
expr: &ast::Expr,
|
||||
store: ty::TraitStore,
|
||||
decl: &ast::FnDecl,
|
||||
body: ast::P<ast::Block>,
|
||||
body: &ast::Block,
|
||||
expected: Expectation) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
|
||||
|
|
@ -3228,7 +3234,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
lvalue_pref: LvaluePreference,
|
||||
base: &ast::Expr,
|
||||
field: &ast::SpannedIdent,
|
||||
tys: &[ast::P<ast::Ty>]) {
|
||||
tys: &[P<ast::Ty>]) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
|
||||
let expr_t = structurally_resolved_type(fcx, expr.span,
|
||||
|
|
@ -3302,7 +3308,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
lvalue_pref: LvaluePreference,
|
||||
base: &ast::Expr,
|
||||
idx: codemap::Spanned<uint>,
|
||||
_tys: &[ast::P<ast::Ty>]) {
|
||||
_tys: &[P<ast::Ty>]) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
|
||||
let expr_t = structurally_resolved_type(fcx, expr.span,
|
||||
|
|
@ -3453,7 +3459,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
span: codemap::Span,
|
||||
class_id: ast::DefId,
|
||||
fields: &[ast::Field],
|
||||
base_expr: Option<Gc<ast::Expr>>) {
|
||||
base_expr: Option<&ast::Expr>) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
|
||||
// Look up the number of type parameters and the raw type, and
|
||||
|
|
@ -3527,14 +3533,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
fn check_struct_fields_on_error(fcx: &FnCtxt,
|
||||
id: ast::NodeId,
|
||||
fields: &[ast::Field],
|
||||
base_expr: Option<Gc<ast::Expr>>) {
|
||||
base_expr: &Option<P<ast::Expr>>) {
|
||||
// Make sure to still write the types
|
||||
// otherwise we might ICE
|
||||
fcx.write_error(id);
|
||||
for field in fields.iter() {
|
||||
check_expr(fcx, &*field.expr);
|
||||
}
|
||||
match base_expr {
|
||||
match *base_expr {
|
||||
Some(ref base) => check_expr(fcx, &**base),
|
||||
None => {}
|
||||
}
|
||||
|
|
@ -3578,12 +3584,12 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
}
|
||||
}
|
||||
|
||||
ast::ExprLit(lit) => {
|
||||
let typ = check_lit(fcx, &*lit, expected);
|
||||
ast::ExprLit(ref lit) => {
|
||||
let typ = check_lit(fcx, &**lit, expected);
|
||||
fcx.write_ty(id, typ);
|
||||
}
|
||||
ast::ExprBinary(op, ref lhs, ref rhs) => {
|
||||
check_binop(fcx, expr, op, lhs.clone(), rhs.clone(), SimpleBinop);
|
||||
check_binop(fcx, expr, op, &**lhs, rhs, SimpleBinop);
|
||||
|
||||
let lhs_ty = fcx.expr_ty(&**lhs);
|
||||
let rhs_ty = fcx.expr_ty(&**rhs);
|
||||
|
|
@ -3597,7 +3603,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
}
|
||||
}
|
||||
ast::ExprAssignOp(op, ref lhs, ref rhs) => {
|
||||
check_binop(fcx, expr, op, lhs.clone(), rhs.clone(), BinopAssignment);
|
||||
check_binop(fcx, expr, op, &**lhs, rhs, BinopAssignment);
|
||||
|
||||
let lhs_t = fcx.expr_ty(&**lhs);
|
||||
let result_t = fcx.expr_ty(expr);
|
||||
|
|
@ -3691,7 +3697,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
ty::get(oprnd_t).sty == ty::ty_bool) {
|
||||
oprnd_t = check_user_unop(fcx, "!", "not",
|
||||
tcx.lang_items.not_trait(),
|
||||
expr, oprnd.clone(), oprnd_t);
|
||||
expr, &**oprnd, oprnd_t);
|
||||
}
|
||||
}
|
||||
ast::UnNeg => {
|
||||
|
|
@ -3701,7 +3707,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
ty::type_is_fp(oprnd_t)) {
|
||||
oprnd_t = check_user_unop(fcx, "-", "neg",
|
||||
tcx.lang_items.neg_trait(),
|
||||
expr, oprnd.clone(), oprnd_t);
|
||||
expr, &**oprnd, oprnd_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3802,12 +3808,12 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
}
|
||||
fcx.write_bot(id);
|
||||
}
|
||||
ast::ExprParen(a) => {
|
||||
ast::ExprParen(ref a) => {
|
||||
check_expr_with_expectation_and_lvalue_pref(fcx,
|
||||
&*a,
|
||||
&**a,
|
||||
expected,
|
||||
lvalue_pref);
|
||||
fcx.write_ty(id, fcx.expr_ty(&*a));
|
||||
fcx.write_ty(id, fcx.expr_ty(&**a));
|
||||
}
|
||||
ast::ExprAssign(ref lhs, ref rhs) => {
|
||||
check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
|
||||
|
|
@ -3831,7 +3837,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
}
|
||||
}
|
||||
ast::ExprIf(ref cond, ref then_blk, ref opt_else_expr) => {
|
||||
check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.clone(),
|
||||
check_then_else(fcx, &**cond, &**then_blk, opt_else_expr.as_ref().map(|e| &**e),
|
||||
id, expr.span, expected);
|
||||
}
|
||||
ast::ExprWhile(ref cond, ref body, _) => {
|
||||
|
|
@ -3851,7 +3857,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
}
|
||||
ast::ExprForLoop(ref pat, ref head, ref block, _) => {
|
||||
check_expr(fcx, &**head);
|
||||
let typ = lookup_method_for_for_loop(fcx, *head, expr.id);
|
||||
let typ = lookup_method_for_for_loop(fcx, &**head, expr.id);
|
||||
vtable::early_resolve_expr(expr, fcx, true);
|
||||
|
||||
let pcx = pat_ctxt {
|
||||
|
|
@ -3865,10 +3871,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
}
|
||||
ast::ExprLoop(ref body, _) => {
|
||||
check_block_no_value(fcx, &**body);
|
||||
if !may_break(tcx, expr.id, body.clone()) {
|
||||
if !may_break(tcx, expr.id, &**body) {
|
||||
fcx.write_bot(id);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fcx.write_nil(id);
|
||||
}
|
||||
}
|
||||
|
|
@ -3884,7 +3889,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
expr,
|
||||
ty::RegionTraitStore(region, ast::MutMutable),
|
||||
&**decl,
|
||||
body.clone(),
|
||||
&**body,
|
||||
expected);
|
||||
}
|
||||
ast::ExprUnboxedFn(_, kind, ref decl, ref body) => {
|
||||
|
|
@ -3892,14 +3897,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
expr,
|
||||
kind,
|
||||
&**decl,
|
||||
*body);
|
||||
&**body);
|
||||
}
|
||||
ast::ExprProc(ref decl, ref body) => {
|
||||
check_expr_fn(fcx,
|
||||
expr,
|
||||
ty::UniqTraitStore,
|
||||
&**decl,
|
||||
body.clone(),
|
||||
&**body,
|
||||
expected);
|
||||
}
|
||||
ast::ExprBlock(ref b) => {
|
||||
|
|
@ -3912,7 +3917,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
check_expr(fcx, &**f);
|
||||
let f_ty = fcx.expr_ty(&**f);
|
||||
|
||||
if !try_overloaded_call(fcx, expr, f.clone(), f_ty, args.as_slice()) {
|
||||
if !try_overloaded_call(fcx, expr, &**f, f_ty, args.as_slice()) {
|
||||
check_call(fcx, expr, &**f, args.as_slice());
|
||||
let (args_bot, args_err) = args.iter().fold((false, false),
|
||||
|(rest_bot, rest_err), a| {
|
||||
|
|
@ -4050,7 +4055,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
fcx.write_ty(id, typ);
|
||||
}
|
||||
}
|
||||
ast::ExprStruct(ref path, ref fields, base_expr) => {
|
||||
ast::ExprStruct(ref path, ref fields, ref base_expr) => {
|
||||
// Resolve the path.
|
||||
let def = tcx.def_map.borrow().find(&id).map(|i| *i);
|
||||
let struct_id = match def {
|
||||
|
|
@ -4079,7 +4084,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
expr.span,
|
||||
struct_did,
|
||||
fields.as_slice(),
|
||||
base_expr);
|
||||
base_expr.as_ref().map(|e| &**e));
|
||||
}
|
||||
_ => {
|
||||
span_err!(tcx.sess, path.span, E0071,
|
||||
|
|
@ -4168,9 +4173,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
|||
match try_overloaded_index(fcx,
|
||||
Some(method_call),
|
||||
expr,
|
||||
*base,
|
||||
&**base,
|
||||
base_t,
|
||||
*idx,
|
||||
idx,
|
||||
lvalue_pref) {
|
||||
Some(mt) => fcx.write_ty(id, mt.ty),
|
||||
None => {
|
||||
|
|
@ -4331,7 +4336,7 @@ pub fn check_stmt(fcx: &FnCtxt, stmt: &ast::Stmt) {
|
|||
let mut saw_bot = false;
|
||||
let mut saw_err = false;
|
||||
match stmt.node {
|
||||
ast::StmtDecl(decl, id) => {
|
||||
ast::StmtDecl(ref decl, id) => {
|
||||
node_id = id;
|
||||
match decl.node {
|
||||
ast::DeclLocal(ref l) => {
|
||||
|
|
@ -4404,7 +4409,7 @@ fn check_block_with_expected(fcx: &FnCtxt,
|
|||
let s_id = ast_util::stmt_id(&**s);
|
||||
let s_ty = fcx.node_ty(s_id);
|
||||
if last_was_bot && !warned && match s.node {
|
||||
ast::StmtDecl(decl, _) => {
|
||||
ast::StmtDecl(ref decl, _) => {
|
||||
match decl.node {
|
||||
ast::DeclLocal(_) => true,
|
||||
_ => false,
|
||||
|
|
@ -4431,14 +4436,12 @@ fn check_block_with_expected(fcx: &FnCtxt,
|
|||
match blk.expr {
|
||||
None => if any_err {
|
||||
fcx.write_error(blk.id);
|
||||
}
|
||||
else if any_bot {
|
||||
} else if any_bot {
|
||||
fcx.write_bot(blk.id);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
fcx.write_nil(blk.id);
|
||||
},
|
||||
Some(e) => {
|
||||
Some(ref e) => {
|
||||
if any_bot && !warned {
|
||||
fcx.ccx
|
||||
.tcx
|
||||
|
|
@ -4450,12 +4453,12 @@ fn check_block_with_expected(fcx: &FnCtxt,
|
|||
}
|
||||
let ety = match expected {
|
||||
ExpectHasType(ety) => {
|
||||
check_expr_coercable_to_type(fcx, &*e, ety);
|
||||
check_expr_coercable_to_type(fcx, &**e, ety);
|
||||
ety
|
||||
}
|
||||
_ => {
|
||||
check_expr_with_expectation(fcx, &*e, expected);
|
||||
fcx.expr_ty(&*e)
|
||||
check_expr_with_expectation(fcx, &**e, expected);
|
||||
fcx.expr_ty(&**e)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -4603,8 +4606,8 @@ pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
|
|||
|
||||
|
||||
pub fn check_enum_variants_sized(ccx: &CrateCtxt,
|
||||
vs: &[ast::P<ast::Variant>]) {
|
||||
for &v in vs.iter() {
|
||||
vs: &[P<ast::Variant>]) {
|
||||
for v in vs.iter() {
|
||||
match v.node.kind {
|
||||
ast::TupleVariantKind(ref args) if args.len() > 0 => {
|
||||
let ctor_ty = ty::node_id_to_type(ccx.tcx, v.node.id);
|
||||
|
|
@ -4626,7 +4629,9 @@ pub fn check_enum_variants_sized(ccx: &CrateCtxt,
|
|||
}
|
||||
}
|
||||
},
|
||||
ast::StructVariantKind(struct_def) => check_fields_sized(ccx.tcx, &*struct_def),
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
check_fields_sized(ccx.tcx, &**struct_def)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4634,7 +4639,7 @@ pub fn check_enum_variants_sized(ccx: &CrateCtxt,
|
|||
|
||||
pub fn check_enum_variants(ccx: &CrateCtxt,
|
||||
sp: Span,
|
||||
vs: &[ast::P<ast::Variant>],
|
||||
vs: &[P<ast::Variant>],
|
||||
id: ast::NodeId) {
|
||||
|
||||
fn disr_in_range(ccx: &CrateCtxt,
|
||||
|
|
@ -4665,7 +4670,7 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
|||
}
|
||||
|
||||
fn do_check(ccx: &CrateCtxt,
|
||||
vs: &[ast::P<ast::Variant>],
|
||||
vs: &[P<ast::Variant>],
|
||||
id: ast::NodeId,
|
||||
hint: attr::ReprAttr)
|
||||
-> Vec<Rc<ty::VariantInfo>> {
|
||||
|
|
@ -4675,7 +4680,7 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
|||
let mut disr_vals: Vec<ty::Disr> = Vec::new();
|
||||
let mut prev_disr_val: Option<ty::Disr> = None;
|
||||
|
||||
for &v in vs.iter() {
|
||||
for v in vs.iter() {
|
||||
|
||||
// If the discriminant value is specified explicitly in the enum check whether the
|
||||
// initialization expression is valid, otherwise use the last value plus one.
|
||||
|
|
@ -4685,8 +4690,8 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
|||
};
|
||||
|
||||
match v.node.disr_expr {
|
||||
Some(e) => {
|
||||
debug!("disr expr, checking {}", pprust::expr_to_string(&*e));
|
||||
Some(ref e) => {
|
||||
debug!("disr expr, checking {}", pprust::expr_to_string(&**e));
|
||||
|
||||
let inh = static_inherited_fields(ccx);
|
||||
let fcx = blank_fn_ctxt(ccx, &inh, rty, e.id);
|
||||
|
|
@ -4699,12 +4704,12 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
|||
ty::mk_mach_uint(ity)
|
||||
},
|
||||
};
|
||||
check_const_with_ty(&fcx, e.span, &*e, declty);
|
||||
check_const_with_ty(&fcx, e.span, &**e, declty);
|
||||
// check_expr (from check_const pass) doesn't guarantee
|
||||
// that the expression is in a form that eval_const_expr can
|
||||
// handle, so we may still get an internal compiler error
|
||||
|
||||
match const_eval::eval_const_expr_partial(ccx.tcx, &*e) {
|
||||
match const_eval::eval_const_expr_partial(ccx.tcx, &**e) {
|
||||
Ok(const_eval::const_int(val)) => current_disr_val = val as Disr,
|
||||
Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr,
|
||||
Ok(_) => {
|
||||
|
|
@ -4742,7 +4747,7 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
|||
}
|
||||
disr_vals.push(current_disr_val);
|
||||
|
||||
let variant_info = Rc::new(VariantInfo::from_ast_variant(ccx.tcx, &*v,
|
||||
let variant_info = Rc::new(VariantInfo::from_ast_variant(ccx.tcx, &**v,
|
||||
current_disr_val));
|
||||
prev_disr_val = Some(current_disr_val);
|
||||
|
||||
|
|
@ -5051,8 +5056,8 @@ pub fn instantiate_path(fcx: &FnCtxt,
|
|||
{
|
||||
let type_count = type_defs.len(space);
|
||||
assert_eq!(substs.types.len(space), 0);
|
||||
for (i, &typ) in segment.types.iter().enumerate() {
|
||||
let t = fcx.to_ty(&*typ);
|
||||
for (i, typ) in segment.types.iter().enumerate() {
|
||||
let t = fcx.to_ty(&**typ);
|
||||
if i < type_count {
|
||||
substs.types.push(space, t);
|
||||
} else if i == type_count {
|
||||
|
|
@ -5256,7 +5261,7 @@ pub fn type_is_c_like_enum(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
|||
}
|
||||
|
||||
// Returns true if b contains a break that can exit from b
|
||||
pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: ast::P<ast::Block>) -> bool {
|
||||
pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
|
||||
// First: is there an unlabeled break immediately
|
||||
// inside the loop?
|
||||
(loop_query(&*b, |e| {
|
||||
|
|
|
|||
|
|
@ -141,7 +141,6 @@ use syntax::visit;
|
|||
use syntax::visit::Visitor;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::gc::Gc;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC ENTRY POINTS
|
||||
|
|
@ -614,23 +613,20 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
|||
match expr.node {
|
||||
ast::ExprCall(ref callee, ref args) => {
|
||||
if has_method_map {
|
||||
constrain_call(rcx, expr, Some(*callee),
|
||||
args.as_slice(), false);
|
||||
constrain_call(rcx, expr, Some(&**callee),
|
||||
args.iter().map(|e| &**e), false);
|
||||
} else {
|
||||
constrain_callee(rcx, callee.id, expr, &**callee);
|
||||
constrain_call(rcx,
|
||||
expr,
|
||||
None,
|
||||
args.as_slice(),
|
||||
false);
|
||||
constrain_call(rcx, expr, None,
|
||||
args.iter().map(|e| &**e), false);
|
||||
}
|
||||
|
||||
visit::walk_expr(rcx, expr);
|
||||
}
|
||||
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
constrain_call(rcx, expr, Some(*args.get(0)),
|
||||
args.slice_from(1), false);
|
||||
constrain_call(rcx, expr, Some(&**args.get(0)),
|
||||
args.slice_from(1).iter().map(|e| &**e), false);
|
||||
|
||||
visit::walk_expr(rcx, expr);
|
||||
}
|
||||
|
|
@ -642,8 +638,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
|||
|
||||
ast::ExprAssignOp(_, ref lhs, ref rhs) => {
|
||||
if has_method_map {
|
||||
constrain_call(rcx, expr, Some(lhs.clone()),
|
||||
[rhs.clone()], true);
|
||||
constrain_call(rcx, expr, Some(&**lhs),
|
||||
Some(&**rhs).move_iter(), true);
|
||||
}
|
||||
|
||||
adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs);
|
||||
|
|
@ -657,15 +653,16 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
|||
// overloaded op. Note that we (sadly) currently use an
|
||||
// implicit "by ref" sort of passing style here. This
|
||||
// should be converted to an adjustment!
|
||||
constrain_call(rcx, expr, Some(lhs.clone()),
|
||||
[rhs.clone()], true);
|
||||
constrain_call(rcx, expr, Some(&**lhs),
|
||||
Some(&**rhs).move_iter(), true);
|
||||
|
||||
visit::walk_expr(rcx, expr);
|
||||
}
|
||||
|
||||
ast::ExprUnary(_, ref lhs) if has_method_map => {
|
||||
// As above.
|
||||
constrain_call(rcx, expr, Some(lhs.clone()), [], true);
|
||||
constrain_call(rcx, expr, Some(&**lhs),
|
||||
None::<ast::Expr>.iter(), true);
|
||||
|
||||
visit::walk_expr(rcx, expr);
|
||||
}
|
||||
|
|
@ -683,7 +680,8 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
|||
let method_call = MethodCall::expr(expr.id);
|
||||
let base_ty = match rcx.fcx.inh.method_map.borrow().find(&method_call) {
|
||||
Some(method) => {
|
||||
constrain_call(rcx, expr, Some(base.clone()), [], true);
|
||||
constrain_call(rcx, expr, Some(&**base),
|
||||
None::<ast::Expr>.iter(), true);
|
||||
ty::ty_fn_ret(method.ty)
|
||||
}
|
||||
None => rcx.resolve_node_type(base.id)
|
||||
|
|
@ -1080,11 +1078,11 @@ fn constrain_callee(rcx: &mut Rcx,
|
|||
}
|
||||
}
|
||||
|
||||
fn constrain_call(rcx: &mut Rcx,
|
||||
call_expr: &ast::Expr,
|
||||
receiver: Option<Gc<ast::Expr>>,
|
||||
arg_exprs: &[Gc<ast::Expr>],
|
||||
implicitly_ref_args: bool) {
|
||||
fn constrain_call<'a, I: Iterator<&'a ast::Expr>>(rcx: &mut Rcx,
|
||||
call_expr: &ast::Expr,
|
||||
receiver: Option<&ast::Expr>,
|
||||
mut arg_exprs: I,
|
||||
implicitly_ref_args: bool) {
|
||||
//! Invoked on every call site (i.e., normal calls, method calls,
|
||||
//! and overloaded operators). Constrains the regions which appear
|
||||
//! in the type of the function. Also constrains the regions that
|
||||
|
|
@ -1093,11 +1091,9 @@ fn constrain_call(rcx: &mut Rcx,
|
|||
let tcx = rcx.fcx.tcx();
|
||||
debug!("constrain_call(call_expr={}, \
|
||||
receiver={}, \
|
||||
arg_exprs={}, \
|
||||
implicitly_ref_args={:?})",
|
||||
call_expr.repr(tcx),
|
||||
receiver.repr(tcx),
|
||||
arg_exprs.repr(tcx),
|
||||
implicitly_ref_args);
|
||||
|
||||
// `callee_region` is the scope representing the time in which the
|
||||
|
|
@ -1109,7 +1105,7 @@ fn constrain_call(rcx: &mut Rcx,
|
|||
|
||||
debug!("callee_region={}", callee_region.repr(tcx));
|
||||
|
||||
for arg_expr in arg_exprs.iter() {
|
||||
for arg_expr in arg_exprs {
|
||||
debug!("Argument: {}", arg_expr.repr(tcx));
|
||||
|
||||
// ensure that any regions appearing in the argument type are
|
||||
|
|
@ -1123,7 +1119,7 @@ fn constrain_call(rcx: &mut Rcx,
|
|||
// result. modes are going away and the "DerefArgs" code
|
||||
// should be ported to use adjustments
|
||||
if implicitly_ref_args {
|
||||
link_by_ref(rcx, &**arg_expr, callee_scope);
|
||||
link_by_ref(rcx, arg_expr, callee_scope);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1292,10 +1288,10 @@ fn link_local(rcx: &Rcx, local: &ast::Local) {
|
|||
debug!("regionck::for_local()");
|
||||
let init_expr = match local.init {
|
||||
None => { return; }
|
||||
Some(ref expr) => expr,
|
||||
Some(ref expr) => &**expr,
|
||||
};
|
||||
let mc = mc::MemCategorizationContext::new(rcx);
|
||||
let discr_cmt = ignore_err!(mc.cat_expr(&**init_expr));
|
||||
let discr_cmt = ignore_err!(mc.cat_expr(init_expr));
|
||||
link_pattern(rcx, mc, discr_cmt, &*local.pat);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -597,7 +597,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
|||
ast_items.iter()
|
||||
.map(|ast_item| {
|
||||
match *ast_item {
|
||||
ast::MethodImplItem(ast_method) => {
|
||||
ast::MethodImplItem(ref ast_method) => {
|
||||
MethodTraitItemId(
|
||||
local_def(ast_method.id))
|
||||
}
|
||||
|
|
@ -820,9 +820,9 @@ fn subst_receiver_types_in_method_ty(tcx: &ty::ctxt,
|
|||
)
|
||||
}
|
||||
|
||||
pub fn check_coherence(crate_context: &CrateCtxt, krate: &Crate) {
|
||||
pub fn check_coherence(crate_context: &CrateCtxt) {
|
||||
CoherenceChecker {
|
||||
crate_context: crate_context,
|
||||
inference_context: new_infer_ctxt(crate_context.tcx),
|
||||
}.check(krate);
|
||||
}.check(crate_context.tcx.map.krate());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,22 +53,22 @@ use util::ppaux::{Repr,UserString};
|
|||
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::rc::Rc;
|
||||
use std::gc::Gc;
|
||||
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::ast_util::{local_def, split_trait_methods, PostExpansionMethod};
|
||||
use syntax::ast_util::{local_def, PostExpansionMethod};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::parse::token::{special_idents};
|
||||
use syntax::parse::token;
|
||||
use syntax::print::pprust::{path_to_string};
|
||||
use syntax::ptr::P;
|
||||
use syntax::visit;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Main entry point
|
||||
|
||||
pub fn collect_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
|
||||
pub fn collect_item_types(ccx: &CrateCtxt) {
|
||||
fn collect_intrinsic_type(ccx: &CrateCtxt,
|
||||
lang_item: ast::DefId) {
|
||||
let ty::Polytype { ty: ty, .. } =
|
||||
|
|
@ -84,10 +84,10 @@ pub fn collect_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
|
|||
}
|
||||
|
||||
let mut visitor = CollectTraitDefVisitor{ ccx: ccx };
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
visit::walk_crate(&mut visitor, ccx.tcx.map.krate());
|
||||
|
||||
let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
|
||||
visit::walk_crate(&mut visitor, krate);
|
||||
visit::walk_crate(&mut visitor, ccx.tcx.map.krate());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -179,7 +179,7 @@ impl<'a, 'tcx> AstConv<'tcx> for CrateCtxt<'a, 'tcx> {
|
|||
|
||||
pub fn get_enum_variant_types(ccx: &CrateCtxt,
|
||||
enum_ty: ty::t,
|
||||
variants: &[ast::P<ast::Variant>],
|
||||
variants: &[P<ast::Variant>],
|
||||
generics: &ast::Generics) {
|
||||
let tcx = ccx.tcx;
|
||||
|
||||
|
|
@ -199,13 +199,13 @@ pub fn get_enum_variant_types(ccx: &CrateCtxt,
|
|||
enum_ty
|
||||
}
|
||||
|
||||
ast::StructVariantKind(struct_def) => {
|
||||
ast::StructVariantKind(ref struct_def) => {
|
||||
let pty = Polytype {
|
||||
generics: ty_generics_for_type(ccx, generics),
|
||||
ty: enum_ty
|
||||
};
|
||||
|
||||
convert_struct(ccx, &*struct_def, pty, variant.node.id);
|
||||
convert_struct(ccx, &**struct_def, pty, variant.node.id);
|
||||
|
||||
let input_tys: Vec<_> = struct_def.fields.iter().map(
|
||||
|f| ty::node_id_to_type(ccx.tcx, f.node.id)).collect();
|
||||
|
|
@ -332,7 +332,7 @@ fn collect_trait_methods(ccx: &CrateCtxt,
|
|||
*m_id,
|
||||
*m_fn_style,
|
||||
trait_self_ty,
|
||||
*m_explicit_self,
|
||||
m_explicit_self,
|
||||
m_decl,
|
||||
m_abi);
|
||||
let ty_generics =
|
||||
|
|
@ -386,13 +386,12 @@ pub fn convert_field(ccx: &CrateCtxt,
|
|||
}
|
||||
}
|
||||
|
||||
fn convert_methods(ccx: &CrateCtxt,
|
||||
container: ImplOrTraitItemContainer,
|
||||
ms: &[Gc<ast::Method>],
|
||||
untransformed_rcvr_ty: ty::t,
|
||||
rcvr_ty_generics: &ty::Generics,
|
||||
rcvr_visibility: ast::Visibility)
|
||||
{
|
||||
fn convert_methods<'a, I: Iterator<&'a ast::Method>>(ccx: &CrateCtxt,
|
||||
container: ImplOrTraitItemContainer,
|
||||
mut ms: I,
|
||||
untransformed_rcvr_ty: ty::t,
|
||||
rcvr_ty_generics: &ty::Generics,
|
||||
rcvr_visibility: ast::Visibility) {
|
||||
debug!("convert_methods(untransformed_rcvr_ty={}, \
|
||||
rcvr_ty_generics={})",
|
||||
untransformed_rcvr_ty.repr(ccx.tcx),
|
||||
|
|
@ -400,14 +399,14 @@ fn convert_methods(ccx: &CrateCtxt,
|
|||
|
||||
let tcx = ccx.tcx;
|
||||
let mut seen_methods = HashSet::new();
|
||||
for m in ms.iter() {
|
||||
for m in ms {
|
||||
if !seen_methods.insert(m.pe_ident().repr(ccx.tcx)) {
|
||||
tcx.sess.span_err(m.span, "duplicate method in trait impl");
|
||||
}
|
||||
|
||||
let mty = Rc::new(ty_of_method(ccx,
|
||||
container,
|
||||
&**m,
|
||||
m,
|
||||
untransformed_rcvr_ty,
|
||||
rcvr_ty_generics,
|
||||
rcvr_visibility));
|
||||
|
|
@ -459,7 +458,7 @@ fn convert_methods(ccx: &CrateCtxt,
|
|||
m.id,
|
||||
m.pe_fn_style(),
|
||||
untransformed_rcvr_ty,
|
||||
*m.pe_explicit_self(),
|
||||
m.pe_explicit_self(),
|
||||
&*m.pe_fn_decl(),
|
||||
real_abi);
|
||||
|
||||
|
|
@ -524,10 +523,10 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
},
|
||||
ast::ItemImpl(ref generics,
|
||||
ref opt_trait_ref,
|
||||
selfty,
|
||||
ref selfty,
|
||||
ref impl_items) => {
|
||||
let ty_generics = ty_generics_for_type(ccx, generics);
|
||||
let selfty = ccx.to_ty(&ExplicitRscope, &*selfty);
|
||||
let selfty = ccx.to_ty(&ExplicitRscope, &**selfty);
|
||||
write_ty_to_tcx(tcx, it.id, selfty);
|
||||
|
||||
tcx.tcache.borrow_mut().insert(local_def(it.id),
|
||||
|
|
@ -554,14 +553,14 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
&BindingRscope::new(method.id),
|
||||
selfty,
|
||||
method.pe_explicit_self());
|
||||
methods.push(*method);
|
||||
methods.push(&**method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
convert_methods(ccx,
|
||||
ImplContainer(local_def(it.id)),
|
||||
methods.as_slice(),
|
||||
methods.move_iter(),
|
||||
selfty,
|
||||
&ty_generics,
|
||||
parent_visibility);
|
||||
|
|
@ -600,12 +599,13 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
}
|
||||
|
||||
// Run convert_methods on the provided methods.
|
||||
let (_, provided_methods) =
|
||||
split_trait_methods(trait_methods.as_slice());
|
||||
let untransformed_rcvr_ty = ty::mk_self_type(tcx, local_def(it.id));
|
||||
convert_methods(ccx,
|
||||
TraitContainer(local_def(it.id)),
|
||||
provided_methods.as_slice(),
|
||||
trait_methods.iter().filter_map(|m| match *m {
|
||||
ast::RequiredMethod(_) => None,
|
||||
ast::ProvidedMethod(ref m) => Some(&**m)
|
||||
}),
|
||||
untransformed_rcvr_ty,
|
||||
&trait_def.generics,
|
||||
it.vis);
|
||||
|
|
@ -615,7 +615,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
// static trait methods. This is somewhat unfortunate.
|
||||
collect_trait_methods(ccx, it.id, &*trait_def);
|
||||
},
|
||||
ast::ItemStruct(struct_def, _) => {
|
||||
ast::ItemStruct(ref struct_def, _) => {
|
||||
// Write the class type.
|
||||
let pty = ty_of_item(ccx, it);
|
||||
write_ty_to_tcx(tcx, it.id, pty.ty);
|
||||
|
|
@ -624,14 +624,14 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
|
|||
|
||||
// Write the super-struct type, if it exists.
|
||||
match struct_def.super_struct {
|
||||
Some(ty) => {
|
||||
let supserty = ccx.to_ty(&ExplicitRscope, &*ty);
|
||||
Some(ref ty) => {
|
||||
let supserty = ccx.to_ty(&ExplicitRscope, &**ty);
|
||||
write_ty_to_tcx(tcx, it.id, supserty);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
convert_struct(ccx, &*struct_def, pty, it.id);
|
||||
convert_struct(ccx, &**struct_def, pty, it.id);
|
||||
},
|
||||
ast::ItemTy(_, ref generics) => {
|
||||
ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
|
||||
|
|
@ -683,7 +683,7 @@ pub fn convert_struct(ccx: &CrateCtxt,
|
|||
tcx.struct_fields.borrow_mut().insert(local_def(id), Rc::new(field_tys));
|
||||
|
||||
let super_struct = match struct_def.super_struct {
|
||||
Some(t) => match t.node {
|
||||
Some(ref t) => match t.node {
|
||||
ast::TyPath(_, _, path_id) => {
|
||||
let def_map = tcx.def_map.borrow();
|
||||
match def_map.find(&path_id) {
|
||||
|
|
@ -692,7 +692,7 @@ pub fn convert_struct(ccx: &CrateCtxt,
|
|||
// Check super-struct is virtual.
|
||||
match tcx.map.find(def_id.node) {
|
||||
Some(ast_map::NodeItem(i)) => match i.node {
|
||||
ast::ItemStruct(struct_def, _) => {
|
||||
ast::ItemStruct(ref struct_def, _) => {
|
||||
if !struct_def.is_virtual {
|
||||
span_err!(tcx.sess, t.span, E0126,
|
||||
"struct inheritance is only \
|
||||
|
|
@ -908,21 +908,21 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
|
|||
_ => {}
|
||||
}
|
||||
match it.node {
|
||||
ast::ItemStatic(t, _, _) => {
|
||||
let typ = ccx.to_ty(&ExplicitRscope, &*t);
|
||||
ast::ItemStatic(ref t, _, _) => {
|
||||
let typ = ccx.to_ty(&ExplicitRscope, &**t);
|
||||
let pty = no_params(typ);
|
||||
|
||||
tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
|
||||
return pty;
|
||||
}
|
||||
ast::ItemFn(decl, fn_style, abi, ref generics, _) => {
|
||||
ast::ItemFn(ref decl, fn_style, abi, ref generics, _) => {
|
||||
let ty_generics = ty_generics_for_fn_or_method(ccx, generics,
|
||||
ty::Generics::empty());
|
||||
let tofd = astconv::ty_of_bare_fn(ccx,
|
||||
it.id,
|
||||
fn_style,
|
||||
abi,
|
||||
&*decl);
|
||||
&**decl);
|
||||
let pty = Polytype {
|
||||
generics: ty_generics,
|
||||
ty: ty::mk_bare_fn(ccx.tcx, tofd)
|
||||
|
|
@ -935,14 +935,14 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item)
|
|||
ccx.tcx.tcache.borrow_mut().insert(local_def(it.id), pty.clone());
|
||||
return pty;
|
||||
}
|
||||
ast::ItemTy(t, ref generics) => {
|
||||
ast::ItemTy(ref t, ref generics) => {
|
||||
match tcx.tcache.borrow_mut().find(&local_def(it.id)) {
|
||||
Some(pty) => return pty.clone(),
|
||||
None => { }
|
||||
}
|
||||
|
||||
let pty = {
|
||||
let ty = ccx.to_ty(&ExplicitRscope, &*t);
|
||||
let ty = ccx.to_ty(&ExplicitRscope, &**t);
|
||||
Polytype {
|
||||
generics: ty_generics_for_type(ccx, generics),
|
||||
ty: ty
|
||||
|
|
@ -990,17 +990,17 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt,
|
|||
abi: abi::Abi) -> ty::Polytype
|
||||
{
|
||||
match it.node {
|
||||
ast::ForeignItemFn(fn_decl, ref generics) => {
|
||||
ast::ForeignItemFn(ref fn_decl, ref generics) => {
|
||||
ty_of_foreign_fn_decl(ccx,
|
||||
&*fn_decl,
|
||||
&**fn_decl,
|
||||
local_def(it.id),
|
||||
generics,
|
||||
abi)
|
||||
}
|
||||
ast::ForeignItemStatic(t, _) => {
|
||||
ast::ForeignItemStatic(ref t, _) => {
|
||||
ty::Polytype {
|
||||
generics: ty::Generics::empty(),
|
||||
ty: ast_ty_to_ty(ccx, &ExplicitRscope, &*t)
|
||||
ty: ast_ty_to_ty(ccx, &ExplicitRscope, &**t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1163,8 +1163,8 @@ fn ty_generics(ccx: &CrateCtxt,
|
|||
¶m.unbound,
|
||||
param.span,
|
||||
where_clause);
|
||||
let default = param.default.map(|path| {
|
||||
let ty = ast_ty_to_ty(ccx, &ExplicitRscope, &*path);
|
||||
let default = param.default.as_ref().map(|path| {
|
||||
let ty = ast_ty_to_ty(ccx, &ExplicitRscope, &**path);
|
||||
let cur_idx = index;
|
||||
|
||||
ty::walk_ty(ty, |t| {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ time of error detection.
|
|||
*/
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::gc::GC;
|
||||
use middle::def;
|
||||
use middle::subst;
|
||||
use middle::ty;
|
||||
|
|
@ -84,12 +83,12 @@ use std::rc::Rc;
|
|||
use std::string::String;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::ast_util;
|
||||
use syntax::ast_util::{name_to_dummy_lifetime, PostExpansionMethod};
|
||||
use syntax::owned_slice::OwnedSlice;
|
||||
use syntax::codemap;
|
||||
use syntax::parse::token;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
use util::ppaux::bound_region_to_string;
|
||||
use util::ppaux::note_and_explain_region;
|
||||
|
||||
|
|
@ -161,7 +160,7 @@ trait ErrorReportingHelpers {
|
|||
decl: &ast::FnDecl,
|
||||
fn_style: ast::FnStyle,
|
||||
ident: ast::Ident,
|
||||
opt_explicit_self: Option<ast::ExplicitSelf_>,
|
||||
opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
||||
generics: &ast::Generics,
|
||||
span: codemap::Span);
|
||||
}
|
||||
|
|
@ -855,8 +854,8 @@ impl<'a, 'tcx> ErrorReporting for InferCtxt<'a, 'tcx> {
|
|||
Some(ref node) => match *node {
|
||||
ast_map::NodeItem(ref item) => {
|
||||
match item.node {
|
||||
ast::ItemFn(fn_decl, ref pur, _, ref gen, _) => {
|
||||
Some((fn_decl, gen, *pur, item.ident, None, item.span))
|
||||
ast::ItemFn(ref fn_decl, pur, _, ref gen, _) => {
|
||||
Some((&**fn_decl, gen, pur, item.ident, None, item.span))
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
|
|
@ -868,7 +867,7 @@ impl<'a, 'tcx> ErrorReporting for InferCtxt<'a, 'tcx> {
|
|||
m.pe_generics(),
|
||||
m.pe_fn_style(),
|
||||
m.pe_ident(),
|
||||
Some(m.pe_explicit_self().node),
|
||||
Some(&m.pe_explicit_self().node),
|
||||
m.span))
|
||||
}
|
||||
}
|
||||
|
|
@ -885,7 +884,7 @@ impl<'a, 'tcx> ErrorReporting for InferCtxt<'a, 'tcx> {
|
|||
generics, same_regions, &life_giver);
|
||||
let (fn_decl, expl_self, generics) = rebuilder.rebuild();
|
||||
self.give_expl_lifetime_param(&fn_decl, fn_style, ident,
|
||||
expl_self, &generics, span);
|
||||
expl_self.as_ref(), &generics, span);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -902,8 +901,8 @@ struct RebuildPathInfo<'a> {
|
|||
|
||||
struct Rebuilder<'a, 'tcx: 'a> {
|
||||
tcx: &'a ty::ctxt<'tcx>,
|
||||
fn_decl: ast::P<ast::FnDecl>,
|
||||
expl_self_opt: Option<ast::ExplicitSelf_>,
|
||||
fn_decl: &'a ast::FnDecl,
|
||||
expl_self_opt: Option<&'a ast::ExplicitSelf_>,
|
||||
generics: &'a ast::Generics,
|
||||
same_regions: &'a [SameRegions],
|
||||
life_giver: &'a LifeGiver,
|
||||
|
|
@ -918,8 +917,8 @@ enum FreshOrKept {
|
|||
|
||||
impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
||||
fn new(tcx: &'a ty::ctxt<'tcx>,
|
||||
fn_decl: ast::P<ast::FnDecl>,
|
||||
expl_self_opt: Option<ast::ExplicitSelf_>,
|
||||
fn_decl: &'a ast::FnDecl,
|
||||
expl_self_opt: Option<&'a ast::ExplicitSelf_>,
|
||||
generics: &'a ast::Generics,
|
||||
same_regions: &'a [SameRegions],
|
||||
life_giver: &'a LifeGiver)
|
||||
|
|
@ -938,9 +937,9 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
|
||||
fn rebuild(&self)
|
||||
-> (ast::FnDecl, Option<ast::ExplicitSelf_>, ast::Generics) {
|
||||
let mut expl_self_opt = self.expl_self_opt;
|
||||
let mut expl_self_opt = self.expl_self_opt.map(|x| x.clone());
|
||||
let mut inputs = self.fn_decl.inputs.clone();
|
||||
let mut output = self.fn_decl.output;
|
||||
let mut output = self.fn_decl.output.clone();
|
||||
let mut ty_params = self.generics.ty_params.clone();
|
||||
let where_clause = self.generics.where_clause.clone();
|
||||
let mut kept_lifetimes = HashSet::new();
|
||||
|
|
@ -958,7 +957,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
&anon_nums, ®ion_names);
|
||||
inputs = self.rebuild_args_ty(inputs.as_slice(), lifetime,
|
||||
&anon_nums, ®ion_names);
|
||||
output = self.rebuild_arg_ty_or_output(output, lifetime,
|
||||
output = self.rebuild_arg_ty_or_output(&*output, lifetime,
|
||||
&anon_nums, ®ion_names);
|
||||
ty_params = self.rebuild_ty_params(ty_params, lifetime,
|
||||
®ion_names);
|
||||
|
|
@ -1068,7 +1067,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
id: ty_param.id,
|
||||
bounds: bounds,
|
||||
unbound: ty_param.unbound.clone(),
|
||||
default: ty_param.default,
|
||||
default: ty_param.default.clone(),
|
||||
span: ty_param.span,
|
||||
}
|
||||
})
|
||||
|
|
@ -1087,8 +1086,8 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
// be passing down a map.
|
||||
ast::RegionTyParamBound(lt)
|
||||
}
|
||||
&ast::UnboxedFnTyParamBound(unboxed_function_type) => {
|
||||
ast::UnboxedFnTyParamBound(unboxed_function_type)
|
||||
&ast::UnboxedFnTyParamBound(ref unboxed_function_type) => {
|
||||
ast::UnboxedFnTyParamBound((*unboxed_function_type).clone())
|
||||
}
|
||||
&ast::TraitTyParamBound(ref tr) => {
|
||||
let last_seg = tr.path.segments.last().unwrap();
|
||||
|
|
@ -1122,7 +1121,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
region_names: &HashSet<ast::Name>)
|
||||
-> Option<ast::ExplicitSelf_> {
|
||||
match expl_self_opt {
|
||||
Some(expl_self) => match expl_self {
|
||||
Some(ref expl_self) => match *expl_self {
|
||||
ast::SelfRegion(lt_opt, muta, id) => match lt_opt {
|
||||
Some(lt) => if region_names.contains(<.name) {
|
||||
return Some(ast::SelfRegion(Some(lifetime), muta, id));
|
||||
|
|
@ -1177,11 +1176,11 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
-> Vec<ast::Arg> {
|
||||
let mut new_inputs = Vec::new();
|
||||
for arg in inputs.iter() {
|
||||
let new_ty = self.rebuild_arg_ty_or_output(arg.ty, lifetime,
|
||||
let new_ty = self.rebuild_arg_ty_or_output(&*arg.ty, lifetime,
|
||||
anon_nums, region_names);
|
||||
let possibly_new_arg = ast::Arg {
|
||||
ty: new_ty,
|
||||
pat: arg.pat,
|
||||
pat: arg.pat.clone(),
|
||||
id: arg.id
|
||||
};
|
||||
new_inputs.push(possibly_new_arg);
|
||||
|
|
@ -1190,36 +1189,40 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn rebuild_arg_ty_or_output(&self,
|
||||
ty: ast::P<ast::Ty>,
|
||||
ty: &ast::Ty,
|
||||
lifetime: ast::Lifetime,
|
||||
anon_nums: &HashSet<uint>,
|
||||
region_names: &HashSet<ast::Name>)
|
||||
-> ast::P<ast::Ty> {
|
||||
let mut new_ty = ty;
|
||||
-> P<ast::Ty> {
|
||||
let mut new_ty = P(ty.clone());
|
||||
let mut ty_queue = vec!(ty);
|
||||
let mut cur_ty;
|
||||
while !ty_queue.is_empty() {
|
||||
cur_ty = ty_queue.shift().unwrap();
|
||||
let cur_ty = ty_queue.shift().unwrap();
|
||||
match cur_ty.node {
|
||||
ast::TyRptr(lt_opt, mut_ty) => {
|
||||
match lt_opt {
|
||||
Some(lt) => if region_names.contains(<.name) {
|
||||
new_ty = self.rebuild_ty(new_ty, cur_ty,
|
||||
lifetime, None);
|
||||
},
|
||||
ast::TyRptr(lt_opt, ref mut_ty) => {
|
||||
let rebuild = match lt_opt {
|
||||
Some(lt) => region_names.contains(<.name),
|
||||
None => {
|
||||
let anon = self.cur_anon.get();
|
||||
if anon_nums.contains(&anon) {
|
||||
new_ty = self.rebuild_ty(new_ty, cur_ty,
|
||||
lifetime, None);
|
||||
let rebuild = anon_nums.contains(&anon);
|
||||
if rebuild {
|
||||
self.track_anon(anon);
|
||||
}
|
||||
self.inc_and_offset_cur_anon(1);
|
||||
rebuild
|
||||
}
|
||||
};
|
||||
if rebuild {
|
||||
let to = ast::Ty {
|
||||
id: cur_ty.id,
|
||||
node: ast::TyRptr(Some(lifetime), mut_ty.clone()),
|
||||
span: cur_ty.span
|
||||
};
|
||||
new_ty = self.rebuild_ty(new_ty, P(to));
|
||||
}
|
||||
ty_queue.push(mut_ty.ty);
|
||||
ty_queue.push(&*mut_ty.ty);
|
||||
}
|
||||
ast::TyPath(ref path, _, id) => {
|
||||
ast::TyPath(ref path, ref bounds, id) => {
|
||||
let a_def = match self.tcx.def_map.borrow().find(&id) {
|
||||
None => {
|
||||
self.tcx
|
||||
|
|
@ -1232,10 +1235,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
};
|
||||
match a_def {
|
||||
def::DefTy(did) | def::DefStruct(did) => {
|
||||
let ty::Polytype {
|
||||
generics: generics,
|
||||
ty: _
|
||||
} = ty::lookup_item_type(self.tcx, did);
|
||||
let generics = ty::lookup_item_type(self.tcx, did).generics;
|
||||
|
||||
let expected =
|
||||
generics.regions.len(subst::TypeSpace);
|
||||
|
|
@ -1266,85 +1266,77 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
anon_nums: anon_nums,
|
||||
region_names: region_names
|
||||
};
|
||||
new_ty = self.rebuild_ty(new_ty, cur_ty,
|
||||
lifetime,
|
||||
Some(rebuild_info));
|
||||
let new_path = self.rebuild_path(rebuild_info, lifetime);
|
||||
let to = ast::Ty {
|
||||
id: cur_ty.id,
|
||||
node: ast::TyPath(new_path, bounds.clone(), id),
|
||||
span: cur_ty.span
|
||||
};
|
||||
new_ty = self.rebuild_ty(new_ty, P(to));
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
}
|
||||
_ => ty_queue.push_all_move(ast_util::get_inner_tys(cur_ty))
|
||||
|
||||
ast::TyPtr(ref mut_ty) => {
|
||||
ty_queue.push(&*mut_ty.ty);
|
||||
}
|
||||
ast::TyBox(ref ty) |
|
||||
ast::TyVec(ref ty) |
|
||||
ast::TyUniq(ref ty) |
|
||||
ast::TyFixedLengthVec(ref ty, _) => {
|
||||
ty_queue.push(&**ty);
|
||||
}
|
||||
ast::TyTup(ref tys) => ty_queue.extend(tys.iter().map(|ty| &**ty)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
new_ty
|
||||
}
|
||||
|
||||
fn rebuild_ty(&self,
|
||||
from: ast::P<ast::Ty>,
|
||||
to: ast::P<ast::Ty>,
|
||||
lifetime: ast::Lifetime,
|
||||
rebuild_path_info: Option<RebuildPathInfo>)
|
||||
-> ast::P<ast::Ty> {
|
||||
from: P<ast::Ty>,
|
||||
to: P<ast::Ty>)
|
||||
-> P<ast::Ty> {
|
||||
|
||||
fn build_to(from: ast::P<ast::Ty>,
|
||||
to: ast::P<ast::Ty>)
|
||||
-> ast::P<ast::Ty> {
|
||||
if from.id == to.id {
|
||||
return to;
|
||||
fn build_to(from: P<ast::Ty>,
|
||||
to: &mut Option<P<ast::Ty>>)
|
||||
-> P<ast::Ty> {
|
||||
if Some(from.id) == to.as_ref().map(|ty| ty.id) {
|
||||
return to.take().expect("`to` type found more than once during rebuild");
|
||||
}
|
||||
let new_node = match from.node {
|
||||
ast::TyRptr(ref lifetime, ref mut_ty) => {
|
||||
let new_mut_ty = ast::MutTy {
|
||||
ty: build_to(mut_ty.ty, to),
|
||||
mutbl: mut_ty.mutbl
|
||||
};
|
||||
ast::TyRptr(*lifetime, new_mut_ty)
|
||||
}
|
||||
ast::TyPtr(ref mut_ty) => {
|
||||
let new_mut_ty = ast::MutTy {
|
||||
ty: build_to(mut_ty.ty, to),
|
||||
mutbl: mut_ty.mutbl
|
||||
};
|
||||
ast::TyPtr(new_mut_ty)
|
||||
}
|
||||
ast::TyBox(ref ty) => ast::TyBox(build_to(*ty, to)),
|
||||
ast::TyVec(ref ty) => ast::TyVec(build_to(*ty, to)),
|
||||
ast::TyUniq(ref ty) => ast::TyUniq(build_to(*ty, to)),
|
||||
ast::TyFixedLengthVec(ref ty, ref e) => {
|
||||
ast::TyFixedLengthVec(build_to(*ty, to), *e)
|
||||
}
|
||||
ast::TyTup(ref tys) => {
|
||||
let mut new_tys = Vec::new();
|
||||
for ty in tys.iter() {
|
||||
new_tys.push(build_to(*ty, to));
|
||||
from.map(|ast::Ty {id, node, span}| {
|
||||
let new_node = match node {
|
||||
ast::TyRptr(lifetime, mut_ty) => {
|
||||
ast::TyRptr(lifetime, ast::MutTy {
|
||||
mutbl: mut_ty.mutbl,
|
||||
ty: build_to(mut_ty.ty, to),
|
||||
})
|
||||
}
|
||||
ast::TyTup(new_tys)
|
||||
}
|
||||
ast::TyParen(ref typ) => ast::TyParen(build_to(*typ, to)),
|
||||
ref other => other.clone()
|
||||
};
|
||||
box(GC) ast::Ty { id: from.id, node: new_node, span: from.span }
|
||||
ast::TyPtr(mut_ty) => {
|
||||
ast::TyPtr(ast::MutTy {
|
||||
mutbl: mut_ty.mutbl,
|
||||
ty: build_to(mut_ty.ty, to),
|
||||
})
|
||||
}
|
||||
ast::TyBox(ty) => ast::TyBox(build_to(ty, to)),
|
||||
ast::TyVec(ty) => ast::TyVec(build_to(ty, to)),
|
||||
ast::TyUniq(ty) => ast::TyUniq(build_to(ty, to)),
|
||||
ast::TyFixedLengthVec(ty, e) => {
|
||||
ast::TyFixedLengthVec(build_to(ty, to), e)
|
||||
}
|
||||
ast::TyTup(tys) => {
|
||||
ast::TyTup(tys.move_iter().map(|ty| build_to(ty, to)).collect())
|
||||
}
|
||||
ast::TyParen(typ) => ast::TyParen(build_to(typ, to)),
|
||||
other => other
|
||||
};
|
||||
ast::Ty { id: id, node: new_node, span: span }
|
||||
})
|
||||
}
|
||||
|
||||
let new_ty_node = match to.node {
|
||||
ast::TyRptr(_, mut_ty) => ast::TyRptr(Some(lifetime), mut_ty),
|
||||
ast::TyPath(_, ref bounds, id) => {
|
||||
let rebuild_info = match rebuild_path_info {
|
||||
Some(ri) => ri,
|
||||
None => fail!("expect index_opt in rebuild_ty/ast::TyPath")
|
||||
};
|
||||
let new_path = self.rebuild_path(rebuild_info, lifetime);
|
||||
ast::TyPath(new_path, bounds.clone(), id)
|
||||
}
|
||||
_ => fail!("expect ast::TyRptr or ast::TyPath")
|
||||
};
|
||||
let new_ty = box(GC) ast::Ty {
|
||||
id: to.id,
|
||||
node: new_ty_node,
|
||||
span: to.span
|
||||
};
|
||||
build_to(from, new_ty)
|
||||
build_to(from, &mut Some(to))
|
||||
}
|
||||
|
||||
fn rebuild_path(&self,
|
||||
|
|
@ -1384,8 +1376,8 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
let new_types = last_seg.types.map(|&t| {
|
||||
self.rebuild_arg_ty_or_output(t, lifetime, anon_nums, region_names)
|
||||
let new_types = last_seg.types.map(|t| {
|
||||
self.rebuild_arg_ty_or_output(&**t, lifetime, anon_nums, region_names)
|
||||
});
|
||||
let new_seg = ast::PathSegment {
|
||||
identifier: last_seg.identifier,
|
||||
|
|
@ -1408,7 +1400,7 @@ impl<'a, 'tcx> ErrorReportingHelpers for InferCtxt<'a, 'tcx> {
|
|||
decl: &ast::FnDecl,
|
||||
fn_style: ast::FnStyle,
|
||||
ident: ast::Ident,
|
||||
opt_explicit_self: Option<ast::ExplicitSelf_>,
|
||||
opt_explicit_self: Option<&ast::ExplicitSelf_>,
|
||||
generics: &ast::Generics,
|
||||
span: codemap::Span) {
|
||||
let suggested_fn = pprust::fun_to_string(decl, fn_style, ident,
|
||||
|
|
@ -1686,7 +1678,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
|
|||
},
|
||||
ast_map::NodeImplItem(ii) => {
|
||||
match *ii {
|
||||
ast::MethodImplItem(m) => {
|
||||
ast::MethodImplItem(ref m) => {
|
||||
taken.push_all(m.pe_generics().lifetimes.as_slice());
|
||||
Some(m.id)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,13 +36,12 @@ use middle::typeck::infer::glb::Glb;
|
|||
use syntax::codemap;
|
||||
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
|
||||
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
|
||||
use syntax::ast;
|
||||
use syntax::{ast, ast_map};
|
||||
use util::ppaux::{ty_to_string, UserString};
|
||||
|
||||
use arena::TypedArena;
|
||||
|
||||
struct Env<'a, 'tcx: 'a> {
|
||||
krate: ast::Crate,
|
||||
infcx: &'a infer::InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
|
|
@ -117,19 +116,22 @@ fn test_env(_test_name: &str,
|
|||
let krate_config = Vec::new();
|
||||
let input = driver::StrInput(source_string.to_string());
|
||||
let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
|
||||
let (krate, ast_map) =
|
||||
driver::phase_2_configure_and_expand(&sess, krate, "test", None)
|
||||
.expect("phase 2 aborted");
|
||||
let krate = driver::phase_2_configure_and_expand(&sess, krate, "test", None)
|
||||
.expect("phase 2 aborted");
|
||||
|
||||
let mut forest = ast_map::Forest::new(krate);
|
||||
let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest);
|
||||
let krate = ast_map.krate();
|
||||
|
||||
// run just enough stuff to build a tcx:
|
||||
let lang_items = lang_items::collect_language_items(&krate, &sess);
|
||||
let lang_items = lang_items::collect_language_items(krate, &sess);
|
||||
let resolve::CrateMap { def_map: def_map, .. } =
|
||||
resolve::resolve_crate(&sess, &lang_items, &krate);
|
||||
resolve::resolve_crate(&sess, &lang_items, krate);
|
||||
let (freevars_map, captures_map) = freevars::annotate_freevars(&def_map,
|
||||
&krate);
|
||||
let named_region_map = resolve_lifetime::krate(&sess, &krate);
|
||||
let region_map = region::resolve_crate(&sess, &krate);
|
||||
let stability_index = stability::Index::build(&krate);
|
||||
krate);
|
||||
let named_region_map = resolve_lifetime::krate(&sess, krate);
|
||||
let region_map = region::resolve_crate(&sess, krate);
|
||||
let stability_index = stability::Index::build(krate);
|
||||
let type_arena = TypedArena::new();
|
||||
let tcx = ty::mk_ctxt(sess,
|
||||
&type_arena,
|
||||
|
|
@ -142,11 +144,7 @@ fn test_env(_test_name: &str,
|
|||
lang_items,
|
||||
stability_index);
|
||||
let infcx = infer::new_infer_ctxt(&tcx);
|
||||
let env = Env {
|
||||
krate: krate,
|
||||
infcx: &infcx
|
||||
};
|
||||
body(env);
|
||||
body(Env { infcx: &infcx });
|
||||
infcx.resolve_regions_and_report_errors();
|
||||
assert_eq!(tcx.sess.err_count(), expected_err_count);
|
||||
}
|
||||
|
|
@ -171,7 +169,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
|
|||
}
|
||||
|
||||
pub fn lookup_item(&self, names: &[String]) -> ast::NodeId {
|
||||
return match search_mod(self, &self.krate.module, 0, names) {
|
||||
return match search_mod(self, &self.infcx.tcx.map.krate().module, 0, names) {
|
||||
Some(id) => id,
|
||||
None => {
|
||||
fail!("no item found: `{}`", names.connect("::"));
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ pub fn write_substs_to_tcx(tcx: &ty::ctxt,
|
|||
}
|
||||
pub fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def {
|
||||
match tcx.def_map.borrow().find(&id) {
|
||||
Some(&x) => x,
|
||||
Some(x) => x.clone(),
|
||||
_ => {
|
||||
tcx.sess.span_fatal(sp, "internal error looking up a definition")
|
||||
}
|
||||
|
|
@ -474,9 +474,7 @@ fn check_for_entry_fn(ccx: &CrateCtxt) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: &ty::ctxt,
|
||||
trait_map: resolve::TraitMap,
|
||||
krate: &ast::Crate) {
|
||||
pub fn check_crate(tcx: &ty::ctxt, trait_map: resolve::TraitMap) {
|
||||
let time_passes = tcx.sess.time_passes();
|
||||
let ccx = CrateCtxt {
|
||||
trait_map: trait_map,
|
||||
|
|
@ -484,20 +482,20 @@ pub fn check_crate(tcx: &ty::ctxt,
|
|||
};
|
||||
|
||||
time(time_passes, "type collecting", (), |_|
|
||||
collect::collect_item_types(&ccx, krate));
|
||||
collect::collect_item_types(&ccx));
|
||||
|
||||
// this ensures that later parts of type checking can assume that items
|
||||
// have valid types and not error
|
||||
tcx.sess.abort_if_errors();
|
||||
|
||||
time(time_passes, "variance inference", (), |_|
|
||||
variance::infer_variance(tcx, krate));
|
||||
variance::infer_variance(tcx));
|
||||
|
||||
time(time_passes, "coherence checking", (), |_|
|
||||
coherence::check_coherence(&ccx, krate));
|
||||
coherence::check_coherence(&ccx));
|
||||
|
||||
time(time_passes, "type checking", (), |_|
|
||||
check::check_item_types(&ccx, krate));
|
||||
check::check_item_types(&ccx));
|
||||
|
||||
check_for_entry_fn(&ccx);
|
||||
tcx.sess.abort_if_errors();
|
||||
|
|
|
|||
|
|
@ -208,8 +208,8 @@ use syntax::visit;
|
|||
use syntax::visit::Visitor;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
pub fn infer_variance(tcx: &ty::ctxt,
|
||||
krate: &ast::Crate) {
|
||||
pub fn infer_variance(tcx: &ty::ctxt) {
|
||||
let krate = tcx.map.krate();
|
||||
let mut arena = arena::Arena::new();
|
||||
let terms_cx = determine_parameters_to_be_inferred(tcx, &mut arena, krate);
|
||||
let constraints_cx = add_constraints_from_crate(terms_cx, krate);
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ impl<'a, 'v> Visitor<'v> for BlockQueryVisitor<'a> {
|
|||
|
||||
// Takes a predicate p, returns true iff p is true for any subexpressions
|
||||
// of b -- skipping any inner loops (loop, while, loop_body)
|
||||
pub fn block_query(b: ast::P<ast::Block>, p: |&ast::Expr| -> bool) -> bool {
|
||||
pub fn block_query(b: &ast::Block, p: |&ast::Expr| -> bool) -> bool {
|
||||
let mut v = BlockQueryVisitor {
|
||||
p: p,
|
||||
flag: false,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ use middle::typeck;
|
|||
use middle::typeck::check::regionmanip;
|
||||
use middle::typeck::infer;
|
||||
|
||||
use std::gc::Gc;
|
||||
use std::rc::Rc;
|
||||
use syntax::abi;
|
||||
use syntax::ast_map;
|
||||
|
|
@ -546,9 +545,9 @@ impl<T:Repr> Repr for Rc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:Repr + 'static> Repr for Gc<T> {
|
||||
impl<'a, T:Repr> Repr for &'a T {
|
||||
fn repr(&self, tcx: &ctxt) -> String {
|
||||
(&**self).repr(tcx)
|
||||
(*self).repr(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -822,21 +821,19 @@ impl Repr for ast::DefId {
|
|||
// a path for a def-id, so I'll just make a best effort for now
|
||||
// and otherwise fallback to just printing the crate/node pair
|
||||
if self.krate == ast::LOCAL_CRATE {
|
||||
{
|
||||
match tcx.map.find(self.node) {
|
||||
Some(ast_map::NodeItem(..)) |
|
||||
Some(ast_map::NodeForeignItem(..)) |
|
||||
Some(ast_map::NodeImplItem(..)) |
|
||||
Some(ast_map::NodeTraitItem(..)) |
|
||||
Some(ast_map::NodeVariant(..)) |
|
||||
Some(ast_map::NodeStructCtor(..)) => {
|
||||
return format!(
|
||||
match tcx.map.find(self.node) {
|
||||
Some(ast_map::NodeItem(..)) |
|
||||
Some(ast_map::NodeForeignItem(..)) |
|
||||
Some(ast_map::NodeImplItem(..)) |
|
||||
Some(ast_map::NodeTraitItem(..)) |
|
||||
Some(ast_map::NodeVariant(..)) |
|
||||
Some(ast_map::NodeStructCtor(..)) => {
|
||||
return format!(
|
||||
"{:?}:{}",
|
||||
*self,
|
||||
ty::item_path_str(tcx, *self))
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
return format!("{:?}", *self)
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ mod svh_visitor {
|
|||
ExprTup(..) => SawExprTup,
|
||||
ExprBinary(op, _, _) => SawExprBinary(op),
|
||||
ExprUnary(op, _) => SawExprUnary(op),
|
||||
ExprLit(lit) => SawExprLit(lit.node.clone()),
|
||||
ExprLit(ref lit) => SawExprLit(lit.node.clone()),
|
||||
ExprCast(..) => SawExprCast,
|
||||
ExprIf(..) => SawExprIf,
|
||||
ExprWhile(..) => SawExprWhile,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue