rustc: fix fallout from using ptr::P.

This commit is contained in:
Eduard Burtescu 2014-09-07 20:09:06 +03:00
parent d379ad111c
commit b06212864f
64 changed files with 1978 additions and 2092 deletions

View file

@ -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

View 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 => {

View file

@ -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)
}

View file

@ -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 })
}

View file

@ -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())
}

View file

@ -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(),
_ => {

View file

@ -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)
}
}

View file

@ -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.

View file

@ -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;
}

View file

@ -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));
}
}
}

View file

@ -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.

View file

@ -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)

View file

@ -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_ {

View file

@ -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

View file

@ -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>,

View file

@ -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)

View file

@ -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 => {

View file

@ -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() }

View file

@ -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");

View file

@ -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(_), _, _) => {

View file

@ -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> {

View file

@ -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 {

View file

@ -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 };

View file

@ -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());
}

View file

@ -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);
}

View file

@ -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,

View file

@ -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());
}

View file

@ -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();
}

View file

@ -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);

View file

@ -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,

View file

@ -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,

View file

@ -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(),

View file

@ -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())
}
}
}

View file

@ -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;
}
_ => {

View file

@ -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, _, _) => {

View file

@ -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)

View file

@ -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(..) => {

View file

@ -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());

View file

@ -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();

View file

@ -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,

View file

@ -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());

View file

@ -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(_)) => {

View file

@ -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;

View file

@ -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() {

View file

@ -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;

View file

@ -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();

View file

@ -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,
&param_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);
}
}
}

View file

@ -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

View file

@ -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(),
_ => {

View file

@ -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())
}

View file

@ -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());

View file

@ -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,

View file

@ -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| {

View file

@ -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);
}

View file

@ -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());
}

View file

@ -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,
&param.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| {

View file

@ -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, &region_names);
inputs = self.rebuild_args_ty(inputs.as_slice(), lifetime,
&anon_nums, &region_names);
output = self.rebuild_arg_ty_or_output(output, lifetime,
output = self.rebuild_arg_ty_or_output(&*output, lifetime,
&anon_nums, &region_names);
ty_params = self.rebuild_ty_params(ty_params, lifetime,
&region_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(&lt.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(&lt.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(&lt.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)
}

View file

@ -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("::"));

View file

@ -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();

View file

@ -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);

View file

@ -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,

View file

@ -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)

View file

@ -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,