Centralize on using Binder to introduce new binding levels, rather than having FnSig carry an implicit binding level. This means that we be more typesafe in general, since things that instantiate bound regions can drop the Binder to reflect that.
This commit is contained in:
parent
ed4952ef39
commit
1205fd88df
48 changed files with 462 additions and 545 deletions
|
|
@ -23,7 +23,10 @@ use middle::ty::{ty_param, ty_ptr, ty_rptr, ty_tup, ty_open};
|
|||
use middle::ty::{ty_unboxed_closure};
|
||||
use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
|
||||
use middle::ty;
|
||||
use middle::ty_fold::TypeFoldable;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
use syntax::abi;
|
||||
use syntax::ast_map;
|
||||
|
|
@ -40,7 +43,7 @@ pub trait Repr<'tcx> for Sized? {
|
|||
}
|
||||
|
||||
/// Produces a string suitable for showing to the user.
|
||||
pub trait UserString<'tcx> {
|
||||
pub trait UserString<'tcx> : Repr<'tcx> {
|
||||
fn user_string(&self, tcx: &ctxt<'tcx>) -> String;
|
||||
}
|
||||
|
||||
|
|
@ -248,21 +251,12 @@ pub fn vec_map_to_string<T, F>(ts: &[T], f: F) -> String where
|
|||
format!("[{}]", tstrs.connect(", "))
|
||||
}
|
||||
|
||||
pub fn fn_sig_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::FnSig<'tcx>) -> String {
|
||||
format!("fn{} -> {}", typ.inputs.repr(cx), typ.output.repr(cx))
|
||||
}
|
||||
|
||||
pub fn trait_ref_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||
trait_ref: &ty::TraitRef<'tcx>) -> String {
|
||||
trait_ref.user_string(cx).to_string()
|
||||
}
|
||||
|
||||
pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
||||
fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>,
|
||||
unsafety: ast::Unsafety,
|
||||
abi: abi::Abi,
|
||||
ident: Option<ast::Ident>,
|
||||
sig: &ty::FnSig<'tcx>)
|
||||
sig: &ty::PolyFnSig<'tcx>)
|
||||
-> String {
|
||||
let mut s = String::new();
|
||||
match unsafety {
|
||||
|
|
@ -336,15 +330,15 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
|||
s: &mut String,
|
||||
bra: char,
|
||||
ket: char,
|
||||
sig: &ty::FnSig<'tcx>,
|
||||
sig: &ty::PolyFnSig<'tcx>,
|
||||
bounds: &str) {
|
||||
s.push(bra);
|
||||
let strs = sig.inputs
|
||||
let strs = sig.0.inputs
|
||||
.iter()
|
||||
.map(|a| ty_to_string(cx, *a))
|
||||
.collect::<Vec<_>>();
|
||||
s.push_str(strs.connect(", ").as_slice());
|
||||
if sig.variadic {
|
||||
if sig.0.variadic {
|
||||
s.push_str(", ...");
|
||||
}
|
||||
s.push(ket);
|
||||
|
|
@ -354,7 +348,7 @@ pub fn ty_to_string<'tcx>(cx: &ctxt<'tcx>, typ: &ty::TyS<'tcx>) -> String {
|
|||
s.push_str(bounds);
|
||||
}
|
||||
|
||||
match sig.output {
|
||||
match sig.0.output {
|
||||
ty::FnConverging(t) => {
|
||||
if !ty::type_is_nil(t) {
|
||||
s.push_str(" -> ");
|
||||
|
|
@ -1013,7 +1007,7 @@ impl<'tcx> Repr<'tcx> for ty::BareFnTy<'tcx> {
|
|||
|
||||
impl<'tcx> Repr<'tcx> for ty::FnSig<'tcx> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
fn_sig_to_string(tcx, self)
|
||||
format!("fn{} -> {}", self.inputs.repr(tcx), self.output.repr(tcx))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1156,7 +1150,9 @@ impl<'tcx> UserString<'tcx> for ty::BuiltinBounds {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UserString<'tcx> for ty::PolyTraitRef<'tcx> {
|
||||
impl<'tcx, T> UserString<'tcx> for ty::Binder<T>
|
||||
where T : UserString<'tcx> + TypeFoldable<'tcx>
|
||||
{
|
||||
fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
// Replace any anonymous late-bound regions with named
|
||||
// variants, using gensym'd identifiers, so that we can
|
||||
|
|
@ -1164,7 +1160,7 @@ impl<'tcx> UserString<'tcx> for ty::PolyTraitRef<'tcx> {
|
|||
// the output. We'll probably want to tweak this over time to
|
||||
// decide just how much information to give.
|
||||
let mut names = Vec::new();
|
||||
let (trait_ref, _) = ty::replace_late_bound_regions(tcx, self, |br, debruijn| {
|
||||
let (unbound_value, _) = ty::replace_late_bound_regions(tcx, self, |br, debruijn| {
|
||||
ty::ReLateBound(debruijn, match br {
|
||||
ty::BrNamed(_, name) => {
|
||||
names.push(token::get_name(name));
|
||||
|
|
@ -1181,11 +1177,11 @@ impl<'tcx> UserString<'tcx> for ty::PolyTraitRef<'tcx> {
|
|||
});
|
||||
let names: Vec<_> = names.iter().map(|s| s.get()).collect();
|
||||
|
||||
let trait_ref_str = trait_ref.value.user_string(tcx);
|
||||
let value_str = unbound_value.user_string(tcx);
|
||||
if names.len() == 0 {
|
||||
trait_ref_str
|
||||
value_str
|
||||
} else {
|
||||
format!("for<{}> {}", names.connect(","), trait_ref_str)
|
||||
format!("for<{}> {}", names.connect(","), value_str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1337,6 +1333,20 @@ impl<'tcx, A:Repr<'tcx>, B:Repr<'tcx>> Repr<'tcx> for (A,B) {
|
|||
|
||||
impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for ty::Binder<T> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
format!("Binder({})", self.value.repr(tcx))
|
||||
format!("Binder({})", self.0.repr(tcx))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, S, H, K, V> Repr<'tcx> for HashMap<K,V,H>
|
||||
where K : Hash<S> + Eq + Repr<'tcx>,
|
||||
V : Repr<'tcx>,
|
||||
H : Hasher<S>
|
||||
{
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
format!("HashMap({})",
|
||||
self.iter()
|
||||
.map(|(k,v)| format!("{} => {}", k.repr(tcx), v.repr(tcx)))
|
||||
.collect::<Vec<String>>()
|
||||
.connect(", "))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue