Centralize on using Binder to introduce new binding levels, rather than having FnSig carry an implicit binding level. This means that we be more typesafe in general, since things that instantiate bound regions can drop the Binder to reflect that.
This commit is contained in:
parent
ed4952ef39
commit
1205fd88df
48 changed files with 462 additions and 545 deletions
|
|
@ -429,7 +429,7 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
|
|||
{
|
||||
let item_doc = lookup_item(id, cdata.data());
|
||||
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
|
||||
Rc::new(ty::bind(doc_trait_ref(tp, tcx, cdata)))
|
||||
Rc::new(ty::Binder(doc_trait_ref(tp, tcx, cdata)))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -704,7 +704,7 @@ pub fn get_enum_variants<'tcx>(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::Nod
|
|||
let name = item_name(&*intr, item);
|
||||
let (ctor_ty, arg_tys, arg_names) = match ctor_ty.sty {
|
||||
ty::ty_bare_fn(ref f) =>
|
||||
(Some(ctor_ty), f.sig.inputs.clone(), None),
|
||||
(Some(ctor_ty), f.sig.0.inputs.clone(), None),
|
||||
_ => { // Nullary or struct enum variant.
|
||||
let mut arg_names = Vec::new();
|
||||
let arg_tys = get_struct_fields(intr.clone(), cdata, did.node)
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
|
|||
}
|
||||
'x' => {
|
||||
assert_eq!(next(st), '[');
|
||||
let trait_ref = ty::bind(parse_trait_ref(st, |x,y| conv(x,y)));
|
||||
let trait_ref = ty::Binder(parse_trait_ref(st, |x,y| conv(x,y)));
|
||||
let bounds = parse_existential_bounds(st, |x,y| conv(x,y));
|
||||
assert_eq!(next(st), ']');
|
||||
return ty::mk_trait(st.tcx, trait_ref, bounds);
|
||||
|
|
@ -603,7 +603,7 @@ fn parse_bare_fn_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_sig<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> ty::FnSig<'tcx> {
|
||||
fn parse_sig<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> ty::PolyFnSig<'tcx> {
|
||||
assert_eq!(next(st), '[');
|
||||
let mut inputs = Vec::new();
|
||||
while peek(st) != ']' {
|
||||
|
|
@ -622,9 +622,9 @@ fn parse_sig<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> ty::FnSig<'
|
|||
}
|
||||
_ => ty::FnConverging(parse_ty(st, |x,y| conv(x,y)))
|
||||
};
|
||||
ty::FnSig {inputs: inputs,
|
||||
output: output,
|
||||
variadic: variadic}
|
||||
ty::Binder(ty::FnSig {inputs: inputs,
|
||||
output: output,
|
||||
variadic: variadic})
|
||||
}
|
||||
|
||||
// Rust metadata parsing
|
||||
|
|
@ -669,7 +669,7 @@ pub fn parse_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>,
|
|||
-> ty::Predicate<'tcx>
|
||||
{
|
||||
match next(st) {
|
||||
't' => ty::Predicate::Trait(Rc::new(ty::bind(parse_trait_ref(st, conv)))),
|
||||
't' => ty::Predicate::Trait(Rc::new(ty::Binder(parse_trait_ref(st, conv)))),
|
||||
'e' => ty::Predicate::Equate(parse_ty(st, |x,y| conv(x,y)),
|
||||
parse_ty(st, |x,y| conv(x,y))),
|
||||
'r' => ty::Predicate::RegionOutlives(parse_region(st, |x,y| conv(x,y)),
|
||||
|
|
@ -764,7 +764,7 @@ fn parse_bounds<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did)
|
|||
}
|
||||
'I' => {
|
||||
param_bounds.trait_bounds.push(
|
||||
Rc::new(ty::bind(parse_trait_ref(st, |x,y| conv(x,y)))));
|
||||
Rc::new(ty::Binder(parse_trait_ref(st, |x,y| conv(x,y)))));
|
||||
}
|
||||
'.' => {
|
||||
return param_bounds;
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ fn enc_sty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
|
|||
ty::ty_trait(box ty::TyTrait { ref principal,
|
||||
ref bounds }) => {
|
||||
mywrite!(w, "x[");
|
||||
enc_trait_ref(w, cx, &principal.value);
|
||||
enc_trait_ref(w, cx, &principal.0);
|
||||
enc_existential_bounds(w, cx, bounds);
|
||||
mywrite!(w, "]");
|
||||
}
|
||||
|
|
@ -351,18 +351,18 @@ pub fn enc_closure_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
|
|||
}
|
||||
|
||||
fn enc_fn_sig<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
|
||||
fsig: &ty::FnSig<'tcx>) {
|
||||
fsig: &ty::PolyFnSig<'tcx>) {
|
||||
mywrite!(w, "[");
|
||||
for ty in fsig.inputs.iter() {
|
||||
for ty in fsig.0.inputs.iter() {
|
||||
enc_ty(w, cx, *ty);
|
||||
}
|
||||
mywrite!(w, "]");
|
||||
if fsig.variadic {
|
||||
if fsig.0.variadic {
|
||||
mywrite!(w, "V");
|
||||
} else {
|
||||
mywrite!(w, "N");
|
||||
}
|
||||
match fsig.output {
|
||||
match fsig.0.output {
|
||||
ty::FnConverging(result_type) => {
|
||||
enc_ty(w, cx, result_type);
|
||||
}
|
||||
|
|
@ -401,7 +401,7 @@ pub fn enc_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
|
|||
|
||||
for tp in bs.trait_bounds.iter() {
|
||||
mywrite!(w, "I");
|
||||
enc_trait_ref(w, cx, &tp.value);
|
||||
enc_trait_ref(w, cx, &tp.0);
|
||||
}
|
||||
|
||||
mywrite!(w, ".");
|
||||
|
|
@ -425,7 +425,7 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
|
|||
match *p {
|
||||
ty::Predicate::Trait(ref trait_ref) => {
|
||||
mywrite!(w, "t");
|
||||
enc_trait_ref(w, cx, &trait_ref.value);
|
||||
enc_trait_ref(w, cx, &trait_ref.0);
|
||||
}
|
||||
ty::Predicate::Equate(a, b) => {
|
||||
mywrite!(w, "e");
|
||||
|
|
|
|||
|
|
@ -887,7 +887,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
|
|||
this.emit_enum_variant("MethodTypeParam", 2, 1, |this| {
|
||||
this.emit_struct("MethodParam", 2, |this| {
|
||||
try!(this.emit_struct_field("trait_ref", 0, |this| {
|
||||
Ok(this.emit_trait_ref(ecx, &p.trait_ref.value))
|
||||
Ok(this.emit_trait_ref(ecx, &p.trait_ref.0))
|
||||
}));
|
||||
try!(this.emit_struct_field("method_num", 0, |this| {
|
||||
this.emit_uint(p.method_num)
|
||||
|
|
@ -901,7 +901,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
|
|||
this.emit_enum_variant("MethodTraitObject", 3, 1, |this| {
|
||||
this.emit_struct("MethodObject", 2, |this| {
|
||||
try!(this.emit_struct_field("trait_ref", 0, |this| {
|
||||
Ok(this.emit_trait_ref(ecx, &o.trait_ref.value))
|
||||
Ok(this.emit_trait_ref(ecx, &o.trait_ref.0))
|
||||
}));
|
||||
try!(this.emit_struct_field("object_trait_id", 0, |this| {
|
||||
Ok(this.emit_def_id(o.object_trait_id))
|
||||
|
|
@ -1113,7 +1113,7 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
|
|||
this.emit_enum_variant("UnsizeVtable", 2, 4, |this| {
|
||||
this.emit_enum_variant_arg(0, |this| {
|
||||
try!(this.emit_struct_field("principal", 0, |this| {
|
||||
Ok(this.emit_trait_ref(ecx, &principal.value))
|
||||
Ok(this.emit_trait_ref(ecx, &principal.0))
|
||||
}));
|
||||
this.emit_struct_field("bounds", 1, |this| {
|
||||
Ok(this.emit_existential_bounds(ecx, b))
|
||||
|
|
@ -1277,7 +1277,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
|||
rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| {
|
||||
rbml_w.id(id);
|
||||
rbml_w.tag(c::tag_table_val, |rbml_w| {
|
||||
rbml_w.emit_trait_ref(ecx, &trait_ref.value);
|
||||
rbml_w.emit_trait_ref(ecx, &trait_ref.0);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
@ -1552,7 +1552,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
|||
|
||||
fn read_poly_trait_ref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
|
||||
-> Rc<ty::PolyTraitRef<'tcx>> {
|
||||
Rc::new(ty::bind(self.read_opaque(|this, doc| {
|
||||
Rc::new(ty::Binder(self.read_opaque(|this, doc| {
|
||||
let ty = tydecode::parse_trait_ref_data(
|
||||
doc.data,
|
||||
dcx.cdata.cnum,
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ impl OverloadedCallType {
|
|||
}
|
||||
Some(ref trait_ref) => (*trait_ref).clone(),
|
||||
};
|
||||
OverloadedCallType::from_trait_id(tcx, trait_ref.value.def_id)
|
||||
OverloadedCallType::from_trait_id(tcx, trait_ref.def_id())
|
||||
}
|
||||
|
||||
fn from_unboxed_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ pub fn simplify_type(tcx: &ty::ctxt,
|
|||
ty::ty_vec(..) => Some(VecSimplifiedType),
|
||||
ty::ty_ptr(_) => Some(PtrSimplifiedType),
|
||||
ty::ty_trait(ref trait_info) => {
|
||||
Some(TraitSimplifiedType(trait_info.principal.value.def_id))
|
||||
Some(TraitSimplifiedType(trait_info.principal.def_id()))
|
||||
}
|
||||
ty::ty_struct(def_id, _) => {
|
||||
Some(StructSimplifiedType(def_id))
|
||||
|
|
@ -83,10 +83,10 @@ pub fn simplify_type(tcx: &ty::ctxt,
|
|||
Some(TupleSimplifiedType(tys.len()))
|
||||
}
|
||||
ty::ty_closure(ref f) => {
|
||||
Some(FunctionSimplifiedType(f.sig.inputs.len()))
|
||||
Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
|
||||
}
|
||||
ty::ty_bare_fn(ref f) => {
|
||||
Some(FunctionSimplifiedType(f.sig.inputs.len()))
|
||||
Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
|
||||
}
|
||||
ty::ty_param(_) => {
|
||||
if can_simplify_params {
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ pub trait Combine<'tcx> {
|
|||
b: &ty::BareFnTy<'tcx>) -> cres<'tcx, ty::BareFnTy<'tcx>> {
|
||||
let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety));
|
||||
let abi = try!(self.abi(a.abi, b.abi));
|
||||
let sig = try!(self.fn_sigs(&a.sig, &b.sig));
|
||||
let sig = try!(self.binders(&a.sig, &b.sig));
|
||||
Ok(ty::BareFnTy {unsafety: unsafety,
|
||||
abi: abi,
|
||||
sig: sig})
|
||||
|
|
@ -222,7 +222,7 @@ pub trait Combine<'tcx> {
|
|||
let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety));
|
||||
let onceness = try!(self.oncenesses(a.onceness, b.onceness));
|
||||
let bounds = try!(self.existential_bounds(a.bounds, b.bounds));
|
||||
let sig = try!(self.fn_sigs(&a.sig, &b.sig));
|
||||
let sig = try!(self.binders(&a.sig, &b.sig));
|
||||
let abi = try!(self.abi(a.abi, b.abi));
|
||||
Ok(ty::ClosureTy {
|
||||
unsafety: unsafety,
|
||||
|
|
@ -234,7 +234,43 @@ pub trait Combine<'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>) -> cres<'tcx, ty::FnSig<'tcx>>;
|
||||
fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>) -> cres<'tcx, ty::FnSig<'tcx>> {
|
||||
if a.variadic != b.variadic {
|
||||
return Err(ty::terr_variadic_mismatch(expected_found(self, a.variadic, b.variadic)));
|
||||
}
|
||||
|
||||
let inputs = try!(argvecs(self,
|
||||
a.inputs.as_slice(),
|
||||
b.inputs.as_slice()));
|
||||
|
||||
let output = try!(match (a.output, b.output) {
|
||||
(ty::FnConverging(a_ty), ty::FnConverging(b_ty)) =>
|
||||
Ok(ty::FnConverging(try!(self.tys(a_ty, b_ty)))),
|
||||
(ty::FnDiverging, ty::FnDiverging) =>
|
||||
Ok(ty::FnDiverging),
|
||||
(a, b) =>
|
||||
Err(ty::terr_convergence_mismatch(
|
||||
expected_found(self, a != ty::FnDiverging, b != ty::FnDiverging))),
|
||||
});
|
||||
|
||||
return Ok(ty::FnSig {inputs: inputs,
|
||||
output: output,
|
||||
variadic: a.variadic});
|
||||
|
||||
|
||||
fn argvecs<'tcx, C: Combine<'tcx>>(combiner: &C,
|
||||
a_args: &[Ty<'tcx>],
|
||||
b_args: &[Ty<'tcx>])
|
||||
-> cres<'tcx, Vec<Ty<'tcx>>>
|
||||
{
|
||||
if a_args.len() == b_args.len() {
|
||||
a_args.iter().zip(b_args.iter())
|
||||
.map(|(a, b)| combiner.args(*a, *b)).collect()
|
||||
} else {
|
||||
Err(ty::terr_arg_count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn args(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
|
||||
self.contratys(a, b).and_then(|t| Ok(t))
|
||||
|
|
@ -312,14 +348,36 @@ pub trait Combine<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn poly_trait_refs(&self,
|
||||
a: &ty::PolyTraitRef<'tcx>,
|
||||
b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>>;
|
||||
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
|
||||
where T : Combineable<'tcx>;
|
||||
// this must be overridden to do correctly, so as to account for higher-ranked
|
||||
// behavior
|
||||
}
|
||||
|
||||
pub trait Combineable<'tcx> : Repr<'tcx> + TypeFoldable<'tcx> {
|
||||
fn combine<C:Combine<'tcx>>(combiner: &C, a: &Self, b: &Self) -> cres<'tcx, Self>;
|
||||
}
|
||||
|
||||
impl<'tcx> Combineable<'tcx> for ty::TraitRef<'tcx> {
|
||||
fn combine<C:Combine<'tcx>>(combiner: &C,
|
||||
a: &ty::TraitRef<'tcx>,
|
||||
b: &ty::TraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::TraitRef<'tcx>>
|
||||
{
|
||||
combiner.trait_refs(a, b)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Combineable<'tcx> for ty::FnSig<'tcx> {
|
||||
fn combine<C:Combine<'tcx>>(combiner: &C,
|
||||
a: &ty::FnSig<'tcx>,
|
||||
b: &ty::FnSig<'tcx>)
|
||||
-> cres<'tcx, ty::FnSig<'tcx>>
|
||||
{
|
||||
combiner.fn_sigs(a, b)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct CombineFields<'a, 'tcx: 'a> {
|
||||
pub infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
|
|
@ -424,7 +482,7 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
|
|||
(&ty::ty_trait(ref a_),
|
||||
&ty::ty_trait(ref b_)) => {
|
||||
debug!("Trying to match traits {} and {}", a, b);
|
||||
let principal = try!(this.poly_trait_refs(&a_.principal, &b_.principal));
|
||||
let principal = try!(this.binders(&a_.principal, &b_.principal));
|
||||
let bounds = try!(this.existential_bounds(a_.bounds, b_.bounds));
|
||||
Ok(ty::mk_trait(tcx, principal, bounds))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,17 +133,10 @@ impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>)
|
||||
-> cres<'tcx, ty::FnSig<'tcx>>
|
||||
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
|
||||
where T : Combineable<'tcx>
|
||||
{
|
||||
try!(self.sub().fn_sigs(a, b));
|
||||
self.sub().fn_sigs(b, a)
|
||||
}
|
||||
|
||||
fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>>
|
||||
{
|
||||
try!(self.sub().poly_trait_refs(a, b));
|
||||
self.sub().poly_trait_refs(b, a)
|
||||
try!(self.sub().binders(a, b));
|
||||
self.sub().binders(b, a)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1653,7 +1653,7 @@ impl<'tcx> Resolvable<'tcx> for Rc<ty::PolyTraitRef<'tcx>> {
|
|||
Rc::new(infcx.resolve_type_vars_if_possible(&**self))
|
||||
}
|
||||
fn contains_error(&self) -> bool {
|
||||
ty::trait_ref_contains_error(&self.value)
|
||||
ty::trait_ref_contains_error(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,13 +121,9 @@ impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
|
|||
super_lattice_tys(self, a, b)
|
||||
}
|
||||
|
||||
fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>)
|
||||
-> cres<'tcx, ty::FnSig<'tcx>> {
|
||||
self.higher_ranked_glb(a, b)
|
||||
}
|
||||
|
||||
fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>> {
|
||||
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
|
||||
where T : Combineable<'tcx>
|
||||
{
|
||||
self.higher_ranked_glb(a, b)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,29 +11,24 @@
|
|||
//! Helper routines for higher-ranked things. See the `doc` module at
|
||||
//! the end of the file for details.
|
||||
|
||||
use super::{combine, CombinedSnapshot, cres, InferCtxt, HigherRankedType};
|
||||
use super::combine::Combine;
|
||||
use super::{CombinedSnapshot, cres, InferCtxt, HigherRankedType};
|
||||
use super::combine::{Combine, Combineable};
|
||||
|
||||
use middle::ty::{mod, Ty, replace_late_bound_regions};
|
||||
use middle::ty_fold::{mod, HigherRankedFoldable, TypeFoldable};
|
||||
use middle::ty::{mod, Binder};
|
||||
use middle::ty_fold::{mod, TypeFoldable};
|
||||
use syntax::codemap::Span;
|
||||
use util::nodemap::{FnvHashMap, FnvHashSet};
|
||||
use util::ppaux::{bound_region_to_string, Repr};
|
||||
|
||||
pub trait HigherRankedCombineable<'tcx>: HigherRankedFoldable<'tcx> +
|
||||
TypeFoldable<'tcx> + Repr<'tcx> {
|
||||
fn super_combine<C:Combine<'tcx>>(combiner: &C, a: &Self, b: &Self) -> cres<'tcx, Self>;
|
||||
}
|
||||
use util::ppaux::Repr;
|
||||
|
||||
pub trait HigherRankedRelations<'tcx> {
|
||||
fn higher_ranked_sub<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
||||
where T : HigherRankedCombineable<'tcx>;
|
||||
fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
|
||||
where T : Combineable<'tcx>;
|
||||
|
||||
fn higher_ranked_lub<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
||||
where T : HigherRankedCombineable<'tcx>;
|
||||
fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
|
||||
where T : Combineable<'tcx>;
|
||||
|
||||
fn higher_ranked_glb<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
||||
where T : HigherRankedCombineable<'tcx>;
|
||||
fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
|
||||
where T : Combineable<'tcx>;
|
||||
}
|
||||
|
||||
trait InferCtxtExt<'tcx> {
|
||||
|
|
@ -47,8 +42,9 @@ trait InferCtxtExt<'tcx> {
|
|||
impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
||||
where C : Combine<'tcx>
|
||||
{
|
||||
fn higher_ranked_sub<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
||||
where T : HigherRankedCombineable<'tcx>
|
||||
fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
|
||||
-> cres<'tcx, Binder<T>>
|
||||
where T : Combineable<'tcx>
|
||||
{
|
||||
debug!("higher_ranked_sub(a={}, b={})",
|
||||
a.repr(self.tcx()), b.repr(self.tcx()));
|
||||
|
|
@ -74,13 +70,14 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||
|
||||
// Second, we instantiate each bound region in the supertype with a
|
||||
// fresh concrete region.
|
||||
let (b_prime, skol_map) = skolemize_regions(self.infcx(), b, snapshot);
|
||||
let (b_prime, skol_map) =
|
||||
self.infcx().skolemize_late_bound_regions(b, snapshot);
|
||||
|
||||
debug!("a_prime={}", a_prime.repr(self.tcx()));
|
||||
debug!("b_prime={}", b_prime.repr(self.tcx()));
|
||||
|
||||
// Compare types now that bound regions have been replaced.
|
||||
let result = try!(HigherRankedCombineable::super_combine(self, &a_prime, &b_prime));
|
||||
let result = try!(Combineable::combine(self, &a_prime, &b_prime));
|
||||
|
||||
// Presuming type comparison succeeds, we need to check
|
||||
// that the skolemized regions do not "leak".
|
||||
|
|
@ -102,12 +99,12 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||
debug!("higher_ranked_sub: OK result={}",
|
||||
result.repr(self.tcx()));
|
||||
|
||||
Ok(result)
|
||||
Ok(ty::Binder(result))
|
||||
});
|
||||
}
|
||||
|
||||
fn higher_ranked_lub<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
||||
where T : HigherRankedCombineable<'tcx>
|
||||
fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
|
||||
where T : Combineable<'tcx>
|
||||
{
|
||||
// Start a snapshot so we can examine "all bindings that were
|
||||
// created as part of this type comparison".
|
||||
|
|
@ -123,7 +120,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||
|
||||
// Collect constraints.
|
||||
let result0 =
|
||||
try!(HigherRankedCombineable::super_combine(self, &a_with_fresh, &b_with_fresh));
|
||||
try!(Combineable::combine(self, &a_with_fresh, &b_with_fresh));
|
||||
let result0 =
|
||||
self.infcx().resolve_type_vars_if_possible(&result0);
|
||||
debug!("lub result0 = {}", result0.repr(self.tcx()));
|
||||
|
|
@ -143,7 +140,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||
b.repr(self.tcx()),
|
||||
result1.repr(self.tcx()));
|
||||
|
||||
Ok(result1)
|
||||
Ok(ty::Binder(result1))
|
||||
});
|
||||
|
||||
fn generalize_region(infcx: &InferCtxt,
|
||||
|
|
@ -196,8 +193,8 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||
}
|
||||
}
|
||||
|
||||
fn higher_ranked_glb<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
||||
where T : HigherRankedCombineable<'tcx>
|
||||
fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
|
||||
where T : Combineable<'tcx>
|
||||
{
|
||||
debug!("{}.higher_ranked_glb({}, {})",
|
||||
self.tag(), a.repr(self.tcx()), b.repr(self.tcx()));
|
||||
|
|
@ -217,7 +214,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||
|
||||
// Collect constraints.
|
||||
let result0 =
|
||||
try!(HigherRankedCombineable::super_combine(self, &a_with_fresh, &b_with_fresh));
|
||||
try!(Combineable::combine(self, &a_with_fresh, &b_with_fresh));
|
||||
let result0 =
|
||||
self.infcx().resolve_type_vars_if_possible(&result0);
|
||||
debug!("glb result0 = {}", result0.repr(self.tcx()));
|
||||
|
|
@ -239,7 +236,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||
b.repr(self.tcx()),
|
||||
result1.repr(self.tcx()));
|
||||
|
||||
Ok(result1)
|
||||
Ok(ty::Binder(result1))
|
||||
});
|
||||
|
||||
fn generalize_region(infcx: &InferCtxt,
|
||||
|
|
@ -334,59 +331,6 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HigherRankedCombineable<'tcx> for ty::FnSig<'tcx> {
|
||||
fn super_combine<C:Combine<'tcx>>(combiner: &C, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>)
|
||||
-> cres<'tcx, ty::FnSig<'tcx>>
|
||||
{
|
||||
if a.variadic != b.variadic {
|
||||
return Err(ty::terr_variadic_mismatch(
|
||||
combine::expected_found(combiner, a.variadic, b.variadic)));
|
||||
}
|
||||
|
||||
let inputs = try!(argvecs(combiner,
|
||||
a.inputs.as_slice(),
|
||||
b.inputs.as_slice()));
|
||||
|
||||
let output = try!(match (a.output, b.output) {
|
||||
(ty::FnConverging(a_ty), ty::FnConverging(b_ty)) =>
|
||||
Ok(ty::FnConverging(try!(combiner.tys(a_ty, b_ty)))),
|
||||
(ty::FnDiverging, ty::FnDiverging) =>
|
||||
Ok(ty::FnDiverging),
|
||||
(a, b) =>
|
||||
Err(ty::terr_convergence_mismatch(
|
||||
combine::expected_found(combiner, a != ty::FnDiverging, b != ty::FnDiverging))),
|
||||
});
|
||||
|
||||
return Ok(ty::FnSig {inputs: inputs,
|
||||
output: output,
|
||||
variadic: a.variadic});
|
||||
|
||||
|
||||
fn argvecs<'tcx, C: Combine<'tcx>>(combiner: &C,
|
||||
a_args: &[Ty<'tcx>],
|
||||
b_args: &[Ty<'tcx>])
|
||||
-> cres<'tcx, Vec<Ty<'tcx>>>
|
||||
{
|
||||
if a_args.len() == b_args.len() {
|
||||
a_args.iter().zip(b_args.iter())
|
||||
.map(|(a, b)| combiner.args(*a, *b)).collect()
|
||||
} else {
|
||||
Err(ty::terr_arg_count)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HigherRankedCombineable<'tcx> for ty::PolyTraitRef<'tcx> {
|
||||
fn super_combine<C:Combine<'tcx>>(combiner: &C,
|
||||
a: &ty::PolyTraitRef<'tcx>,
|
||||
b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>>
|
||||
{
|
||||
Ok(ty::bind(try!(combiner.trait_refs(&a.value, &b.value))))
|
||||
}
|
||||
}
|
||||
|
||||
fn var_ids<'tcx, T: Combine<'tcx>>(combiner: &T,
|
||||
map: &FnvHashMap<ty::BoundRegion, ty::Region>)
|
||||
-> Vec<ty::RegionVid> {
|
||||
|
|
@ -407,11 +351,14 @@ fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>, value: &T, mut fldr: F) -> T where
|
||||
T: HigherRankedFoldable<'tcx>,
|
||||
F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
|
||||
fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>,
|
||||
unbound_value: &T,
|
||||
mut fldr: F)
|
||||
-> T
|
||||
where T : Combineable<'tcx>,
|
||||
F : FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
|
||||
{
|
||||
value.fold_contents(&mut ty_fold::RegionFolder::new(tcx, |region, current_depth| {
|
||||
unbound_value.fold_with(&mut ty_fold::RegionFolder::new(tcx, |region, current_depth| {
|
||||
// we should only be encountering "escaping" late-bound regions here,
|
||||
// because the ones at the current level should have been replaced
|
||||
// with fresh variables
|
||||
|
|
@ -508,26 +455,6 @@ impl<'a,'tcx> InferCtxtExt<'tcx> for InferCtxt<'a,'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn skolemize_regions<'a,'tcx,HR>(infcx: &InferCtxt<'a,'tcx>,
|
||||
value: &HR,
|
||||
snapshot: &CombinedSnapshot)
|
||||
-> (HR, FnvHashMap<ty::BoundRegion,ty::Region>)
|
||||
where HR : HigherRankedFoldable<'tcx>
|
||||
{
|
||||
replace_late_bound_regions(infcx.tcx, value, |br, _| {
|
||||
let skol =
|
||||
infcx.region_vars.new_skolemized(
|
||||
br,
|
||||
&snapshot.region_vars_snapshot);
|
||||
|
||||
debug!("Bound region {} skolemized to {}",
|
||||
bound_region_to_string(infcx.tcx, "", false, br),
|
||||
skol);
|
||||
|
||||
skol
|
||||
})
|
||||
}
|
||||
|
||||
fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||
skol_map: &FnvHashMap<ty::BoundRegion,ty::Region>,
|
||||
snapshot: &CombinedSnapshot)
|
||||
|
|
|
|||
|
|
@ -113,17 +113,13 @@ impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
|
|||
Ok(self.infcx().region_vars.lub_regions(Subtype(self.trace()), a, b))
|
||||
}
|
||||
|
||||
fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>)
|
||||
-> cres<'tcx, ty::FnSig<'tcx>> {
|
||||
self.higher_ranked_lub(a, b)
|
||||
}
|
||||
|
||||
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
|
||||
super_lattice_tys(self, a, b)
|
||||
}
|
||||
|
||||
fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>> {
|
||||
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
|
||||
where T : Combineable<'tcx>
|
||||
{
|
||||
self.higher_ranked_lub(a, b)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use middle::subst::Substs;
|
|||
use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
|
||||
use middle::ty::replace_late_bound_regions;
|
||||
use middle::ty::{mod, Ty};
|
||||
use middle::ty_fold::{HigherRankedFoldable, TypeFolder, TypeFoldable};
|
||||
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||
use std::cell::{RefCell};
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
|
|
@ -35,7 +35,7 @@ use syntax::codemap::Span;
|
|||
use util::common::indent;
|
||||
use util::nodemap::FnvHashMap;
|
||||
use util::ppaux::{ty_to_string};
|
||||
use util::ppaux::{trait_ref_to_string, Repr};
|
||||
use util::ppaux::{Repr, UserString};
|
||||
|
||||
use self::coercion::Coerce;
|
||||
use self::combine::{Combine, CombineFields};
|
||||
|
|
@ -699,26 +699,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
values: TraitRefs(expected_found(a_is_expected,
|
||||
a.clone(), b.clone()))
|
||||
};
|
||||
self.sub(a_is_expected, trace).poly_trait_refs(&*a, &*b).to_ures()
|
||||
self.sub(a_is_expected, trace).binders(&*a, &*b).to_ures()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn skolemize_bound_regions<T>(&self,
|
||||
value: &ty::Binder<T>,
|
||||
snapshot: &CombinedSnapshot)
|
||||
-> (T, SkolemizationMap)
|
||||
where T : TypeFoldable<'tcx>
|
||||
pub fn skolemize_late_bound_regions<T>(&self,
|
||||
value: &ty::Binder<T>,
|
||||
snapshot: &CombinedSnapshot)
|
||||
-> (T, SkolemizationMap)
|
||||
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||
{
|
||||
let (result_binder, map) = replace_late_bound_regions(self.tcx, value, |br, _| {
|
||||
let (result, map) = replace_late_bound_regions(self.tcx, value, |br, _| {
|
||||
self.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
|
||||
});
|
||||
|
||||
debug!("skolemize_bound_regions(value={}, result={}, map={})",
|
||||
value.repr(self.tcx),
|
||||
result_binder.value.repr(self.tcx),
|
||||
result.repr(self.tcx),
|
||||
map.repr(self.tcx));
|
||||
|
||||
(result_binder.value, map)
|
||||
(result, map)
|
||||
}
|
||||
|
||||
pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
|
||||
|
|
@ -828,7 +828,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
|
||||
pub fn trait_ref_to_string(&self, t: &Rc<ty::TraitRef<'tcx>>) -> String {
|
||||
let t = self.resolve_type_vars_if_possible(&**t);
|
||||
trait_ref_to_string(self.tcx, &t)
|
||||
t.user_string(self.tcx)
|
||||
}
|
||||
|
||||
pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
|
||||
|
|
@ -982,9 +982,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
&self,
|
||||
span: Span,
|
||||
lbrct: LateBoundRegionConversionTime,
|
||||
value: &T)
|
||||
value: &ty::Binder<T>)
|
||||
-> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
|
||||
where T : HigherRankedFoldable<'tcx>
|
||||
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||
{
|
||||
ty::replace_late_bound_regions(
|
||||
self.tcx,
|
||||
|
|
|
|||
|
|
@ -155,13 +155,9 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>)
|
||||
-> cres<'tcx, ty::FnSig<'tcx>> {
|
||||
self.higher_ranked_sub(a, b)
|
||||
}
|
||||
|
||||
fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
|
||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>> {
|
||||
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
|
||||
where T : Combineable<'tcx>
|
||||
{
|
||||
self.higher_ranked_sub(a, b)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,8 +124,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
|
|||
let typ = ty::node_id_to_type(self.tcx, expr.id);
|
||||
match typ.sty {
|
||||
ty_bare_fn(ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
|
||||
if let ty::FnConverging(to) = bare_fn_ty.sig.output {
|
||||
let from = bare_fn_ty.sig.inputs[0];
|
||||
if let ty::FnConverging(to) = bare_fn_ty.sig.0.output {
|
||||
let from = bare_fn_ty.sig.0.inputs[0];
|
||||
self.check_transmute(expr.span, from, to, expr.id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1534,6 +1534,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
.unwrap()
|
||||
.closure_type
|
||||
.sig
|
||||
.0
|
||||
.output,
|
||||
_ => ty::ty_fn_ret(fn_ty)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -257,8 +257,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
|
|||
};
|
||||
let tr = ty::impl_trait_ref(self.tcx, local_def(item.id));
|
||||
let public_trait = tr.clone().map_or(false, |tr| {
|
||||
!is_local(tr.value.def_id) ||
|
||||
self.exported_items.contains(&tr.value.def_id.node)
|
||||
!is_local(tr.def_id()) ||
|
||||
self.exported_items.contains(&tr.def_id().node)
|
||||
});
|
||||
|
||||
if public_ty || public_trait {
|
||||
|
|
@ -407,7 +407,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
|||
match ty::impl_trait_ref(self.tcx, id) {
|
||||
Some(t) => {
|
||||
debug!("privacy - impl of trait {}", id);
|
||||
self.def_privacy(t.value.def_id)
|
||||
self.def_privacy(t.def_id())
|
||||
}
|
||||
None => {
|
||||
debug!("privacy - found a method {}",
|
||||
|
|
@ -432,7 +432,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
|||
match ty::impl_trait_ref(self.tcx, id) {
|
||||
Some(t) => {
|
||||
debug!("privacy - impl of trait {}", id);
|
||||
self.def_privacy(t.value.def_id)
|
||||
self.def_privacy(t.def_id())
|
||||
}
|
||||
None => {
|
||||
debug!("privacy - found a typedef {}",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ use middle::subst;
|
|||
use middle::subst::Subst;
|
||||
use middle::ty::{mod, Ty};
|
||||
use middle::infer::{mod, InferCtxt};
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
use util::ppaux::Repr;
|
||||
|
|
@ -42,13 +43,14 @@ pub fn impl_can_satisfy(infcx: &InferCtxt,
|
|||
let impl1_trait_ref =
|
||||
infcx.replace_late_bound_regions_with_fresh_var(DUMMY_SP,
|
||||
infer::FnCall,
|
||||
&impl1_trait_ref).0;
|
||||
&*impl1_trait_ref).0;
|
||||
|
||||
// Determine whether `impl2` can provide an implementation for those
|
||||
// same types.
|
||||
let param_env = ty::empty_parameter_environment();
|
||||
let mut selcx = SelectionContext::intercrate(infcx, ¶m_env, infcx.tcx);
|
||||
let obligation = Obligation::new(ObligationCause::dummy(), impl1_trait_ref);
|
||||
let obligation = Obligation::new(ObligationCause::dummy(),
|
||||
Rc::new(ty::Binder(impl1_trait_ref)));
|
||||
debug!("impl_can_satisfy(obligation={})", obligation.repr(infcx.tcx));
|
||||
selcx.evaluate_impl(impl2_def_id, &obligation)
|
||||
}
|
||||
|
|
@ -65,15 +67,15 @@ pub fn impl_is_local(tcx: &ty::ctxt,
|
|||
debug!("trait_ref={}", trait_ref.repr(tcx));
|
||||
|
||||
// If the trait is local to the crate, ok.
|
||||
if trait_ref.value.def_id.krate == ast::LOCAL_CRATE {
|
||||
if trait_ref.def_id().krate == ast::LOCAL_CRATE {
|
||||
debug!("trait {} is local to current crate",
|
||||
trait_ref.value.def_id.repr(tcx));
|
||||
trait_ref.def_id().repr(tcx));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, at least one of the input types must be local to the
|
||||
// crate.
|
||||
trait_ref.value.input_types().iter().any(|&t| ty_is_local(tcx, t))
|
||||
trait_ref.0.input_types().iter().any(|&t| ty_is_local(tcx, t))
|
||||
}
|
||||
|
||||
pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
|
|
@ -143,7 +145,7 @@ pub fn ty_is_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
|||
}
|
||||
|
||||
ty::ty_trait(ref tt) => {
|
||||
tt.principal.value.def_id.krate == ast::LOCAL_CRATE
|
||||
tt.principal.def_id().krate == ast::LOCAL_CRATE
|
||||
}
|
||||
|
||||
// Type parameters may be bound to types that are not local to
|
||||
|
|
|
|||
|
|
@ -347,13 +347,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// This suffices to allow chains like `FnMut` implemented in
|
||||
// terms of `Fn` etc, but we could probably make this more
|
||||
// precise still.
|
||||
let input_types = stack.fresh_trait_ref.value.input_types();
|
||||
let input_types = stack.fresh_trait_ref.0.input_types();
|
||||
let unbound_input_types = input_types.iter().any(|&t| ty::type_is_fresh(t));
|
||||
if
|
||||
unbound_input_types &&
|
||||
(self.intercrate ||
|
||||
stack.iter().skip(1).any(
|
||||
|prev| stack.fresh_trait_ref.value.def_id == prev.fresh_trait_ref.value.def_id))
|
||||
|prev| stack.fresh_trait_ref.def_id() == prev.fresh_trait_ref.def_id()))
|
||||
{
|
||||
debug!("evaluate_stack({}) --> unbound argument, recursion --> ambiguous",
|
||||
stack.fresh_trait_ref.repr(self.tcx()));
|
||||
|
|
@ -591,7 +591,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// If the trait refers to any parameters in scope, then use
|
||||
// the cache of the param-environment.
|
||||
if
|
||||
cache_fresh_trait_ref.value.input_types().iter().any(
|
||||
cache_fresh_trait_ref.0.input_types().iter().any(
|
||||
|&t| ty::type_has_self(t) || ty::type_has_params(t))
|
||||
{
|
||||
return &self.param_env.selection_cache;
|
||||
|
|
@ -604,7 +604,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// See the discussion in doc.rs for more details.
|
||||
if
|
||||
!self.param_env.caller_bounds.is_empty() &&
|
||||
cache_fresh_trait_ref.value.input_types().iter().any(
|
||||
cache_fresh_trait_ref.0.input_types().iter().any(
|
||||
|&t| ty::type_has_ty_infer(t))
|
||||
{
|
||||
return &self.param_env.selection_cache;
|
||||
|
|
@ -648,7 +648,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// Other bounds. Consider both in-scope bounds from fn decl
|
||||
// and applicable impls. There is a certain set of precedence rules here.
|
||||
|
||||
match self.tcx().lang_items.to_builtin_kind(obligation.trait_ref.value.def_id) {
|
||||
match self.tcx().lang_items.to_builtin_kind(obligation.trait_ref.def_id()) {
|
||||
Some(ty::BoundCopy) => {
|
||||
debug!("obligation self ty is {}",
|
||||
obligation.self_ty().repr(self.tcx()));
|
||||
|
|
@ -731,7 +731,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
candidates: &mut CandidateSet<'tcx>)
|
||||
-> Result<(),SelectionError<'tcx>>
|
||||
{
|
||||
let kind = match self.fn_family_trait_kind(obligation.trait_ref.value.def_id) {
|
||||
let kind = match self.fn_family_trait_kind(obligation.trait_ref.def_id()) {
|
||||
Some(k) => k,
|
||||
None => { return Ok(()); }
|
||||
};
|
||||
|
|
@ -779,7 +779,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// We provide a `Fn` impl for fn pointers. There is no need to provide
|
||||
// the other traits (e.g. `FnMut`) since those are provided by blanket
|
||||
// impls.
|
||||
if Some(obligation.trait_ref.value.def_id) != self.tcx().lang_items.fn_trait() {
|
||||
if Some(obligation.trait_ref.def_id()) != self.tcx().lang_items.fn_trait() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
@ -793,11 +793,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
ty::ty_bare_fn(ty::BareFnTy {
|
||||
unsafety: ast::Unsafety::Normal,
|
||||
abi: abi::Rust,
|
||||
sig: ty::FnSig {
|
||||
sig: ty::Binder(ty::FnSig {
|
||||
inputs: _,
|
||||
output: ty::FnConverging(_),
|
||||
variadic: false
|
||||
}
|
||||
})
|
||||
}) => {
|
||||
candidates.vec.push(FnPointerCandidate);
|
||||
}
|
||||
|
|
@ -814,7 +814,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
candidates: &mut CandidateSet<'tcx>)
|
||||
-> Result<(), SelectionError<'tcx>>
|
||||
{
|
||||
let all_impls = self.all_impls(obligation.trait_ref.value.def_id);
|
||||
let all_impls = self.all_impls(obligation.trait_ref.def_id());
|
||||
for &impl_def_id in all_impls.iter() {
|
||||
self.infcx.probe(|| {
|
||||
match self.match_impl(impl_def_id, obligation) {
|
||||
|
|
@ -1083,7 +1083,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// bounds are required and thus we must fulfill.
|
||||
let tmp_tr = data.principal_trait_ref_with_self_ty(ty::mk_err());
|
||||
for tr in util::supertraits(self.tcx(), tmp_tr) {
|
||||
let td = ty::lookup_trait_def(self.tcx(), tr.value.def_id);
|
||||
let td = ty::lookup_trait_def(self.tcx(), tr.def_id());
|
||||
|
||||
if td.bounds.builtin_bounds.contains(&bound) {
|
||||
return Ok(If(Vec::new()))
|
||||
|
|
@ -1519,15 +1519,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
};
|
||||
|
||||
let arguments_tuple = ty::mk_tup(self.tcx(), sig.inputs.to_vec());
|
||||
let output_type = sig.output.unwrap();
|
||||
let arguments_tuple = ty::mk_tup(self.tcx(), sig.0.inputs.to_vec());
|
||||
let output_type = sig.0.output.unwrap();
|
||||
let substs =
|
||||
Substs::new_trait(
|
||||
vec![arguments_tuple, output_type],
|
||||
vec![],
|
||||
vec![],
|
||||
self_ty);
|
||||
let trait_ref = Rc::new(ty::bind(ty::TraitRef {
|
||||
let trait_ref = Rc::new(ty::Binder(ty::TraitRef {
|
||||
def_id: obligation.trait_ref.def_id(),
|
||||
substs: substs,
|
||||
}));
|
||||
|
|
@ -1562,15 +1562,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
};
|
||||
|
||||
let closure_sig = &closure_type.sig;
|
||||
let arguments_tuple = closure_sig.inputs[0];
|
||||
let arguments_tuple = closure_sig.0.inputs[0];
|
||||
let substs =
|
||||
Substs::new_trait(
|
||||
vec![arguments_tuple.subst(self.tcx(), substs),
|
||||
closure_sig.output.unwrap().subst(self.tcx(), substs)],
|
||||
closure_sig.0.output.unwrap().subst(self.tcx(), substs)],
|
||||
vec![],
|
||||
vec![],
|
||||
obligation.self_ty());
|
||||
let trait_ref = Rc::new(ty::bind(ty::TraitRef {
|
||||
let trait_ref = Rc::new(ty::Binder(ty::TraitRef {
|
||||
def_id: obligation.trait_ref.def_id(),
|
||||
substs: substs,
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ pub fn poly_trait_ref_for_builtin_bound<'tcx>(
|
|||
{
|
||||
match tcx.lang_items.from_builtin_kind(builtin_bound) {
|
||||
Ok(def_id) => {
|
||||
Ok(Rc::new(ty::bind(ty::TraitRef {
|
||||
Ok(Rc::new(ty::Binder(ty::TraitRef {
|
||||
def_id: def_id,
|
||||
substs: Substs::empty().with_self_ty(param_ty)
|
||||
})))
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ use middle::subst::{mod, Subst, Substs, VecPerParamSpace};
|
|||
use middle::traits::ObligationCause;
|
||||
use middle::traits;
|
||||
use middle::ty;
|
||||
use middle::ty_fold::{mod, TypeFoldable, TypeFolder, HigherRankedFoldable};
|
||||
use middle::ty_fold::{mod, TypeFoldable, TypeFolder};
|
||||
use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string};
|
||||
use util::ppaux::{trait_store_to_string, ty_to_string};
|
||||
use util::ppaux::{Repr, UserString};
|
||||
|
|
@ -908,7 +908,7 @@ pub fn type_escapes_depth(ty: Ty, depth: uint) -> bool {
|
|||
pub struct BareFnTy<'tcx> {
|
||||
pub unsafety: ast::Unsafety,
|
||||
pub abi: abi::Abi,
|
||||
pub sig: FnSig<'tcx>,
|
||||
pub sig: PolyFnSig<'tcx>,
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
||||
|
|
@ -917,7 +917,7 @@ pub struct ClosureTy<'tcx> {
|
|||
pub onceness: ast::Onceness,
|
||||
pub store: TraitStore,
|
||||
pub bounds: ExistentialBounds,
|
||||
pub sig: FnSig<'tcx>,
|
||||
pub sig: PolyFnSig<'tcx>,
|
||||
pub abi: abi::Abi,
|
||||
}
|
||||
|
||||
|
|
@ -944,10 +944,6 @@ impl<'tcx> Copy for FnOutput<'tcx> {}
|
|||
/// - `inputs` is the list of arguments and their modes.
|
||||
/// - `output` is the return type.
|
||||
/// - `variadic` indicates whether this is a varidic function. (only true for foreign fns)
|
||||
///
|
||||
/// Note that a `FnSig` introduces a level of region binding, to
|
||||
/// account for late-bound parameters that appear in the types of the
|
||||
/// fn's arguments or the fn's return type.
|
||||
#[deriving(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct FnSig<'tcx> {
|
||||
pub inputs: Vec<Ty<'tcx>>,
|
||||
|
|
@ -955,6 +951,8 @@ pub struct FnSig<'tcx> {
|
|||
pub variadic: bool
|
||||
}
|
||||
|
||||
pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
||||
pub struct ParamTy {
|
||||
pub space: subst::ParamSpace,
|
||||
|
|
@ -1318,9 +1316,9 @@ impl<'tcx> TyTrait<'tcx> {
|
|||
/// you must give *some* self-type. A common choice is `mk_err()`
|
||||
/// or some skolemized type.
|
||||
pub fn principal_trait_ref_with_self_ty(&self, self_ty: Ty<'tcx>) -> Rc<ty::PolyTraitRef<'tcx>> {
|
||||
Rc::new(ty::bind(ty::TraitRef {
|
||||
def_id: self.principal.value.def_id,
|
||||
substs: self.principal.value.substs.with_self_ty(self_ty),
|
||||
Rc::new(ty::Binder(ty::TraitRef {
|
||||
def_id: self.principal.def_id(),
|
||||
substs: self.principal.substs().with_self_ty(self_ty),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
@ -1350,19 +1348,19 @@ pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
|
|||
|
||||
impl<'tcx> PolyTraitRef<'tcx> {
|
||||
pub fn self_ty(&self) -> Ty<'tcx> {
|
||||
self.value.self_ty()
|
||||
self.0.self_ty()
|
||||
}
|
||||
|
||||
pub fn def_id(&self) -> ast::DefId {
|
||||
self.value.def_id
|
||||
self.0.def_id
|
||||
}
|
||||
|
||||
pub fn substs(&self) -> &Substs<'tcx> {
|
||||
&self.value.substs
|
||||
&self.0.substs
|
||||
}
|
||||
|
||||
pub fn input_types(&self) -> &[Ty<'tcx>] {
|
||||
self.value.input_types()
|
||||
self.0.input_types()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1373,13 +1371,7 @@ impl<'tcx> PolyTraitRef<'tcx> {
|
|||
/// by the binder supplied to it; but a type is not a binder, so you
|
||||
/// must introduce an artificial one).
|
||||
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
||||
pub struct Binder<T> {
|
||||
pub value: T
|
||||
}
|
||||
|
||||
pub fn bind<T>(value: T) -> Binder<T> {
|
||||
Binder { value: value }
|
||||
}
|
||||
pub struct Binder<T>(pub T);
|
||||
|
||||
#[deriving(Clone, PartialEq)]
|
||||
pub enum IntVarValue {
|
||||
|
|
@ -2237,12 +2229,12 @@ impl FlagComputation {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_fn_sig(&mut self, fn_sig: &FnSig) {
|
||||
fn add_fn_sig(&mut self, fn_sig: &PolyFnSig) {
|
||||
let mut computation = FlagComputation::new();
|
||||
|
||||
computation.add_tys(fn_sig.inputs[]);
|
||||
computation.add_tys(fn_sig.0.inputs[]);
|
||||
|
||||
if let ty::FnConverging(output) = fn_sig.output {
|
||||
if let ty::FnConverging(output) = fn_sig.0.output {
|
||||
computation.add_ty(output);
|
||||
}
|
||||
|
||||
|
|
@ -2385,11 +2377,11 @@ pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
|
|||
BareFnTy {
|
||||
unsafety: ast::Unsafety::Normal,
|
||||
abi: abi::Rust,
|
||||
sig: FnSig {
|
||||
sig: ty::Binder(FnSig {
|
||||
inputs: input_args,
|
||||
output: ty::FnConverging(output),
|
||||
variadic: false
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -2481,14 +2473,14 @@ pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) {
|
|||
}
|
||||
ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty(*tt, |x| f(x)); } }
|
||||
ty_bare_fn(ref ft) => {
|
||||
for a in ft.sig.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
|
||||
if let ty::FnConverging(output) = ft.sig.output {
|
||||
for a in ft.sig.0.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
|
||||
if let ty::FnConverging(output) = ft.sig.0.output {
|
||||
maybe_walk_ty(output, f);
|
||||
}
|
||||
}
|
||||
ty_closure(ref ft) => {
|
||||
for a in ft.sig.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
|
||||
if let ty::FnConverging(output) = ft.sig.output {
|
||||
for a in ft.sig.0.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
|
||||
if let ty::FnConverging(output) = ft.sig.0.output {
|
||||
maybe_walk_ty(output, f);
|
||||
}
|
||||
}
|
||||
|
|
@ -3857,15 +3849,15 @@ pub fn node_id_item_substs<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> ItemSubsts
|
|||
|
||||
pub fn fn_is_variadic(fty: Ty) -> bool {
|
||||
match fty.sty {
|
||||
ty_bare_fn(ref f) => f.sig.variadic,
|
||||
ty_closure(ref f) => f.sig.variadic,
|
||||
ty_bare_fn(ref f) => f.sig.0.variadic,
|
||||
ty_closure(ref f) => f.sig.0.variadic,
|
||||
ref s => {
|
||||
panic!("fn_is_variadic() called on non-fn type: {}", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ty_fn_sig<'tcx>(fty: Ty<'tcx>) -> &'tcx FnSig<'tcx> {
|
||||
pub fn ty_fn_sig<'tcx>(fty: Ty<'tcx>) -> &'tcx PolyFnSig<'tcx> {
|
||||
match fty.sty {
|
||||
ty_bare_fn(ref f) => &f.sig,
|
||||
ty_closure(ref f) => &f.sig,
|
||||
|
|
@ -3886,7 +3878,7 @@ pub fn ty_fn_abi(fty: Ty) -> abi::Abi {
|
|||
|
||||
// Type accessors for substructures of types
|
||||
pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> &'tcx [Ty<'tcx>] {
|
||||
ty_fn_sig(fty).inputs.as_slice()
|
||||
ty_fn_sig(fty).0.inputs.as_slice()
|
||||
}
|
||||
|
||||
pub fn ty_closure_store(fty: Ty) -> TraitStore {
|
||||
|
|
@ -3905,8 +3897,8 @@ pub fn ty_closure_store(fty: Ty) -> TraitStore {
|
|||
|
||||
pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> FnOutput<'tcx> {
|
||||
match fty.sty {
|
||||
ty_bare_fn(ref f) => f.sig.output,
|
||||
ty_closure(ref f) => f.sig.output,
|
||||
ty_bare_fn(ref f) => f.sig.0.output,
|
||||
ty_closure(ref f) => f.sig.0.output,
|
||||
ref s => {
|
||||
panic!("ty_fn_ret() called on non-fn type: {}", s)
|
||||
}
|
||||
|
|
@ -4801,7 +4793,7 @@ pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
|
|||
&Some(ref t) => {
|
||||
let trait_ref =
|
||||
(*ty::node_id_to_trait_ref(cx, t.ref_id)).clone();
|
||||
Some(Rc::new(ty::bind(trait_ref)))
|
||||
Some(Rc::new(ty::Binder(trait_ref)))
|
||||
}
|
||||
&None => None
|
||||
}
|
||||
|
|
@ -5180,7 +5172,7 @@ pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
|
|||
trait_def.bounds.trait_bounds
|
||||
.iter()
|
||||
.map(|bound_trait_ref| {
|
||||
ty::bind(
|
||||
ty::Binder(
|
||||
ty::TraitRef::new(bound_trait_ref.def_id(),
|
||||
bound_trait_ref.substs().subst(tcx, trait_ref.substs())))
|
||||
})
|
||||
|
|
@ -5515,18 +5507,6 @@ pub fn normalize_ty<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
|||
subst::Substs { regions: subst::ErasedRegions,
|
||||
types: substs.types.fold_with(self) }
|
||||
}
|
||||
|
||||
fn fold_fn_sig(&mut self,
|
||||
sig: &ty::FnSig<'tcx>)
|
||||
-> ty::FnSig<'tcx> {
|
||||
// The binder-id is only relevant to bound regions, which
|
||||
// are erased at trans time.
|
||||
ty::FnSig {
|
||||
inputs: sig.inputs.fold_with(self),
|
||||
output: sig.output.fold_with(self),
|
||||
variadic: sig.variadic,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5602,7 +5582,7 @@ pub fn object_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
|
|||
|
||||
let opt_trait_ref = opt_principal.map_or(Vec::new(), |principal| {
|
||||
let substs = principal.substs().with_self_ty(open_ty);
|
||||
vec!(Rc::new(ty::bind(ty::TraitRef::new(principal.def_id(), substs))))
|
||||
vec!(Rc::new(ty::Binder(ty::TraitRef::new(principal.def_id(), substs))))
|
||||
});
|
||||
|
||||
let param_bounds = ty::ParamBounds {
|
||||
|
|
@ -5856,12 +5836,12 @@ pub fn trait_item_of_item(tcx: &ctxt, def_id: ast::DefId)
|
|||
|
||||
/// Creates a hash of the type `Ty` which will be the same no matter what crate
|
||||
/// context it's calculated within. This is used by the `type_id` intrinsic.
|
||||
pub fn hash_crate_independent(tcx: &ctxt, ty: Ty, svh: &Svh) -> u64 {
|
||||
pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -> u64 {
|
||||
let mut state = sip::SipState::new();
|
||||
helper(tcx, ty, svh, &mut state);
|
||||
return state.result();
|
||||
|
||||
fn helper(tcx: &ctxt, ty: Ty, svh: &Svh, state: &mut sip::SipState) {
|
||||
fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh, state: &mut sip::SipState) {
|
||||
macro_rules! byte( ($b:expr) => { ($b as u8).hash(state) } );
|
||||
macro_rules! hash( ($e:expr) => { $e.hash(state) } );
|
||||
|
||||
|
|
@ -5894,7 +5874,7 @@ pub fn hash_crate_independent(tcx: &ctxt, ty: Ty, svh: &Svh) -> u64 {
|
|||
let mt = |state: &mut sip::SipState, mt: mt| {
|
||||
mt.mutbl.hash(state);
|
||||
};
|
||||
let fn_sig = |state: &mut sip::SipState, sig: &FnSig| {
|
||||
let fn_sig = |state: &mut sip::SipState, sig: &Binder<FnSig<'tcx>>| {
|
||||
let sig = anonymize_late_bound_regions(tcx, sig);
|
||||
for a in sig.inputs.iter() { helper(tcx, *a, svh, state); }
|
||||
if let ty::FnConverging(output) = sig.output {
|
||||
|
|
@ -5974,7 +5954,7 @@ pub fn hash_crate_independent(tcx: &ctxt, ty: Ty, svh: &Svh) -> u64 {
|
|||
hash!(bounds);
|
||||
|
||||
let principal = anonymize_late_bound_regions(tcx, principal);
|
||||
for subty in principal.substs().types.iter() {
|
||||
for subty in principal.substs.types.iter() {
|
||||
helper(tcx, *subty, svh, state);
|
||||
}
|
||||
|
||||
|
|
@ -6065,7 +6045,7 @@ pub fn construct_parameter_environment<'tcx>(
|
|||
//
|
||||
|
||||
let bounds = generics.to_bounds(tcx, &free_substs);
|
||||
let bounds = liberate_late_bound_regions(tcx, free_id_scope, &bind(bounds)).value;
|
||||
let bounds = liberate_late_bound_regions(tcx, free_id_scope, &ty::Binder(bounds));
|
||||
|
||||
//
|
||||
// Compute region bounds. For now, these relations are stored in a
|
||||
|
|
@ -6321,12 +6301,12 @@ impl<'tcx> AutoDerefRef<'tcx> {
|
|||
|
||||
/// Replace any late-bound regions bound in `value` with free variants attached to scope-id
|
||||
/// `scope_id`.
|
||||
pub fn liberate_late_bound_regions<'tcx, HR>(
|
||||
pub fn liberate_late_bound_regions<'tcx, T>(
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
scope: region::CodeExtent,
|
||||
value: &HR)
|
||||
-> HR
|
||||
where HR : HigherRankedFoldable<'tcx>
|
||||
value: &Binder<T>)
|
||||
-> T
|
||||
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||
{
|
||||
replace_late_bound_regions(
|
||||
tcx, value,
|
||||
|
|
@ -6335,11 +6315,11 @@ pub fn liberate_late_bound_regions<'tcx, HR>(
|
|||
|
||||
/// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
|
||||
/// method lookup and a few other places where precise region relationships are not required.
|
||||
pub fn erase_late_bound_regions<'tcx, HR>(
|
||||
pub fn erase_late_bound_regions<'tcx, T>(
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
value: &HR)
|
||||
-> HR
|
||||
where HR : HigherRankedFoldable<'tcx>
|
||||
value: &Binder<T>)
|
||||
-> T
|
||||
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||
{
|
||||
replace_late_bound_regions(tcx, value, |_, _| ty::ReStatic).0
|
||||
}
|
||||
|
|
@ -6352,8 +6332,12 @@ pub fn erase_late_bound_regions<'tcx, HR>(
|
|||
/// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
|
||||
/// structurally identical. For example, `for<'a, 'b> fn(&'a int, &'b int)` and
|
||||
/// `for<'a, 'b> fn(&'b int, &'a int)` will become identical after anonymization.
|
||||
pub fn anonymize_late_bound_regions<'tcx, HR>(tcx: &ctxt<'tcx>, sig: &HR) -> HR
|
||||
where HR: HigherRankedFoldable<'tcx> {
|
||||
pub fn anonymize_late_bound_regions<'tcx, T>(
|
||||
tcx: &ctxt<'tcx>,
|
||||
sig: &Binder<T>)
|
||||
-> T
|
||||
where T : TypeFoldable<'tcx> + Repr<'tcx>,
|
||||
{
|
||||
let mut counter = 0;
|
||||
replace_late_bound_regions(tcx, sig, |_, db| {
|
||||
counter += 1;
|
||||
|
|
@ -6362,15 +6346,15 @@ pub fn anonymize_late_bound_regions<'tcx, HR>(tcx: &ctxt<'tcx>, sig: &HR) -> HR
|
|||
}
|
||||
|
||||
/// Replaces the late-bound-regions in `value` that are bound by `value`.
|
||||
pub fn replace_late_bound_regions<'tcx, HR, F>(
|
||||
pub fn replace_late_bound_regions<'tcx, T, F>(
|
||||
tcx: &ty::ctxt<'tcx>,
|
||||
value: &HR,
|
||||
binder: &Binder<T>,
|
||||
mut mapf: F)
|
||||
-> (HR, FnvHashMap<ty::BoundRegion, ty::Region>) where
|
||||
HR : HigherRankedFoldable<'tcx>,
|
||||
F: FnMut(BoundRegion, DebruijnIndex) -> ty::Region,
|
||||
-> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
|
||||
where T : TypeFoldable<'tcx> + Repr<'tcx>,
|
||||
F : FnMut(BoundRegion, DebruijnIndex) -> ty::Region,
|
||||
{
|
||||
debug!("replace_late_bound_regions({})", value.repr(tcx));
|
||||
debug!("replace_late_bound_regions({})", binder.repr(tcx));
|
||||
|
||||
let mut map = FnvHashMap::new();
|
||||
let value = {
|
||||
|
|
@ -6389,11 +6373,9 @@ pub fn replace_late_bound_regions<'tcx, HR, F>(
|
|||
}
|
||||
});
|
||||
|
||||
// Note: use `fold_contents` not `fold_with`. If we used
|
||||
// `fold_with`, it would consider the late-bound regions bound
|
||||
// by `value` to be bound, but we want to consider them as
|
||||
// `free`.
|
||||
value.fold_contents(&mut f)
|
||||
// Note: fold the field `0`, not the binder, so that late-bound
|
||||
// regions bound by `binder` are considered free.
|
||||
binder.0.fold_with(&mut f)
|
||||
};
|
||||
debug!("resulting map: {} value: {}", map, value.repr(tcx));
|
||||
(value, map)
|
||||
|
|
@ -6600,13 +6582,13 @@ impl<'tcx> RegionEscape for TraitRef<'tcx> {
|
|||
|
||||
impl<'tcx,T:RegionEscape> RegionEscape for Binder<T> {
|
||||
fn has_regions_escaping_depth(&self, depth: uint) -> bool {
|
||||
self.value.has_regions_escaping_depth(depth + 1)
|
||||
self.0.has_regions_escaping_depth(depth + 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:RegionEscape> Binder<T> {
|
||||
pub fn has_bound_regions(&self) -> bool {
|
||||
self.value.has_regions_escaping_depth(0)
|
||||
self.0.has_regions_escaping_depth(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,8 +93,8 @@ pub trait TypeFolder<'tcx> {
|
|||
}
|
||||
|
||||
fn fold_fn_sig(&mut self,
|
||||
sig: &ty::FnSig<'tcx>)
|
||||
-> ty::FnSig<'tcx> {
|
||||
sig: &ty::FnSig<'tcx>)
|
||||
-> ty::FnSig<'tcx> {
|
||||
super_fold_fn_sig(self, sig)
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
|
|||
impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Binder<T> {
|
||||
folder.enter_region_binder();
|
||||
let result = ty::bind(self.value.fold_with(folder));
|
||||
let result = ty::Binder(self.0.fold_with(folder));
|
||||
folder.exit_region_binder();
|
||||
result
|
||||
}
|
||||
|
|
@ -532,16 +532,6 @@ pub fn super_fold_substs<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
|||
pub fn super_fold_fn_sig<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||
sig: &ty::FnSig<'tcx>)
|
||||
-> ty::FnSig<'tcx>
|
||||
{
|
||||
this.enter_region_binder();
|
||||
let result = super_fold_fn_sig_contents(this, sig);
|
||||
this.exit_region_binder();
|
||||
result
|
||||
}
|
||||
|
||||
pub fn super_fold_fn_sig_contents<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||
sig: &ty::FnSig<'tcx>)
|
||||
-> ty::FnSig<'tcx>
|
||||
{
|
||||
ty::FnSig { inputs: sig.inputs.fold_with(this),
|
||||
output: sig.output.fold_with(this),
|
||||
|
|
@ -696,34 +686,6 @@ pub fn super_fold_item_substs<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
|||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Higher-ranked things
|
||||
|
||||
/// Designates a "binder" for late-bound regions.
|
||||
pub trait HigherRankedFoldable<'tcx>: Repr<'tcx> {
|
||||
/// Folds the contents of `self`, ignoring the region binder created
|
||||
/// by `self`.
|
||||
fn fold_contents<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self;
|
||||
}
|
||||
|
||||
impl<'tcx> HigherRankedFoldable<'tcx> for ty::FnSig<'tcx> {
|
||||
fn fold_contents<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::FnSig<'tcx> {
|
||||
super_fold_fn_sig_contents(folder, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T:TypeFoldable<'tcx>+Repr<'tcx>> HigherRankedFoldable<'tcx> for ty::Binder<T> {
|
||||
fn fold_contents<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Binder<T> {
|
||||
ty::bind(self.value.fold_with(folder))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T:HigherRankedFoldable<'tcx>> HigherRankedFoldable<'tcx> for Rc<T> {
|
||||
fn fold_contents<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Rc<T> {
|
||||
Rc::new((**self).fold_contents(folder))
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Some sample folders
|
||||
|
||||
|
|
@ -754,10 +716,6 @@ impl<'a, 'tcx, F> TypeFolder<'tcx> for BottomUpFolder<'a, 'tcx, F> where
|
|||
/// regions (aka "lifetimes") that are bound within a type are not
|
||||
/// visited by this folder; only regions that occur free will be
|
||||
/// visited by `fld_r`.
|
||||
///
|
||||
/// (The distinction between "free" and "bound" is represented by
|
||||
/// keeping track of each `FnSig` in the lexical context of the
|
||||
/// current position of the fold.)
|
||||
pub struct RegionFolder<'a, 'tcx: 'a, F> where F: FnMut(ty::Region, uint) -> ty::Region {
|
||||
tcx: &'a ty::ctxt<'tcx>,
|
||||
current_depth: uint,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,10 @@ use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open};
|
|||
use middle::ty::{ty_unboxed_closure};
|
||||
use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
|
||||
use middle::ty;
|
||||
use middle::ty_fold::TypeFoldable;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
use syntax::abi;
|
||||
use syntax::ast_map;
|
||||
|
|
@ -40,7 +43,7 @@ pub trait Repr<'tcx> for Sized? {
|
|||
}
|
||||
|
||||
/// Produces a string suitable for showing to the user.
|
||||
pub trait UserString<'tcx> {
|
||||
pub trait UserString<'tcx> : Repr<'tcx> {
|
||||
fn user_string(&self, tcx: &ctxt<'tcx>) -> String;
|
||||
}
|
||||
|
||||
|
|
@ -248,21 +251,12 @@ pub fn vec_map_to_string<T, F>(ts: &[T], f: F) -> String where
|
|||
format!("[{}]", tstrs.connect(", "))
|
||||
}
|
||||
|
||||
pub fn fn_sig_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::FnSig<'tcx>) -> String {
|
||||
format!("fn{} -> {}", typ.inputs.repr(cx), typ.output.repr(cx))
|
||||
}
|
||||
|
||||
pub fn trait_ref_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||
trait_ref: &ty::TraitRef<'tcx>) -> String {
|
||||
trait_ref.user_string(cx).to_string()
|
||||
}
|
||||
|
||||
pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
||||
fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||
unsafety: ast::Unsafety,
|
||||
abi: abi::Abi,
|
||||
ident: Option<ast::Ident>,
|
||||
sig: &ty::FnSig<'tcx>)
|
||||
sig: &ty::PolyFnSig<'tcx>)
|
||||
-> String {
|
||||
let mut s = String::new();
|
||||
match unsafety {
|
||||
|
|
@ -336,15 +330,15 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
|||
s: &mut String,
|
||||
bra: char,
|
||||
ket: char,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
sig: &ty::PolyFnSig<'tcx>,
|
||||
bounds: &str) {
|
||||
s.push(bra);
|
||||
let strs = sig.inputs
|
||||
let strs = sig.0.inputs
|
||||
.iter()
|
||||
.map(|a| ty_to_string(cx, *a))
|
||||
.collect::<Vec<_>>();
|
||||
s.push_str(strs.connect(", ").as_slice());
|
||||
if sig.variadic {
|
||||
if sig.0.variadic {
|
||||
s.push_str(", ...");
|
||||
}
|
||||
s.push(ket);
|
||||
|
|
@ -354,7 +348,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
|||
s.push_str(bounds);
|
||||
}
|
||||
|
||||
match sig.output {
|
||||
match sig.0.output {
|
||||
ty::FnConverging(t) => {
|
||||
if !ty::type_is_nil(t) {
|
||||
s.push_str(" -> ");
|
||||
|
|
@ -1013,7 +1007,7 @@ impl<'tcx> Repr<'tcx> for ty::BareFnTy<'tcx> {
|
|||
|
||||
impl<'tcx> Repr<'tcx> for ty::FnSig<'tcx> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
fn_sig_to_string(tcx, self)
|
||||
format!("fn{} -> {}", self.inputs.repr(tcx), self.output.repr(tcx))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1156,7 +1150,9 @@ impl<'tcx> UserString<'tcx> for ty::BuiltinBounds {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UserString<'tcx> for ty::PolyTraitRef<'tcx> {
|
||||
impl<'tcx, T> UserString<'tcx> for ty::Binder<T>
|
||||
where T : UserString<'tcx> + TypeFoldable<'tcx>
|
||||
{
|
||||
fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
// Replace any anonymous late-bound regions with named
|
||||
// variants, using gensym'd identifiers, so that we can
|
||||
|
|
@ -1164,7 +1160,7 @@ impl<'tcx> UserString<'tcx> for ty::PolyTraitRef<'tcx> {
|
|||
// the output. We'll probably want to tweak this over time to
|
||||
// decide just how much information to give.
|
||||
let mut names = Vec::new();
|
||||
let (trait_ref, _) = ty::replace_late_bound_regions(tcx, self, |br, debruijn| {
|
||||
let (unbound_value, _) = ty::replace_late_bound_regions(tcx, self, |br, debruijn| {
|
||||
ty::ReLateBound(debruijn, match br {
|
||||
ty::BrNamed(_, name) => {
|
||||
names.push(token::get_name(name));
|
||||
|
|
@ -1181,11 +1177,11 @@ impl<'tcx> UserString<'tcx> for ty::PolyTraitRef<'tcx> {
|
|||
});
|
||||
let names: Vec<_> = names.iter().map(|s| s.get()).collect();
|
||||
|
||||
let trait_ref_str = trait_ref.value.user_string(tcx);
|
||||
let value_str = unbound_value.user_string(tcx);
|
||||
if names.len() == 0 {
|
||||
trait_ref_str
|
||||
value_str
|
||||
} else {
|
||||
format!("for<{}> {}", names.connect(","), trait_ref_str)
|
||||
format!("for<{}> {}", names.connect(","), value_str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1337,6 +1333,20 @@ impl<'tcx, A:Repr<'tcx>, B:Repr<'tcx>> Repr<'tcx> for (A,B) {
|
|||
|
||||
impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for ty::Binder<T> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
format!("Binder({})", self.value.repr(tcx))
|
||||
format!("Binder({})", self.0.repr(tcx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, S, H, K, V> Repr<'tcx> for HashMap<K,V,H>
|
||||
where K : Hash<S> + Eq + Repr<'tcx>,
|
||||
V : Repr<'tcx>,
|
||||
H : Hasher<S>
|
||||
{
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
format!("HashMap({})",
|
||||
self.iter()
|
||||
.map(|(k,v)| format!("{} => {}", k.repr(tcx), v.repr(tcx)))
|
||||
.collect::<Vec<String>>()
|
||||
.connect(", "))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue