rustc: de-@ middle::ty.

This commit is contained in:
Eduard Burtescu 2014-04-22 02:21:52 +03:00
parent 1e5a112922
commit 57aa0eb0aa
33 changed files with 440 additions and 435 deletions

View file

@ -107,10 +107,10 @@ pub fn maybe_get_item_ast(tcx: &ty::ctxt, def: ast::DefId,
}
pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId)
-> Vec<@ty::VariantInfo> {
-> Vec<Rc<ty::VariantInfo>> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
return decoder::get_enum_variants(cstore.intr.clone(), &*cdata, def.node, tcx)
decoder::get_enum_variants(cstore.intr.clone(), &*cdata, def.node, tcx)
}
/// Returns information about the given implementation.
@ -147,13 +147,13 @@ pub fn get_item_variances(cstore: &cstore::CStore,
pub fn get_provided_trait_methods(tcx: &ty::ctxt,
def: ast::DefId)
-> Vec<@ty::Method> {
-> Vec<Rc<ty::Method>> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx)
}
pub fn get_supertraits(tcx: &ty::ctxt, def: ast::DefId) -> Vec<@ty::TraitRef> {
pub fn get_supertraits(tcx: &ty::ctxt, def: ast::DefId) -> Vec<Rc<ty::TraitRef>> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_supertraits(&*cdata, def.node, tcx)
@ -224,7 +224,7 @@ pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId,
// Given a def_id for an impl, return the trait it implements,
// if there is one.
pub fn get_impl_trait(tcx: &ty::ctxt,
def: ast::DefId) -> Option<@ty::TraitRef> {
def: ast::DefId) -> Option<Rc<ty::TraitRef>> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_impl_trait(&*cdata, def.node, tcx)

View file

@ -386,7 +386,7 @@ pub fn get_trait_def(cdata: Cmd,
generics: ty::Generics {type_param_defs: tp_defs,
region_param_defs: rp_defs},
bounds: bounds,
trait_ref: @item_trait_ref(item_doc, tcx, cdata)
trait_ref: Rc::new(item_trait_ref(item_doc, tcx, cdata))
}
}
@ -410,11 +410,11 @@ pub fn get_type(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
pub fn get_impl_trait(cdata: Cmd,
id: ast::NodeId,
tcx: &ty::ctxt) -> Option<@ty::TraitRef>
tcx: &ty::ctxt) -> Option<Rc<ty::TraitRef>>
{
let item_doc = lookup_item(id, cdata.data());
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
@doc_trait_ref(tp, tcx, cdata)
Rc::new(doc_trait_ref(tp, tcx, cdata))
})
}
@ -675,27 +675,27 @@ pub fn maybe_get_item_ast(cdata: Cmd, tcx: &ty::ctxt, id: ast::NodeId,
}
pub fn get_enum_variants(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
tcx: &ty::ctxt) -> Vec<@ty::VariantInfo> {
tcx: &ty::ctxt) -> Vec<Rc<ty::VariantInfo>> {
let data = cdata.data();
let items = reader::get_doc(reader::Doc(data), tag_items);
let item = find_item(id, items);
let mut infos: Vec<@ty::VariantInfo> = Vec::new();
let variant_ids = enum_variant_ids(item, cdata);
let mut disr_val = 0;
for did in variant_ids.iter() {
enum_variant_ids(item, cdata).iter().map(|did| {
let item = find_item(did.node, items);
let ctor_ty = item_type(ast::DefId { krate: cdata.cnum, node: id},
item, tcx, cdata);
let name = item_name(&*intr, item);
let arg_tys = match ty::get(ctor_ty).sty {
ty::ty_bare_fn(ref f) => f.sig.inputs.clone(),
_ => Vec::new(), // Nullary enum variant.
ty::ty_bare_fn(ref f) => f.sig.inputs.clone(),
_ => Vec::new(), // Nullary enum variant.
};
match variant_disr_val(item) {
Some(val) => { disr_val = val; }
_ => { /* empty */ }
Some(val) => { disr_val = val; }
_ => { /* empty */ }
}
infos.push(@ty::VariantInfo{
let old_disr_val = disr_val;
disr_val += 1;
Rc::new(ty::VariantInfo {
args: arg_tys,
arg_names: None,
ctor_ty: ctor_ty,
@ -703,11 +703,10 @@ pub fn get_enum_variants(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
// I'm not even sure if we encode visibility
// for variants -- TEST -- tjc
id: *did,
disr_val: disr_val,
vis: ast::Inherited});
disr_val += 1;
}
return infos;
disr_val: old_disr_val,
vis: ast::Inherited
})
}).collect()
}
fn get_explicit_self(item: ebml::Doc) -> ast::ExplicitSelf_ {
@ -816,8 +815,8 @@ pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances {
}
pub fn get_provided_trait_methods(intr: Rc<IdentInterner>, cdata: Cmd,
id: ast::NodeId, tcx: &ty::ctxt) ->
Vec<@ty::Method> {
id: ast::NodeId, tcx: &ty::ctxt)
-> Vec<Rc<ty::Method>> {
let data = cdata.data();
let item = lookup_item(id, data);
let mut result = Vec::new();
@ -827,7 +826,7 @@ pub fn get_provided_trait_methods(intr: Rc<IdentInterner>, cdata: Cmd,
let mth = lookup_item(did.node, data);
if item_method_sort(mth) == 'p' {
result.push(@get_method(intr.clone(), cdata, did.node, tcx));
result.push(Rc::new(get_method(intr.clone(), cdata, did.node, tcx)));
}
true
});
@ -837,7 +836,7 @@ pub fn get_provided_trait_methods(intr: Rc<IdentInterner>, cdata: Cmd,
/// Returns the supertraits of the given trait.
pub fn get_supertraits(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
-> Vec<@ty::TraitRef> {
-> Vec<Rc<ty::TraitRef>> {
let mut results = Vec::new();
let item_doc = lookup_item(id, cdata.data());
reader::tagged_docs(item_doc, tag_item_super_trait_ref, |trait_doc| {
@ -846,7 +845,7 @@ pub fn get_supertraits(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
// FIXME(#8559): The builtin bounds shouldn't be encoded in the first place.
let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() {
results.push(@trait_ref);
results.push(Rc::new(trait_ref));
}
true
});

View file

@ -422,7 +422,7 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext,
-> bool {
match ecx.tcx.trait_methods_cache.borrow().find(&exp.def_id) {
Some(methods) => {
for &m in methods.iter() {
for m in methods.iter() {
if m.explicit_self == ast::SelfStatic {
encode_reexported_static_method(ebml_w, exp, m.def_id, m.ident);
}
@ -1057,7 +1057,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
for ast_trait_ref in opt_trait.iter() {
let trait_ref = ty::node_id_to_trait_ref(
tcx, ast_trait_ref.ref_id);
encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_trait_ref);
encode_trait_ref(ebml_w, ecx, &*trait_ref, tag_item_trait_ref);
let impl_vtables = ty::lookup_impl_vtables(tcx, def_id);
encode_impl_vtables(ebml_w, ecx, &impl_vtables);
}
@ -1078,10 +1078,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
val: method_def_id.node as i64,
pos: ebml_w.writer.tell().unwrap(),
});
let m = ty::method(tcx, method_def_id);
encode_info_for_method(ecx,
ebml_w,
m,
&*ty::method(tcx, method_def_id),
path.clone(),
false,
item.id,
@ -1099,7 +1098,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
trait_def.generics.type_param_defs(),
tag_items_data_item_ty_param_bounds);
encode_region_param_defs(ebml_w, trait_def.generics.region_param_defs());
encode_trait_ref(ebml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
encode_trait_ref(ebml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
encode_name(ebml_w, item.ident.name);
encode_attributes(ebml_w, item.attrs.as_slice());
encode_visibility(ebml_w, vis);
@ -1118,7 +1117,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
// the builtin-kinds-as-supertraits. See corresponding fixme in decoder.
for ast_trait_ref in super_traits.iter() {
let trait_ref = ty::node_id_to_trait_ref(ecx.tcx, ast_trait_ref.ref_id);
encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_super_trait_ref);
encode_trait_ref(ebml_w, ecx, &*trait_ref, tag_item_super_trait_ref);
}
// Encode the implementations of this trait.
@ -1140,7 +1139,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
ebml_w.start_tag(tag_items_data_item);
encode_method_ty_fields(ecx, ebml_w, method_ty);
encode_method_ty_fields(ecx, ebml_w, &*method_ty);
encode_parent_item(ebml_w, def_id);

View file

@ -592,7 +592,7 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
param_bounds.builtin_bounds.add(ty::BoundShare);
}
'I' => {
param_bounds.trait_bounds.push(@parse_trait_ref(st, |x,y| conv(x,y)));
param_bounds.trait_bounds.push(Rc::new(parse_trait_ref(st, |x,y| conv(x,y))));
}
'.' => {
return param_bounds;

View file

@ -366,9 +366,9 @@ fn enc_bounds(w: &mut MemWriter, cx: &ctxt, bs: &ty::ParamBounds) {
}
}
for &tp in bs.trait_bounds.iter() {
for tp in bs.trait_bounds.iter() {
mywrite!(w, "I");
enc_trait_ref(w, cx, tp);
enc_trait_ref(w, cx, &**tp);
}
mywrite!(w, ".");

View file

@ -112,9 +112,9 @@ fn check_impl_of_trait(cx: &mut Context, it: &Item, trait_ref: &TraitRef, self_t
.find(&trait_ref.ref_id)
.expect("trait ref not in def map!");
let trait_def_id = ast_util::def_id_of_def(ast_trait_def);
let trait_def = *cx.tcx.trait_defs.borrow()
.find(&trait_def_id)
.expect("trait def not in trait-defs map!");
let trait_def = cx.tcx.trait_defs.borrow()
.find_copy(&trait_def_id)
.expect("trait def not in trait-defs map!");
// If this trait has builtin-kind supertraits, meet them.
let self_ty: ty::t = ty::node_id_to_type(cx.tcx, it.id);

View file

@ -53,6 +53,7 @@ use std::i16;
use std::i32;
use std::i64;
use std::i8;
use std::rc::Rc;
use std::to_str::ToStr;
use std::u16;
use std::u32;
@ -678,7 +679,7 @@ impl<'a> AstConv for Context<'a>{
ty::lookup_item_type(self.tcx, id)
}
fn get_trait_def(&self, id: ast::DefId) -> @ty::TraitDef {
fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef> {
ty::lookup_trait_def(self.tcx, id)
}
@ -1465,7 +1466,7 @@ fn check_missing_doc_method(cx: &Context, m: &ast::Method) {
node: m.id
};
match cx.tcx.methods.borrow().find(&did).map(|method| *method) {
match cx.tcx.methods.borrow().find_copy(&did) {
None => cx.tcx.sess.span_bug(m.span, "missing method descriptor?!"),
Some(md) => {
match md.container {

View file

@ -254,7 +254,7 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
_ => true,
};
let tr = ty::impl_trait_ref(self.tcx, local_def(item.id));
let public_trait = tr.map_or(false, |tr| {
let public_trait = tr.clone().map_or(false, |tr| {
!is_local(tr.def_id) ||
self.exported_items.contains(&tr.def_id.node)
});

View file

@ -75,6 +75,7 @@ use libc::c_uint;
use std::c_str::ToCStr;
use std::cell::{Cell, RefCell};
use std::local_data;
use std::rc::Rc;
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic};
use syntax::ast_util::{local_def, is_local};
use syntax::attr::AttrMetaMethods;
@ -637,7 +638,7 @@ pub fn iter_structural_ty<'r,
cx: &'b Block<'b>,
repr: &adt::Repr,
av: ValueRef,
variant: @ty::VariantInfo,
variant: &ty::VariantInfo,
tps: &[ty::t],
f: val_and_ty_fn<'r,'b>)
-> &'b Block<'b> {
@ -694,7 +695,7 @@ pub fn iter_structural_ty<'r,
match adt::trans_switch(cx, repr, av) {
(_match::single, None) => {
cx = iter_variant(cx, repr, av, *variants.get(0),
cx = iter_variant(cx, repr, av, &**variants.get(0),
substs.tps.as_slice(), f);
}
(_match::switch, Some(lldiscrim_a)) => {
@ -720,7 +721,7 @@ pub fn iter_structural_ty<'r,
iter_variant(variant_cx,
repr,
av,
*variant,
&**variant,
substs.tps.as_slice(),
|x,y,z| f(x,y,z));
Br(variant_cx, next_cx.llbb);
@ -1525,11 +1526,11 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
finish_fn(&fcx, bcx);
}
pub fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef,
id: ast::NodeId, vi: @Vec<@ty::VariantInfo>,
i: &mut uint) {
fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef,
id: ast::NodeId, vi: &[Rc<ty::VariantInfo>],
i: &mut uint) {
for &variant in enum_definition.variants.iter() {
let disr_val = vi.get(*i).disr_val;
let disr_val = vi[*i].disr_val;
*i += 1;
match variant.node.kind {
@ -1592,7 +1593,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
if !generics.is_type_parameterized() {
let vi = ty::enum_variants(ccx.tcx(), local_def(item.id));
let mut i = 0;
trans_enum_def(ccx, enum_definition, item.id, vi, &mut i);
trans_enum_def(ccx, enum_definition, item.id, vi.as_slice(), &mut i);
}
}
ast::ItemStatic(_, m, expr) => {

View file

@ -318,7 +318,7 @@ pub fn trans_fn_ref_with_vtables(
// Compute the first substitution
let first_subst = make_substs_for_receiver_types(
tcx, impl_id, trait_ref, method);
tcx, impl_id, &*trait_ref, &*method);
// And compose them
let new_substs = first_subst.subst(tcx, &substs);
@ -333,7 +333,7 @@ pub fn trans_fn_ref_with_vtables(
let (param_vtables, self_vtables) =
resolve_default_method_vtables(bcx, impl_id,
method, &substs, vtables);
&*method, &substs, vtables);
debug!("trans_fn_with_vtables - default method: \
self_vtable = {}, param_vtables = {}",

View file

@ -144,6 +144,7 @@ use util::ppaux;
use std::c_str::{CString, ToCStr};
use std::cell::{Cell, RefCell};
use std::rc::Rc;
use collections::HashMap;
use collections::HashSet;
use libc::{c_uint, c_ulonglong, c_longlong};
@ -1389,7 +1390,7 @@ fn prepare_tuple_metadata(cx: &CrateContext,
struct GeneralMemberDescriptionFactory {
type_rep: @adt::Repr,
variants: @Vec<@ty::VariantInfo> ,
variants: Rc<Vec<Rc<ty::VariantInfo>>>,
discriminant_type_metadata: ValueRef,
containing_scope: DIScope,
file_metadata: DIFile,
@ -1412,7 +1413,7 @@ impl GeneralMemberDescriptionFactory {
let (variant_type_metadata, variant_llvm_type, member_desc_factory) =
describe_enum_variant(cx,
struct_def,
*self.variants.get(i),
&**self.variants.get(i),
Some(self.discriminant_type_metadata),
self.containing_scope,
self.file_metadata,
@ -1617,7 +1618,7 @@ fn prepare_enum_metadata(cx: &CrateContext,
member_description_factory) =
describe_enum_variant(cx,
struct_def,
*variants.get(0),
&**variants.get(0),
None,
containing_scope,
file_metadata,
@ -1676,7 +1677,7 @@ fn prepare_enum_metadata(cx: &CrateContext,
member_description_factory) =
describe_enum_variant(cx,
struct_def,
*variants.get(nndiscr as uint),
&**variants.get(nndiscr as uint),
None,
containing_scope,
file_metadata,

View file

@ -243,7 +243,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
ast_map::NodeVariant(v) => {
let parent = ccx.tcx.map.get_parent(fn_id.node);
let tvs = ty::enum_variants(ccx.tcx(), local_def(parent));
let this_tv = *tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap();
let this_tv = tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap();
let d = mk_lldecl();
set_inline_hint(d);
match v.node.kind {

View file

@ -25,6 +25,7 @@ use middle::trans::type_of::*;
use middle::ty;
use util::ppaux::ty_to_str;
use std::rc::Rc;
use arena::TypedArena;
use libc::c_uint;
use syntax::ast::DefId;
@ -33,15 +34,15 @@ use syntax::ast_map;
use syntax::parse::token::{InternedString, special_idents};
use syntax::parse::token;
pub struct Reflector<'a> {
pub struct Reflector<'a, 'b> {
visitor_val: ValueRef,
visitor_methods: @Vec<@ty::Method> ,
final_bcx: &'a Block<'a>,
visitor_methods: &'a [Rc<ty::Method>],
final_bcx: &'b Block<'b>,
tydesc_ty: Type,
bcx: &'a Block<'a>
bcx: &'b Block<'b>
}
impl<'a> Reflector<'a> {
impl<'a, 'b> Reflector<'a, 'b> {
pub fn c_uint(&mut self, u: uint) -> ValueRef {
C_uint(self.bcx.ccx(), u)
}
@ -92,7 +93,7 @@ impl<'a> Reflector<'a> {
format!("couldn't find visit method for {}", ty_name));
let mth_ty =
ty::mk_bare_fn(tcx,
self.visitor_methods.get(mth_idx).fty.clone());
self.visitor_methods[mth_idx].fty.clone());
let v = self.visitor_val;
debug!("passing {} args:", args.len());
let mut bcx = self.bcx;
@ -401,9 +402,10 @@ pub fn emit_calls_to_trait_visit_ty<'a>(
let final = fcx.new_temp_block("final");
let tydesc_ty = ty::get_tydesc_ty(bcx.tcx()).unwrap();
let tydesc_ty = type_of(bcx.ccx(), tydesc_ty);
let visitor_methods = ty::trait_methods(bcx.tcx(), visitor_trait_id);
let mut r = Reflector {
visitor_val: visitor_val,
visitor_methods: ty::trait_methods(bcx.tcx(), visitor_trait_id),
visitor_methods: visitor_methods.as_slice(),
final_bcx: final,
tydesc_ty: tydesc_ty,
bcx: bcx

View file

@ -38,9 +38,11 @@ use std::cmp;
use std::fmt::Show;
use std::fmt;
use std::hash::{Hash, sip};
use std::iter::AdditiveIterator;
use std::ops;
use std::rc::Rc;
use collections::{HashMap, HashSet};
use syntax::abi;
use syntax::ast::*;
use syntax::ast_util::{is_local, lit_is_str};
use syntax::ast_util;
@ -51,7 +53,7 @@ use syntax::parse::token;
use syntax::parse::token::InternedString;
use syntax::{ast, ast_map};
use syntax::owned_slice::OwnedSlice;
use syntax::abi;
use syntax::util::small_vector::SmallVector;
use collections::enum_set::{EnumSet, CLike};
pub type Disr = u64;
@ -267,18 +269,18 @@ pub struct ctxt {
pub node_type_substs: RefCell<NodeMap<Vec<t>>>,
// Maps from a method to the method "descriptor"
pub methods: RefCell<DefIdMap<@Method>>,
pub methods: RefCell<DefIdMap<Rc<Method>>>,
// Maps from a trait def-id to a list of the def-ids of its methods
pub trait_method_def_ids: RefCell<DefIdMap<@Vec<DefId> >>,
pub trait_method_def_ids: RefCell<DefIdMap<Rc<Vec<DefId>>>>,
// A cache for the trait_methods() routine
pub trait_methods_cache: RefCell<DefIdMap<@Vec<@Method> >>,
pub trait_methods_cache: RefCell<DefIdMap<Rc<Vec<Rc<Method>>>>>,
pub impl_trait_cache: RefCell<DefIdMap<Option<@ty::TraitRef>>>,
pub impl_trait_cache: RefCell<DefIdMap<Option<Rc<ty::TraitRef>>>>,
pub trait_refs: RefCell<NodeMap<@TraitRef>>,
pub trait_defs: RefCell<DefIdMap<@TraitDef>>,
pub trait_refs: RefCell<NodeMap<Rc<TraitRef>>>,
pub trait_defs: RefCell<DefIdMap<Rc<TraitDef>>>,
pub map: ast_map::Map,
pub intrinsic_defs: RefCell<DefIdMap<t>>,
@ -289,20 +291,20 @@ pub struct ctxt {
pub needs_unwind_cleanup_cache: RefCell<HashMap<t, bool>>,
pub tc_cache: RefCell<HashMap<uint, TypeContents>>,
pub ast_ty_to_ty_cache: RefCell<NodeMap<ast_ty_to_ty_cache_entry>>,
pub enum_var_cache: RefCell<DefIdMap<@Vec<@VariantInfo> >>,
pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo>>>>>,
pub ty_param_defs: RefCell<NodeMap<TypeParameterDef>>,
pub adjustments: RefCell<NodeMap<AutoAdjustment>>,
pub normalized_cache: RefCell<HashMap<t, t>>,
pub lang_items: middle::lang_items::LanguageItems,
// A mapping of fake provided method def_ids to the default implementation
pub provided_method_sources: RefCell<DefIdMap<ast::DefId>>,
pub supertraits: RefCell<DefIdMap<@Vec<@TraitRef> >>,
pub supertraits: RefCell<DefIdMap<Rc<Vec<Rc<TraitRef>>>>>,
pub superstructs: RefCell<DefIdMap<Option<ast::DefId>>>,
pub struct_fields: RefCell<DefIdMap<@Vec<field_ty>>>,
pub struct_fields: RefCell<DefIdMap<Rc<Vec<field_ty>>>>,
// Maps from def-id of a type or region parameter to its
// (inferred) variance.
pub item_variance_map: RefCell<DefIdMap<@ItemVariances>>,
pub item_variance_map: RefCell<DefIdMap<Rc<ItemVariances>>>,
// A mapping from the def ID of an enum or struct type to the def ID
// of the method that implements its destructor. If the type is not
@ -314,12 +316,12 @@ pub struct ctxt {
pub destructors: RefCell<DefIdSet>,
// Maps a trait onto a list of impls of that trait.
pub trait_impls: RefCell<DefIdMap<@RefCell<Vec<ast::DefId>>>>,
pub trait_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
// Maps a DefId of a type to a list of its inherent impls.
// Contains implementations of methods that are inherent to a type.
// Methods in these implementations don't need to be exported.
pub inherent_impls: RefCell<DefIdMap<@RefCell<Vec<ast::DefId>>>>,
pub inherent_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
// Maps a DefId of an impl to a list of its methods.
// Note that this contains all of the impls that we know about,
@ -826,7 +828,7 @@ pub enum type_err {
#[deriving(Eq, TotalEq, Hash)]
pub struct ParamBounds {
pub builtin_bounds: BuiltinBounds,
pub trait_bounds: Vec<@TraitRef>
pub trait_bounds: Vec<Rc<TraitRef>>
}
pub type BuiltinBounds = EnumSet<BuiltinBound>;
@ -1036,7 +1038,7 @@ pub struct ParameterEnvironment {
pub free_substs: ty::substs,
/// Bound on the Self parameter
pub self_param_bound: Option<@TraitRef>,
pub self_param_bound: Option<Rc<TraitRef>>,
/// Bounds on each numbered type parameter
pub type_param_bounds: Vec<ParamBounds> ,
@ -1062,7 +1064,7 @@ pub struct ty_param_bounds_and_ty {
pub struct TraitDef {
pub generics: Generics,
pub bounds: BuiltinBounds,
pub trait_ref: @ty::TraitRef,
pub trait_ref: Rc<ty::TraitRef>,
}
pub struct ty_param_substs_and_ty {
@ -2174,7 +2176,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
// Self may be bounded if the associated trait has builtin kinds
// for supertraits. If so we can use those bounds.
let trait_def = lookup_trait_def(cx, def_id);
let traits = [trait_def.trait_ref];
let traits = [trait_def.trait_ref.clone()];
kind_bounds_to_contents(cx, trait_def.bounds, traits)
}
@ -2269,7 +2271,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
fn kind_bounds_to_contents(cx: &ctxt,
bounds: BuiltinBounds,
traits: &[@TraitRef])
traits: &[Rc<TraitRef>])
-> TypeContents {
let _i = indenter();
let mut tc = TC::All;
@ -2288,7 +2290,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
// those inherited from traits with builtin-kind-supertraits.
fn each_inherited_builtin_bound(cx: &ctxt,
bounds: BuiltinBounds,
traits: &[@TraitRef],
traits: &[Rc<TraitRef>],
f: |BuiltinBound|) {
for bound in bounds.iter() {
f(bound);
@ -2654,12 +2656,12 @@ pub fn index(t: t) -> Option<mt> {
}
}
pub fn node_id_to_trait_ref(cx: &ctxt, id: ast::NodeId) -> @ty::TraitRef {
pub fn node_id_to_trait_ref(cx: &ctxt, id: ast::NodeId) -> Rc<ty::TraitRef> {
match cx.trait_refs.borrow().find(&id) {
Some(&t) => t,
None => cx.sess.bug(
format!("node_id_to_trait_ref: no trait ref for node `{}`",
cx.map.node_to_str(id)))
Some(t) => t.clone(),
None => cx.sess.bug(
format!("node_id_to_trait_ref: no trait ref for node `{}`",
cx.map.node_to_str(id)))
}
}
@ -3045,8 +3047,8 @@ pub fn method_call_type_param_defs(tcx: &ctxt, origin: typeck::MethodOrigin)
// method bounds, so we must preprend the tps from the
// trait itself. This ought to be harmonized.
let trait_type_param_defs =
lookup_trait_def(tcx, trt_id).generics.type_param_defs();
Rc::new(Vec::from_slice(trait_type_param_defs).append(
Vec::from_slice(lookup_trait_def(tcx, trt_id).generics.type_param_defs());
Rc::new(trait_type_param_defs.append(
ty::trait_method(tcx, trt_id, n_mth).generics.type_param_defs()))
}
}
@ -3255,7 +3257,7 @@ pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
fields.iter().map(|f| token::get_ident(f.ident).get().to_str()).collect::<Vec<~str>>()));
}
pub fn method_idx(id: ast::Ident, meths: &[@Method]) -> Option<uint> {
pub fn method_idx(id: ast::Ident, meths: &[Rc<Method>]) -> Option<uint> {
meths.iter().position(|m| m.ident == id)
}
@ -3479,42 +3481,29 @@ pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option<ast::DefId> {
cx.provided_method_sources.borrow().find(&id).map(|x| *x)
}
pub fn provided_trait_methods(cx: &ctxt, id: ast::DefId) -> Vec<@Method> {
pub fn provided_trait_methods(cx: &ctxt, id: ast::DefId) -> Vec<Rc<Method>> {
if is_local(id) {
{
match cx.map.find(id.node) {
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| method(cx, ast_util::local_def(m.id)))
.collect()
}
_ => {
cx.sess.bug(format!("provided_trait_methods: \
`{:?}` is not a trait",
id))
}
match cx.map.find(id.node) {
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| method(cx, ast_util::local_def(m.id))).collect()
}
}
_ => {
cx.sess.bug(format!("provided_trait_methods: `{:?}` is not \
a trait",
id))
_ => cx.sess.bug(format!("provided_trait_methods: `{}` is not a trait", id))
}
}
_ => cx.sess.bug(format!("provided_trait_methods: `{}` is not a trait", id))
}
} else {
csearch::get_provided_trait_methods(cx, id)
}
}
pub fn trait_supertraits(cx: &ctxt, id: ast::DefId) -> @Vec<@TraitRef> {
pub fn trait_supertraits(cx: &ctxt, id: ast::DefId) -> Rc<Vec<Rc<TraitRef>>> {
// Check the cache.
match cx.supertraits.borrow().find(&id) {
Some(&trait_refs) => { return trait_refs; }
Some(trait_refs) => { return trait_refs.clone(); }
None => {} // Continue.
}
@ -3524,12 +3513,12 @@ pub fn trait_supertraits(cx: &ctxt, id: ast::DefId) -> @Vec<@TraitRef> {
// Get the supertraits out of the metadata and create the
// TraitRef for each.
let result = @csearch::get_supertraits(cx, id);
cx.supertraits.borrow_mut().insert(id, result);
return result;
let result = Rc::new(csearch::get_supertraits(cx, id));
cx.supertraits.borrow_mut().insert(id, result.clone());
result
}
pub fn trait_ref_supertraits(cx: &ctxt, trait_ref: &ty::TraitRef) -> Vec<@TraitRef> {
pub fn trait_ref_supertraits(cx: &ctxt, trait_ref: &ty::TraitRef) -> Vec<Rc<TraitRef>> {
let supertrait_refs = trait_supertraits(cx, trait_ref.def_id);
supertrait_refs.iter().map(
|supertrait_ref| supertrait_ref.subst(cx, &trait_ref.substs)).collect()
@ -3563,44 +3552,46 @@ fn lookup_locally_or_in_crate_store<V:Clone>(
v
}
pub fn trait_method(cx: &ctxt, trait_did: ast::DefId, idx: uint) -> @Method {
pub fn trait_method(cx: &ctxt, trait_did: ast::DefId, idx: uint) -> Rc<Method> {
let method_def_id = *ty::trait_method_def_ids(cx, trait_did).get(idx);
ty::method(cx, method_def_id)
}
pub fn trait_methods(cx: &ctxt, trait_did: ast::DefId) -> @Vec<@Method> {
pub fn trait_methods(cx: &ctxt, trait_did: ast::DefId) -> Rc<Vec<Rc<Method>>> {
let mut trait_methods = cx.trait_methods_cache.borrow_mut();
match trait_methods.find(&trait_did) {
Some(&methods) => methods,
match trait_methods.find_copy(&trait_did) {
Some(methods) => methods,
None => {
let def_ids = ty::trait_method_def_ids(cx, trait_did);
let methods = @def_ids.iter().map(|d| ty::method(cx, *d)).collect();
trait_methods.insert(trait_did, methods);
let methods: Rc<Vec<Rc<Method>>> = Rc::new(def_ids.iter().map(|d| {
ty::method(cx, *d)
}).collect());
trait_methods.insert(trait_did, methods.clone());
methods
}
}
}
pub fn method(cx: &ctxt, id: ast::DefId) -> @Method {
pub fn method(cx: &ctxt, id: ast::DefId) -> Rc<Method> {
lookup_locally_or_in_crate_store("methods", id,
&mut *cx.methods.borrow_mut(), || {
@csearch::get_method(cx, id)
Rc::new(csearch::get_method(cx, id))
})
}
pub fn trait_method_def_ids(cx: &ctxt, id: ast::DefId) -> @Vec<DefId> {
pub fn trait_method_def_ids(cx: &ctxt, id: ast::DefId) -> Rc<Vec<DefId>> {
lookup_locally_or_in_crate_store("trait_method_def_ids",
id,
&mut *cx.trait_method_def_ids.borrow_mut(),
|| {
@csearch::get_trait_method_def_ids(&cx.sess.cstore, id)
Rc::new(csearch::get_trait_method_def_ids(&cx.sess.cstore, id))
})
}
pub fn impl_trait_ref(cx: &ctxt, id: ast::DefId) -> Option<@TraitRef> {
pub fn impl_trait_ref(cx: &ctxt, id: ast::DefId) -> Option<Rc<TraitRef>> {
match cx.impl_trait_cache.borrow().find(&id) {
Some(&ret) => { return ret; }
Some(ret) => { return ret.clone(); }
None => {}
}
@ -3626,8 +3617,8 @@ pub fn impl_trait_ref(cx: &ctxt, id: ast::DefId) -> Option<@TraitRef> {
csearch::get_impl_trait(cx, id)
};
cx.impl_trait_cache.borrow_mut().insert(id, ret);
return ret;
cx.impl_trait_cache.borrow_mut().insert(id, ret.clone());
ret
}
pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId {
@ -3730,18 +3721,18 @@ impl VariantInfo {
pub fn substd_enum_variants(cx: &ctxt,
id: ast::DefId,
substs: &substs)
-> Vec<@VariantInfo> {
-> Vec<Rc<VariantInfo>> {
enum_variants(cx, id).iter().map(|variant_info| {
let substd_args = variant_info.args.iter()
.map(|aty| subst(cx, substs, *aty)).collect();
let substd_ctor_ty = subst(cx, substs, variant_info.ctor_ty);
@VariantInfo {
Rc::new(VariantInfo {
args: substd_args,
ctor_ty: substd_ctor_ty,
..(**variant_info).clone()
}
})
}).collect()
}
@ -3810,27 +3801,26 @@ pub fn type_is_empty(cx: &ctxt, t: t) -> bool {
}
}
pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> @Vec<@VariantInfo> {
pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> Rc<Vec<Rc<VariantInfo>>> {
match cx.enum_var_cache.borrow().find(&id) {
Some(&variants) => return variants,
Some(variants) => return variants.clone(),
_ => { /* fallthrough */ }
}
let result = if ast::LOCAL_CRATE != id.krate {
@csearch::get_enum_variants(cx, id)
Rc::new(csearch::get_enum_variants(cx, id))
} else {
/*
Although both this code and check_enum_variants in typeck/check
call eval_const_expr, it should never get called twice for the same
expr, since check_enum_variants also updates the enum_var_cache
*/
{
match cx.map.get(id.node) {
ast_map::NodeItem(item) => {
match item.node {
match cx.map.get(id.node) {
ast_map::NodeItem(item) => {
match item.node {
ast::ItemEnum(ref enum_definition, _) => {
let mut last_discriminant: Option<Disr> = None;
@enum_definition.variants.iter().map(|&variant| {
Rc::new(enum_definition.variants.iter().map(|&variant| {
let mut discriminant = match last_discriminant {
Some(val) => val + 1,
@ -3848,40 +3838,33 @@ pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> @Vec<@VariantInfo> {
Ok(_) => {
cx.sess
.span_err(e.span,
"expected signed integer \
constant");
"expected signed integer constant");
}
Err(ref err) => {
cx.sess
.span_err(e.span,
format!("expected \
constant: {}",
format!("expected constant: {}",
*err));
}
},
None => {}
};
let variant_info =
@VariantInfo::from_ast_variant(cx,
variant,
discriminant);
last_discriminant = Some(discriminant);
variant_info
}).collect()
Rc::new(VariantInfo::from_ast_variant(cx, variant,
discriminant))
}).collect())
}
_ => {
cx.sess.bug("enum_variants: id not bound to an enum")
}
}
}
_ => cx.sess.bug("enum_variants: id not bound to an enum")
}
}
_ => cx.sess.bug("enum_variants: id not bound to an enum")
}
};
cx.enum_var_cache.borrow_mut().insert(id, result);
cx.enum_var_cache.borrow_mut().insert(id, result.clone());
result
}
@ -3890,17 +3873,11 @@ pub fn enum_variants(cx: &ctxt, id: ast::DefId) -> @Vec<@VariantInfo> {
pub fn enum_variant_with_id(cx: &ctxt,
enum_id: ast::DefId,
variant_id: ast::DefId)
-> @VariantInfo {
let variants = enum_variants(cx, enum_id);
let mut i = 0;
while i < variants.len() {
let variant = *variants.get(i);
if variant.id == variant_id {
return variant
}
i += 1;
}
cx.sess.bug("enum_variant_with_id(): no variant exists with that ID");
-> Rc<VariantInfo> {
enum_variants(cx, enum_id).iter()
.find(|variant| variant.id == variant_id)
.expect("enum_variant_with_id(): no variant exists with that ID")
.clone()
}
@ -3923,19 +3900,19 @@ pub fn lookup_impl_vtables(cx: &ctxt,
}
/// Given the did of a trait, returns its canonical trait ref.
pub fn lookup_trait_def(cx: &ctxt, did: ast::DefId) -> @ty::TraitDef {
pub fn lookup_trait_def(cx: &ctxt, did: ast::DefId) -> Rc<ty::TraitDef> {
let mut trait_defs = cx.trait_defs.borrow_mut();
match trait_defs.find(&did) {
Some(&trait_def) => {
match trait_defs.find_copy(&did) {
Some(trait_def) => {
// The item is in this crate. The caller should have added it to the
// type cache already
return trait_def;
trait_def
}
None => {
assert!(did.krate != ast::LOCAL_CRATE);
let trait_def = @csearch::get_trait_def(cx, did);
trait_defs.insert(did, trait_def);
return trait_def;
let trait_def = Rc::new(csearch::get_trait_def(cx, did));
trait_defs.insert(did, trait_def.clone());
trait_def
}
}
}
@ -3943,7 +3920,7 @@ pub fn lookup_trait_def(cx: &ctxt, did: ast::DefId) -> @ty::TraitDef {
/// Iterate over meta_items of a definition.
// (This should really be an iterator, but that would require csearch and
// decoder to use iterators instead of higher-order functions.)
pub fn each_attr(tcx: &ctxt, did: DefId, f: |@MetaItem| -> bool) -> bool {
pub fn each_attr(tcx: &ctxt, did: DefId, f: |@ast::MetaItem| -> bool) -> bool {
if is_local(did) {
let item = tcx.map.expect_item(did.node);
item.attrs.iter().advance(|attr| f(attr.node.value))
@ -4017,20 +3994,21 @@ pub fn lookup_field_type(tcx: &ctxt,
// Lookup all ancestor structs of a struct indicated by did. That is the reflexive,
// transitive closure of doing a single lookup in cx.superstructs.
fn lookup_super_structs(cx: &ctxt,
did: ast::DefId) -> Vec<DefId> {
let mut this_result: Vec<DefId> = vec!(did);
match cx.superstructs.borrow().find(&did) {
Some(&Some(def_id)) => {
let ss: Vec<DefId> = lookup_super_structs(cx, def_id);
this_result.extend(ss.move_iter());
this_result
},
Some(&None) => this_result,
None => {
cx.sess.bug(
format!("ID not mapped to super-struct: {}",
cx.map.node_to_str(did.node)));
fn each_super_struct(cx: &ctxt, mut did: ast::DefId, f: |ast::DefId|) {
let superstructs = cx.superstructs.borrow();
loop {
f(did);
match superstructs.find(&did) {
Some(&Some(def_id)) => {
did = def_id;
},
Some(&None) => break,
None => {
cx.sess.bug(
format!("ID not mapped to super-struct: {}",
cx.map.node_to_str(did.node)));
}
}
}
}
@ -4043,26 +4021,22 @@ pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
// we have to walk the inheritance chain of the struct to get all the
// structs (explicit and inherited) for a struct. If this is expensive
// we could cache the whole list of fields here.
let structs = lookup_super_structs(cx, did);
let struct_fields = cx.struct_fields.borrow();
let results: Vec<&@Vec<field_ty>> = structs.iter().map(|s| {
match struct_fields.find(s) {
Some(fields) => fields,
let mut results: SmallVector<&[field_ty]> = SmallVector::zero();
each_super_struct(cx, did, |s| {
match struct_fields.find(&s) {
Some(fields) => results.push(fields.as_slice()),
_ => {
cx.sess.bug(
format!("ID not mapped to struct fields: {}",
cx.map.node_to_str(did.node)));
}
}
}).collect();
});
let len = results.iter().map(|x| x.len()).fold(0, |a, b| a + b);
let len = results.as_slice().iter().map(|x| x.len()).sum();
let mut result: Vec<field_ty> = Vec::with_capacity(len);
for rs in results.iter() {
for r in rs.iter() {
result.push(*r);
}
}
result.extend(results.as_slice().iter().flat_map(|rs| rs.iter().map(|&f| f)));
assert!(result.len() == len);
result
} else {
@ -4293,31 +4267,31 @@ pub fn eval_repeat_count<T: ExprTyProvider>(tcx: &T, count_expr: &ast::Expr) ->
// relation on the supertraits from each bounded trait's constraint
// list.
pub fn each_bound_trait_and_supertraits(tcx: &ctxt,
bounds: &[@TraitRef],
f: |@TraitRef| -> bool)
bounds: &[Rc<TraitRef>],
f: |Rc<TraitRef>| -> bool)
-> bool {
for &bound_trait_ref in bounds.iter() {
for bound_trait_ref in bounds.iter() {
let mut supertrait_set = HashMap::new();
let mut trait_refs = Vec::new();
let mut i = 0;
// Seed the worklist with the trait from the bound
supertrait_set.insert(bound_trait_ref.def_id, ());
trait_refs.push(bound_trait_ref);
trait_refs.push(bound_trait_ref.clone());
// Add the given trait ty to the hash map
while i < trait_refs.len() {
debug!("each_bound_trait_and_supertraits(i={:?}, trait_ref={})",
i, trait_refs.get(i).repr(tcx));
if !f(*trait_refs.get(i)) {
if !f(trait_refs.get(i).clone()) {
return false;
}
// Add supertraits to supertrait_set
let supertrait_refs = trait_ref_supertraits(tcx,
*trait_refs.get(i));
for &supertrait_ref in supertrait_refs.iter() {
&**trait_refs.get(i));
for supertrait_ref in supertrait_refs.iter() {
debug!("each_bound_trait_and_supertraits(supertrait_ref={})",
supertrait_ref.repr(tcx));
@ -4325,7 +4299,7 @@ pub fn each_bound_trait_and_supertraits(tcx: &ctxt,
if !supertrait_set.contains_key(&d_id) {
// FIXME(#5527) Could have same trait multiple times
supertrait_set.insert(d_id, ());
trait_refs.push(supertrait_ref);
trait_refs.push(supertrait_ref.clone());
}
}
@ -4350,7 +4324,7 @@ pub fn get_opaque_ty(tcx: &ctxt) -> Result<t, ~str> {
}
pub fn visitor_object_ty(tcx: &ctxt,
region: ty::Region) -> Result<(@TraitRef, t), ~str> {
region: ty::Region) -> Result<(Rc<TraitRef>, t), ~str> {
let trait_lang_item = match tcx.lang_items.require(TyVisitorTraitLangItem) {
Ok(id) => id,
Err(s) => { return Err(s); }
@ -4360,8 +4334,8 @@ pub fn visitor_object_ty(tcx: &ctxt,
self_ty: None,
tps: Vec::new()
};
let trait_ref = @TraitRef { def_id: trait_lang_item, substs: substs };
Ok((trait_ref,
let trait_ref = Rc::new(TraitRef { def_id: trait_lang_item, substs: substs });
Ok((trait_ref.clone(),
mk_trait(tcx,
trait_ref.def_id,
trait_ref.substs.clone(),
@ -4369,10 +4343,10 @@ pub fn visitor_object_ty(tcx: &ctxt,
EmptyBuiltinBounds())))
}
pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> @ItemVariances {
pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
lookup_locally_or_in_crate_store(
"item_variance_map", item_id, &mut *tcx.item_variance_map.borrow_mut(),
|| @csearch::get_item_variances(&tcx.sess.cstore, item_id))
|| Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id)))
}
/// Records a trait-to-implementation mapping.
@ -4386,7 +4360,7 @@ pub fn record_trait_implementation(tcx: &ctxt,
}
None => {}
}
tcx.trait_impls.borrow_mut().insert(trait_def_id, @RefCell::new(vec!(impl_def_id)));
tcx.trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id))));
}
/// Populates the type context with all the implementations for the given type
@ -4430,7 +4404,8 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
}
None => {}
}
tcx.inherent_impls.borrow_mut().insert(type_id, @RefCell::new(vec!(impl_def_id)));
tcx.inherent_impls.borrow_mut().insert(type_id,
Rc::new(RefCell::new(vec!(impl_def_id))));
}
});
@ -4500,7 +4475,7 @@ pub fn trait_of_method(tcx: &ctxt, def_id: ast::DefId)
if def_id.krate != LOCAL_CRATE {
return csearch::get_trait_of_method(&tcx.sess.cstore, def_id, tcx);
}
match tcx.methods.borrow().find(&def_id).map(|m| *m) {
match tcx.methods.borrow().find_copy(&def_id) {
Some(method) => {
match method.container {
TraitContainer(def_id) => Some(def_id),
@ -4520,7 +4495,7 @@ pub fn trait_of_method(tcx: &ctxt, def_id: ast::DefId)
pub fn trait_method_of_method(tcx: &ctxt,
def_id: ast::DefId) -> Option<ast::DefId> {
let method = match tcx.methods.borrow().find(&def_id) {
Some(&m) => m,
Some(m) => m.clone(),
None => return None,
};
let name = method.ident.name;
@ -4689,7 +4664,7 @@ impl Variance {
pub fn construct_parameter_environment(
tcx: &ctxt,
self_bound: Option<@TraitRef>,
self_bound: Option<Rc<TraitRef>>,
item_type_params: &[TypeParameterDef],
method_type_params: &[TypeParameterDef],
item_region_params: &[RegionParameterDef],
@ -4704,7 +4679,7 @@ pub fn construct_parameter_environment(
//
// map Self => Self
let self_ty = self_bound.map(|t| ty::mk_self(tcx, t.def_id));
let self_ty = self_bound.as_ref().map(|t| ty::mk_self(tcx, t.def_id));
// map A => A
let num_item_type_params = item_type_params.len();

View file

@ -60,6 +60,7 @@ use middle::typeck::rscope::{RegionScope};
use middle::typeck::lookup_def_tcx;
use util::ppaux::Repr;
use std::rc::Rc;
use syntax::abi;
use syntax::{ast, ast_util};
use syntax::codemap::Span;
@ -69,7 +70,7 @@ use syntax::print::pprust::{lifetime_to_str, path_to_str};
pub trait AstConv {
fn tcx<'a>(&'a self) -> &'a ty::ctxt;
fn get_item_ty(&self, id: ast::DefId) -> ty::ty_param_bounds_and_ty;
fn get_trait_def(&self, id: ast::DefId) -> @ty::TraitDef;
fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef>;
// what type should we use when a type is omitted?
fn ty_infer(&self, span: Span) -> ty::t;
@ -261,25 +262,16 @@ pub fn ast_path_to_substs_and_ty<AC:AstConv,
}
pub fn ast_path_to_trait_ref<AC:AstConv,RS:RegionScope>(
this: &AC,
rscope: &RS,
trait_def_id: ast::DefId,
self_ty: Option<ty::t>,
path: &ast::Path) -> @ty::TraitRef
{
let trait_def =
this.get_trait_def(trait_def_id);
let substs =
ast_path_substs(
this,
rscope,
&trait_def.generics,
self_ty,
path);
let trait_ref =
@ty::TraitRef {def_id: trait_def_id,
substs: substs};
return trait_ref;
this: &AC,
rscope: &RS,
trait_def_id: ast::DefId,
self_ty: Option<ty::t>,
path: &ast::Path) -> Rc<ty::TraitRef> {
let trait_def = this.get_trait_def(trait_def_id);
Rc::new(ty::TraitRef {
def_id: trait_def_id,
substs: ast_path_substs(this, rscope, &trait_def.generics, self_ty, path)
})
}
pub fn ast_path_to_ty<AC:AstConv,RS:RegionScope>(

View file

@ -30,7 +30,7 @@ itself (note that inherent impls can only be defined in the same
module as the type itself).
Inherent candidates are not always derived from impls. If you have a
trait instance, such as a value of type `@ToStr`, then the trait
trait instance, such as a value of type `~ToStr`, then the trait
methods (`to_str()`, in this case) are inherently associated with it.
Another case is type parameters, in which case the methods of their
bounds are inherent.
@ -97,7 +97,7 @@ use util::ppaux;
use util::ppaux::Repr;
use collections::HashSet;
use std::result;
use std::rc::Rc;
use syntax::ast::{DefId, SelfValue, SelfRegion};
use syntax::ast::{SelfUniq, SelfStatic};
use syntax::ast::{MutMutable, MutImmutable};
@ -203,7 +203,7 @@ pub fn lookup_in_trait<'a>(
// to a trait and its supertraits.
fn get_method_index(tcx: &ty::ctxt,
trait_ref: &TraitRef,
subtrait: @TraitRef,
subtrait: Rc<TraitRef>,
n_method: uint) -> uint {
// We need to figure the "real index" of the method in a
// listing of all the methods of an object. We do this by
@ -311,7 +311,7 @@ struct LookupContext<'a> {
struct Candidate {
rcvr_match_condition: RcvrMatchCondition,
rcvr_substs: ty::substs,
method_ty: @ty::Method,
method_ty: Rc<ty::Method>,
origin: MethodOrigin,
}
@ -412,7 +412,7 @@ impl<'a> LookupContext<'a> {
* `self.inherent_candidates`. See comment at the start of
* the file. To find the inherent candidates, we repeatedly
* deref the self-ty to find the "base-type". So, for
* example, if the receiver is @@C where `C` is a struct type,
* example, if the receiver is ~~C where `C` is a struct type,
* we'll want to find the inherent impls for `C`.
*/
@ -511,12 +511,15 @@ impl<'a> LookupContext<'a> {
self_ty: Some(ty::mk_err()),
..(*substs).clone()
};
let trait_ref = @TraitRef { def_id: did, substs: rcvr_substs.clone() };
let trait_ref = Rc::new(TraitRef {
def_id: did,
substs: rcvr_substs.clone()
});
self.push_inherent_candidates_from_bounds_inner(&[trait_ref],
self.push_inherent_candidates_from_bounds_inner(&[trait_ref.clone()],
|new_trait_ref, m, method_num, _bound_num| {
let vtable_index = get_method_index(tcx, new_trait_ref,
trait_ref, method_num);
let vtable_index = get_method_index(tcx, &*new_trait_ref,
trait_ref.clone(), method_num);
let mut m = (*m).clone();
// We need to fix up the transformed self type.
*m.fty.sig.inputs.get_mut(0) =
@ -526,7 +529,7 @@ impl<'a> LookupContext<'a> {
Some(Candidate {
rcvr_match_condition: RcvrMatchesIfObject(did),
rcvr_substs: new_trait_ref.substs.clone(),
method_ty: @m,
method_ty: Rc::new(m),
origin: MethodObject(MethodObject {
trait_id: new_trait_ref.def_id,
object_trait_id: did,
@ -563,14 +566,14 @@ impl<'a> LookupContext<'a> {
debug!("push_inherent_candidates_from_self()");
self.push_inherent_candidates_from_bounds(
rcvr_ty,
[self.fcx.inh.param_env.self_param_bound.unwrap()],
[self.fcx.inh.param_env.self_param_bound.clone().unwrap()],
restrict_to,
param_self)
}
fn push_inherent_candidates_from_bounds(&mut self,
self_ty: ty::t,
bounds: &[@TraitRef],
bounds: &[Rc<TraitRef>],
restrict_to: Option<DefId>,
param: param_index) {
self.push_inherent_candidates_from_bounds_inner(bounds,
@ -600,9 +603,9 @@ impl<'a> LookupContext<'a> {
// Do a search through a list of bounds, using a callback to actually
// create the candidates.
fn push_inherent_candidates_from_bounds_inner(&mut self,
bounds: &[@TraitRef],
mk_cand: |tr: @TraitRef,
m: @ty::Method,
bounds: &[Rc<TraitRef>],
mk_cand: |tr: Rc<TraitRef>,
m: Rc<ty::Method>,
method_num: uint,
bound_num: uint|
-> Option<Candidate>) {
@ -618,7 +621,7 @@ impl<'a> LookupContext<'a> {
m.explicit_self != ast::SelfStatic &&
m.ident.name == self.m_name }) {
Some(pos) => {
let method = *trait_methods.get(pos);
let method = trait_methods.get(pos).clone();
match mk_cand(bound_trait_ref, method, pos, this_bound_idx) {
Some(cand) => {
@ -692,8 +695,8 @@ impl<'a> LookupContext<'a> {
candidates.push(Candidate {
rcvr_match_condition: RcvrMatchesIfSubtype(impl_ty),
rcvr_substs: impl_substs,
origin: MethodStatic(method.def_id),
method_ty: method,
origin: MethodStatic(method.def_id)
});
}
@ -874,7 +877,7 @@ impl<'a> LookupContext<'a> {
}
ty_trait(~ty::TyTrait { def_id: trt_did, substs: trt_substs, bounds: b, .. }) => {
// Coerce ~/@/&Trait instances to &Trait.
// Coerce ~/&Trait instances to &Trait.
self.search_for_some_kind_of_autorefd_method(
AutoBorrowObj, autoderefs, [MutImmutable, MutMutable],
@ -1184,8 +1187,8 @@ impl<'a> LookupContext<'a> {
let span = self.self_expr.map_or(self.span, |e| e.span);
match self.fcx.mk_subty(false, infer::Misc(span),
rcvr_ty, transformed_self_ty) {
result::Ok(_) => {}
result::Err(_) => {
Ok(_) => {}
Err(_) => {
self.bug(format!("{} was a subtype of {} but now is not?",
self.ty_to_str(rcvr_ty),
self.ty_to_str(transformed_self_ty)));

View file

@ -117,7 +117,7 @@ use util::nodemap::{FnvHashMap, NodeMap};
use std::cell::{Cell, RefCell};
use collections::HashMap;
use std::mem::replace;
use std::result;
use std::rc::Rc;
use std::vec::Vec;
use syntax::abi;
use syntax::ast::{Provided, Required};
@ -622,9 +622,9 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
it.span,
&impl_tpt.generics,
ast_trait_ref,
impl_trait_ref,
&*impl_trait_ref,
ms.as_slice());
vtable::resolve_impl(ccx.tcx, it, &impl_tpt.generics, impl_trait_ref);
vtable::resolve_impl(ccx.tcx, it, &impl_tpt.generics, &*impl_trait_ref);
}
None => { }
}
@ -640,7 +640,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
}
Provided(m) => {
check_method_body(ccx, &trait_def.generics,
Some(trait_def.trait_ref), m);
Some(trait_def.trait_ref.clone()), m);
}
}
}
@ -682,7 +682,7 @@ pub fn check_item(ccx: &CrateCtxt, it: &ast::Item) {
fn check_method_body(ccx: &CrateCtxt,
item_generics: &ty::Generics,
self_bound: Option<@ty::TraitRef>,
self_bound: Option<Rc<ty::TraitRef>>,
method: &ast::Method) {
/*!
* Type checks a method body.
@ -744,10 +744,10 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
Some(trait_method_ty) => {
compare_impl_method(ccx.tcx,
impl_generics,
impl_method_ty,
&*impl_method_ty,
impl_method.span,
impl_method.body.id,
*trait_method_ty,
&**trait_method_ty,
&impl_trait_ref.substs);
}
None => {
@ -800,7 +800,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
*/
fn compare_impl_method(tcx: &ty::ctxt,
impl_generics: &ty::Generics,
impl_m: @ty::Method,
impl_m: &ty::Method,
impl_m_span: Span,
impl_m_body_id: ast::NodeId,
trait_m: &ty::Method,
@ -973,8 +973,8 @@ fn compare_impl_method(tcx: &ty::ctxt,
match infer::mk_subty(&infcx, false, infer::MethodCompatCheck(impl_m_span),
impl_fty, trait_fty) {
result::Ok(()) => {}
result::Err(ref terr) => {
Ok(()) => {}
Err(ref terr) => {
tcx.sess.span_err(
impl_m_span,
format!("method `{}` has an incompatible type for trait: {}",
@ -992,7 +992,7 @@ impl<'a> AstConv for FnCtxt<'a> {
ty::lookup_item_type(self.tcx(), id)
}
fn get_trait_def(&self, id: ast::DefId) -> @ty::TraitDef {
fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef> {
ty::lookup_trait_def(self.tcx(), id)
}
@ -1175,8 +1175,8 @@ impl<'a> FnCtxt<'a> {
infer::ExprAssignable(expr.span),
sub,
sup) {
Ok(None) => result::Ok(()),
Err(ref e) => result::Err((*e)),
Ok(None) => Ok(()),
Err(ref e) => Err((*e)),
Ok(Some(adjustment)) => {
self.write_adjustment(expr.id, adjustment);
Ok(())
@ -2844,8 +2844,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
match expr_opt {
None => match fcx.mk_eqty(false, infer::Misc(expr.span),
ret_ty, ty::mk_nil()) {
result::Ok(_) => { /* fall through */ }
result::Err(_) => {
Ok(_) => { /* fall through */ }
Err(_) => {
tcx.sess.span_err(
expr.span,
"`return;` in function returning non-nil");
@ -3541,10 +3541,10 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
vs: &[ast::P<ast::Variant>],
id: ast::NodeId,
hint: attr::ReprAttr)
-> Vec<@ty::VariantInfo> {
-> Vec<Rc<ty::VariantInfo>> {
let rty = ty::node_id_to_type(ccx.tcx, id);
let mut variants: Vec<@ty::VariantInfo> = Vec::new();
let mut variants: Vec<Rc<ty::VariantInfo>> = Vec::new();
let mut disr_vals: Vec<ty::Disr> = Vec::new();
let mut prev_disr_val: Option<ty::Disr> = None;
@ -3600,7 +3600,8 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
}
disr_vals.push(current_disr_val);
let variant_info = @VariantInfo::from_ast_variant(ccx.tcx, v, current_disr_val);
let variant_info = Rc::new(VariantInfo::from_ast_variant(ccx.tcx, v,
current_disr_val));
prev_disr_val = Some(current_disr_val);
variants.push(variant_info);
@ -3622,7 +3623,7 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
let variants = do_check(ccx, vs, id, hint);
// cache so that ty::enum_variants won't repeat this work
ccx.tcx.enum_var_cache.borrow_mut().insert(local_def(id), @variants);
ccx.tcx.enum_var_cache.borrow_mut().insert(local_def(id), Rc::new(variants));
// Check that it is possible to represent this enum.
check_representable(ccx.tcx, sp, id, "enum");

View file

@ -1008,7 +1008,7 @@ fn constrain_regions_in_type(
// for regions that are as-yet-unknown.
} else if r_sub == minimum_lifetime {
rcx.fcx.mk_subr(
true, origin,
true, origin.clone(),
r_sub, r_sup);
} else {
rcx.fcx.mk_subr(

View file

@ -27,6 +27,7 @@ use util::common::indenter;
use util::ppaux;
use util::ppaux::Repr;
use std::rc::Rc;
use collections::HashSet;
use syntax::ast;
use syntax::ast_util;
@ -137,7 +138,7 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
// Substitute the values of the type parameters that may
// appear in the bound.
let trait_ref = substs.as_ref().map_or(trait_ref, |substs| {
let trait_ref = substs.as_ref().map_or(trait_ref.clone(), |substs| {
debug!("about to subst: {}, {}",
trait_ref.repr(tcx), substs.repr(tcx));
trait_ref.subst(tcx, *substs)
@ -145,13 +146,13 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
debug!("after subst: {}", trait_ref.repr(tcx));
match lookup_vtable(vcx, span, ty, trait_ref, is_early) {
match lookup_vtable(vcx, span, ty, trait_ref.clone(), is_early) {
Some(vtable) => param_result.push(vtable),
None => {
vcx.tcx().sess.span_fatal(span,
format!("failed to find an implementation of \
trait {} for {}",
vcx.infcx.trait_ref_to_str(trait_ref),
vcx.infcx.trait_ref_to_str(&*trait_ref),
vcx.infcx.ty_to_str(ty)));
}
}
@ -173,8 +174,8 @@ fn lookup_vtables_for_param(vcx: &VtableContext,
fn relate_trait_refs(vcx: &VtableContext,
span: Span,
act_trait_ref: @ty::TraitRef,
exp_trait_ref: @ty::TraitRef) {
act_trait_ref: Rc<ty::TraitRef>,
exp_trait_ref: Rc<ty::TraitRef>) {
/*!
*
* Checks that an implementation of `act_trait_ref` is suitable
@ -185,17 +186,17 @@ fn relate_trait_refs(vcx: &VtableContext,
match infer::mk_sub_trait_refs(vcx.infcx,
false,
infer::RelateTraitRefs(span),
act_trait_ref,
exp_trait_ref) {
act_trait_ref.clone(),
exp_trait_ref.clone()) {
Ok(()) => {} // Ok.
Err(ref err) => {
// There is an error, but we need to do some work to make
// the message good.
// Resolve any type vars in the trait refs
let r_act_trait_ref =
vcx.infcx.resolve_type_vars_in_trait_ref_if_possible(act_trait_ref);
vcx.infcx.resolve_type_vars_in_trait_ref_if_possible(&*act_trait_ref);
let r_exp_trait_ref =
vcx.infcx.resolve_type_vars_in_trait_ref_if_possible(exp_trait_ref);
vcx.infcx.resolve_type_vars_in_trait_ref_if_possible(&*exp_trait_ref);
// Only print the message if there aren't any previous type errors
// inside the types.
if !ty::trait_ref_contains_error(&r_act_trait_ref) &&
@ -216,12 +217,12 @@ fn relate_trait_refs(vcx: &VtableContext,
fn lookup_vtable(vcx: &VtableContext,
span: Span,
ty: ty::t,
trait_ref: @ty::TraitRef,
trait_ref: Rc<ty::TraitRef>,
is_early: bool)
-> Option<vtable_origin> {
debug!("lookup_vtable(ty={}, trait_ref={})",
vcx.infcx.ty_to_str(ty),
vcx.infcx.trait_ref_to_str(trait_ref));
vcx.infcx.trait_ref_to_str(&*trait_ref));
let _i = indenter();
let ty = match fixup_ty(vcx, span, ty, is_early) {
@ -242,23 +243,23 @@ fn lookup_vtable(vcx: &VtableContext,
ty::ty_param(param_ty {idx: n, ..}) => {
let env_bounds = &vcx.param_env.type_param_bounds;
if env_bounds.len() > n {
let type_param_bounds: &[@ty::TraitRef] =
let type_param_bounds: &[Rc<ty::TraitRef>] =
env_bounds.get(n).trait_bounds.as_slice();
lookup_vtable_from_bounds(vcx, span,
type_param_bounds,
param_numbered(n),
trait_ref)
trait_ref.clone())
} else {
None
}
}
ty::ty_self(_) => {
let self_param_bound = vcx.param_env.self_param_bound.unwrap();
let self_param_bound = vcx.param_env.self_param_bound.clone().unwrap();
lookup_vtable_from_bounds(vcx, span,
[self_param_bound],
param_self,
trait_ref)
trait_ref.clone())
}
// Default case just falls through
@ -276,9 +277,9 @@ fn lookup_vtable(vcx: &VtableContext,
// of them are the vtable we are looking for.
fn lookup_vtable_from_bounds(vcx: &VtableContext,
span: Span,
bounds: &[@ty::TraitRef],
bounds: &[Rc<ty::TraitRef>],
param: param_index,
trait_ref: @ty::TraitRef)
trait_ref: Rc<ty::TraitRef>)
-> Option<vtable_origin> {
let tcx = vcx.tcx();
@ -289,7 +290,7 @@ fn lookup_vtable_from_bounds(vcx: &VtableContext,
bound_trait_ref.repr(vcx.tcx()));
if bound_trait_ref.def_id == trait_ref.def_id {
relate_trait_refs(vcx, span, bound_trait_ref, trait_ref);
relate_trait_refs(vcx, span, bound_trait_ref, trait_ref.clone());
let vtable = vtable_param(param, n_bound);
debug!("found param vtable: {:?}",
vtable);
@ -306,7 +307,7 @@ fn lookup_vtable_from_bounds(vcx: &VtableContext,
fn search_for_vtable(vcx: &VtableContext,
span: Span,
ty: ty::t,
trait_ref: @ty::TraitRef,
trait_ref: Rc<ty::TraitRef>,
is_early: bool)
-> Option<vtable_origin> {
let tcx = vcx.tcx();
@ -388,13 +389,13 @@ fn search_for_vtable(vcx: &VtableContext,
// some value of U) with some_trait<T>. This would fail if T
// and U weren't compatible.
debug!("(checking vtable) @2 relating trait \
debug!("(checking vtable) \\#2 relating trait \
ty {} to of_trait_ref {}",
vcx.infcx.trait_ref_to_str(trait_ref),
vcx.infcx.trait_ref_to_str(of_trait_ref));
vcx.infcx.trait_ref_to_str(&*trait_ref),
vcx.infcx.trait_ref_to_str(&*of_trait_ref));
let of_trait_ref = of_trait_ref.subst(tcx, &substs);
relate_trait_refs(vcx, span, of_trait_ref, trait_ref);
relate_trait_refs(vcx, span, of_trait_ref, trait_ref.clone());
// Recall that trait_ref -- the trait type we're casting to --
@ -429,7 +430,7 @@ fn search_for_vtable(vcx: &VtableContext,
they will be unified with the bounds for \
the target ty, {}",
vcx.infcx.tys_to_str(substs_f.tps.as_slice()),
vcx.infcx.trait_ref_to_str(trait_ref));
vcx.infcx.trait_ref_to_str(&*trait_ref));
// Next, we unify the fixed-up substitutions for the impl self
// ty with the substitutions from the trait type that we're
@ -438,7 +439,7 @@ fn search_for_vtable(vcx: &VtableContext,
// I am a little confused about this, since it seems to be
// very similar to the relate_trait_refs we already do,
// but problems crop up if it is removed, so... -sully
connect_trait_tps(vcx, span, &substs_f, trait_ref, impl_did);
connect_trait_tps(vcx, span, &substs_f, trait_ref.clone(), impl_did);
// Finally, we register that we found a matching impl, and
// record the def ID of the impl as well as the resolved list
@ -502,7 +503,7 @@ fn fixup_ty(vcx: &VtableContext,
fn connect_trait_tps(vcx: &VtableContext,
span: Span,
impl_substs: &ty::substs,
trait_ref: @ty::TraitRef,
trait_ref: Rc<ty::TraitRef>,
impl_did: ast::DefId) {
let tcx = vcx.tcx();
@ -561,14 +562,14 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
};
let vcx = fcx.vtable_context();
let target_trait_ref = @ty::TraitRef {
let target_trait_ref = Rc::new(ty::TraitRef {
def_id: target_def_id,
substs: ty::substs {
tps: target_substs.tps.clone(),
regions: target_substs.regions.clone(),
self_ty: Some(typ)
}
};
});
let param_bounds = ty::ParamBounds {
builtin_bounds: ty::EmptyBuiltinBounds(),
@ -761,7 +762,7 @@ pub fn resolve_impl(tcx: &ty::ctxt,
// but that falls out of doing this.
let param_bounds = ty::ParamBounds {
builtin_bounds: ty::EmptyBuiltinBounds(),
trait_bounds: vec!(@impl_trait_ref)
trait_bounds: vec!(Rc::new(impl_trait_ref))
};
let t = ty::node_id_to_type(tcx, impl_item.id);
let t = t.subst(tcx, &param_env.free_substs);

View file

@ -330,13 +330,13 @@ impl<'a> CoherenceChecker<'a> {
// Create substitutions for the various trait parameters.
let new_method_ty =
@subst_receiver_types_in_method_ty(
Rc::new(subst_receiver_types_in_method_ty(
tcx,
impl_id,
trait_ref,
new_did,
*trait_method,
Some(trait_method.def_id));
&**trait_method,
Some(trait_method.def_id)));
debug!("new_method_ty={}", new_method_ty.repr(tcx));
all_methods.push(new_did);
@ -376,7 +376,8 @@ impl<'a> CoherenceChecker<'a> {
None => {}
}
tcx.inherent_impls.borrow_mut().insert(base_def_id, @RefCell::new(vec!(impl_def_id)));
tcx.inherent_impls.borrow_mut().insert(base_def_id,
Rc::new(RefCell::new(vec!(impl_def_id))));
}
fn add_trait_impl(&self, base_def_id: DefId, impl_def_id: DefId) {
@ -575,7 +576,7 @@ impl<'a> CoherenceChecker<'a> {
trait_ref.ref_id);
self.instantiate_default_methods(local_def(item.id),
ty_trait_ref,
&*ty_trait_ref,
&mut methods);
}

View file

@ -126,7 +126,7 @@ impl<'a> AstConv for CrateCtxt<'a> {
}
}
fn get_trait_def(&self, id: ast::DefId) -> @ty::TraitDef {
fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef> {
get_trait_def(self, id)
}
@ -195,7 +195,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) {
// For each method, construct a suitable ty::Method and
// store it into the `tcx.methods` table:
for m in ms.iter() {
let ty_method = @match m {
let ty_method = Rc::new(match m {
&ast::Required(ref m) => {
ty_method_of_trait_method(
ccx, trait_id, &trait_ty_generics,
@ -209,10 +209,10 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) {
&m.id, &m.ident, &m.explicit_self,
&m.generics, &m.fn_style, m.decl)
}
};
});
if ty_method.explicit_self == ast::SelfStatic {
make_static_method_ty(ccx, trait_id, ty_method,
make_static_method_ty(ccx, trait_id, &*ty_method,
&trait_ty_generics);
}
@ -221,7 +221,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) {
}
// Add an entry mapping
let method_def_ids = @ms.iter().map(|m| {
let method_def_ids = Rc::new(ms.iter().map(|m| {
match m {
&ast::Required(ref ty_method) => {
local_def(ty_method.id)
@ -230,7 +230,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) {
local_def(method.id)
}
}
}).collect();
}).collect());
let trait_def_id = local_def(trait_id);
tcx.trait_method_def_ids.borrow_mut()
@ -412,7 +412,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt,
assert!(!tcx.supertraits.borrow().contains_key(&local_def(id)));
let self_ty = ty::mk_self(ccx.tcx, local_def(id));
let mut ty_trait_refs: Vec<@ty::TraitRef> = Vec::new();
let mut ty_trait_refs: Vec<Rc<ty::TraitRef>> = Vec::new();
let mut bounds = ty::EmptyBuiltinBounds();
for ast_trait_ref in ast_trait_refs.iter() {
let trait_def_id = ty::trait_ref_to_def_id(ccx.tcx, ast_trait_ref);
@ -434,7 +434,7 @@ pub fn ensure_supertraits(ccx: &CrateCtxt,
}
}
tcx.supertraits.borrow_mut().insert(local_def(id), @ty_trait_refs);
tcx.supertraits.borrow_mut().insert(local_def(id), Rc::new(ty_trait_refs));
bounds
}
@ -489,12 +489,12 @@ fn convert_methods(ccx: &CrateCtxt,
let num_rcvr_ty_params = rcvr_ty_generics.type_param_defs().len();
let m_ty_generics = ty_generics_for_fn_or_method(ccx, &m.generics,
num_rcvr_ty_params);
let mty = @ty_of_method(ccx,
container,
*m,
untransformed_rcvr_ty,
rcvr_ast_generics,
rcvr_visibility);
let mty = Rc::new(ty_of_method(ccx,
container,
*m,
untransformed_rcvr_ty,
rcvr_ast_generics,
rcvr_visibility));
let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
debug!("method {} (id {}) has type {}",
m.ident.repr(ccx.tcx),
@ -726,7 +726,7 @@ pub fn convert_struct(ccx: &CrateCtxt,
result
}).collect();
tcx.struct_fields.borrow_mut().insert(local_def(id), @field_tys);
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 {
@ -813,8 +813,7 @@ pub fn convert_foreign(ccx: &CrateCtxt, i: &ast::ForeignItem) {
pub fn instantiate_trait_ref(ccx: &CrateCtxt,
ast_trait_ref: &ast::TraitRef,
self_ty: ty::t) -> @ty::TraitRef
{
self_ty: ty::t) -> Rc<ty::TraitRef> {
/*!
* Instantiates the path for the given trait reference, assuming that
* it's bound to a valid trait type. Returns the def_id for the defining
@ -831,8 +830,8 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt,
ccx, &rscope, trait_did, Some(self_ty), &ast_trait_ref.path);
ccx.tcx.trait_refs.borrow_mut().insert(ast_trait_ref.ref_id,
trait_ref);
return trait_ref;
trait_ref.clone());
trait_ref
}
_ => {
ccx.tcx.sess.span_fatal(
@ -843,7 +842,7 @@ pub fn instantiate_trait_ref(ccx: &CrateCtxt,
}
}
fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> @ty::TraitDef {
fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> Rc<ty::TraitDef> {
if trait_id.krate != ast::LOCAL_CRATE {
return ty::lookup_trait_def(ccx.tcx, trait_id)
}
@ -855,11 +854,11 @@ fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> @ty::TraitDef {
}
}
pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> @ty::TraitDef {
pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc<ty::TraitDef> {
let def_id = local_def(it.id);
let tcx = ccx.tcx;
match tcx.trait_defs.borrow().find(&def_id) {
Some(&def) => return def,
Some(def) => return def.clone(),
_ => {}
}
@ -872,13 +871,16 @@ pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> @ty::TraitDef {
it.id,
it.span,
supertraits.as_slice());
let trait_ref = @ty::TraitRef {def_id: def_id,
substs: substs};
let trait_def = @ty::TraitDef {generics: ty_generics,
bounds: bounds,
trait_ref: trait_ref};
tcx.trait_defs.borrow_mut().insert(def_id, trait_def);
return trait_def;
let trait_def = Rc::new(ty::TraitDef {
generics: ty_generics,
bounds: bounds,
trait_ref: Rc::new(ty::TraitRef {
def_id: def_id,
substs: substs
})
});
tcx.trait_defs.borrow_mut().insert(def_id, trait_def.clone());
trait_def
}
ref s => {
tcx.sess.span_bug(

View file

@ -195,7 +195,7 @@ impl<'f> Coerce<'f> {
}
pub fn subtype(&self, a: ty::t, b: ty::t) -> CoerceResult {
match Sub(*self.get_ref()).tys(a, b) {
match Sub(self.get_ref().clone()).tys(a, b) {
Ok(_) => Ok(None), // No coercion required.
Err(ref e) => Err(*e)
}
@ -232,8 +232,9 @@ impl<'f> Coerce<'f> {
// to type check, we will construct the type that `&M*expr` would
// yield.
let sub = Sub(*self.get_ref());
let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
let sub = Sub(self.get_ref().clone());
let coercion = Coercion(self.get_ref().trace.clone());
let r_borrow = self.get_ref().infcx.next_region_var(coercion);
let inner_ty = match *sty_a {
ty::ty_box(typ) | ty::ty_uniq(typ) => typ,
@ -269,7 +270,8 @@ impl<'f> Coerce<'f> {
}
};
let r_a = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
let coercion = Coercion(self.get_ref().trace.clone());
let r_a = self.get_ref().infcx.next_region_var(coercion);
let a_borrowed = ty::mk_str(self.get_ref().infcx.tcx, VstoreSlice(r_a));
if_ok!(self.subtype(a_borrowed, b));
Ok(Some(AutoDerefRef(AutoDerefRef {
@ -288,8 +290,9 @@ impl<'f> Coerce<'f> {
a.inf_str(self.get_ref().infcx), sty_a,
b.inf_str(self.get_ref().infcx));
let sub = Sub(*self.get_ref());
let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
let sub = Sub(self.get_ref().clone());
let coercion = Coercion(self.get_ref().trace.clone());
let r_borrow = self.get_ref().infcx.next_region_var(coercion);
let ty_inner = match *sty_a {
ty::ty_uniq(t) | ty::ty_ptr(ty::mt{ty: t, ..}) |
ty::ty_rptr(_, ty::mt{ty: t, ..}) => match ty::get(t).sty {
@ -324,7 +327,8 @@ impl<'f> Coerce<'f> {
b.inf_str(self.get_ref().infcx));
let tcx = self.get_ref().infcx.tcx;
let r_a = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
let coercion = Coercion(self.get_ref().trace.clone());
let r_a = self.get_ref().infcx.next_region_var(coercion);
let a_borrowed = match *sty_a {
ty::ty_trait(~ty::TyTrait { def_id, ref substs, bounds, .. }) => {

View file

@ -324,6 +324,7 @@ pub trait Combine {
}
}
#[deriving(Clone)]
pub struct CombineFields<'a> {
pub infcx: &'a InferCtxt<'a>,
pub a_is_expected: bool,

View file

@ -76,6 +76,7 @@ use middle::typeck::infer::region_inference::ProcessedErrors;
use middle::typeck::infer::region_inference::SameRegions;
use std::cell::{Cell, RefCell};
use std::char::from_u32;
use std::rc::Rc;
use std::strbuf::StrBuf;
use syntax::ast;
use syntax::ast_map;
@ -158,7 +159,7 @@ impl<'a> ErrorReporting for InferCtxt<'a> {
let p_errors = self.process_errors(errors);
let errors = if p_errors.is_empty() { errors } else { &p_errors };
for error in errors.iter() {
match *error {
match error.clone() {
ConcreteFailure(origin, sub, sup) => {
self.report_concrete_failure(origin, sub, sup);
}
@ -206,7 +207,7 @@ impl<'a> ErrorReporting for InferCtxt<'a> {
let mut same_regions = Vec::new();
let mut processed_errors = Vec::new();
for error in errors.iter() {
match *error {
match error.clone() {
ConcreteFailure(origin, sub, sup) => {
debug!("processing ConcreteFailure")
let trace = match origin {
@ -661,10 +662,10 @@ impl<'a> ErrorReporting for InferCtxt<'a> {
same_regions: &[SameRegions]) {
self.give_suggestion(same_regions);
for vo in var_origins.iter() {
self.report_inference_failure(*vo);
self.report_inference_failure(vo.clone());
}
for &(trace, terr) in trace_origins.iter() {
self.report_type_error(trace, &terr);
for &(ref trace, terr) in trace_origins.iter() {
self.report_type_error(trace.clone(), &terr);
}
}
@ -1391,12 +1392,12 @@ impl Resolvable for ty::t {
}
}
impl Resolvable for @ty::TraitRef {
fn resolve(&self, infcx: &InferCtxt) -> @ty::TraitRef {
@infcx.resolve_type_vars_in_trait_ref_if_possible(*self)
impl Resolvable for Rc<ty::TraitRef> {
fn resolve(&self, infcx: &InferCtxt) -> Rc<ty::TraitRef> {
Rc::new(infcx.resolve_type_vars_in_trait_ref_if_possible(&**self))
}
fn contains_error(&self) -> bool {
ty::trait_ref_contains_error(*self)
ty::trait_ref_contains_error(&**self)
}
}

View file

@ -38,11 +38,11 @@ impl<'f> Combine for Glb<'f> {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a> { self.get_ref().infcx }
fn tag(&self) -> ~str { "glb".to_owned() }
fn a_is_expected(&self) -> bool { self.get_ref().a_is_expected }
fn trace(&self) -> TypeTrace { self.get_ref().trace }
fn trace(&self) -> TypeTrace { self.get_ref().trace.clone() }
fn sub<'a>(&'a self) -> Sub<'a> { Sub(*self.get_ref()) }
fn lub<'a>(&'a self) -> Lub<'a> { Lub(*self.get_ref()) }
fn glb<'a>(&'a self) -> Glb<'a> { Glb(*self.get_ref()) }
fn sub<'a>(&'a self) -> Sub<'a> { Sub(self.get_ref().clone()) }
fn lub<'a>(&'a self) -> Lub<'a> { Lub(self.get_ref().clone()) }
fn glb<'a>(&'a self) -> Glb<'a> { Glb(self.get_ref().clone()) }
fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
let tcx = self.get_ref().infcx.tcx;
@ -78,7 +78,7 @@ impl<'f> Combine for Glb<'f> {
}
fn contratys(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
Lub(*self.get_ref()).tys(a, b)
self.lub().tys(a, b)
}
fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres<FnStyle> {
@ -108,12 +108,12 @@ impl<'f> Combine for Glb<'f> {
a.inf_str(self.get_ref().infcx),
b.inf_str(self.get_ref().infcx));
Ok(self.get_ref().infcx.region_vars.glb_regions(Subtype(self.get_ref().trace), a, b))
Ok(self.get_ref().infcx.region_vars.glb_regions(Subtype(self.trace()), a, b))
}
fn contraregions(&self, a: ty::Region, b: ty::Region)
-> cres<ty::Region> {
Lub(*self.get_ref()).regions(a, b)
self.lub().regions(a, b)
}
fn tys(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
@ -137,11 +137,11 @@ impl<'f> Combine for Glb<'f> {
// Instantiate each bound region with a fresh region variable.
let (a_with_fresh, a_map) =
self.get_ref().infcx.replace_late_bound_regions_with_fresh_regions(
self.get_ref().trace, a);
self.trace(), a);
let a_vars = var_ids(self, &a_map);
let (b_with_fresh, b_map) =
self.get_ref().infcx.replace_late_bound_regions_with_fresh_regions(
self.get_ref().trace, b);
self.trace(), b);
let b_vars = var_ids(self, &b_map);
// Collect constraints.

View file

@ -47,26 +47,26 @@ use util::common::indenter;
use collections::HashMap;
pub trait LatticeValue {
fn sub(cf: &CombineFields, a: &Self, b: &Self) -> ures;
fn lub(cf: &CombineFields, a: &Self, b: &Self) -> cres<Self>;
fn glb(cf: &CombineFields, a: &Self, b: &Self) -> cres<Self>;
trait LatticeValue {
fn sub(cf: CombineFields, a: &Self, b: &Self) -> ures;
fn lub(cf: CombineFields, a: &Self, b: &Self) -> cres<Self>;
fn glb(cf: CombineFields, a: &Self, b: &Self) -> cres<Self>;
}
pub type LatticeOp<'a, T> =
|cf: &CombineFields, a: &T, b: &T|: 'a -> cres<T>;
|cf: CombineFields, a: &T, b: &T|: 'a -> cres<T>;
impl LatticeValue for ty::t {
fn sub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> ures {
Sub(*cf).tys(*a, *b).to_ures()
fn sub(cf: CombineFields, a: &ty::t, b: &ty::t) -> ures {
Sub(cf).tys(*a, *b).to_ures()
}
fn lub(cf: &CombineFields, a: &ty::t, b: &ty::t) -> cres<ty::t> {
Lub(*cf).tys(*a, *b)
fn lub(cf: CombineFields, a: &ty::t, b: &ty::t) -> cres<ty::t> {
Lub(cf).tys(*a, *b)
}
fn glb(cf: &CombineFields, a: &ty::t, b: &ty::t) -> cres<ty::t> {
Glb(*cf).tys(*a, *b)
fn glb(cf: CombineFields, a: &ty::t, b: &ty::t) -> cres<ty::t> {
Glb(cf).tys(*a, *b)
}
}
@ -142,7 +142,7 @@ impl<'f> CombineFieldsLatticeMethods for CombineFields<'f> {
match (&a_bounds.ub, &b_bounds.lb) {
(&Some(ref a_ub), &Some(ref b_lb)) => {
let r = self.infcx.try(
|| LatticeValue::sub(self, a_ub, b_lb));
|| LatticeValue::sub(self.clone(), a_ub, b_lb));
match r {
Ok(()) => {
return Ok(());
@ -232,7 +232,7 @@ impl<'f> CombineFieldsLatticeMethods for CombineFields<'f> {
(&Some(_), &None) => Ok((*a).clone()),
(&None, &Some(_)) => Ok((*b).clone()),
(&Some(ref v_a), &Some(ref v_b)) => {
lattice_op(self, v_a, v_b).and_then(|v| Ok(Some(v)))
lattice_op(self.clone(), v_a, v_b).and_then(|v| Ok(Some(v)))
}
}
}
@ -314,7 +314,7 @@ impl<'f> CombineFieldsLatticeMethods for CombineFields<'f> {
uok()
}
(&Some(ref t_a), &Some(ref t_b)) => {
LatticeValue::sub(self, t_a, t_b)
LatticeValue::sub(self.clone(), t_a, t_b)
}
}
}
@ -337,7 +337,7 @@ pub trait TyLatticeDir {
}
impl<'f> LatticeDir for Lub<'f> {
fn combine_fields<'a>(&'a self) -> CombineFields<'a> { *self.get_ref() }
fn combine_fields<'a>(&'a self) -> CombineFields<'a> { self.get_ref().clone() }
fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T> { b.ub.clone() }
fn with_bnd<T:Clone>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
Bounds { ub: Some(t), ..(*b).clone() }
@ -351,7 +351,7 @@ impl<'f> TyLatticeDir for Lub<'f> {
}
impl<'f> LatticeDir for Glb<'f> {
fn combine_fields<'a>(&'a self) -> CombineFields<'a> { *self.get_ref() }
fn combine_fields<'a>(&'a self) -> CombineFields<'a> { self.get_ref().clone() }
fn bnd<T:Clone>(&self, b: &Bounds<T>) -> Option<T> { b.lb.clone() }
fn with_bnd<T:Clone>(&self, b: &Bounds<T>, t: T) -> Bounds<T> {
Bounds { lb: Some(t), ..(*b).clone() }

View file

@ -37,11 +37,11 @@ impl<'f> Combine for Lub<'f> {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a> { self.get_ref().infcx }
fn tag(&self) -> ~str { "lub".to_owned() }
fn a_is_expected(&self) -> bool { self.get_ref().a_is_expected }
fn trace(&self) -> TypeTrace { self.get_ref().trace }
fn trace(&self) -> TypeTrace { self.get_ref().trace.clone() }
fn sub<'a>(&'a self) -> Sub<'a> { Sub(*self.get_ref()) }
fn lub<'a>(&'a self) -> Lub<'a> { Lub(*self.get_ref()) }
fn glb<'a>(&'a self) -> Glb<'a> { Glb(*self.get_ref()) }
fn sub<'a>(&'a self) -> Sub<'a> { Sub(self.get_ref().clone()) }
fn lub<'a>(&'a self) -> Lub<'a> { Lub(self.get_ref().clone()) }
fn glb<'a>(&'a self) -> Glb<'a> { Glb(self.get_ref().clone()) }
fn mts(&self, a: &ty::mt, b: &ty::mt) -> cres<ty::mt> {
let tcx = self.get_ref().infcx.tcx;
@ -72,7 +72,7 @@ impl<'f> Combine for Lub<'f> {
}
fn contratys(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
Glb(*self.get_ref()).tys(a, b)
self.glb().tys(a, b)
}
fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres<FnStyle> {
@ -98,7 +98,7 @@ impl<'f> Combine for Lub<'f> {
fn contraregions(&self, a: ty::Region, b: ty::Region)
-> cres<ty::Region> {
return Glb(*self.get_ref()).regions(a, b);
self.glb().regions(a, b)
}
fn regions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region> {
@ -107,7 +107,7 @@ impl<'f> Combine for Lub<'f> {
a.inf_str(self.get_ref().infcx),
b.inf_str(self.get_ref().infcx));
Ok(self.get_ref().infcx.region_vars.lub_regions(Subtype(self.get_ref().trace), a, b))
Ok(self.get_ref().infcx.region_vars.lub_regions(Subtype(self.trace()), a, b))
}
fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
@ -123,10 +123,10 @@ impl<'f> Combine for Lub<'f> {
// Instantiate each bound region with a fresh region variable.
let (a_with_fresh, a_map) =
self.get_ref().infcx.replace_late_bound_regions_with_fresh_regions(
self.get_ref().trace, a);
self.trace(), a);
let (b_with_fresh, _) =
self.get_ref().infcx.replace_late_bound_regions_with_fresh_regions(
self.get_ref().trace, b);
self.trace(), b);
// Collect constraints.
let sig0 = if_ok!(super_fn_sigs(self, &a_with_fresh, &b_with_fresh));

View file

@ -38,7 +38,7 @@ use middle::typeck::infer::to_str::InferStr;
use middle::typeck::infer::unify::{ValsAndBindings, Root};
use middle::typeck::infer::error_reporting::ErrorReporting;
use std::cell::{Cell, RefCell};
use std::result;
use std::rc::Rc;
use syntax::ast::{MutImmutable, MutMutable};
use syntax::ast;
use syntax::codemap;
@ -129,7 +129,7 @@ pub enum TypeOrigin {
#[deriving(Clone)]
pub enum ValuePairs {
Types(ty::expected_found<ty::t>),
TraitRefs(ty::expected_found<@ty::TraitRef>),
TraitRefs(ty::expected_found<Rc<ty::TraitRef>>),
}
/// The trace designates the path through inference that we took to
@ -301,7 +301,7 @@ pub fn common_supertype(cx: &InferCtxt,
values: Types(expected_found(a_is_expected, a, b))
};
let result = cx.commit(|| cx.lub(a_is_expected, trace).tys(a, b));
let result = cx.commit(|| cx.lub(a_is_expected, trace.clone()).tys(a, b));
match result {
Ok(t) => t,
Err(ref err) => {
@ -375,8 +375,8 @@ pub fn mk_eqty(cx: &InferCtxt,
pub fn mk_sub_trait_refs(cx: &InferCtxt,
a_is_expected: bool,
origin: TypeOrigin,
a: @ty::TraitRef,
b: @ty::TraitRef)
a: Rc<ty::TraitRef>,
b: Rc<ty::TraitRef>)
-> ures
{
debug!("mk_sub_trait_refs({} <: {})",
@ -385,10 +385,10 @@ pub fn mk_sub_trait_refs(cx: &InferCtxt,
cx.commit(|| {
let trace = TypeTrace {
origin: origin,
values: TraitRefs(expected_found(a_is_expected, a, b))
values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
};
let suber = cx.sub(a_is_expected, trace);
suber.trait_refs(a, b)
suber.trait_refs(&*a, &*b)
})
}).to_ures()
}
@ -666,8 +666,8 @@ impl<'a> InferCtxt<'a> {
pub fn resolve_type_vars_if_possible(&self, typ: ty::t) -> ty::t {
match resolve_type(self, typ, resolve_nested_tvar | resolve_ivar) {
result::Ok(new_type) => new_type,
result::Err(_) => typ
Ok(new_type) => new_type,
Err(_) => typ
}
}
@ -854,7 +854,7 @@ impl Repr for TypeOrigin {
impl SubregionOrigin {
pub fn span(&self) -> Span {
match *self {
Subtype(a) => a.span(),
Subtype(ref a) => a.span(),
InfStackClosure(a) => a,
InvokeClosure(a) => a,
DerefPointer(a) => a,
@ -877,7 +877,7 @@ impl SubregionOrigin {
impl Repr for SubregionOrigin {
fn repr(&self, tcx: &ty::ctxt) -> ~str {
match *self {
Subtype(a) => format!("Subtype({})", a.repr(tcx)),
Subtype(ref a) => format!("Subtype({})", a.repr(tcx)),
InfStackClosure(a) => format!("InfStackClosure({})", a.repr(tcx)),
InvokeClosure(a) => format!("InvokeClosure({})", a.repr(tcx)),
DerefPointer(a) => format!("DerefPointer({})", a.repr(tcx)),
@ -907,7 +907,7 @@ impl RegionVariableOrigin {
AddrOfRegion(a) => a,
AddrOfSlice(a) => a,
Autoref(a) => a,
Coercion(a) => a.span(),
Coercion(ref a) => a.span(),
EarlyBoundRegion(a, _) => a,
LateBoundRegion(a, _) => a,
BoundRegionInFnType(a, _) => a,
@ -925,7 +925,7 @@ impl Repr for RegionVariableOrigin {
AddrOfRegion(a) => format!("AddrOfRegion({})", a.repr(tcx)),
AddrOfSlice(a) => format!("AddrOfSlice({})", a.repr(tcx)),
Autoref(a) => format!("Autoref({})", a.repr(tcx)),
Coercion(a) => format!("Coercion({})", a.repr(tcx)),
Coercion(ref a) => format!("Coercion({})", a.repr(tcx)),
EarlyBoundRegion(a, b) => format!("EarlyBoundRegion({},{})",
a.repr(tcx), b.repr(tcx)),
LateBoundRegion(a, b) => format!("LateBoundRegion({},{})",

View file

@ -212,7 +212,7 @@ impl<'a> RegionVarBindings<'a> {
pub fn new_region_var(&self, origin: RegionVariableOrigin) -> RegionVid {
let id = self.num_vars();
self.var_origins.borrow_mut().push(origin);
self.var_origins.borrow_mut().push(origin.clone());
let vid = RegionVid { id: id };
if self.in_snapshot() {
self.undo_log.borrow_mut().push(AddVar(vid));
@ -330,9 +330,9 @@ impl<'a> RegionVarBindings<'a> {
_ => {
self.combine_vars(
Lub, a, b, origin,
Lub, a, b, origin.clone(),
|this, old_r, new_r|
this.make_subregion(origin, old_r, new_r))
this.make_subregion(origin.clone(), old_r, new_r))
}
}
}
@ -354,9 +354,9 @@ impl<'a> RegionVarBindings<'a> {
_ => {
self.combine_vars(
Glb, a, b, origin,
Glb, a, b, origin.clone(),
|this, old_r, new_r|
this.make_subregion(origin, new_r, old_r))
this.make_subregion(origin.clone(), new_r, old_r))
}
}
}
@ -1150,10 +1150,10 @@ impl<'a> RegionVarBindings<'a> {
if !self.is_subregion_of(lower_bound.region,
upper_bound.region) {
errors.push(SubSupConflict(
*self.var_origins.borrow().get(node_idx.to_uint()),
lower_bound.origin,
self.var_origins.borrow().get(node_idx.to_uint()).clone(),
lower_bound.origin.clone(),
lower_bound.region,
upper_bound.origin,
upper_bound.origin.clone(),
upper_bound.region));
return;
}
@ -1200,10 +1200,10 @@ impl<'a> RegionVarBindings<'a> {
Ok(_) => {}
Err(_) => {
errors.push(SupSupConflict(
*self.var_origins.borrow().get(node_idx.to_uint()),
upper_bound_1.origin,
self.var_origins.borrow().get(node_idx.to_uint()).clone(),
upper_bound_1.origin.clone(),
upper_bound_1.region,
upper_bound_2.origin,
upper_bound_2.origin.clone(),
upper_bound_2.region));
return;
}

View file

@ -37,15 +37,16 @@ impl<'f> Combine for Sub<'f> {
fn infcx<'a>(&'a self) -> &'a InferCtxt<'a> { self.get_ref().infcx }
fn tag(&self) -> ~str { "sub".to_owned() }
fn a_is_expected(&self) -> bool { self.get_ref().a_is_expected }
fn trace(&self) -> TypeTrace { self.get_ref().trace }
fn trace(&self) -> TypeTrace { self.get_ref().trace.clone() }
fn sub<'a>(&'a self) -> Sub<'a> { Sub(*self.get_ref()) }
fn lub<'a>(&'a self) -> Lub<'a> { Lub(*self.get_ref()) }
fn glb<'a>(&'a self) -> Glb<'a> { Glb(*self.get_ref()) }
fn sub<'a>(&'a self) -> Sub<'a> { Sub(self.get_ref().clone()) }
fn lub<'a>(&'a self) -> Lub<'a> { Lub(self.get_ref().clone()) }
fn glb<'a>(&'a self) -> Glb<'a> { Glb(self.get_ref().clone()) }
fn contratys(&self, a: ty::t, b: ty::t) -> cres<ty::t> {
let opp = CombineFields {
a_is_expected: !self.get_ref().a_is_expected,.. *self.get_ref()
a_is_expected: !self.get_ref().a_is_expected,
..self.get_ref().clone()
};
Sub(opp).tys(b, a)
}
@ -53,7 +54,8 @@ impl<'f> Combine for Sub<'f> {
fn contraregions(&self, a: ty::Region, b: ty::Region)
-> cres<ty::Region> {
let opp = CombineFields {
a_is_expected: !self.get_ref().a_is_expected,.. *self.get_ref()
a_is_expected: !self.get_ref().a_is_expected,
..self.get_ref().clone()
};
Sub(opp).regions(b, a)
}
@ -63,7 +65,7 @@ impl<'f> Combine for Sub<'f> {
self.tag(),
a.inf_str(self.get_ref().infcx),
b.inf_str(self.get_ref().infcx));
self.get_ref().infcx.region_vars.make_subregion(Subtype(self.get_ref().trace), a, b);
self.get_ref().infcx.region_vars.make_subregion(Subtype(self.trace()), a, b);
Ok(a)
}
@ -167,7 +169,7 @@ impl<'f> Combine for Sub<'f> {
// region variable.
let (a_sig, _) =
self.get_ref().infcx.replace_late_bound_regions_with_fresh_regions(
self.get_ref().trace, a);
self.trace(), a);
// Second, we instantiate each bound region in the supertype with a
// fresh concrete region.

View file

@ -197,6 +197,7 @@ use arena;
use arena::Arena;
use middle::ty;
use std::fmt;
use std::rc::Rc;
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util;
@ -254,7 +255,7 @@ struct TermsContext<'a> {
tcx: &'a ty::ctxt,
arena: &'a Arena,
empty_variances: @ty::ItemVariances,
empty_variances: Rc<ty::ItemVariances>,
// Maps from the node id of a type/generic parameter to the
// corresponding inferred index.
@ -286,9 +287,11 @@ fn determine_parameters_to_be_inferred<'a>(tcx: &'a ty::ctxt,
// cache and share the variance struct used for items with
// no type/region parameters
empty_variances: @ty::ItemVariances { self_param: None,
type_params: OwnedSlice::empty(),
region_params: OwnedSlice::empty() }
empty_variances: Rc::new(ty::ItemVariances {
self_param: None,
type_params: OwnedSlice::empty(),
region_params: OwnedSlice::empty()
})
};
visit::walk_crate(&mut terms_cx, krate, ());
@ -362,7 +365,7 @@ impl<'a> Visitor<()> for TermsContext<'a> {
if self.num_inferred() == inferreds_on_entry {
let newly_added = self.tcx.item_variance_map.borrow_mut().insert(
ast_util::local_def(item.id),
self.empty_variances);
self.empty_variances.clone());
assert!(newly_added);
}
@ -1016,7 +1019,7 @@ impl<'a> SolveContext<'a> {
}
let newly_added = tcx.item_variance_map.borrow_mut()
.insert(item_def_id, @item_variances);
.insert(item_def_id, Rc::new(item_variances));
assert!(newly_added);
}
}

View file

@ -22,6 +22,7 @@ use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
use middle::ty;
use middle::typeck;
use std::rc::Rc;
use std::strbuf::StrBuf;
use syntax::abi;
use syntax::ast_map;
@ -497,6 +498,12 @@ impl Repr for () {
}
}
impl<T:Repr> Repr for Rc<T> {
fn repr(&self, tcx: &ctxt) -> ~str {
(&**self).repr(tcx)
}
}
impl<T:Repr> Repr for @T {
fn repr(&self, tcx: &ctxt) -> ~str {
(&**self).repr(tcx)
@ -887,7 +894,7 @@ impl Repr for Span {
}
}
impl<A:UserString> UserString for @A {
impl<A:UserString> UserString for Rc<A> {
fn user_string(&self, tcx: &ctxt) -> ~str {
let this: &A = &**self;
this.user_string(tcx)

View file

@ -9,6 +9,7 @@
// except according to those terms.
use std::mem;
use std::slice;
use std::vec;
/// A vector type optimized for cases where the size is almost always 0 or 1
@ -61,6 +62,14 @@ impl<T> SmallVector<T> {
SmallVector { repr: Many(vs) }
}
pub fn as_slice<'a>(&'a self) -> &'a [T] {
match self.repr {
Zero => &[],
One(ref v) => slice::ref_slice(v),
Many(ref vs) => vs.as_slice()
}
}
pub fn push(&mut self, v: T) {
match self.repr {
Zero => self.repr = One(v),