mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
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
@ -429,7 +429,7 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
|
|||||||
{
|
{
|
||||||
let item_doc = lookup_item(id, cdata.data());
|
let item_doc = lookup_item(id, cdata.data());
|
||||||
reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| {
|
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 name = item_name(&*intr, item);
|
||||||
let (ctor_ty, arg_tys, arg_names) = match ctor_ty.sty {
|
let (ctor_ty, arg_tys, arg_names) = match ctor_ty.sty {
|
||||||
ty::ty_bare_fn(ref f) =>
|
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.
|
_ => { // Nullary or struct enum variant.
|
||||||
let mut arg_names = Vec::new();
|
let mut arg_names = Vec::new();
|
||||||
let arg_tys = get_struct_fields(intr.clone(), cdata, did.node)
|
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' => {
|
'x' => {
|
||||||
assert_eq!(next(st), '[');
|
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));
|
let bounds = parse_existential_bounds(st, |x,y| conv(x,y));
|
||||||
assert_eq!(next(st), ']');
|
assert_eq!(next(st), ']');
|
||||||
return ty::mk_trait(st.tcx, trait_ref, bounds);
|
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), '[');
|
assert_eq!(next(st), '[');
|
||||||
let mut inputs = Vec::new();
|
let mut inputs = Vec::new();
|
||||||
while peek(st) != ']' {
|
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::FnConverging(parse_ty(st, |x,y| conv(x,y)))
|
||||||
};
|
};
|
||||||
ty::FnSig {inputs: inputs,
|
ty::Binder(ty::FnSig {inputs: inputs,
|
||||||
output: output,
|
output: output,
|
||||||
variadic: variadic}
|
variadic: variadic})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rust metadata parsing
|
// Rust metadata parsing
|
||||||
@ -669,7 +669,7 @@ pub fn parse_predicate<'a,'tcx>(st: &mut PState<'a, 'tcx>,
|
|||||||
-> ty::Predicate<'tcx>
|
-> ty::Predicate<'tcx>
|
||||||
{
|
{
|
||||||
match next(st) {
|
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)),
|
'e' => ty::Predicate::Equate(parse_ty(st, |x,y| conv(x,y)),
|
||||||
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)),
|
'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' => {
|
'I' => {
|
||||||
param_bounds.trait_bounds.push(
|
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;
|
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,
|
ty::ty_trait(box ty::TyTrait { ref principal,
|
||||||
ref bounds }) => {
|
ref bounds }) => {
|
||||||
mywrite!(w, "x[");
|
mywrite!(w, "x[");
|
||||||
enc_trait_ref(w, cx, &principal.value);
|
enc_trait_ref(w, cx, &principal.0);
|
||||||
enc_existential_bounds(w, cx, bounds);
|
enc_existential_bounds(w, cx, bounds);
|
||||||
mywrite!(w, "]");
|
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>,
|
fn enc_fn_sig<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
|
||||||
fsig: &ty::FnSig<'tcx>) {
|
fsig: &ty::PolyFnSig<'tcx>) {
|
||||||
mywrite!(w, "[");
|
mywrite!(w, "[");
|
||||||
for ty in fsig.inputs.iter() {
|
for ty in fsig.0.inputs.iter() {
|
||||||
enc_ty(w, cx, *ty);
|
enc_ty(w, cx, *ty);
|
||||||
}
|
}
|
||||||
mywrite!(w, "]");
|
mywrite!(w, "]");
|
||||||
if fsig.variadic {
|
if fsig.0.variadic {
|
||||||
mywrite!(w, "V");
|
mywrite!(w, "V");
|
||||||
} else {
|
} else {
|
||||||
mywrite!(w, "N");
|
mywrite!(w, "N");
|
||||||
}
|
}
|
||||||
match fsig.output {
|
match fsig.0.output {
|
||||||
ty::FnConverging(result_type) => {
|
ty::FnConverging(result_type) => {
|
||||||
enc_ty(w, cx, 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() {
|
for tp in bs.trait_bounds.iter() {
|
||||||
mywrite!(w, "I");
|
mywrite!(w, "I");
|
||||||
enc_trait_ref(w, cx, &tp.value);
|
enc_trait_ref(w, cx, &tp.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mywrite!(w, ".");
|
mywrite!(w, ".");
|
||||||
@ -425,7 +425,7 @@ pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
|
|||||||
match *p {
|
match *p {
|
||||||
ty::Predicate::Trait(ref trait_ref) => {
|
ty::Predicate::Trait(ref trait_ref) => {
|
||||||
mywrite!(w, "t");
|
mywrite!(w, "t");
|
||||||
enc_trait_ref(w, cx, &trait_ref.value);
|
enc_trait_ref(w, cx, &trait_ref.0);
|
||||||
}
|
}
|
||||||
ty::Predicate::Equate(a, b) => {
|
ty::Predicate::Equate(a, b) => {
|
||||||
mywrite!(w, "e");
|
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_enum_variant("MethodTypeParam", 2, 1, |this| {
|
||||||
this.emit_struct("MethodParam", 2, |this| {
|
this.emit_struct("MethodParam", 2, |this| {
|
||||||
try!(this.emit_struct_field("trait_ref", 0, |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| {
|
try!(this.emit_struct_field("method_num", 0, |this| {
|
||||||
this.emit_uint(p.method_num)
|
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_enum_variant("MethodTraitObject", 3, 1, |this| {
|
||||||
this.emit_struct("MethodObject", 2, |this| {
|
this.emit_struct("MethodObject", 2, |this| {
|
||||||
try!(this.emit_struct_field("trait_ref", 0, |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| {
|
try!(this.emit_struct_field("object_trait_id", 0, |this| {
|
||||||
Ok(this.emit_def_id(o.object_trait_id))
|
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("UnsizeVtable", 2, 4, |this| {
|
||||||
this.emit_enum_variant_arg(0, |this| {
|
this.emit_enum_variant_arg(0, |this| {
|
||||||
try!(this.emit_struct_field("principal", 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| {
|
this.emit_struct_field("bounds", 1, |this| {
|
||||||
Ok(this.emit_existential_bounds(ecx, b))
|
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.tag(c::tag_table_object_cast_map, |rbml_w| {
|
||||||
rbml_w.id(id);
|
rbml_w.id(id);
|
||||||
rbml_w.tag(c::tag_table_val, |rbml_w| {
|
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>)
|
fn read_poly_trait_ref<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
|
||||||
-> Rc<ty::PolyTraitRef<'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(
|
let ty = tydecode::parse_trait_ref_data(
|
||||||
doc.data,
|
doc.data,
|
||||||
dcx.cdata.cnum,
|
dcx.cdata.cnum,
|
||||||
|
@ -265,7 +265,7 @@ impl OverloadedCallType {
|
|||||||
}
|
}
|
||||||
Some(ref trait_ref) => (*trait_ref).clone(),
|
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)
|
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_vec(..) => Some(VecSimplifiedType),
|
||||||
ty::ty_ptr(_) => Some(PtrSimplifiedType),
|
ty::ty_ptr(_) => Some(PtrSimplifiedType),
|
||||||
ty::ty_trait(ref trait_info) => {
|
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, _) => {
|
ty::ty_struct(def_id, _) => {
|
||||||
Some(StructSimplifiedType(def_id))
|
Some(StructSimplifiedType(def_id))
|
||||||
@ -83,10 +83,10 @@ pub fn simplify_type(tcx: &ty::ctxt,
|
|||||||
Some(TupleSimplifiedType(tys.len()))
|
Some(TupleSimplifiedType(tys.len()))
|
||||||
}
|
}
|
||||||
ty::ty_closure(ref f) => {
|
ty::ty_closure(ref f) => {
|
||||||
Some(FunctionSimplifiedType(f.sig.inputs.len()))
|
Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
|
||||||
}
|
}
|
||||||
ty::ty_bare_fn(ref f) => {
|
ty::ty_bare_fn(ref f) => {
|
||||||
Some(FunctionSimplifiedType(f.sig.inputs.len()))
|
Some(FunctionSimplifiedType(f.sig.0.inputs.len()))
|
||||||
}
|
}
|
||||||
ty::ty_param(_) => {
|
ty::ty_param(_) => {
|
||||||
if can_simplify_params {
|
if can_simplify_params {
|
||||||
|
@ -195,7 +195,7 @@ pub trait Combine<'tcx> {
|
|||||||
b: &ty::BareFnTy<'tcx>) -> cres<'tcx, ty::BareFnTy<'tcx>> {
|
b: &ty::BareFnTy<'tcx>) -> cres<'tcx, ty::BareFnTy<'tcx>> {
|
||||||
let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety));
|
let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety));
|
||||||
let abi = try!(self.abi(a.abi, b.abi));
|
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,
|
Ok(ty::BareFnTy {unsafety: unsafety,
|
||||||
abi: abi,
|
abi: abi,
|
||||||
sig: sig})
|
sig: sig})
|
||||||
@ -222,7 +222,7 @@ pub trait Combine<'tcx> {
|
|||||||
let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety));
|
let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety));
|
||||||
let onceness = try!(self.oncenesses(a.onceness, b.onceness));
|
let onceness = try!(self.oncenesses(a.onceness, b.onceness));
|
||||||
let bounds = try!(self.existential_bounds(a.bounds, b.bounds));
|
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));
|
let abi = try!(self.abi(a.abi, b.abi));
|
||||||
Ok(ty::ClosureTy {
|
Ok(ty::ClosureTy {
|
||||||
unsafety: unsafety,
|
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>> {
|
fn args(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
|
||||||
self.contratys(a, b).and_then(|t| Ok(t))
|
self.contratys(a, b).and_then(|t| Ok(t))
|
||||||
@ -312,14 +348,36 @@ pub trait Combine<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poly_trait_refs(&self,
|
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
|
||||||
a: &ty::PolyTraitRef<'tcx>,
|
where T : Combineable<'tcx>;
|
||||||
b: &ty::PolyTraitRef<'tcx>)
|
|
||||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>>;
|
|
||||||
// this must be overridden to do correctly, so as to account for higher-ranked
|
// this must be overridden to do correctly, so as to account for higher-ranked
|
||||||
// behavior
|
// 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)]
|
#[deriving(Clone)]
|
||||||
pub struct CombineFields<'a, 'tcx: 'a> {
|
pub struct CombineFields<'a, 'tcx: 'a> {
|
||||||
pub infcx: &'a InferCtxt<'a, 'tcx>,
|
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 a_),
|
||||||
&ty::ty_trait(ref b_)) => {
|
&ty::ty_trait(ref b_)) => {
|
||||||
debug!("Trying to match traits {} and {}", a, 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));
|
let bounds = try!(this.existential_bounds(a_.bounds, b_.bounds));
|
||||||
Ok(ty::mk_trait(tcx, principal, 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>)
|
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
|
||||||
-> cres<'tcx, ty::FnSig<'tcx>>
|
where T : Combineable<'tcx>
|
||||||
{
|
{
|
||||||
try!(self.sub().fn_sigs(a, b));
|
try!(self.sub().binders(a, b));
|
||||||
self.sub().fn_sigs(b, a)
|
self.sub().binders(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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1653,7 +1653,7 @@ impl<'tcx> Resolvable<'tcx> for Rc<ty::PolyTraitRef<'tcx>> {
|
|||||||
Rc::new(infcx.resolve_type_vars_if_possible(&**self))
|
Rc::new(infcx.resolve_type_vars_if_possible(&**self))
|
||||||
}
|
}
|
||||||
fn contains_error(&self) -> bool {
|
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)
|
super_lattice_tys(self, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>)
|
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
|
||||||
-> cres<'tcx, ty::FnSig<'tcx>> {
|
where T : Combineable<'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>> {
|
|
||||||
self.higher_ranked_glb(a, b)
|
self.higher_ranked_glb(a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,29 +11,24 @@
|
|||||||
//! Helper routines for higher-ranked things. See the `doc` module at
|
//! Helper routines for higher-ranked things. See the `doc` module at
|
||||||
//! the end of the file for details.
|
//! the end of the file for details.
|
||||||
|
|
||||||
use super::{combine, CombinedSnapshot, cres, InferCtxt, HigherRankedType};
|
use super::{CombinedSnapshot, cres, InferCtxt, HigherRankedType};
|
||||||
use super::combine::Combine;
|
use super::combine::{Combine, Combineable};
|
||||||
|
|
||||||
use middle::ty::{mod, Ty, replace_late_bound_regions};
|
use middle::ty::{mod, Binder};
|
||||||
use middle::ty_fold::{mod, HigherRankedFoldable, TypeFoldable};
|
use middle::ty_fold::{mod, TypeFoldable};
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use util::nodemap::{FnvHashMap, FnvHashSet};
|
use util::nodemap::{FnvHashMap, FnvHashSet};
|
||||||
use util::ppaux::{bound_region_to_string, Repr};
|
use util::ppaux::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>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait HigherRankedRelations<'tcx> {
|
pub trait HigherRankedRelations<'tcx> {
|
||||||
fn higher_ranked_sub<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
|
||||||
where T : HigherRankedCombineable<'tcx>;
|
where T : Combineable<'tcx>;
|
||||||
|
|
||||||
fn higher_ranked_lub<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
|
||||||
where T : HigherRankedCombineable<'tcx>;
|
where T : Combineable<'tcx>;
|
||||||
|
|
||||||
fn higher_ranked_glb<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
|
||||||
where T : HigherRankedCombineable<'tcx>;
|
where T : Combineable<'tcx>;
|
||||||
}
|
}
|
||||||
|
|
||||||
trait InferCtxtExt<'tcx> {
|
trait InferCtxtExt<'tcx> {
|
||||||
@ -47,8 +42,9 @@ trait InferCtxtExt<'tcx> {
|
|||||||
impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
||||||
where C : Combine<'tcx>
|
where C : Combine<'tcx>
|
||||||
{
|
{
|
||||||
fn higher_ranked_sub<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
|
||||||
where T : HigherRankedCombineable<'tcx>
|
-> cres<'tcx, Binder<T>>
|
||||||
|
where T : Combineable<'tcx>
|
||||||
{
|
{
|
||||||
debug!("higher_ranked_sub(a={}, b={})",
|
debug!("higher_ranked_sub(a={}, b={})",
|
||||||
a.repr(self.tcx()), b.repr(self.tcx()));
|
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
|
// Second, we instantiate each bound region in the supertype with a
|
||||||
// fresh concrete region.
|
// 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!("a_prime={}", a_prime.repr(self.tcx()));
|
||||||
debug!("b_prime={}", b_prime.repr(self.tcx()));
|
debug!("b_prime={}", b_prime.repr(self.tcx()));
|
||||||
|
|
||||||
// Compare types now that bound regions have been replaced.
|
// 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
|
// Presuming type comparison succeeds, we need to check
|
||||||
// that the skolemized regions do not "leak".
|
// that the skolemized regions do not "leak".
|
||||||
@ -102,12 +99,12 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||||||
debug!("higher_ranked_sub: OK result={}",
|
debug!("higher_ranked_sub: OK result={}",
|
||||||
result.repr(self.tcx()));
|
result.repr(self.tcx()));
|
||||||
|
|
||||||
Ok(result)
|
Ok(ty::Binder(result))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn higher_ranked_lub<T>(&self, a: &T, b: &T) -> cres<'tcx, T>
|
fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
|
||||||
where T : HigherRankedCombineable<'tcx>
|
where T : Combineable<'tcx>
|
||||||
{
|
{
|
||||||
// Start a snapshot so we can examine "all bindings that were
|
// Start a snapshot so we can examine "all bindings that were
|
||||||
// created as part of this type comparison".
|
// created as part of this type comparison".
|
||||||
@ -123,7 +120,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||||||
|
|
||||||
// Collect constraints.
|
// Collect constraints.
|
||||||
let result0 =
|
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 =
|
let result0 =
|
||||||
self.infcx().resolve_type_vars_if_possible(&result0);
|
self.infcx().resolve_type_vars_if_possible(&result0);
|
||||||
debug!("lub result0 = {}", result0.repr(self.tcx()));
|
debug!("lub result0 = {}", result0.repr(self.tcx()));
|
||||||
@ -143,7 +140,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||||||
b.repr(self.tcx()),
|
b.repr(self.tcx()),
|
||||||
result1.repr(self.tcx()));
|
result1.repr(self.tcx()));
|
||||||
|
|
||||||
Ok(result1)
|
Ok(ty::Binder(result1))
|
||||||
});
|
});
|
||||||
|
|
||||||
fn generalize_region(infcx: &InferCtxt,
|
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>
|
fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> cres<'tcx, Binder<T>>
|
||||||
where T : HigherRankedCombineable<'tcx>
|
where T : Combineable<'tcx>
|
||||||
{
|
{
|
||||||
debug!("{}.higher_ranked_glb({}, {})",
|
debug!("{}.higher_ranked_glb({}, {})",
|
||||||
self.tag(), a.repr(self.tcx()), b.repr(self.tcx()));
|
self.tag(), a.repr(self.tcx()), b.repr(self.tcx()));
|
||||||
@ -217,7 +214,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||||||
|
|
||||||
// Collect constraints.
|
// Collect constraints.
|
||||||
let result0 =
|
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 =
|
let result0 =
|
||||||
self.infcx().resolve_type_vars_if_possible(&result0);
|
self.infcx().resolve_type_vars_if_possible(&result0);
|
||||||
debug!("glb result0 = {}", result0.repr(self.tcx()));
|
debug!("glb result0 = {}", result0.repr(self.tcx()));
|
||||||
@ -239,7 +236,7 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
|
|||||||
b.repr(self.tcx()),
|
b.repr(self.tcx()),
|
||||||
result1.repr(self.tcx()));
|
result1.repr(self.tcx()));
|
||||||
|
|
||||||
Ok(result1)
|
Ok(ty::Binder(result1))
|
||||||
});
|
});
|
||||||
|
|
||||||
fn generalize_region(infcx: &InferCtxt,
|
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,
|
fn var_ids<'tcx, T: Combine<'tcx>>(combiner: &T,
|
||||||
map: &FnvHashMap<ty::BoundRegion, ty::Region>)
|
map: &FnvHashMap<ty::BoundRegion, ty::Region>)
|
||||||
-> Vec<ty::RegionVid> {
|
-> 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
|
fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>,
|
||||||
T: HigherRankedFoldable<'tcx>,
|
unbound_value: &T,
|
||||||
F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
|
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,
|
// we should only be encountering "escaping" late-bound regions here,
|
||||||
// because the ones at the current level should have been replaced
|
// because the ones at the current level should have been replaced
|
||||||
// with fresh variables
|
// 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>,
|
fn leak_check<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||||
skol_map: &FnvHashMap<ty::BoundRegion,ty::Region>,
|
skol_map: &FnvHashMap<ty::BoundRegion,ty::Region>,
|
||||||
snapshot: &CombinedSnapshot)
|
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))
|
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>> {
|
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> cres<'tcx, Ty<'tcx>> {
|
||||||
super_lattice_tys(self, a, b)
|
super_lattice_tys(self, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poly_trait_refs(&self, a: &ty::PolyTraitRef<'tcx>, b: &ty::PolyTraitRef<'tcx>)
|
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
|
||||||
-> cres<'tcx, ty::PolyTraitRef<'tcx>> {
|
where T : Combineable<'tcx>
|
||||||
|
{
|
||||||
self.higher_ranked_lub(a, b)
|
self.higher_ranked_lub(a, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ use middle::subst::Substs;
|
|||||||
use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
|
use middle::ty::{TyVid, IntVid, FloatVid, RegionVid};
|
||||||
use middle::ty::replace_late_bound_regions;
|
use middle::ty::replace_late_bound_regions;
|
||||||
use middle::ty::{mod, Ty};
|
use middle::ty::{mod, Ty};
|
||||||
use middle::ty_fold::{HigherRankedFoldable, TypeFolder, TypeFoldable};
|
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||||
use std::cell::{RefCell};
|
use std::cell::{RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
@ -35,7 +35,7 @@ use syntax::codemap::Span;
|
|||||||
use util::common::indent;
|
use util::common::indent;
|
||||||
use util::nodemap::FnvHashMap;
|
use util::nodemap::FnvHashMap;
|
||||||
use util::ppaux::{ty_to_string};
|
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::coercion::Coerce;
|
||||||
use self::combine::{Combine, CombineFields};
|
use self::combine::{Combine, CombineFields};
|
||||||
@ -699,26 +699,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
values: TraitRefs(expected_found(a_is_expected,
|
values: TraitRefs(expected_found(a_is_expected,
|
||||||
a.clone(), b.clone()))
|
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,
|
pub fn skolemize_late_bound_regions<T>(&self,
|
||||||
value: &ty::Binder<T>,
|
value: &ty::Binder<T>,
|
||||||
snapshot: &CombinedSnapshot)
|
snapshot: &CombinedSnapshot)
|
||||||
-> (T, SkolemizationMap)
|
-> (T, SkolemizationMap)
|
||||||
where T : TypeFoldable<'tcx>
|
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)
|
self.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot)
|
||||||
});
|
});
|
||||||
|
|
||||||
debug!("skolemize_bound_regions(value={}, result={}, map={})",
|
debug!("skolemize_bound_regions(value={}, result={}, map={})",
|
||||||
value.repr(self.tcx),
|
value.repr(self.tcx),
|
||||||
result_binder.value.repr(self.tcx),
|
result.repr(self.tcx),
|
||||||
map.repr(self.tcx));
|
map.repr(self.tcx));
|
||||||
|
|
||||||
(result_binder.value, map)
|
(result, map)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_ty_var_id(&self, diverging: bool) -> TyVid {
|
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 {
|
pub fn trait_ref_to_string(&self, t: &Rc<ty::TraitRef<'tcx>>) -> String {
|
||||||
let t = self.resolve_type_vars_if_possible(&**t);
|
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> {
|
pub fn shallow_resolve(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
@ -982,9 +982,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
lbrct: LateBoundRegionConversionTime,
|
lbrct: LateBoundRegionConversionTime,
|
||||||
value: &T)
|
value: &ty::Binder<T>)
|
||||||
-> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
|
-> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
|
||||||
where T : HigherRankedFoldable<'tcx>
|
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||||
{
|
{
|
||||||
ty::replace_late_bound_regions(
|
ty::replace_late_bound_regions(
|
||||||
self.tcx,
|
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>)
|
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> cres<'tcx, ty::Binder<T>>
|
||||||
-> cres<'tcx, ty::FnSig<'tcx>> {
|
where T : Combineable<'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>> {
|
|
||||||
self.higher_ranked_sub(a, b)
|
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);
|
let typ = ty::node_id_to_type(self.tcx, expr.id);
|
||||||
match typ.sty {
|
match typ.sty {
|
||||||
ty_bare_fn(ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
|
ty_bare_fn(ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
|
||||||
if let ty::FnConverging(to) = bare_fn_ty.sig.output {
|
if let ty::FnConverging(to) = bare_fn_ty.sig.0.output {
|
||||||
let from = bare_fn_ty.sig.inputs[0];
|
let from = bare_fn_ty.sig.0.inputs[0];
|
||||||
self.check_transmute(expr.span, from, to, expr.id);
|
self.check_transmute(expr.span, from, to, expr.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1534,6 +1534,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.closure_type
|
.closure_type
|
||||||
.sig
|
.sig
|
||||||
|
.0
|
||||||
.output,
|
.output,
|
||||||
_ => ty::ty_fn_ret(fn_ty)
|
_ => 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 tr = ty::impl_trait_ref(self.tcx, local_def(item.id));
|
||||||
let public_trait = tr.clone().map_or(false, |tr| {
|
let public_trait = tr.clone().map_or(false, |tr| {
|
||||||
!is_local(tr.value.def_id) ||
|
!is_local(tr.def_id()) ||
|
||||||
self.exported_items.contains(&tr.value.def_id.node)
|
self.exported_items.contains(&tr.def_id().node)
|
||||||
});
|
});
|
||||||
|
|
||||||
if public_ty || public_trait {
|
if public_ty || public_trait {
|
||||||
@ -407,7 +407,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
|||||||
match ty::impl_trait_ref(self.tcx, id) {
|
match ty::impl_trait_ref(self.tcx, id) {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
debug!("privacy - impl of trait {}", id);
|
debug!("privacy - impl of trait {}", id);
|
||||||
self.def_privacy(t.value.def_id)
|
self.def_privacy(t.def_id())
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
debug!("privacy - found a method {}",
|
debug!("privacy - found a method {}",
|
||||||
@ -432,7 +432,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
|||||||
match ty::impl_trait_ref(self.tcx, id) {
|
match ty::impl_trait_ref(self.tcx, id) {
|
||||||
Some(t) => {
|
Some(t) => {
|
||||||
debug!("privacy - impl of trait {}", id);
|
debug!("privacy - impl of trait {}", id);
|
||||||
self.def_privacy(t.value.def_id)
|
self.def_privacy(t.def_id())
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
debug!("privacy - found a typedef {}",
|
debug!("privacy - found a typedef {}",
|
||||||
|
@ -18,6 +18,7 @@ use middle::subst;
|
|||||||
use middle::subst::Subst;
|
use middle::subst::Subst;
|
||||||
use middle::ty::{mod, Ty};
|
use middle::ty::{mod, Ty};
|
||||||
use middle::infer::{mod, InferCtxt};
|
use middle::infer::{mod, InferCtxt};
|
||||||
|
use std::rc::Rc;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::DUMMY_SP;
|
use syntax::codemap::DUMMY_SP;
|
||||||
use util::ppaux::Repr;
|
use util::ppaux::Repr;
|
||||||
@ -42,13 +43,14 @@ pub fn impl_can_satisfy(infcx: &InferCtxt,
|
|||||||
let impl1_trait_ref =
|
let impl1_trait_ref =
|
||||||
infcx.replace_late_bound_regions_with_fresh_var(DUMMY_SP,
|
infcx.replace_late_bound_regions_with_fresh_var(DUMMY_SP,
|
||||||
infer::FnCall,
|
infer::FnCall,
|
||||||
&impl1_trait_ref).0;
|
&*impl1_trait_ref).0;
|
||||||
|
|
||||||
// Determine whether `impl2` can provide an implementation for those
|
// Determine whether `impl2` can provide an implementation for those
|
||||||
// same types.
|
// same types.
|
||||||
let param_env = ty::empty_parameter_environment();
|
let param_env = ty::empty_parameter_environment();
|
||||||
let mut selcx = SelectionContext::intercrate(infcx, ¶m_env, infcx.tcx);
|
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));
|
debug!("impl_can_satisfy(obligation={})", obligation.repr(infcx.tcx));
|
||||||
selcx.evaluate_impl(impl2_def_id, &obligation)
|
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));
|
debug!("trait_ref={}", trait_ref.repr(tcx));
|
||||||
|
|
||||||
// If the trait is local to the crate, ok.
|
// 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",
|
debug!("trait {} is local to current crate",
|
||||||
trait_ref.value.def_id.repr(tcx));
|
trait_ref.def_id().repr(tcx));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, at least one of the input types must be local to the
|
// Otherwise, at least one of the input types must be local to the
|
||||||
// crate.
|
// 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 {
|
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) => {
|
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
|
// 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
|
// This suffices to allow chains like `FnMut` implemented in
|
||||||
// terms of `Fn` etc, but we could probably make this more
|
// terms of `Fn` etc, but we could probably make this more
|
||||||
// precise still.
|
// 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));
|
let unbound_input_types = input_types.iter().any(|&t| ty::type_is_fresh(t));
|
||||||
if
|
if
|
||||||
unbound_input_types &&
|
unbound_input_types &&
|
||||||
(self.intercrate ||
|
(self.intercrate ||
|
||||||
stack.iter().skip(1).any(
|
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",
|
debug!("evaluate_stack({}) --> unbound argument, recursion --> ambiguous",
|
||||||
stack.fresh_trait_ref.repr(self.tcx()));
|
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
|
// If the trait refers to any parameters in scope, then use
|
||||||
// the cache of the param-environment.
|
// the cache of the param-environment.
|
||||||
if
|
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))
|
|&t| ty::type_has_self(t) || ty::type_has_params(t))
|
||||||
{
|
{
|
||||||
return &self.param_env.selection_cache;
|
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.
|
// See the discussion in doc.rs for more details.
|
||||||
if
|
if
|
||||||
!self.param_env.caller_bounds.is_empty() &&
|
!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))
|
|&t| ty::type_has_ty_infer(t))
|
||||||
{
|
{
|
||||||
return &self.param_env.selection_cache;
|
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
|
// Other bounds. Consider both in-scope bounds from fn decl
|
||||||
// and applicable impls. There is a certain set of precedence rules here.
|
// 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) => {
|
Some(ty::BoundCopy) => {
|
||||||
debug!("obligation self ty is {}",
|
debug!("obligation self ty is {}",
|
||||||
obligation.self_ty().repr(self.tcx()));
|
obligation.self_ty().repr(self.tcx()));
|
||||||
@ -731,7 +731,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
candidates: &mut CandidateSet<'tcx>)
|
candidates: &mut CandidateSet<'tcx>)
|
||||||
-> Result<(),SelectionError<'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,
|
Some(k) => k,
|
||||||
None => { return Ok(()); }
|
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
|
// 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
|
// the other traits (e.g. `FnMut`) since those are provided by blanket
|
||||||
// impls.
|
// 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(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,11 +793,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
ty::ty_bare_fn(ty::BareFnTy {
|
ty::ty_bare_fn(ty::BareFnTy {
|
||||||
unsafety: ast::Unsafety::Normal,
|
unsafety: ast::Unsafety::Normal,
|
||||||
abi: abi::Rust,
|
abi: abi::Rust,
|
||||||
sig: ty::FnSig {
|
sig: ty::Binder(ty::FnSig {
|
||||||
inputs: _,
|
inputs: _,
|
||||||
output: ty::FnConverging(_),
|
output: ty::FnConverging(_),
|
||||||
variadic: false
|
variadic: false
|
||||||
}
|
})
|
||||||
}) => {
|
}) => {
|
||||||
candidates.vec.push(FnPointerCandidate);
|
candidates.vec.push(FnPointerCandidate);
|
||||||
}
|
}
|
||||||
@ -814,7 +814,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
candidates: &mut CandidateSet<'tcx>)
|
candidates: &mut CandidateSet<'tcx>)
|
||||||
-> Result<(), SelectionError<'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() {
|
for &impl_def_id in all_impls.iter() {
|
||||||
self.infcx.probe(|| {
|
self.infcx.probe(|| {
|
||||||
match self.match_impl(impl_def_id, obligation) {
|
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.
|
// bounds are required and thus we must fulfill.
|
||||||
let tmp_tr = data.principal_trait_ref_with_self_ty(ty::mk_err());
|
let tmp_tr = data.principal_trait_ref_with_self_ty(ty::mk_err());
|
||||||
for tr in util::supertraits(self.tcx(), tmp_tr) {
|
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) {
|
if td.bounds.builtin_bounds.contains(&bound) {
|
||||||
return Ok(If(Vec::new()))
|
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 arguments_tuple = ty::mk_tup(self.tcx(), sig.0.inputs.to_vec());
|
||||||
let output_type = sig.output.unwrap();
|
let output_type = sig.0.output.unwrap();
|
||||||
let substs =
|
let substs =
|
||||||
Substs::new_trait(
|
Substs::new_trait(
|
||||||
vec![arguments_tuple, output_type],
|
vec![arguments_tuple, output_type],
|
||||||
vec![],
|
vec![],
|
||||||
vec![],
|
vec![],
|
||||||
self_ty);
|
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(),
|
def_id: obligation.trait_ref.def_id(),
|
||||||
substs: substs,
|
substs: substs,
|
||||||
}));
|
}));
|
||||||
@ -1562,15 +1562,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let closure_sig = &closure_type.sig;
|
let closure_sig = &closure_type.sig;
|
||||||
let arguments_tuple = closure_sig.inputs[0];
|
let arguments_tuple = closure_sig.0.inputs[0];
|
||||||
let substs =
|
let substs =
|
||||||
Substs::new_trait(
|
Substs::new_trait(
|
||||||
vec![arguments_tuple.subst(self.tcx(), substs),
|
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![],
|
||||||
vec![],
|
vec![],
|
||||||
obligation.self_ty());
|
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(),
|
def_id: obligation.trait_ref.def_id(),
|
||||||
substs: substs,
|
substs: substs,
|
||||||
}));
|
}));
|
||||||
|
@ -274,7 +274,7 @@ pub fn poly_trait_ref_for_builtin_bound<'tcx>(
|
|||||||
{
|
{
|
||||||
match tcx.lang_items.from_builtin_kind(builtin_bound) {
|
match tcx.lang_items.from_builtin_kind(builtin_bound) {
|
||||||
Ok(def_id) => {
|
Ok(def_id) => {
|
||||||
Ok(Rc::new(ty::bind(ty::TraitRef {
|
Ok(Rc::new(ty::Binder(ty::TraitRef {
|
||||||
def_id: def_id,
|
def_id: def_id,
|
||||||
substs: Substs::empty().with_self_ty(param_ty)
|
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::ObligationCause;
|
||||||
use middle::traits;
|
use middle::traits;
|
||||||
use middle::ty;
|
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::{note_and_explain_region, bound_region_ptr_to_string};
|
||||||
use util::ppaux::{trait_store_to_string, ty_to_string};
|
use util::ppaux::{trait_store_to_string, ty_to_string};
|
||||||
use util::ppaux::{Repr, UserString};
|
use util::ppaux::{Repr, UserString};
|
||||||
@ -908,7 +908,7 @@ pub fn type_escapes_depth(ty: Ty, depth: uint) -> bool {
|
|||||||
pub struct BareFnTy<'tcx> {
|
pub struct BareFnTy<'tcx> {
|
||||||
pub unsafety: ast::Unsafety,
|
pub unsafety: ast::Unsafety,
|
||||||
pub abi: abi::Abi,
|
pub abi: abi::Abi,
|
||||||
pub sig: FnSig<'tcx>,
|
pub sig: PolyFnSig<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
||||||
@ -917,7 +917,7 @@ pub struct ClosureTy<'tcx> {
|
|||||||
pub onceness: ast::Onceness,
|
pub onceness: ast::Onceness,
|
||||||
pub store: TraitStore,
|
pub store: TraitStore,
|
||||||
pub bounds: ExistentialBounds,
|
pub bounds: ExistentialBounds,
|
||||||
pub sig: FnSig<'tcx>,
|
pub sig: PolyFnSig<'tcx>,
|
||||||
pub abi: abi::Abi,
|
pub abi: abi::Abi,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -944,10 +944,6 @@ impl<'tcx> Copy for FnOutput<'tcx> {}
|
|||||||
/// - `inputs` is the list of arguments and their modes.
|
/// - `inputs` is the list of arguments and their modes.
|
||||||
/// - `output` is the return type.
|
/// - `output` is the return type.
|
||||||
/// - `variadic` indicates whether this is a varidic function. (only true for foreign fns)
|
/// - `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)]
|
#[deriving(Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct FnSig<'tcx> {
|
pub struct FnSig<'tcx> {
|
||||||
pub inputs: Vec<Ty<'tcx>>,
|
pub inputs: Vec<Ty<'tcx>>,
|
||||||
@ -955,6 +951,8 @@ pub struct FnSig<'tcx> {
|
|||||||
pub variadic: bool
|
pub variadic: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type PolyFnSig<'tcx> = Binder<FnSig<'tcx>>;
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
||||||
pub struct ParamTy {
|
pub struct ParamTy {
|
||||||
pub space: subst::ParamSpace,
|
pub space: subst::ParamSpace,
|
||||||
@ -1318,9 +1316,9 @@ impl<'tcx> TyTrait<'tcx> {
|
|||||||
/// you must give *some* self-type. A common choice is `mk_err()`
|
/// you must give *some* self-type. A common choice is `mk_err()`
|
||||||
/// or some skolemized type.
|
/// or some skolemized type.
|
||||||
pub fn principal_trait_ref_with_self_ty(&self, self_ty: Ty<'tcx>) -> Rc<ty::PolyTraitRef<'tcx>> {
|
pub fn principal_trait_ref_with_self_ty(&self, self_ty: Ty<'tcx>) -> Rc<ty::PolyTraitRef<'tcx>> {
|
||||||
Rc::new(ty::bind(ty::TraitRef {
|
Rc::new(ty::Binder(ty::TraitRef {
|
||||||
def_id: self.principal.value.def_id,
|
def_id: self.principal.def_id(),
|
||||||
substs: self.principal.value.substs.with_self_ty(self_ty),
|
substs: self.principal.substs().with_self_ty(self_ty),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1350,19 +1348,19 @@ pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
|
|||||||
|
|
||||||
impl<'tcx> PolyTraitRef<'tcx> {
|
impl<'tcx> PolyTraitRef<'tcx> {
|
||||||
pub fn self_ty(&self) -> Ty<'tcx> {
|
pub fn self_ty(&self) -> Ty<'tcx> {
|
||||||
self.value.self_ty()
|
self.0.self_ty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn def_id(&self) -> ast::DefId {
|
pub fn def_id(&self) -> ast::DefId {
|
||||||
self.value.def_id
|
self.0.def_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn substs(&self) -> &Substs<'tcx> {
|
pub fn substs(&self) -> &Substs<'tcx> {
|
||||||
&self.value.substs
|
&self.0.substs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_types(&self) -> &[Ty<'tcx>] {
|
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
|
/// by the binder supplied to it; but a type is not a binder, so you
|
||||||
/// must introduce an artificial one).
|
/// must introduce an artificial one).
|
||||||
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
#[deriving(Clone, PartialEq, Eq, Hash, Show)]
|
||||||
pub struct Binder<T> {
|
pub struct Binder<T>(pub T);
|
||||||
pub value: T
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bind<T>(value: T) -> Binder<T> {
|
|
||||||
Binder { value: value }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[deriving(Clone, PartialEq)]
|
#[deriving(Clone, PartialEq)]
|
||||||
pub enum IntVarValue {
|
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();
|
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);
|
computation.add_ty(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2385,11 +2377,11 @@ pub fn mk_ctor_fn<'tcx>(cx: &ctxt<'tcx>,
|
|||||||
BareFnTy {
|
BareFnTy {
|
||||||
unsafety: ast::Unsafety::Normal,
|
unsafety: ast::Unsafety::Normal,
|
||||||
abi: abi::Rust,
|
abi: abi::Rust,
|
||||||
sig: FnSig {
|
sig: ty::Binder(FnSig {
|
||||||
inputs: input_args,
|
inputs: input_args,
|
||||||
output: ty::FnConverging(output),
|
output: ty::FnConverging(output),
|
||||||
variadic: false
|
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_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty(*tt, |x| f(x)); } }
|
||||||
ty_bare_fn(ref ft) => {
|
ty_bare_fn(ref ft) => {
|
||||||
for a in ft.sig.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
|
for a in ft.sig.0.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
|
||||||
if let ty::FnConverging(output) = ft.sig.output {
|
if let ty::FnConverging(output) = ft.sig.0.output {
|
||||||
maybe_walk_ty(output, f);
|
maybe_walk_ty(output, f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty_closure(ref ft) => {
|
ty_closure(ref ft) => {
|
||||||
for a in ft.sig.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
|
for a in ft.sig.0.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
|
||||||
if let ty::FnConverging(output) = ft.sig.output {
|
if let ty::FnConverging(output) = ft.sig.0.output {
|
||||||
maybe_walk_ty(output, f);
|
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 {
|
pub fn fn_is_variadic(fty: Ty) -> bool {
|
||||||
match fty.sty {
|
match fty.sty {
|
||||||
ty_bare_fn(ref f) => f.sig.variadic,
|
ty_bare_fn(ref f) => f.sig.0.variadic,
|
||||||
ty_closure(ref f) => f.sig.variadic,
|
ty_closure(ref f) => f.sig.0.variadic,
|
||||||
ref s => {
|
ref s => {
|
||||||
panic!("fn_is_variadic() called on non-fn type: {}", 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 {
|
match fty.sty {
|
||||||
ty_bare_fn(ref f) => &f.sig,
|
ty_bare_fn(ref f) => &f.sig,
|
||||||
ty_closure(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
|
// Type accessors for substructures of types
|
||||||
pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> &'tcx [Ty<'tcx>] {
|
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 {
|
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> {
|
pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> FnOutput<'tcx> {
|
||||||
match fty.sty {
|
match fty.sty {
|
||||||
ty_bare_fn(ref f) => f.sig.output,
|
ty_bare_fn(ref f) => f.sig.0.output,
|
||||||
ty_closure(ref f) => f.sig.output,
|
ty_closure(ref f) => f.sig.0.output,
|
||||||
ref s => {
|
ref s => {
|
||||||
panic!("ty_fn_ret() called on non-fn type: {}", 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) => {
|
&Some(ref t) => {
|
||||||
let trait_ref =
|
let trait_ref =
|
||||||
(*ty::node_id_to_trait_ref(cx, t.ref_id)).clone();
|
(*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
|
&None => None
|
||||||
}
|
}
|
||||||
@ -5180,7 +5172,7 @@ pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
|
|||||||
trait_def.bounds.trait_bounds
|
trait_def.bounds.trait_bounds
|
||||||
.iter()
|
.iter()
|
||||||
.map(|bound_trait_ref| {
|
.map(|bound_trait_ref| {
|
||||||
ty::bind(
|
ty::Binder(
|
||||||
ty::TraitRef::new(bound_trait_ref.def_id(),
|
ty::TraitRef::new(bound_trait_ref.def_id(),
|
||||||
bound_trait_ref.substs().subst(tcx, trait_ref.substs())))
|
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,
|
subst::Substs { regions: subst::ErasedRegions,
|
||||||
types: substs.types.fold_with(self) }
|
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 opt_trait_ref = opt_principal.map_or(Vec::new(), |principal| {
|
||||||
let substs = principal.substs().with_self_ty(open_ty);
|
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 {
|
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
|
/// 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.
|
/// 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();
|
let mut state = sip::SipState::new();
|
||||||
helper(tcx, ty, svh, &mut state);
|
helper(tcx, ty, svh, &mut state);
|
||||||
return state.result();
|
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! byte( ($b:expr) => { ($b as u8).hash(state) } );
|
||||||
macro_rules! hash( ($e:expr) => { $e.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| {
|
let mt = |state: &mut sip::SipState, mt: mt| {
|
||||||
mt.mutbl.hash(state);
|
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);
|
let sig = anonymize_late_bound_regions(tcx, sig);
|
||||||
for a in sig.inputs.iter() { helper(tcx, *a, svh, state); }
|
for a in sig.inputs.iter() { helper(tcx, *a, svh, state); }
|
||||||
if let ty::FnConverging(output) = sig.output {
|
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);
|
hash!(bounds);
|
||||||
|
|
||||||
let principal = anonymize_late_bound_regions(tcx, principal);
|
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);
|
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 = 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
|
// 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
|
/// Replace any late-bound regions bound in `value` with free variants attached to scope-id
|
||||||
/// `scope_id`.
|
/// `scope_id`.
|
||||||
pub fn liberate_late_bound_regions<'tcx, HR>(
|
pub fn liberate_late_bound_regions<'tcx, T>(
|
||||||
tcx: &ty::ctxt<'tcx>,
|
tcx: &ty::ctxt<'tcx>,
|
||||||
scope: region::CodeExtent,
|
scope: region::CodeExtent,
|
||||||
value: &HR)
|
value: &Binder<T>)
|
||||||
-> HR
|
-> T
|
||||||
where HR : HigherRankedFoldable<'tcx>
|
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||||
{
|
{
|
||||||
replace_late_bound_regions(
|
replace_late_bound_regions(
|
||||||
tcx, value,
|
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
|
/// 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.
|
/// 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>,
|
tcx: &ty::ctxt<'tcx>,
|
||||||
value: &HR)
|
value: &Binder<T>)
|
||||||
-> HR
|
-> T
|
||||||
where HR : HigherRankedFoldable<'tcx>
|
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||||
{
|
{
|
||||||
replace_late_bound_regions(tcx, value, |_, _| ty::ReStatic).0
|
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
|
/// `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
|
/// 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.
|
/// `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
|
pub fn anonymize_late_bound_regions<'tcx, T>(
|
||||||
where HR: HigherRankedFoldable<'tcx> {
|
tcx: &ctxt<'tcx>,
|
||||||
|
sig: &Binder<T>)
|
||||||
|
-> T
|
||||||
|
where T : TypeFoldable<'tcx> + Repr<'tcx>,
|
||||||
|
{
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
replace_late_bound_regions(tcx, sig, |_, db| {
|
replace_late_bound_regions(tcx, sig, |_, db| {
|
||||||
counter += 1;
|
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`.
|
/// 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>,
|
tcx: &ty::ctxt<'tcx>,
|
||||||
value: &HR,
|
binder: &Binder<T>,
|
||||||
mut mapf: F)
|
mut mapf: F)
|
||||||
-> (HR, FnvHashMap<ty::BoundRegion, ty::Region>) where
|
-> (T, FnvHashMap<ty::BoundRegion,ty::Region>)
|
||||||
HR : HigherRankedFoldable<'tcx>,
|
where T : TypeFoldable<'tcx> + Repr<'tcx>,
|
||||||
F: FnMut(BoundRegion, DebruijnIndex) -> ty::Region,
|
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 mut map = FnvHashMap::new();
|
||||||
let value = {
|
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
|
// Note: fold the field `0`, not the binder, so that late-bound
|
||||||
// `fold_with`, it would consider the late-bound regions bound
|
// regions bound by `binder` are considered free.
|
||||||
// by `value` to be bound, but we want to consider them as
|
binder.0.fold_with(&mut f)
|
||||||
// `free`.
|
|
||||||
value.fold_contents(&mut f)
|
|
||||||
};
|
};
|
||||||
debug!("resulting map: {} value: {}", map, value.repr(tcx));
|
debug!("resulting map: {} value: {}", map, value.repr(tcx));
|
||||||
(value, map)
|
(value, map)
|
||||||
@ -6600,13 +6582,13 @@ impl<'tcx> RegionEscape for TraitRef<'tcx> {
|
|||||||
|
|
||||||
impl<'tcx,T:RegionEscape> RegionEscape for Binder<T> {
|
impl<'tcx,T:RegionEscape> RegionEscape for Binder<T> {
|
||||||
fn has_regions_escaping_depth(&self, depth: uint) -> bool {
|
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> {
|
impl<T:RegionEscape> Binder<T> {
|
||||||
pub fn has_bound_regions(&self) -> bool {
|
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,
|
fn fold_fn_sig(&mut self,
|
||||||
sig: &ty::FnSig<'tcx>)
|
sig: &ty::FnSig<'tcx>)
|
||||||
-> ty::FnSig<'tcx> {
|
-> ty::FnSig<'tcx> {
|
||||||
super_fold_fn_sig(self, sig)
|
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> {
|
impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
|
||||||
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Binder<T> {
|
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::Binder<T> {
|
||||||
folder.enter_region_binder();
|
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();
|
folder.exit_region_binder();
|
||||||
result
|
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,
|
pub fn super_fold_fn_sig<'tcx, T: TypeFolder<'tcx>>(this: &mut T,
|
||||||
sig: &ty::FnSig<'tcx>)
|
sig: &ty::FnSig<'tcx>)
|
||||||
-> 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),
|
ty::FnSig { inputs: sig.inputs.fold_with(this),
|
||||||
output: sig.output.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
|
// 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
|
/// regions (aka "lifetimes") that are bound within a type are not
|
||||||
/// visited by this folder; only regions that occur free will be
|
/// visited by this folder; only regions that occur free will be
|
||||||
/// visited by `fld_r`.
|
/// 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 {
|
pub struct RegionFolder<'a, 'tcx: 'a, F> where F: FnMut(ty::Region, uint) -> ty::Region {
|
||||||
tcx: &'a ty::ctxt<'tcx>,
|
tcx: &'a ty::ctxt<'tcx>,
|
||||||
current_depth: uint,
|
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_unboxed_closure};
|
||||||
use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
|
use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
|
use middle::ty_fold::TypeFoldable;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use syntax::abi;
|
use syntax::abi;
|
||||||
use syntax::ast_map;
|
use syntax::ast_map;
|
||||||
@ -40,7 +43,7 @@ pub trait Repr<'tcx> for Sized? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Produces a string suitable for showing to the user.
|
/// 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;
|
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(", "))
|
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 {
|
pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
||||||
fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>,
|
fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||||
unsafety: ast::Unsafety,
|
unsafety: ast::Unsafety,
|
||||||
abi: abi::Abi,
|
abi: abi::Abi,
|
||||||
ident: Option<ast::Ident>,
|
ident: Option<ast::Ident>,
|
||||||
sig: &ty::FnSig<'tcx>)
|
sig: &ty::PolyFnSig<'tcx>)
|
||||||
-> String {
|
-> String {
|
||||||
let mut s = String::new();
|
let mut s = String::new();
|
||||||
match unsafety {
|
match unsafety {
|
||||||
@ -336,15 +330,15 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
|||||||
s: &mut String,
|
s: &mut String,
|
||||||
bra: char,
|
bra: char,
|
||||||
ket: char,
|
ket: char,
|
||||||
sig: &ty::FnSig<'tcx>,
|
sig: &ty::PolyFnSig<'tcx>,
|
||||||
bounds: &str) {
|
bounds: &str) {
|
||||||
s.push(bra);
|
s.push(bra);
|
||||||
let strs = sig.inputs
|
let strs = sig.0.inputs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| ty_to_string(cx, *a))
|
.map(|a| ty_to_string(cx, *a))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
s.push_str(strs.connect(", ").as_slice());
|
s.push_str(strs.connect(", ").as_slice());
|
||||||
if sig.variadic {
|
if sig.0.variadic {
|
||||||
s.push_str(", ...");
|
s.push_str(", ...");
|
||||||
}
|
}
|
||||||
s.push(ket);
|
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);
|
s.push_str(bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
match sig.output {
|
match sig.0.output {
|
||||||
ty::FnConverging(t) => {
|
ty::FnConverging(t) => {
|
||||||
if !ty::type_is_nil(t) {
|
if !ty::type_is_nil(t) {
|
||||||
s.push_str(" -> ");
|
s.push_str(" -> ");
|
||||||
@ -1013,7 +1007,7 @@ impl<'tcx> Repr<'tcx> for ty::BareFnTy<'tcx> {
|
|||||||
|
|
||||||
impl<'tcx> Repr<'tcx> for ty::FnSig<'tcx> {
|
impl<'tcx> Repr<'tcx> for ty::FnSig<'tcx> {
|
||||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
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 {
|
fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
|
||||||
// Replace any anonymous late-bound regions with named
|
// Replace any anonymous late-bound regions with named
|
||||||
// variants, using gensym'd identifiers, so that we can
|
// 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
|
// the output. We'll probably want to tweak this over time to
|
||||||
// decide just how much information to give.
|
// decide just how much information to give.
|
||||||
let mut names = Vec::new();
|
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::ReLateBound(debruijn, match br {
|
||||||
ty::BrNamed(_, name) => {
|
ty::BrNamed(_, name) => {
|
||||||
names.push(token::get_name(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 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 {
|
if names.len() == 0 {
|
||||||
trait_ref_str
|
value_str
|
||||||
} else {
|
} 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> {
|
impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for ty::Binder<T> {
|
||||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
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(", "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,11 +275,11 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
|
|||||||
onceness: ast::Many,
|
onceness: ast::Many,
|
||||||
store: ty::RegionTraitStore(region_bound, ast::MutMutable),
|
store: ty::RegionTraitStore(region_bound, ast::MutMutable),
|
||||||
bounds: ty::region_existential_bound(region_bound),
|
bounds: ty::region_existential_bound(region_bound),
|
||||||
sig: ty::FnSig {
|
sig: ty::Binder(ty::FnSig {
|
||||||
inputs: input_tys.to_vec(),
|
inputs: input_tys.to_vec(),
|
||||||
output: ty::FnConverging(output_ty),
|
output: ty::FnConverging(output_ty),
|
||||||
variadic: false,
|
variadic: false,
|
||||||
},
|
}),
|
||||||
abi: abi::Rust,
|
abi: abi::Rust,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -282,10 +282,10 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
fn_ty: Ty<'tcx>, name: &str) -> ValueRef {
|
fn_ty: Ty<'tcx>, name: &str) -> ValueRef {
|
||||||
let (inputs, output, abi, env) = match fn_ty.sty {
|
let (inputs, output, abi, env) = match fn_ty.sty {
|
||||||
ty::ty_bare_fn(ref f) => {
|
ty::ty_bare_fn(ref f) => {
|
||||||
(f.sig.inputs.clone(), f.sig.output, f.abi, None)
|
(f.sig.0.inputs.clone(), f.sig.0.output, f.abi, None)
|
||||||
}
|
}
|
||||||
ty::ty_closure(ref f) => {
|
ty::ty_closure(ref f) => {
|
||||||
(f.sig.inputs.clone(), f.sig.output, f.abi, Some(Type::i8p(ccx)))
|
(f.sig.0.inputs.clone(), f.sig.0.output, f.abi, Some(Type::i8p(ccx)))
|
||||||
}
|
}
|
||||||
ty::ty_unboxed_closure(closure_did, _, ref substs) => {
|
ty::ty_unboxed_closure(closure_did, _, ref substs) => {
|
||||||
let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
|
let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
|
||||||
@ -293,8 +293,8 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
let function_type = unboxed_closure.closure_type.clone();
|
let function_type = unboxed_closure.closure_type.clone();
|
||||||
let self_type = self_type_for_unboxed_closure(ccx, closure_did, fn_ty);
|
let self_type = self_type_for_unboxed_closure(ccx, closure_did, fn_ty);
|
||||||
let llenvironment_type = type_of_explicit_arg(ccx, self_type);
|
let llenvironment_type = type_of_explicit_arg(ccx, self_type);
|
||||||
(function_type.sig.inputs.iter().map(|t| t.subst(ccx.tcx(), substs)).collect(),
|
(function_type.sig.0.inputs.iter().map(|t| t.subst(ccx.tcx(), substs)).collect(),
|
||||||
function_type.sig.output.subst(ccx.tcx(), substs),
|
function_type.sig.0.output.subst(ccx.tcx(), substs),
|
||||||
RustCall,
|
RustCall,
|
||||||
Some(llenvironment_type))
|
Some(llenvironment_type))
|
||||||
}
|
}
|
||||||
@ -1998,7 +1998,7 @@ pub fn trans_named_tuple_constructor<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||||||
let tcx = ccx.tcx();
|
let tcx = ccx.tcx();
|
||||||
|
|
||||||
let result_ty = match ctor_ty.sty {
|
let result_ty = match ctor_ty.sty {
|
||||||
ty::ty_bare_fn(ref bft) => bft.sig.output.unwrap(),
|
ty::ty_bare_fn(ref bft) => bft.sig.0.output.unwrap(),
|
||||||
_ => ccx.sess().bug(
|
_ => ccx.sess().bug(
|
||||||
format!("trans_enum_variant_constructor: \
|
format!("trans_enum_variant_constructor: \
|
||||||
unexpected ctor return type {}",
|
unexpected ctor return type {}",
|
||||||
@ -2070,7 +2070,7 @@ fn trans_enum_variant_or_tuple_like_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx
|
|||||||
let ctor_ty = ctor_ty.subst(ccx.tcx(), param_substs);
|
let ctor_ty = ctor_ty.subst(ccx.tcx(), param_substs);
|
||||||
|
|
||||||
let result_ty = match ctor_ty.sty {
|
let result_ty = match ctor_ty.sty {
|
||||||
ty::ty_bare_fn(ref bft) => bft.sig.output,
|
ty::ty_bare_fn(ref bft) => bft.sig.0.output,
|
||||||
_ => ccx.sess().bug(
|
_ => ccx.sess().bug(
|
||||||
format!("trans_enum_variant_or_tuple_like_struct: \
|
format!("trans_enum_variant_or_tuple_like_struct: \
|
||||||
unexpected ctor return type {}",
|
unexpected ctor return type {}",
|
||||||
@ -2439,7 +2439,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
|
|||||||
// at either 1 or 2 depending on whether there's an env slot or not
|
// at either 1 or 2 depending on whether there's an env slot or not
|
||||||
let mut first_arg_offset = if has_env { 2 } else { 1 };
|
let mut first_arg_offset = if has_env { 2 } else { 1 };
|
||||||
let mut attrs = llvm::AttrBuilder::new();
|
let mut attrs = llvm::AttrBuilder::new();
|
||||||
let ret_ty = fn_sig.output;
|
let ret_ty = fn_sig.0.output;
|
||||||
|
|
||||||
// These have an odd calling convention, so we need to manually
|
// These have an odd calling convention, so we need to manually
|
||||||
// unpack the input ty's
|
// unpack the input ty's
|
||||||
@ -2447,15 +2447,15 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
|
|||||||
ty::ty_unboxed_closure(_, _, _) => {
|
ty::ty_unboxed_closure(_, _, _) => {
|
||||||
assert!(abi == RustCall);
|
assert!(abi == RustCall);
|
||||||
|
|
||||||
match fn_sig.inputs[0].sty {
|
match fn_sig.0.inputs[0].sty {
|
||||||
ty::ty_tup(ref inputs) => inputs.clone(),
|
ty::ty_tup(ref inputs) => inputs.clone(),
|
||||||
_ => ccx.sess().bug("expected tuple'd inputs")
|
_ => ccx.sess().bug("expected tuple'd inputs")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ty::ty_bare_fn(_) if abi == RustCall => {
|
ty::ty_bare_fn(_) if abi == RustCall => {
|
||||||
let mut inputs = vec![fn_sig.inputs[0]];
|
let mut inputs = vec![fn_sig.0.inputs[0]];
|
||||||
|
|
||||||
match fn_sig.inputs[1].sty {
|
match fn_sig.0.inputs[1].sty {
|
||||||
ty::ty_tup(ref t_in) => {
|
ty::ty_tup(ref t_in) => {
|
||||||
inputs.push_all(t_in.as_slice());
|
inputs.push_all(t_in.as_slice());
|
||||||
inputs
|
inputs
|
||||||
@ -2463,7 +2463,7 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
|
|||||||
_ => ccx.sess().bug("expected tuple'd inputs")
|
_ => ccx.sess().bug("expected tuple'd inputs")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => fn_sig.inputs.clone()
|
_ => fn_sig.0.inputs.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let ty::FnConverging(ret_ty) = ret_ty {
|
if let ty::FnConverging(ret_ty) = ret_ty {
|
||||||
|
@ -280,9 +280,9 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
|
|||||||
match bare_fn_ty.sty {
|
match bare_fn_ty.sty {
|
||||||
ty::ty_bare_fn(ty::BareFnTy { unsafety: ast::Unsafety::Normal,
|
ty::ty_bare_fn(ty::BareFnTy { unsafety: ast::Unsafety::Normal,
|
||||||
abi: synabi::Rust,
|
abi: synabi::Rust,
|
||||||
sig: ty::FnSig { inputs: ref input_tys,
|
sig: ty::Binder(ty::FnSig { inputs: ref input_tys,
|
||||||
output: output_ty,
|
output: output_ty,
|
||||||
variadic: false }}) =>
|
variadic: false })}) =>
|
||||||
{
|
{
|
||||||
(input_tys, output_ty)
|
(input_tys, output_ty)
|
||||||
}
|
}
|
||||||
@ -296,12 +296,12 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
|
|||||||
let tuple_fn_ty = ty::mk_bare_fn(tcx,
|
let tuple_fn_ty = ty::mk_bare_fn(tcx,
|
||||||
ty::BareFnTy { unsafety: ast::Unsafety::Normal,
|
ty::BareFnTy { unsafety: ast::Unsafety::Normal,
|
||||||
abi: synabi::RustCall,
|
abi: synabi::RustCall,
|
||||||
sig: ty::FnSig {
|
sig: ty::Binder(ty::FnSig {
|
||||||
inputs: vec![bare_fn_ty_ref,
|
inputs: vec![bare_fn_ty_ref,
|
||||||
tuple_input_ty],
|
tuple_input_ty],
|
||||||
output: output_ty,
|
output: output_ty,
|
||||||
variadic: false
|
variadic: false
|
||||||
}});
|
})});
|
||||||
debug!("tuple_fn_ty: {}", tuple_fn_ty.repr(tcx));
|
debug!("tuple_fn_ty: {}", tuple_fn_ty.repr(tcx));
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -421,12 +421,12 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
|
|||||||
let impl_or_trait_item = ty::impl_or_trait_item(tcx, source_id);
|
let impl_or_trait_item = ty::impl_or_trait_item(tcx, source_id);
|
||||||
match impl_or_trait_item {
|
match impl_or_trait_item {
|
||||||
ty::MethodTraitItem(method) => {
|
ty::MethodTraitItem(method) => {
|
||||||
let trait_ref = ty::impl_trait_ref(tcx, impl_id).unwrap();
|
let poly_trait_ref = ty::impl_trait_ref(tcx, impl_id).unwrap();
|
||||||
let trait_ref = ty::erase_late_bound_regions(tcx, &trait_ref);
|
let trait_ref = ty::erase_late_bound_regions(tcx, &*poly_trait_ref);
|
||||||
|
|
||||||
// Compute the first substitution
|
// Compute the first substitution
|
||||||
let first_subst =
|
let first_subst =
|
||||||
ty::make_substs_for_receiver_types(tcx, &trait_ref.value, &*method)
|
ty::make_substs_for_receiver_types(tcx, &trait_ref, &*method)
|
||||||
.erase_regions();
|
.erase_regions();
|
||||||
|
|
||||||
// And compose them
|
// And compose them
|
||||||
@ -435,7 +435,7 @@ pub fn trans_fn_ref_with_substs<'blk, 'tcx>(
|
|||||||
debug!("trans_fn_with_vtables - default method: \
|
debug!("trans_fn_with_vtables - default method: \
|
||||||
substs = {}, trait_subst = {}, \
|
substs = {}, trait_subst = {}, \
|
||||||
first_subst = {}, new_subst = {}",
|
first_subst = {}, new_subst = {}",
|
||||||
substs.repr(tcx), trait_ref.substs().repr(tcx),
|
substs.repr(tcx), trait_ref.substs.repr(tcx),
|
||||||
first_subst.repr(tcx), new_substs.repr(tcx));
|
first_subst.repr(tcx), new_substs.repr(tcx));
|
||||||
|
|
||||||
(true, source_id, new_substs)
|
(true, source_id, new_substs)
|
||||||
@ -657,8 +657,8 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
|
|||||||
let mut bcx = callee.bcx;
|
let mut bcx = callee.bcx;
|
||||||
|
|
||||||
let (abi, ret_ty) = match callee_ty.sty {
|
let (abi, ret_ty) = match callee_ty.sty {
|
||||||
ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
|
ty::ty_bare_fn(ref f) => (f.abi, f.sig.0.output),
|
||||||
ty::ty_closure(ref f) => (f.abi, f.sig.output),
|
ty::ty_closure(ref f) => (f.abi, f.sig.0.output),
|
||||||
_ => panic!("expected bare rust fn or closure in trans_call_inner")
|
_ => panic!("expected bare rust fn or closure in trans_call_inner")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -658,9 +658,9 @@ pub fn get_wrapper_for_bare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
|
|
||||||
let arena = TypedArena::new();
|
let arena = TypedArena::new();
|
||||||
let empty_param_substs = Substs::trans_empty();
|
let empty_param_substs = Substs::trans_empty();
|
||||||
let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, true, f.sig.output,
|
let fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, true, f.sig.0.output,
|
||||||
&empty_param_substs, None, &arena);
|
&empty_param_substs, None, &arena);
|
||||||
let bcx = init_function(&fcx, true, f.sig.output);
|
let bcx = init_function(&fcx, true, f.sig.0.output);
|
||||||
|
|
||||||
let args = create_datums_for_fn_args(&fcx,
|
let args = create_datums_for_fn_args(&fcx,
|
||||||
ty::ty_fn_args(closure_ty)
|
ty::ty_fn_args(closure_ty)
|
||||||
@ -676,7 +676,7 @@ pub fn get_wrapper_for_bare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
llargs.extend(args.iter().map(|arg| arg.val));
|
llargs.extend(args.iter().map(|arg| arg.val));
|
||||||
|
|
||||||
let retval = Call(bcx, fn_ptr, llargs.as_slice(), None);
|
let retval = Call(bcx, fn_ptr, llargs.as_slice(), None);
|
||||||
match f.sig.output {
|
match f.sig.0.output {
|
||||||
ty::FnConverging(output_type) => {
|
ty::FnConverging(output_type) => {
|
||||||
if return_type_is_void(ccx, output_type) || fcx.llretslotptr.get().is_some() {
|
if return_type_is_void(ccx, output_type) || fcx.llretslotptr.get().is_some() {
|
||||||
RetVoid(bcx);
|
RetVoid(bcx);
|
||||||
|
@ -442,7 +442,7 @@ impl<'tcx> TypeMap<'tcx> {
|
|||||||
|
|
||||||
unique_type_id.push_str(" fn(");
|
unique_type_id.push_str(" fn(");
|
||||||
|
|
||||||
for ¶meter_type in sig.inputs.iter() {
|
for ¶meter_type in sig.0.inputs.iter() {
|
||||||
let parameter_type_id =
|
let parameter_type_id =
|
||||||
self.get_unique_type_id_of_type(cx, parameter_type);
|
self.get_unique_type_id_of_type(cx, parameter_type);
|
||||||
let parameter_type_id =
|
let parameter_type_id =
|
||||||
@ -451,12 +451,12 @@ impl<'tcx> TypeMap<'tcx> {
|
|||||||
unique_type_id.push(',');
|
unique_type_id.push(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
if sig.variadic {
|
if sig.0.variadic {
|
||||||
unique_type_id.push_str("...");
|
unique_type_id.push_str("...");
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_type_id.push_str(")->");
|
unique_type_id.push_str(")->");
|
||||||
match sig.output {
|
match sig.0.output {
|
||||||
ty::FnConverging(ret_ty) => {
|
ty::FnConverging(ret_ty) => {
|
||||||
let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
|
let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
|
||||||
let return_type_id = self.get_unique_type_id_as_string(return_type_id);
|
let return_type_id = self.get_unique_type_id_as_string(return_type_id);
|
||||||
@ -575,7 +575,7 @@ impl<'tcx> TypeMap<'tcx> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for ¶meter_type in sig.inputs.iter() {
|
for ¶meter_type in sig.0.inputs.iter() {
|
||||||
let parameter_type_id =
|
let parameter_type_id =
|
||||||
self.get_unique_type_id_of_type(cx, parameter_type);
|
self.get_unique_type_id_of_type(cx, parameter_type);
|
||||||
let parameter_type_id =
|
let parameter_type_id =
|
||||||
@ -584,13 +584,13 @@ impl<'tcx> TypeMap<'tcx> {
|
|||||||
unique_type_id.push(',');
|
unique_type_id.push(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
if sig.variadic {
|
if sig.0.variadic {
|
||||||
unique_type_id.push_str("...");
|
unique_type_id.push_str("...");
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_type_id.push_str("|->");
|
unique_type_id.push_str("|->");
|
||||||
|
|
||||||
match sig.output {
|
match sig.0.output {
|
||||||
ty::FnConverging(ret_ty) => {
|
ty::FnConverging(ret_ty) => {
|
||||||
let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
|
let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
|
||||||
let return_type_id = self.get_unique_type_id_as_string(return_type_id);
|
let return_type_id = self.get_unique_type_id_as_string(return_type_id);
|
||||||
@ -2787,13 +2787,13 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
|
|
||||||
fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
unique_type_id: UniqueTypeId,
|
unique_type_id: UniqueTypeId,
|
||||||
signature: &ty::FnSig<'tcx>,
|
signature: &ty::PolyFnSig<'tcx>,
|
||||||
span: Span)
|
span: Span)
|
||||||
-> MetadataCreationResult {
|
-> MetadataCreationResult {
|
||||||
let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
|
let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.0.inputs.len() + 1);
|
||||||
|
|
||||||
// return type
|
// return type
|
||||||
signature_metadata.push(match signature.output {
|
signature_metadata.push(match signature.0.output {
|
||||||
ty::FnConverging(ret_ty) => match ret_ty.sty {
|
ty::FnConverging(ret_ty) => match ret_ty.sty {
|
||||||
ty::ty_tup(ref tys) if tys.is_empty() => ptr::null_mut(),
|
ty::ty_tup(ref tys) if tys.is_empty() => ptr::null_mut(),
|
||||||
_ => type_metadata(cx, ret_ty, span)
|
_ => type_metadata(cx, ret_ty, span)
|
||||||
@ -2802,7 +2802,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
});
|
});
|
||||||
|
|
||||||
// regular arguments
|
// regular arguments
|
||||||
for &argument_type in signature.inputs.iter() {
|
for &argument_type in signature.0.inputs.iter() {
|
||||||
signature_metadata.push(type_metadata(cx, argument_type, span));
|
signature_metadata.push(type_metadata(cx, argument_type, span));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3781,8 +3781,8 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
|
|
||||||
output.push_str("fn(");
|
output.push_str("fn(");
|
||||||
|
|
||||||
if sig.inputs.len() > 0 {
|
if sig.0.inputs.len() > 0 {
|
||||||
for ¶meter_type in sig.inputs.iter() {
|
for ¶meter_type in sig.0.inputs.iter() {
|
||||||
push_debuginfo_type_name(cx, parameter_type, true, output);
|
push_debuginfo_type_name(cx, parameter_type, true, output);
|
||||||
output.push_str(", ");
|
output.push_str(", ");
|
||||||
}
|
}
|
||||||
@ -3790,8 +3790,8 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
output.pop();
|
output.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if sig.variadic {
|
if sig.0.variadic {
|
||||||
if sig.inputs.len() > 0 {
|
if sig.0.inputs.len() > 0 {
|
||||||
output.push_str(", ...");
|
output.push_str(", ...");
|
||||||
} else {
|
} else {
|
||||||
output.push_str("...");
|
output.push_str("...");
|
||||||
@ -3800,7 +3800,7 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
|
|
||||||
output.push(')');
|
output.push(')');
|
||||||
|
|
||||||
match sig.output {
|
match sig.0.output {
|
||||||
ty::FnConverging(result_type) if ty::type_is_nil(result_type) => {}
|
ty::FnConverging(result_type) if ty::type_is_nil(result_type) => {}
|
||||||
ty::FnConverging(result_type) => {
|
ty::FnConverging(result_type) => {
|
||||||
output.push_str(" -> ");
|
output.push_str(" -> ");
|
||||||
@ -3841,8 +3841,8 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if sig.inputs.len() > 0 {
|
if sig.0.inputs.len() > 0 {
|
||||||
for ¶meter_type in sig.inputs.iter() {
|
for ¶meter_type in sig.0.inputs.iter() {
|
||||||
push_debuginfo_type_name(cx, parameter_type, true, output);
|
push_debuginfo_type_name(cx, parameter_type, true, output);
|
||||||
output.push_str(", ");
|
output.push_str(", ");
|
||||||
}
|
}
|
||||||
@ -3850,8 +3850,8 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
output.pop();
|
output.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if sig.variadic {
|
if sig.0.variadic {
|
||||||
if sig.inputs.len() > 0 {
|
if sig.0.inputs.len() > 0 {
|
||||||
output.push_str(", ...");
|
output.push_str(", ...");
|
||||||
} else {
|
} else {
|
||||||
output.push_str("...");
|
output.push_str("...");
|
||||||
@ -3860,7 +3860,7 @@ fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
|||||||
|
|
||||||
output.push(param_list_closing_char);
|
output.push(param_list_closing_char);
|
||||||
|
|
||||||
match sig.output {
|
match sig.0.output {
|
||||||
ty::FnConverging(result_type) if ty::type_is_nil(result_type) => {}
|
ty::FnConverging(result_type) if ty::type_is_nil(result_type) => {}
|
||||||
ty::FnConverging(result_type) => {
|
ty::FnConverging(result_type) => {
|
||||||
output.push_str(" -> ");
|
output.push_str(" -> ");
|
||||||
|
@ -318,8 +318,8 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||||||
&ty::UnsizeVtable(ty::TyTrait { ref principal, .. }, _) => {
|
&ty::UnsizeVtable(ty::TyTrait { ref principal, .. }, _) => {
|
||||||
let substs = principal.substs().with_self_ty(unadjusted_ty).erase_regions();
|
let substs = principal.substs().with_self_ty(unadjusted_ty).erase_regions();
|
||||||
let trait_ref =
|
let trait_ref =
|
||||||
Rc::new(ty::bind(ty::TraitRef { def_id: principal.def_id(),
|
Rc::new(ty::Binder(ty::TraitRef { def_id: principal.def_id(),
|
||||||
substs: substs }));
|
substs: substs }));
|
||||||
let trait_ref = trait_ref.subst(bcx.tcx(), bcx.fcx.param_substs);
|
let trait_ref = trait_ref.subst(bcx.tcx(), bcx.fcx.param_substs);
|
||||||
let box_ty = mk_ty(unadjusted_ty);
|
let box_ty = mk_ty(unadjusted_ty);
|
||||||
PointerCast(bcx,
|
PointerCast(bcx,
|
||||||
|
@ -22,7 +22,6 @@ use trans::machine;
|
|||||||
use trans::type_::Type;
|
use trans::type_::Type;
|
||||||
use trans::type_of::*;
|
use trans::type_of::*;
|
||||||
use trans::type_of;
|
use trans::type_of;
|
||||||
use middle::ty::FnSig;
|
|
||||||
use middle::ty::{mod, Ty};
|
use middle::ty::{mod, Ty};
|
||||||
use middle::subst::{Subst, Substs};
|
use middle::subst::{Subst, Substs};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
@ -41,7 +40,7 @@ use util::ppaux::Repr;
|
|||||||
|
|
||||||
struct ForeignTypes<'tcx> {
|
struct ForeignTypes<'tcx> {
|
||||||
/// Rust signature of the function
|
/// Rust signature of the function
|
||||||
fn_sig: ty::FnSig<'tcx>,
|
fn_sig: ty::PolyFnSig<'tcx>,
|
||||||
|
|
||||||
/// Adapter object for handling native ABI rules (trust me, you
|
/// Adapter object for handling native ABI rules (trust me, you
|
||||||
/// don't want to know)
|
/// don't want to know)
|
||||||
@ -179,7 +178,7 @@ pub fn register_foreign_item_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
|
|
||||||
// Make sure the calling convention is right for variadic functions
|
// Make sure the calling convention is right for variadic functions
|
||||||
// (should've been caught if not in typeck)
|
// (should've been caught if not in typeck)
|
||||||
if tys.fn_sig.variadic {
|
if tys.fn_sig.0.variadic {
|
||||||
assert!(cc == llvm::CCallConv);
|
assert!(cc == llvm::CCallConv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +385,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||||||
debug!("llforeign_ret_ty={}", ccx.tn().type_to_string(llforeign_ret_ty));
|
debug!("llforeign_ret_ty={}", ccx.tn().type_to_string(llforeign_ret_ty));
|
||||||
|
|
||||||
if llrust_ret_ty == llforeign_ret_ty {
|
if llrust_ret_ty == llforeign_ret_ty {
|
||||||
match fn_sig.output {
|
match fn_sig.0.output {
|
||||||
ty::FnConverging(result_ty) => {
|
ty::FnConverging(result_ty) => {
|
||||||
base::store_ty(bcx, llforeign_retval, llretptr, result_ty)
|
base::store_ty(bcx, llforeign_retval, llretptr, result_ty)
|
||||||
}
|
}
|
||||||
@ -632,7 +631,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Push Rust return pointer, using null if it will be unused.
|
// Push Rust return pointer, using null if it will be unused.
|
||||||
let rust_uses_outptr = match tys.fn_sig.output {
|
let rust_uses_outptr = match tys.fn_sig.0.output {
|
||||||
ty::FnConverging(ret_ty) => type_of::return_uses_outptr(ccx, ret_ty),
|
ty::FnConverging(ret_ty) => type_of::return_uses_outptr(ccx, ret_ty),
|
||||||
ty::FnDiverging => false
|
ty::FnDiverging => false
|
||||||
};
|
};
|
||||||
@ -665,7 +664,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
return_ty={}",
|
return_ty={}",
|
||||||
ccx.tn().val_to_string(slot),
|
ccx.tn().val_to_string(slot),
|
||||||
ccx.tn().type_to_string(llrust_ret_ty),
|
ccx.tn().type_to_string(llrust_ret_ty),
|
||||||
tys.fn_sig.output.repr(tcx));
|
tys.fn_sig.0.output.repr(tcx));
|
||||||
llrust_args.push(slot);
|
llrust_args.push(slot);
|
||||||
return_alloca = Some(slot);
|
return_alloca = Some(slot);
|
||||||
}
|
}
|
||||||
@ -680,8 +679,8 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
// Build up the arguments to the call to the rust function.
|
// Build up the arguments to the call to the rust function.
|
||||||
// Careful to adapt for cases where the native convention uses
|
// Careful to adapt for cases where the native convention uses
|
||||||
// a pointer and Rust does not or vice versa.
|
// a pointer and Rust does not or vice versa.
|
||||||
for i in range(0, tys.fn_sig.inputs.len()) {
|
for i in range(0, tys.fn_sig.0.inputs.len()) {
|
||||||
let rust_ty = tys.fn_sig.inputs[i];
|
let rust_ty = tys.fn_sig.0.inputs[i];
|
||||||
let llrust_ty = tys.llsig.llarg_tys[i];
|
let llrust_ty = tys.llsig.llarg_tys[i];
|
||||||
let rust_indirect = type_of::arg_is_indirect(ccx, rust_ty);
|
let rust_indirect = type_of::arg_is_indirect(ccx, rust_ty);
|
||||||
let llforeign_arg_ty = tys.fn_ty.arg_tys[i];
|
let llforeign_arg_ty = tys.fn_ty.arg_tys[i];
|
||||||
@ -826,10 +825,10 @@ pub fn link_name(i: &ast::ForeignItem) -> InternedString {
|
|||||||
/// because foreign functions just plain ignore modes. They also don't pass aggregate values by
|
/// because foreign functions just plain ignore modes. They also don't pass aggregate values by
|
||||||
/// pointer like we do.
|
/// pointer like we do.
|
||||||
fn foreign_signature<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
fn foreign_signature<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
fn_sig: &ty::FnSig<'tcx>, arg_tys: &[Ty<'tcx>])
|
fn_sig: &ty::PolyFnSig<'tcx>, arg_tys: &[Ty<'tcx>])
|
||||||
-> LlvmSignature {
|
-> LlvmSignature {
|
||||||
let llarg_tys = arg_tys.iter().map(|&arg| arg_type_of(ccx, arg)).collect();
|
let llarg_tys = arg_tys.iter().map(|&arg| arg_type_of(ccx, arg)).collect();
|
||||||
let (llret_ty, ret_def) = match fn_sig.output {
|
let (llret_ty, ret_def) = match fn_sig.0.output {
|
||||||
ty::FnConverging(ret_ty) =>
|
ty::FnConverging(ret_ty) =>
|
||||||
(type_of::arg_type_of(ccx, ret_ty), !return_type_is_void(ccx, ret_ty)),
|
(type_of::arg_type_of(ccx, ret_ty), !return_type_is_void(ccx, ret_ty)),
|
||||||
ty::FnDiverging =>
|
ty::FnDiverging =>
|
||||||
@ -853,7 +852,7 @@ fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
ty::ty_bare_fn(ref fn_ty) => fn_ty.sig.clone(),
|
ty::ty_bare_fn(ref fn_ty) => fn_ty.sig.clone(),
|
||||||
_ => ccx.sess().bug("foreign_types_for_fn_ty called on non-function type")
|
_ => ccx.sess().bug("foreign_types_for_fn_ty called on non-function type")
|
||||||
};
|
};
|
||||||
let llsig = foreign_signature(ccx, &fn_sig, fn_sig.inputs.as_slice());
|
let llsig = foreign_signature(ccx, &fn_sig, fn_sig.0.inputs.as_slice());
|
||||||
let fn_ty = cabi::compute_abi_info(ccx,
|
let fn_ty = cabi::compute_abi_info(ccx,
|
||||||
llsig.llarg_tys.as_slice(),
|
llsig.llarg_tys.as_slice(),
|
||||||
llsig.llret_ty,
|
llsig.llret_ty,
|
||||||
@ -913,7 +912,7 @@ fn lltype_for_fn_from_foreign_types(ccx: &CrateContext, tys: &ForeignTypes) -> T
|
|||||||
llargument_tys.push(llarg_ty);
|
llargument_tys.push(llarg_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if tys.fn_sig.variadic {
|
if tys.fn_sig.0.variadic {
|
||||||
Type::variadic_func(llargument_tys.as_slice(), &llreturn_ty)
|
Type::variadic_func(llargument_tys.as_slice(), &llreturn_ty)
|
||||||
} else {
|
} else {
|
||||||
Type::func(llargument_tys.as_slice(), &llreturn_ty)
|
Type::func(llargument_tys.as_slice(), &llreturn_ty)
|
||||||
|
@ -227,8 +227,8 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||||||
let fty = ty::lookup_item_type(bcx.tcx(), dtor_did).ty.subst(bcx.tcx(), substs);
|
let fty = ty::lookup_item_type(bcx.tcx(), dtor_did).ty.subst(bcx.tcx(), substs);
|
||||||
let self_ty = match fty.sty {
|
let self_ty = match fty.sty {
|
||||||
ty::ty_bare_fn(ref f) => {
|
ty::ty_bare_fn(ref f) => {
|
||||||
assert!(f.sig.inputs.len() == 1);
|
assert!(f.sig.0.inputs.len() == 1);
|
||||||
f.sig.inputs[0]
|
f.sig.0.inputs[0]
|
||||||
}
|
}
|
||||||
_ => bcx.sess().bug(format!("Expected function type, found {}",
|
_ => bcx.sess().bug(format!("Expected function type, found {}",
|
||||||
bcx.ty_to_string(fty)).as_slice())
|
bcx.ty_to_string(fty)).as_slice())
|
||||||
|
@ -150,7 +150,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
|||||||
let tcx = bcx.tcx();
|
let tcx = bcx.tcx();
|
||||||
|
|
||||||
let ret_ty = match callee_ty.sty {
|
let ret_ty = match callee_ty.sty {
|
||||||
ty::ty_bare_fn(ref f) => f.sig.output,
|
ty::ty_bare_fn(ref f) => f.sig.0.output,
|
||||||
_ => panic!("expected bare_fn in trans_intrinsic_call")
|
_ => panic!("expected bare_fn in trans_intrinsic_call")
|
||||||
};
|
};
|
||||||
let foreign_item = tcx.map.expect_foreign_item(node);
|
let foreign_item = tcx.map.expect_foreign_item(node);
|
||||||
|
@ -239,8 +239,8 @@ pub fn trans_static_method_callee(bcx: Block,
|
|||||||
rcvr_assoc,
|
rcvr_assoc,
|
||||||
Vec::new()));
|
Vec::new()));
|
||||||
debug!("trait_substs={}", trait_substs.repr(bcx.tcx()));
|
debug!("trait_substs={}", trait_substs.repr(bcx.tcx()));
|
||||||
let trait_ref = Rc::new(ty::bind(ty::TraitRef { def_id: trait_id,
|
let trait_ref = Rc::new(ty::Binder(ty::TraitRef { def_id: trait_id,
|
||||||
substs: trait_substs }));
|
substs: trait_substs }));
|
||||||
let vtbl = fulfill_obligation(bcx.ccx(),
|
let vtbl = fulfill_obligation(bcx.ccx(),
|
||||||
DUMMY_SP,
|
DUMMY_SP,
|
||||||
trait_ref);
|
trait_ref);
|
||||||
@ -480,8 +480,8 @@ pub fn trans_trait_callee_from_llval<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||||||
ty::ty_bare_fn(ref f) if f.abi == Rust || f.abi == RustCall => {
|
ty::ty_bare_fn(ref f) if f.abi == Rust || f.abi == RustCall => {
|
||||||
type_of_rust_fn(ccx,
|
type_of_rust_fn(ccx,
|
||||||
Some(Type::i8p(ccx)),
|
Some(Type::i8p(ccx)),
|
||||||
f.sig.inputs.slice_from(1),
|
f.sig.0.inputs.slice_from(1),
|
||||||
f.sig.output,
|
f.sig.0.output,
|
||||||
f.abi)
|
f.abi)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -146,16 +146,16 @@ pub fn type_of_fn_from_ty<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, fty: Ty<'tcx>)
|
|||||||
ty::ty_closure(ref f) => {
|
ty::ty_closure(ref f) => {
|
||||||
type_of_rust_fn(cx,
|
type_of_rust_fn(cx,
|
||||||
Some(Type::i8p(cx)),
|
Some(Type::i8p(cx)),
|
||||||
f.sig.inputs.as_slice(),
|
f.sig.0.inputs.as_slice(),
|
||||||
f.sig.output,
|
f.sig.0.output,
|
||||||
f.abi)
|
f.abi)
|
||||||
}
|
}
|
||||||
ty::ty_bare_fn(ref f) => {
|
ty::ty_bare_fn(ref f) => {
|
||||||
if f.abi == abi::Rust || f.abi == abi::RustCall {
|
if f.abi == abi::Rust || f.abi == abi::RustCall {
|
||||||
type_of_rust_fn(cx,
|
type_of_rust_fn(cx,
|
||||||
None,
|
None,
|
||||||
f.sig.inputs.as_slice(),
|
f.sig.0.inputs.as_slice(),
|
||||||
f.sig.output,
|
f.sig.0.output,
|
||||||
f.abi)
|
f.abi)
|
||||||
} else {
|
} else {
|
||||||
foreign::lltype_for_foreign_fn(cx, fty)
|
foreign::lltype_for_foreign_fn(cx, fty)
|
||||||
|
@ -535,7 +535,7 @@ pub fn instantiate_poly_trait_ref<'tcx,AC,RS>(
|
|||||||
{
|
{
|
||||||
let trait_ref = instantiate_trait_ref(this, rscope, &ast_trait_ref.trait_ref, self_ty, allow_eq);
|
let trait_ref = instantiate_trait_ref(this, rscope, &ast_trait_ref.trait_ref, self_ty, allow_eq);
|
||||||
let trait_ref = (*trait_ref).clone();
|
let trait_ref = (*trait_ref).clone();
|
||||||
Rc::new(ty::bind(trait_ref)) // Ugh.
|
Rc::new(ty::Binder(trait_ref)) // Ugh.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instantiates the path for the given trait reference, assuming that it's
|
/// Instantiates the path for the given trait reference, assuming that it's
|
||||||
@ -778,12 +778,12 @@ fn ast_ty_to_trait_ref<'tcx,AC,RS>(this: &AC,
|
|||||||
ast::TyPath(ref path, id) => {
|
ast::TyPath(ref path, id) => {
|
||||||
match this.tcx().def_map.borrow().get(&id) {
|
match this.tcx().def_map.borrow().get(&id) {
|
||||||
Some(&def::DefTrait(trait_def_id)) => {
|
Some(&def::DefTrait(trait_def_id)) => {
|
||||||
return Ok(ty::bind(ast_path_to_trait_ref(this,
|
return Ok(ty::Binder(ast_path_to_trait_ref(this,
|
||||||
rscope,
|
rscope,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
None,
|
None,
|
||||||
path,
|
path,
|
||||||
AllowEqConstraints::Allow)));
|
AllowEqConstraints::Allow)));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
span_err!(this.tcx().sess, ty.span, E0172, "expected a reference to a trait");
|
span_err!(this.tcx().sess, ty.span, E0172, "expected a reference to a trait");
|
||||||
@ -993,12 +993,12 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||||||
def::DefTrait(trait_def_id) => {
|
def::DefTrait(trait_def_id) => {
|
||||||
// N.B. this case overlaps somewhat with
|
// N.B. this case overlaps somewhat with
|
||||||
// TyObjectSum, see that fn for details
|
// TyObjectSum, see that fn for details
|
||||||
let result = ty::bind(ast_path_to_trait_ref(this,
|
let result = ty::Binder(ast_path_to_trait_ref(this,
|
||||||
rscope,
|
rscope,
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
None,
|
None,
|
||||||
path,
|
path,
|
||||||
AllowEqConstraints::Allow));
|
AllowEqConstraints::Allow));
|
||||||
trait_ref_to_object_type(this, rscope, path.span, result, &[])
|
trait_ref_to_object_type(this, rscope, path.span, result, &[])
|
||||||
}
|
}
|
||||||
def::DefTy(did, _) | def::DefStruct(did) => {
|
def::DefTy(did, _) | def::DefStruct(did) => {
|
||||||
@ -1050,7 +1050,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
|
|||||||
let ty_param_defs = tcx.ty_param_defs.borrow();
|
let ty_param_defs = tcx.ty_param_defs.borrow();
|
||||||
let tp_def = &(*ty_param_defs)[did.node];
|
let tp_def = &(*ty_param_defs)[did.node];
|
||||||
let assoc_tys = tp_def.bounds.trait_bounds.iter()
|
let assoc_tys = tp_def.bounds.trait_bounds.iter()
|
||||||
.filter_map(|b| find_assoc_ty(this, &b.value, assoc_ident))
|
.filter_map(|b| find_assoc_ty(this, &b.0, assoc_ident))
|
||||||
.collect();
|
.collect();
|
||||||
(assoc_tys, token::get_name(tp_def.name).to_string())
|
(assoc_tys, token::get_name(tp_def.name).to_string())
|
||||||
}
|
}
|
||||||
@ -1278,11 +1278,11 @@ fn ty_of_method_or_bare_fn<'a, 'tcx, AC: AstConv<'tcx>>(
|
|||||||
(ty::BareFnTy {
|
(ty::BareFnTy {
|
||||||
unsafety: unsafety,
|
unsafety: unsafety,
|
||||||
abi: abi,
|
abi: abi,
|
||||||
sig: ty::FnSig {
|
sig: ty::Binder(ty::FnSig {
|
||||||
inputs: self_and_input_tys,
|
inputs: self_and_input_tys,
|
||||||
output: output_ty,
|
output: output_ty,
|
||||||
variadic: decl.variadic
|
variadic: decl.variadic
|
||||||
}
|
}),
|
||||||
}, explicit_self_category_result)
|
}, explicit_self_category_result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1420,9 +1420,9 @@ pub fn ty_of_closure<'tcx, AC: AstConv<'tcx>>(
|
|||||||
store: store,
|
store: store,
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
abi: abi,
|
abi: abi,
|
||||||
sig: ty::FnSig {inputs: input_tys,
|
sig: ty::Binder(ty::FnSig {inputs: input_tys,
|
||||||
output: output_ty,
|
output: output_ty,
|
||||||
variadic: decl.variadic}
|
variadic: decl.variadic}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
|||||||
|
|
||||||
// Tuple up the arguments and insert the resulting function type into
|
// Tuple up the arguments and insert the resulting function type into
|
||||||
// the `unboxed_closures` table.
|
// the `unboxed_closures` table.
|
||||||
fn_ty.sig.inputs = vec![ty::mk_tup(fcx.tcx(), fn_ty.sig.inputs)];
|
fn_ty.sig.0.inputs = vec![ty::mk_tup(fcx.tcx(), fn_ty.sig.0.inputs)];
|
||||||
|
|
||||||
debug!("unboxed_closure for {} --> sig={} kind={}",
|
debug!("unboxed_closure for {} --> sig={} kind={}",
|
||||||
expr_def_id.repr(fcx.tcx()),
|
expr_def_id.repr(fcx.tcx()),
|
||||||
|
@ -16,9 +16,9 @@ use middle::traits;
|
|||||||
use middle::ty::{mod, Ty};
|
use middle::ty::{mod, Ty};
|
||||||
use middle::ty::{MethodCall, MethodCallee, MethodObject, MethodOrigin,
|
use middle::ty::{MethodCall, MethodCallee, MethodObject, MethodOrigin,
|
||||||
MethodParam, MethodStatic, MethodTraitObject, MethodTypeParam};
|
MethodParam, MethodStatic, MethodTraitObject, MethodTypeParam};
|
||||||
|
use middle::ty_fold::TypeFoldable;
|
||||||
use middle::infer;
|
use middle::infer;
|
||||||
use middle::infer::InferCtxt;
|
use middle::infer::InferCtxt;
|
||||||
use middle::ty_fold::HigherRankedFoldable;
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -114,7 +114,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||||||
|
|
||||||
// Create the final `MethodCallee`.
|
// Create the final `MethodCallee`.
|
||||||
let fty = ty::mk_bare_fn(self.tcx(), ty::BareFnTy {
|
let fty = ty::mk_bare_fn(self.tcx(), ty::BareFnTy {
|
||||||
sig: method_sig,
|
sig: ty::Binder(method_sig),
|
||||||
unsafety: pick.method_ty.fty.unsafety,
|
unsafety: pick.method_ty.fty.unsafety,
|
||||||
abi: pick.method_ty.fty.abi.clone(),
|
abi: pick.method_ty.fty.abi.clone(),
|
||||||
});
|
});
|
||||||
@ -272,7 +272,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||||||
&trait_def.generics,
|
&trait_def.generics,
|
||||||
self.infcx().next_ty_var());
|
self.infcx().next_ty_var());
|
||||||
|
|
||||||
let trait_ref = Rc::new(ty::bind(ty::TraitRef::new(trait_def_id, substs.clone())));
|
let trait_ref =
|
||||||
|
Rc::new(ty::Binder(ty::TraitRef::new(trait_def_id, substs.clone())));
|
||||||
let origin = MethodTypeParam(MethodParam { trait_ref: trait_ref,
|
let origin = MethodTypeParam(MethodParam { trait_ref: trait_ref,
|
||||||
method_num: method_num });
|
method_num: method_num });
|
||||||
(substs, origin)
|
(substs, origin)
|
||||||
@ -388,9 +389,9 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||||||
// The binder level here corresponds to the impl.
|
// The binder level here corresponds to the impl.
|
||||||
let (all_substs, (method_sig, method_generics)) =
|
let (all_substs, (method_sig, method_generics)) =
|
||||||
self.replace_late_bound_regions_with_fresh_var(
|
self.replace_late_bound_regions_with_fresh_var(
|
||||||
&ty::bind((all_substs,
|
&ty::Binder((all_substs,
|
||||||
(pick.method_ty.fty.sig.clone(),
|
(pick.method_ty.fty.sig.clone(),
|
||||||
pick.method_ty.generics.clone())))).value;
|
pick.method_ty.generics.clone()))));
|
||||||
|
|
||||||
debug!("late-bound lifetimes from impl instantiated, \
|
debug!("late-bound lifetimes from impl instantiated, \
|
||||||
all_substs={} method_sig={} method_generics={}",
|
all_substs={} method_sig={} method_generics={}",
|
||||||
@ -481,7 +482,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
match sig.inputs[0].sty {
|
match sig.0.inputs[0].sty {
|
||||||
ty::ty_rptr(_, ty::mt {
|
ty::ty_rptr(_, ty::mt {
|
||||||
ty: _,
|
ty: _,
|
||||||
mutbl: ast::MutMutable,
|
mutbl: ast::MutMutable,
|
||||||
@ -654,8 +655,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||||||
target_trait_def_id.repr(self.tcx()))[]);
|
target_trait_def_id.repr(self.tcx()))[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_late_bound_regions_with_fresh_var<T>(&self, value: &T) -> T
|
fn replace_late_bound_regions_with_fresh_var<T>(&self, value: &ty::Binder<T>) -> T
|
||||||
where T : HigherRankedFoldable<'tcx>
|
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||||
{
|
{
|
||||||
self.infcx().replace_late_bound_regions_with_fresh_var(
|
self.infcx().replace_late_bound_regions_with_fresh_var(
|
||||||
self.span, infer::FnCall, value).0
|
self.span, infer::FnCall, value).0
|
||||||
|
@ -166,7 +166,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
|
|||||||
|
|
||||||
// Construct a trait-reference `self_ty : Trait<input_tys>`
|
// Construct a trait-reference `self_ty : Trait<input_tys>`
|
||||||
let substs = subst::Substs::new_trait(input_types, Vec::new(), assoc_types, self_ty);
|
let substs = subst::Substs::new_trait(input_types, Vec::new(), assoc_types, self_ty);
|
||||||
let trait_ref = Rc::new(ty::bind(ty::TraitRef::new(trait_def_id, substs)));
|
let trait_ref = Rc::new(ty::Binder(ty::TraitRef::new(trait_def_id, substs)));
|
||||||
|
|
||||||
// Construct an obligation
|
// Construct an obligation
|
||||||
let obligation = traits::Obligation::misc(span,
|
let obligation = traits::Obligation::misc(span,
|
||||||
@ -204,7 +204,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
|
|||||||
&fn_sig).0;
|
&fn_sig).0;
|
||||||
let transformed_self_ty = fn_sig.inputs[0];
|
let transformed_self_ty = fn_sig.inputs[0];
|
||||||
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
||||||
sig: fn_sig,
|
sig: ty::Binder(fn_sig),
|
||||||
unsafety: bare_fn_ty.unsafety,
|
unsafety: bare_fn_ty.unsafety,
|
||||||
abi: bare_fn_ty.abi.clone(),
|
abi: bare_fn_ty.abi.clone(),
|
||||||
});
|
});
|
||||||
|
@ -20,7 +20,7 @@ use middle::subst::Subst;
|
|||||||
use middle::traits;
|
use middle::traits;
|
||||||
use middle::ty::{mod, Ty};
|
use middle::ty::{mod, Ty};
|
||||||
use middle::ty::{MethodObject};
|
use middle::ty::{MethodObject};
|
||||||
use middle::ty_fold::HigherRankedFoldable;
|
use middle::ty_fold::TypeFoldable;
|
||||||
use middle::infer;
|
use middle::infer;
|
||||||
use middle::infer::InferCtxt;
|
use middle::infer::InferCtxt;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
@ -308,8 +308,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||||||
let vtable_index =
|
let vtable_index =
|
||||||
get_method_index(tcx, &*new_trait_ref, trait_ref.clone(), method_num);
|
get_method_index(tcx, &*new_trait_ref, trait_ref.clone(), method_num);
|
||||||
|
|
||||||
let xform_self_ty =
|
let xform_self_ty = this.xform_self_ty(&m, new_trait_ref.substs());
|
||||||
this.xform_self_ty(&m, new_trait_ref.substs());
|
|
||||||
|
|
||||||
this.inherent_candidates.push(Candidate {
|
this.inherent_candidates.push(Candidate {
|
||||||
xform_self_ty: xform_self_ty,
|
xform_self_ty: xform_self_ty,
|
||||||
@ -772,7 +771,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||||||
|
|
||||||
// Erase any late-bound regions bound in the impl
|
// Erase any late-bound regions bound in the impl
|
||||||
// which appear in the bounds.
|
// which appear in the bounds.
|
||||||
let impl_bounds = self.erase_late_bound_regions(&ty::bind(impl_bounds)).value;
|
let impl_bounds = self.erase_late_bound_regions(&ty::Binder(impl_bounds));
|
||||||
|
|
||||||
// Convert the bounds into obligations.
|
// Convert the bounds into obligations.
|
||||||
let obligations =
|
let obligations =
|
||||||
@ -874,9 +873,10 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||||||
fn xform_self_ty(&self,
|
fn xform_self_ty(&self,
|
||||||
method: &Rc<ty::Method<'tcx>>,
|
method: &Rc<ty::Method<'tcx>>,
|
||||||
substs: &subst::Substs<'tcx>)
|
substs: &subst::Substs<'tcx>)
|
||||||
-> Ty<'tcx> {
|
-> Ty<'tcx>
|
||||||
|
{
|
||||||
debug!("xform_self_ty(self_ty={}, substs={})",
|
debug!("xform_self_ty(self_ty={}, substs={})",
|
||||||
method.fty.sig.inputs[0].repr(self.tcx()),
|
method.fty.sig.0.inputs[0].repr(self.tcx()),
|
||||||
substs.repr(self.tcx()));
|
substs.repr(self.tcx()));
|
||||||
|
|
||||||
// It is possible for type parameters or early-bound lifetimes
|
// It is possible for type parameters or early-bound lifetimes
|
||||||
@ -909,15 +909,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replace early-bound regions and types.
|
// Replace early-bound regions and types.
|
||||||
let xform_self_ty = method.fty.sig.inputs[0].subst(self.tcx(), substs);
|
let xform_self_ty = method.fty.sig.0.inputs[0].subst(self.tcx(), substs);
|
||||||
|
|
||||||
// Replace late-bound regions bound in the impl or
|
// Replace late-bound regions bound in the impl or
|
||||||
// where-clause (2 levels of binding).
|
// where-clause (2 levels of binding) and method (1 level of binding).
|
||||||
let xform_self_ty =
|
self.erase_late_bound_regions(
|
||||||
self.erase_late_bound_regions(&ty::bind(ty::bind(xform_self_ty))).value.value;
|
&self.erase_late_bound_regions(
|
||||||
|
&ty::Binder(ty::Binder(xform_self_ty))))
|
||||||
// Replace late-bound regions bound in the method (1 level of binding).
|
|
||||||
self.erase_late_bound_regions(&ty::bind(xform_self_ty)).value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn impl_substs(&self,
|
fn impl_substs(&self,
|
||||||
@ -955,8 +953,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
|||||||
/// region got replaced with the same variable, which requires a bit more coordination
|
/// region got replaced with the same variable, which requires a bit more coordination
|
||||||
/// and/or tracking the substitution and
|
/// and/or tracking the substitution and
|
||||||
/// so forth.
|
/// so forth.
|
||||||
fn erase_late_bound_regions<T>(&self, value: &T) -> T
|
fn erase_late_bound_regions<T>(&self, value: &ty::Binder<T>) -> T
|
||||||
where T : HigherRankedFoldable<'tcx>
|
where T : TypeFoldable<'tcx> + Repr<'tcx>
|
||||||
{
|
{
|
||||||
ty::erase_late_bound_regions(self.tcx(), value)
|
ty::erase_late_bound_regions(self.tcx(), value)
|
||||||
}
|
}
|
||||||
|
@ -506,7 +506,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for GatherLocalsVisitor<'a, 'tcx> {
|
|||||||
fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
|
fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
|
||||||
unsafety: ast::Unsafety,
|
unsafety: ast::Unsafety,
|
||||||
unsafety_id: ast::NodeId,
|
unsafety_id: ast::NodeId,
|
||||||
fn_sig: &ty::FnSig<'tcx>,
|
fn_sig: &ty::PolyFnSig<'tcx>,
|
||||||
decl: &ast::FnDecl,
|
decl: &ast::FnDecl,
|
||||||
fn_id: ast::NodeId,
|
fn_id: ast::NodeId,
|
||||||
body: &ast::Block,
|
body: &ast::Block,
|
||||||
@ -723,7 +723,7 @@ fn check_method_body<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
|
|
||||||
let body_id = method.pe_body().id;
|
let body_id = method.pe_body().id;
|
||||||
let fty = liberate_late_bound_regions(
|
let fty = liberate_late_bound_regions(
|
||||||
ccx.tcx, CodeExtent::from_node_id(body_id), &ty::bind(fty)).value;
|
ccx.tcx, CodeExtent::from_node_id(body_id), &ty::Binder(fty));
|
||||||
debug!("fty (liberated): {}", fty.repr(ccx.tcx));
|
debug!("fty (liberated): {}", fty.repr(ccx.tcx));
|
||||||
|
|
||||||
check_bare_fn(ccx,
|
check_bare_fn(ccx,
|
||||||
@ -924,7 +924,7 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||||||
|
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
let infcx = infer::new_infer_ctxt(tcx);
|
||||||
|
|
||||||
let trait_to_impl_substs = impl_trait_ref.substs();
|
let trait_to_impl_substs = impl_trait_ref.substs;
|
||||||
|
|
||||||
// Try to give more informative error messages about self typing
|
// Try to give more informative error messages about self typing
|
||||||
// mismatches. Note that any mismatch will also be detected
|
// mismatches. Note that any mismatch will also be detected
|
||||||
@ -975,15 +975,15 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if impl_m.fty.sig.inputs.len() != trait_m.fty.sig.inputs.len() {
|
if impl_m.fty.sig.0.inputs.len() != trait_m.fty.sig.0.inputs.len() {
|
||||||
span_err!(tcx.sess, impl_m_span, E0050,
|
span_err!(tcx.sess, impl_m_span, E0050,
|
||||||
"method `{}` has {} parameter{} \
|
"method `{}` has {} parameter{} \
|
||||||
but the declaration in trait `{}` has {}",
|
but the declaration in trait `{}` has {}",
|
||||||
token::get_name(trait_m.name),
|
token::get_name(trait_m.name),
|
||||||
impl_m.fty.sig.inputs.len(),
|
impl_m.fty.sig.0.inputs.len(),
|
||||||
if impl_m.fty.sig.inputs.len() == 1 {""} else {"s"},
|
if impl_m.fty.sig.0.inputs.len() == 1 {""} else {"s"},
|
||||||
ty::item_path_str(tcx, trait_m.def_id),
|
ty::item_path_str(tcx, trait_m.def_id),
|
||||||
trait_m.fty.sig.inputs.len());
|
trait_m.fty.sig.0.inputs.len());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1085,7 +1085,7 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||||||
// `Bound<&'a T>`, the lifetime `'a` will be late-bound with a
|
// `Bound<&'a T>`, the lifetime `'a` will be late-bound with a
|
||||||
// depth of 3 (it is nested within 3 binders: the impl, method,
|
// depth of 3 (it is nested within 3 binders: the impl, method,
|
||||||
// and trait-ref itself). So when we do the liberation, we have
|
// and trait-ref itself). So when we do the liberation, we have
|
||||||
// two introduce two `ty::bind` scopes, one for the impl and one
|
// two introduce two `ty::Binder` scopes, one for the impl and one
|
||||||
// the method.
|
// the method.
|
||||||
//
|
//
|
||||||
// The only late-bounded regions that can possibly appear here are
|
// The only late-bounded regions that can possibly appear here are
|
||||||
@ -1103,7 +1103,7 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||||||
liberate_late_bound_regions(
|
liberate_late_bound_regions(
|
||||||
tcx,
|
tcx,
|
||||||
impl_m_body_scope,
|
impl_m_body_scope,
|
||||||
&ty::bind(ty::bind(impl_param_def.bounds.clone()))).value.value);
|
&ty::Binder(ty::Binder(impl_param_def.bounds.clone()))).0);
|
||||||
for (i, (trait_param_bounds, impl_param_bounds)) in
|
for (i, (trait_param_bounds, impl_param_bounds)) in
|
||||||
trait_bounds.zip(impl_bounds).enumerate()
|
trait_bounds.zip(impl_bounds).enumerate()
|
||||||
{
|
{
|
||||||
@ -1169,7 +1169,7 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||||||
let impl_fty = ty::mk_bare_fn(tcx, impl_m.fty.clone());
|
let impl_fty = ty::mk_bare_fn(tcx, impl_m.fty.clone());
|
||||||
let impl_fty = impl_fty.subst(tcx, &impl_to_skol_substs);
|
let impl_fty = impl_fty.subst(tcx, &impl_to_skol_substs);
|
||||||
let impl_fty = liberate_late_bound_regions(
|
let impl_fty = liberate_late_bound_regions(
|
||||||
tcx, impl_m_body_scope, &ty::bind(impl_fty)).value;
|
tcx, impl_m_body_scope, &ty::Binder(impl_fty));
|
||||||
let trait_fty = ty::mk_bare_fn(tcx, trait_m.fty.clone());
|
let trait_fty = ty::mk_bare_fn(tcx, trait_m.fty.clone());
|
||||||
let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs);
|
let trait_fty = trait_fty.subst(tcx, &trait_to_skol_substs);
|
||||||
|
|
||||||
@ -1289,7 +1289,7 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||||||
// impl, and the method.
|
// impl, and the method.
|
||||||
let impl_bounds =
|
let impl_bounds =
|
||||||
ty::liberate_late_bound_regions(
|
ty::liberate_late_bound_regions(
|
||||||
tcx, impl_m_body_scope, &ty::bind(ty::bind(impl_bounds))).value.value;
|
tcx, impl_m_body_scope, &ty::Binder(ty::Binder(impl_bounds))).0;
|
||||||
|
|
||||||
debug!("check_region_bounds_on_impl_method: \
|
debug!("check_region_bounds_on_impl_method: \
|
||||||
trait_param={} \
|
trait_param={} \
|
||||||
@ -2546,13 +2546,13 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||||||
// HACK(eddyb) ignore self in the definition (see above).
|
// HACK(eddyb) ignore self in the definition (see above).
|
||||||
check_argument_types(fcx,
|
check_argument_types(fcx,
|
||||||
sp,
|
sp,
|
||||||
fty.sig.inputs.slice_from(1),
|
fty.sig.0.inputs.slice_from(1),
|
||||||
callee_expr,
|
callee_expr,
|
||||||
args_no_rcvr,
|
args_no_rcvr,
|
||||||
autoref_args,
|
autoref_args,
|
||||||
fty.sig.variadic,
|
fty.sig.0.variadic,
|
||||||
tuple_arguments);
|
tuple_arguments);
|
||||||
fty.sig.output
|
fty.sig.0.output
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
fcx.tcx().sess.span_bug(callee_expr.span,
|
fcx.tcx().sess.span_bug(callee_expr.span,
|
||||||
@ -2966,11 +2966,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
|||||||
// This is the "default" function signature, used in case of error.
|
// This is the "default" function signature, used in case of error.
|
||||||
// In that case, we check each argument against "error" in order to
|
// In that case, we check each argument against "error" in order to
|
||||||
// set up all the node type bindings.
|
// set up all the node type bindings.
|
||||||
let error_fn_sig = FnSig {
|
let error_fn_sig = ty::Binder(FnSig {
|
||||||
inputs: err_args(args.len()),
|
inputs: err_args(args.len()),
|
||||||
output: ty::FnConverging(ty::mk_err()),
|
output: ty::FnConverging(ty::mk_err()),
|
||||||
variadic: false
|
variadic: false
|
||||||
};
|
});
|
||||||
|
|
||||||
let fn_sig = match *fn_sty {
|
let fn_sig = match *fn_sty {
|
||||||
ty::ty_bare_fn(ty::BareFnTy {ref sig, ..}) |
|
ty::ty_bare_fn(ty::BareFnTy {ref sig, ..}) |
|
||||||
@ -5070,7 +5070,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||||||
fcx.infcx().replace_late_bound_regions_with_fresh_var(
|
fcx.infcx().replace_late_bound_regions_with_fresh_var(
|
||||||
span,
|
span,
|
||||||
infer::FnCall,
|
infer::FnCall,
|
||||||
&ty::bind((polytype.ty, bounds))).0.value;
|
&ty::Binder((polytype.ty, bounds))).0;
|
||||||
|
|
||||||
debug!("after late-bounds have been replaced: ty_late_bound={}", ty_late_bound.repr(fcx.tcx()));
|
debug!("after late-bounds have been replaced: ty_late_bound={}", ty_late_bound.repr(fcx.tcx()));
|
||||||
debug!("after late-bounds have been replaced: bounds={}", bounds.repr(fcx.tcx()));
|
debug!("after late-bounds have been replaced: bounds={}", bounds.repr(fcx.tcx()));
|
||||||
@ -5686,11 +5686,11 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
|
|||||||
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
||||||
unsafety: ast::Unsafety::Unsafe,
|
unsafety: ast::Unsafety::Unsafe,
|
||||||
abi: abi::RustIntrinsic,
|
abi: abi::RustIntrinsic,
|
||||||
sig: FnSig {
|
sig: ty::Binder(FnSig {
|
||||||
inputs: inputs,
|
inputs: inputs,
|
||||||
output: output,
|
output: output,
|
||||||
variadic: false,
|
variadic: false,
|
||||||
}
|
}),
|
||||||
});
|
});
|
||||||
let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));
|
let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));
|
||||||
let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
|
let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
|
||||||
|
@ -1181,7 +1181,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
|
|||||||
// Treat overloaded autoderefs as if an AutoRef adjustment
|
// Treat overloaded autoderefs as if an AutoRef adjustment
|
||||||
// was applied on the base type, as that is always the case.
|
// was applied on the base type, as that is always the case.
|
||||||
let fn_sig = ty::ty_fn_sig(method.ty);
|
let fn_sig = ty::ty_fn_sig(method.ty);
|
||||||
let self_ty = fn_sig.inputs[0];
|
let self_ty = fn_sig.0.inputs[0];
|
||||||
let (m, r) = match self_ty.sty {
|
let (m, r) = match self_ty.sty {
|
||||||
ty::ty_rptr(r, ref m) => (m.mutbl, r),
|
ty::ty_rptr(r, ref m) => (m.mutbl, r),
|
||||||
_ => rcx.tcx().sess.span_bug(deref_expr.span,
|
_ => rcx.tcx().sess.span_bug(deref_expr.span,
|
||||||
@ -1198,7 +1198,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
|
|||||||
// Specialized version of constrain_call.
|
// Specialized version of constrain_call.
|
||||||
type_must_outlive(rcx, infer::CallRcvr(deref_expr.span),
|
type_must_outlive(rcx, infer::CallRcvr(deref_expr.span),
|
||||||
self_ty, r_deref_expr);
|
self_ty, r_deref_expr);
|
||||||
match fn_sig.output {
|
match fn_sig.0.output {
|
||||||
ty::FnConverging(return_type) => {
|
ty::FnConverging(return_type) => {
|
||||||
type_must_outlive(rcx, infer::CallReturn(deref_expr.span),
|
type_must_outlive(rcx, infer::CallReturn(deref_expr.span),
|
||||||
return_type, r_deref_expr);
|
return_type, r_deref_expr);
|
||||||
|
@ -207,12 +207,12 @@ fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let ref sig = method.fty.sig;
|
let ref sig = method.fty.sig;
|
||||||
for &input_ty in sig.inputs[1..].iter() {
|
for &input_ty in sig.0.inputs[1..].iter() {
|
||||||
if let Some(msg) = check_for_self_ty(input_ty) {
|
if let Some(msg) = check_for_self_ty(input_ty) {
|
||||||
msgs.push(msg);
|
msgs.push(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let ty::FnConverging(result_type) = sig.output {
|
if let ty::FnConverging(result_type) = sig.0.output {
|
||||||
if let Some(msg) = check_for_self_ty(result_type) {
|
if let Some(msg) = check_for_self_ty(result_type) {
|
||||||
msgs.push(msg);
|
msgs.push(msg);
|
||||||
}
|
}
|
||||||
|
@ -170,8 +170,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
|||||||
// liberated.
|
// liberated.
|
||||||
let self_ty = ty::node_id_to_type(fcx.tcx(), item.id);
|
let self_ty = ty::node_id_to_type(fcx.tcx(), item.id);
|
||||||
let self_ty = self_ty.subst(fcx.tcx(), &fcx.inh.param_env.free_substs);
|
let self_ty = self_ty.subst(fcx.tcx(), &fcx.inh.param_env.free_substs);
|
||||||
let self_ty = liberate_late_bound_regions(
|
let self_ty = liberate_late_bound_regions(fcx.tcx(), item_scope, &ty::Binder(self_ty));
|
||||||
fcx.tcx(), item_scope, &ty::bind(self_ty)).value;
|
|
||||||
|
|
||||||
bounds_checker.check_traits_in_ty(self_ty);
|
bounds_checker.check_traits_in_ty(self_ty);
|
||||||
|
|
||||||
@ -186,7 +185,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
|||||||
|
|
||||||
// There are special rules that apply to drop.
|
// There are special rules that apply to drop.
|
||||||
if
|
if
|
||||||
fcx.tcx().lang_items.drop_trait() == Some(trait_ref.def_id()) &&
|
fcx.tcx().lang_items.drop_trait() == Some(trait_ref.def_id) &&
|
||||||
!attr::contains_name(item.attrs.as_slice(), "unsafe_destructor")
|
!attr::contains_name(item.attrs.as_slice(), "unsafe_destructor")
|
||||||
{
|
{
|
||||||
match self_ty.sty {
|
match self_ty.sty {
|
||||||
@ -200,7 +199,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if fcx.tcx().lang_items.copy_trait() == Some(trait_ref.def_id()) {
|
if fcx.tcx().lang_items.copy_trait() == Some(trait_ref.def_id) {
|
||||||
// This is checked in coherence.
|
// This is checked in coherence.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -219,10 +218,11 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
|||||||
traits::ObligationCause::new(
|
traits::ObligationCause::new(
|
||||||
item.span,
|
item.span,
|
||||||
fcx.body_id,
|
fcx.body_id,
|
||||||
traits::ItemObligation(trait_ref.def_id()));
|
traits::ItemObligation(trait_ref.def_id));
|
||||||
|
|
||||||
// Find the supertrait bounds. This will add `int:Bar`.
|
// Find the supertrait bounds. This will add `int:Bar`.
|
||||||
let predicates = ty::predicates_for_trait_ref(fcx.tcx(), &trait_ref);
|
let poly_trait_ref = ty::Binder(trait_ref);
|
||||||
|
let predicates = ty::predicates_for_trait_ref(fcx.tcx(), &poly_trait_ref);
|
||||||
for predicate in predicates.into_iter() {
|
for predicate in predicates.into_iter() {
|
||||||
fcx.register_predicate(traits::Obligation::new(cause, predicate));
|
fcx.register_predicate(traits::Obligation::new(cause, predicate));
|
||||||
}
|
}
|
||||||
@ -264,18 +264,18 @@ impl<'cx,'tcx> BoundsChecker<'cx,'tcx> {
|
|||||||
///
|
///
|
||||||
/// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated
|
/// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated
|
||||||
/// to the point where impl `A : Trait<B>` is implemented).
|
/// to the point where impl `A : Trait<B>` is implemented).
|
||||||
pub fn check_trait_ref(&mut self, trait_ref: &ty::PolyTraitRef<'tcx>) {
|
pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
|
||||||
let trait_def = ty::lookup_trait_def(self.fcx.tcx(), trait_ref.def_id());
|
let trait_def = ty::lookup_trait_def(self.fcx.tcx(), trait_ref.def_id);
|
||||||
|
|
||||||
let bounds = trait_def.generics.to_bounds(self.tcx(), trait_ref.substs());
|
let bounds = trait_def.generics.to_bounds(self.tcx(), &trait_ref.substs);
|
||||||
self.fcx.add_obligations_for_parameters(
|
self.fcx.add_obligations_for_parameters(
|
||||||
traits::ObligationCause::new(
|
traits::ObligationCause::new(
|
||||||
self.span,
|
self.span,
|
||||||
self.fcx.body_id,
|
self.fcx.body_id,
|
||||||
traits::ItemObligation(trait_ref.def_id())),
|
traits::ItemObligation(trait_ref.def_id)),
|
||||||
&bounds);
|
&bounds);
|
||||||
|
|
||||||
for &ty in trait_ref.substs().types.iter() {
|
for &ty in trait_ref.substs.types.iter() {
|
||||||
self.check_traits_in_ty(ty);
|
self.check_traits_in_ty(ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,7 +477,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
|||||||
let self_type =
|
let self_type =
|
||||||
ty::liberate_late_bound_regions(tcx,
|
ty::liberate_late_bound_regions(tcx,
|
||||||
item_scope,
|
item_scope,
|
||||||
&ty::bind(self_type)).value;
|
&ty::Binder(self_type));
|
||||||
|
|
||||||
debug!("can_type_implement_copy(self_type={})",
|
debug!("can_type_implement_copy(self_type={})",
|
||||||
self_type.repr(tcx));
|
self_type.repr(tcx));
|
||||||
|
@ -1638,8 +1638,8 @@ fn ty_generics_for_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
let param_id = trait_id;
|
let param_id = trait_id;
|
||||||
|
|
||||||
let self_trait_ref =
|
let self_trait_ref =
|
||||||
Rc::new(ty::bind(ty::TraitRef { def_id: local_def(trait_id),
|
Rc::new(ty::Binder(ty::TraitRef { def_id: local_def(trait_id),
|
||||||
substs: (*substs).clone() }));
|
substs: (*substs).clone() }));
|
||||||
|
|
||||||
let def = ty::TypeParameterDef {
|
let def = ty::TypeParameterDef {
|
||||||
space: subst::SelfSpace,
|
space: subst::SelfSpace,
|
||||||
@ -2155,9 +2155,9 @@ pub fn ty_of_foreign_fn_decl<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
ty::BareFnTy {
|
ty::BareFnTy {
|
||||||
abi: abi,
|
abi: abi,
|
||||||
unsafety: ast::Unsafety::Unsafe,
|
unsafety: ast::Unsafety::Unsafe,
|
||||||
sig: ty::FnSig {inputs: input_tys,
|
sig: ty::Binder(ty::FnSig {inputs: input_tys,
|
||||||
output: output,
|
output: output,
|
||||||
variadic: decl.variadic}
|
variadic: decl.variadic}),
|
||||||
});
|
});
|
||||||
let pty = Polytype {
|
let pty = Polytype {
|
||||||
generics: ty_generics_for_fn_or_method,
|
generics: ty_generics_for_fn_or_method,
|
||||||
@ -2209,16 +2209,16 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
|
|||||||
assert!(!ty::type_escapes_depth(required_type, 1));
|
assert!(!ty::type_escapes_depth(required_type, 1));
|
||||||
let required_type_free =
|
let required_type_free =
|
||||||
ty::liberate_late_bound_regions(
|
ty::liberate_late_bound_regions(
|
||||||
crate_context.tcx, body_scope, &ty::bind(required_type)).value;
|
crate_context.tcx, body_scope, &ty::Binder(required_type));
|
||||||
|
|
||||||
// The "base type" comes from the impl. It may have late-bound
|
// The "base type" comes from the impl. It may have late-bound
|
||||||
// regions from the impl or the method.
|
// regions from the impl or the method.
|
||||||
let base_type_free = // liberate impl regions:
|
let base_type_free =
|
||||||
ty::liberate_late_bound_regions(
|
ty::liberate_late_bound_regions( // liberate impl regions:
|
||||||
crate_context.tcx, body_scope, &ty::bind(ty::bind(base_type))).value.value;
|
crate_context.tcx, body_scope,
|
||||||
let base_type_free = // liberate method regions:
|
&ty::liberate_late_bound_regions( // liberate method regions:
|
||||||
ty::liberate_late_bound_regions(
|
crate_context.tcx, body_scope,
|
||||||
crate_context.tcx, body_scope, &ty::bind(base_type_free)).value;
|
&ty::Binder(ty::Binder(base_type))));
|
||||||
|
|
||||||
debug!("required_type={} required_type_free={} \
|
debug!("required_type={} required_type_free={} \
|
||||||
base_type={} base_type_free={}",
|
base_type={} base_type_free={}",
|
||||||
|
@ -228,11 +228,11 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
|
|||||||
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
||||||
unsafety: ast::Unsafety::Normal,
|
unsafety: ast::Unsafety::Normal,
|
||||||
abi: abi::Rust,
|
abi: abi::Rust,
|
||||||
sig: ty::FnSig {
|
sig: ty::Binder(ty::FnSig {
|
||||||
inputs: Vec::new(),
|
inputs: Vec::new(),
|
||||||
output: ty::FnConverging(ty::mk_nil(tcx)),
|
output: ty::FnConverging(ty::mk_nil(tcx)),
|
||||||
variadic: false
|
variadic: false
|
||||||
}
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
require_same_types(tcx, None, false, main_span, main_t, se_ty,
|
require_same_types(tcx, None, false, main_span, main_t, se_ty,
|
||||||
@ -276,14 +276,14 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
|
|||||||
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
let se_ty = ty::mk_bare_fn(tcx, ty::BareFnTy {
|
||||||
unsafety: ast::Unsafety::Normal,
|
unsafety: ast::Unsafety::Normal,
|
||||||
abi: abi::Rust,
|
abi: abi::Rust,
|
||||||
sig: ty::FnSig {
|
sig: ty::Binder(ty::FnSig {
|
||||||
inputs: vec!(
|
inputs: vec!(
|
||||||
ty::mk_int(),
|
ty::mk_int(),
|
||||||
ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8()))
|
ty::mk_imm_ptr(tcx, ty::mk_imm_ptr(tcx, ty::mk_u8()))
|
||||||
),
|
),
|
||||||
output: ty::FnConverging(ty::mk_int()),
|
output: ty::FnConverging(ty::mk_int()),
|
||||||
variadic: false
|
variadic: false
|
||||||
}
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
require_same_types(tcx, None, false, start_span, start_t, se_ty,
|
require_same_types(tcx, None, false, start_span, start_t, se_ty,
|
||||||
|
@ -878,13 +878,13 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
/// Adds constraints appropriate for a function with signature
|
/// Adds constraints appropriate for a function with signature
|
||||||
/// `sig` appearing in a context with ambient variance `variance`
|
/// `sig` appearing in a context with ambient variance `variance`
|
||||||
fn add_constraints_from_sig(&mut self,
|
fn add_constraints_from_sig(&mut self,
|
||||||
sig: &ty::FnSig<'tcx>,
|
sig: &ty::PolyFnSig<'tcx>,
|
||||||
variance: VarianceTermPtr<'a>) {
|
variance: VarianceTermPtr<'a>) {
|
||||||
let contra = self.contravariant(variance);
|
let contra = self.contravariant(variance);
|
||||||
for &input in sig.inputs.iter() {
|
for &input in sig.0.inputs.iter() {
|
||||||
self.add_constraints_from_ty(input, contra);
|
self.add_constraints_from_ty(input, contra);
|
||||||
}
|
}
|
||||||
if let ty::FnConverging(result_type) = sig.output {
|
if let ty::FnConverging(result_type) = sig.0.output {
|
||||||
self.add_constraints_from_ty(result_type, variance);
|
self.add_constraints_from_ty(result_type, variance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -577,7 +577,7 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
|
|||||||
|
|
||||||
impl<'tcx> Clean<TyParamBound> for ty::PolyTraitRef<'tcx> {
|
impl<'tcx> Clean<TyParamBound> for ty::PolyTraitRef<'tcx> {
|
||||||
fn clean(&self, cx: &DocContext) -> TyParamBound {
|
fn clean(&self, cx: &DocContext) -> TyParamBound {
|
||||||
self.value.clean(cx)
|
self.0.clean(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,7 +919,7 @@ impl<'tcx> Clean<Type> for ty::FnOutput<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Clean<FnDecl> for (ast::DefId, &'a ty::FnSig<'tcx>) {
|
impl<'a, 'tcx> Clean<FnDecl> for (ast::DefId, &'a ty::PolyFnSig<'tcx>) {
|
||||||
fn clean(&self, cx: &DocContext) -> FnDecl {
|
fn clean(&self, cx: &DocContext) -> FnDecl {
|
||||||
let (did, sig) = *self;
|
let (did, sig) = *self;
|
||||||
let mut names = if did.node != 0 {
|
let mut names = if did.node != 0 {
|
||||||
@ -931,10 +931,10 @@ impl<'a, 'tcx> Clean<FnDecl> for (ast::DefId, &'a ty::FnSig<'tcx>) {
|
|||||||
let _ = names.next();
|
let _ = names.next();
|
||||||
}
|
}
|
||||||
FnDecl {
|
FnDecl {
|
||||||
output: Return(sig.output.clean(cx)),
|
output: Return(sig.0.output.clean(cx)),
|
||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
inputs: Arguments {
|
inputs: Arguments {
|
||||||
values: sig.inputs.iter().map(|t| {
|
values: sig.0.inputs.iter().map(|t| {
|
||||||
Argument {
|
Argument {
|
||||||
type_: t.clean(cx),
|
type_: t.clean(cx),
|
||||||
id: 0,
|
id: 0,
|
||||||
@ -1088,14 +1088,14 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
|
|||||||
ty::StaticExplicitSelfCategory => (ast::SelfStatic.clean(cx),
|
ty::StaticExplicitSelfCategory => (ast::SelfStatic.clean(cx),
|
||||||
self.fty.sig.clone()),
|
self.fty.sig.clone()),
|
||||||
s => {
|
s => {
|
||||||
let sig = ty::FnSig {
|
let sig = ty::Binder(ty::FnSig {
|
||||||
inputs: self.fty.sig.inputs[1..].to_vec(),
|
inputs: self.fty.sig.0.inputs[1..].to_vec(),
|
||||||
..self.fty.sig.clone()
|
..self.fty.sig.0.clone()
|
||||||
};
|
});
|
||||||
let s = match s {
|
let s = match s {
|
||||||
ty::ByValueExplicitSelfCategory => SelfValue,
|
ty::ByValueExplicitSelfCategory => SelfValue,
|
||||||
ty::ByReferenceExplicitSelfCategory(..) => {
|
ty::ByReferenceExplicitSelfCategory(..) => {
|
||||||
match self.fty.sig.inputs[0].sty {
|
match self.fty.sig.0.inputs[0].sty {
|
||||||
ty::ty_rptr(r, mt) => {
|
ty::ty_rptr(r, mt) => {
|
||||||
SelfBorrowed(r.clean(cx), mt.mutbl.clean(cx))
|
SelfBorrowed(r.clean(cx), mt.mutbl.clean(cx))
|
||||||
}
|
}
|
||||||
@ -1103,7 +1103,7 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ByBoxExplicitSelfCategory => {
|
ty::ByBoxExplicitSelfCategory => {
|
||||||
SelfExplicit(self.fty.sig.inputs[0].clean(cx))
|
SelfExplicit(self.fty.sig.0.inputs[0].clean(cx))
|
||||||
}
|
}
|
||||||
ty::StaticExplicitSelfCategory => unreachable!(),
|
ty::StaticExplicitSelfCategory => unreachable!(),
|
||||||
};
|
};
|
||||||
@ -1398,7 +1398,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
|||||||
ty::ty_struct(did, ref substs) |
|
ty::ty_struct(did, ref substs) |
|
||||||
ty::ty_enum(did, ref substs) |
|
ty::ty_enum(did, ref substs) |
|
||||||
ty::ty_trait(box ty::TyTrait {
|
ty::ty_trait(box ty::TyTrait {
|
||||||
principal: ty::Binder { value: ty::TraitRef { def_id: did, ref substs } },
|
principal: ty::Binder(ty::TraitRef { def_id: did, ref substs }),
|
||||||
.. }) =>
|
.. }) =>
|
||||||
{
|
{
|
||||||
let fqn = csearch::get_item_path(cx.tcx(), did);
|
let fqn = csearch::get_item_path(cx.tcx(), did);
|
||||||
|
Loading…
Reference in New Issue
Block a user