rustc: de-@ middle::ty.
This commit is contained in:
parent
1e5a112922
commit
57aa0eb0aa
33 changed files with 440 additions and 435 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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, ".");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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 = {}",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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>(
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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, ¶m_env.free_substs);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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, .. }) => {
|
||||
|
|
|
|||
|
|
@ -324,6 +324,7 @@ pub trait Combine {
|
|||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct CombineFields<'a> {
|
||||
pub infcx: &'a InferCtxt<'a>,
|
||||
pub a_is_expected: bool,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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() }
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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({},{})",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue