Refactor BuiltinBounds to Vec<DefId> on TraitObject.
This commit is contained in:
parent
46c7a117f8
commit
607af7218b
@ -41,6 +41,7 @@ use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
|
||||
use traits;
|
||||
use ty::fast_reject;
|
||||
use ty::relate::TypeRelation;
|
||||
use middle::lang_items;
|
||||
|
||||
use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc_data_structures::snapshot_vec::{SnapshotVecDelegate, SnapshotVec};
|
||||
@ -49,6 +50,7 @@ use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use std::iter;
|
||||
use syntax::abi::Abi;
|
||||
use hir;
|
||||
use util::nodemap::FxHashMap;
|
||||
@ -1516,16 +1518,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
let self_ty = this.tcx().erase_late_bound_regions(&obligation.self_ty());
|
||||
let poly_trait_ref = match self_ty.sty {
|
||||
ty::TyTrait(ref data) => {
|
||||
match this.tcx().lang_items.to_builtin_kind(obligation.predicate.def_id()) {
|
||||
Some(bound @ ty::BoundSend) | Some(bound @ ty::BoundSync) => {
|
||||
if data.builtin_bounds.contains(&bound) {
|
||||
debug!("assemble_candidates_from_object_ty: matched builtin bound, \
|
||||
pushing candidate");
|
||||
candidates.vec.push(BuiltinObjectCandidate);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
|
||||
debug!("assemble_candidates_from_object_ty: matched builtin bound, \
|
||||
pushing candidate");
|
||||
candidates.vec.push(BuiltinObjectCandidate);
|
||||
return;
|
||||
}
|
||||
|
||||
match data.principal() {
|
||||
@ -1616,7 +1613,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
// #2 (region bounds).
|
||||
match (data_a.principal(), data_b.principal()) {
|
||||
(Some(ref a), Some(ref b)) => a.def_id() == b.def_id() &&
|
||||
data_a.builtin_bounds.is_superset(&data_b.builtin_bounds),
|
||||
data_b.auto_traits()
|
||||
// All of a's auto traits need to be in b's auto traits.
|
||||
.all(|b| data_a.auto_traits().any(|a| a == b)),
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
@ -2481,7 +2480,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
let new_trait = tcx.mk_trait(ty::TraitObject::new(
|
||||
data_a.principal(),
|
||||
data_b.region_bound,
|
||||
data_b.builtin_bounds,
|
||||
data_b.auto_traits().collect(),
|
||||
data_a.projection_bounds.clone(),
|
||||
));
|
||||
let origin = TypeOrigin::Misc(obligation.cause.span);
|
||||
@ -2504,10 +2503,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
// T -> Trait.
|
||||
(_, &ty::TyTrait(ref data)) => {
|
||||
let mut object_dids =
|
||||
data.builtin_bounds.iter().flat_map(|bound| {
|
||||
tcx.lang_items.from_builtin_kind(bound).ok()
|
||||
})
|
||||
.chain(data.principal().map(|ref p| p.def_id()));
|
||||
data.auto_traits().chain(data.principal().map(|ref p| p.def_id()));
|
||||
if let Some(did) = object_dids.find(|did| {
|
||||
!tcx.is_object_safe(*did)
|
||||
}) {
|
||||
@ -2527,19 +2523,21 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
push(data.principal().unwrap().with_self_ty(tcx, source).to_predicate());
|
||||
|
||||
// We can only make objects from sized types.
|
||||
let mut builtin_bounds = data.builtin_bounds;
|
||||
builtin_bounds.insert(ty::BoundSized);
|
||||
let trait_refs = data.auto_traits()
|
||||
.chain(iter::once(
|
||||
tcx.lang_items.require(lang_items::SizedTraitLangItem)
|
||||
.unwrap_or_else(|msg| tcx.sess.fatal(&msg[..]))))
|
||||
.map(|did| ty::TraitRef {
|
||||
def_id: did,
|
||||
substs: tcx.mk_substs_trait(source, &[]),
|
||||
});
|
||||
|
||||
// Create additional obligations for all the various builtin
|
||||
// bounds attached to the object cast. (In other words, if the
|
||||
// object type is Foo+Send, this would create an obligation
|
||||
// for the Send check.)
|
||||
for bound in &builtin_bounds {
|
||||
if let Ok(tr) = tcx.trait_ref_for_builtin_bound(bound, source) {
|
||||
push(tr.to_predicate());
|
||||
} else {
|
||||
return Err(Unimplemented);
|
||||
}
|
||||
for tr in trait_refs {
|
||||
push(tr.to_predicate());
|
||||
}
|
||||
|
||||
// Create obligations for the projection predicates.
|
||||
|
@ -428,7 +428,11 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
||||
|relation| relation.relate_with_variance(ty::Contravariant,
|
||||
&a_obj.region_bound,
|
||||
&b_obj.region_bound))?;
|
||||
let nb = relation.relate(&a_obj.builtin_bounds, &b_obj.builtin_bounds)?;
|
||||
let nb = if !a_obj.auto_traits().eq(b_obj.auto_traits()) {
|
||||
return Err(TypeError::Sorts(expected_found(relation, &a, &b)));
|
||||
} else {
|
||||
a_obj.auto_traits().collect()
|
||||
};
|
||||
let pb = relation.relate(&a_obj.projection_bounds, &b_obj.projection_bounds)?;
|
||||
Ok(tcx.mk_trait(ty::TraitObject::new(principal, r, nb, pb)))
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TraitObject<'tcx> {
|
||||
ty::TraitObject::new(
|
||||
self.principal().map(|p| p.fold_with(folder)),
|
||||
self.region_bound.fold_with(folder),
|
||||
self.builtin_bounds,
|
||||
self.auto_traits().collect(),
|
||||
self.projection_bounds.fold_with(folder),
|
||||
)
|
||||
}
|
||||
|
@ -279,18 +279,18 @@ impl<'a, 'gcx, 'acx, 'tcx> ClosureSubsts<'tcx> {
|
||||
pub struct TraitObject<'tcx> {
|
||||
principal: Option<PolyExistentialTraitRef<'tcx>>,
|
||||
pub region_bound: &'tcx ty::Region,
|
||||
pub builtin_bounds: BuiltinBounds,
|
||||
auto_traits: Vec<DefId>,
|
||||
pub projection_bounds: Vec<PolyExistentialProjection<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> TraitObject<'tcx> {
|
||||
pub fn new(principal: Option<PolyExistentialTraitRef<'tcx>>, region_bound: &'tcx ty::Region,
|
||||
builtin_bounds: BuiltinBounds, projection_bounds: Vec<PolyExistentialProjection<'tcx>>)
|
||||
auto_traits: Vec<DefId>, projection_bounds: Vec<PolyExistentialProjection<'tcx>>)
|
||||
-> Self {
|
||||
TraitObject {
|
||||
principal: principal,
|
||||
region_bound: region_bound,
|
||||
builtin_bounds: builtin_bounds,
|
||||
auto_traits: auto_traits,
|
||||
projection_bounds: projection_bounds,
|
||||
}
|
||||
}
|
||||
@ -298,6 +298,10 @@ impl<'tcx> TraitObject<'tcx> {
|
||||
pub fn principal(&self) -> Option<PolyExistentialTraitRef<'tcx>> {
|
||||
self.principal
|
||||
}
|
||||
|
||||
pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item=DefId> + 'a {
|
||||
self.auto_traits.iter().cloned()
|
||||
}
|
||||
}
|
||||
|
||||
/// A complete reference to a trait. These take numerous guises in syntax,
|
||||
@ -833,18 +837,22 @@ impl CLike for BuiltinBound {
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn try_add_builtin_trait(self,
|
||||
trait_def_id: DefId,
|
||||
builtin_bounds: &mut EnumSet<BuiltinBound>)
|
||||
id: DefId,
|
||||
auto_traits: &mut Vec<DefId>)
|
||||
-> bool
|
||||
{
|
||||
//! Checks whether `trait_ref` refers to one of the builtin
|
||||
//! traits, like `Send`, and adds the corresponding
|
||||
//! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
|
||||
//! is a builtin trait.
|
||||
//! Checks whether `id` refers to one of the builtin
|
||||
//! traits, like `Send`, and adds it to `auto_traits` if so.
|
||||
//! Returns true if `idf` refers to a builtin trait.
|
||||
|
||||
match self.lang_items.to_builtin_kind(trait_def_id) {
|
||||
Some(bound) => { builtin_bounds.insert(bound); true }
|
||||
None => false
|
||||
if Some(id) == self.lang_items.send_trait() ||
|
||||
Some(id) == self.lang_items.sized_trait() ||
|
||||
Some(id) == self.lang_items.copy_trait() ||
|
||||
Some(id) == self.lang_items.sync_trait() {
|
||||
auto_traits.push(id);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -535,7 +535,9 @@ impl<'a, 'gcx, 'tcx, H: Hasher> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tc
|
||||
if let Some(ref p) = data.principal() {
|
||||
self.def_id(p.def_id());
|
||||
}
|
||||
self.hash(data.builtin_bounds);
|
||||
for d in data.auto_traits() {
|
||||
self.def_id(d);
|
||||
}
|
||||
}
|
||||
TyTuple(tys) => {
|
||||
self.hash(tys.len());
|
||||
|
@ -298,7 +298,6 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
/// is WF. Returns false if `ty0` is an unresolved type variable,
|
||||
/// in which case we are not able to simplify at all.
|
||||
fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
|
||||
let tcx = self.infcx.tcx;
|
||||
let mut subtys = ty0.walk();
|
||||
while let Some(ty) = subtys.next() {
|
||||
match ty.sty {
|
||||
@ -391,15 +390,12 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
let cause = self.cause(traits::MiscObligation);
|
||||
|
||||
let component_traits =
|
||||
data.builtin_bounds.iter().flat_map(|bound| {
|
||||
tcx.lang_items.from_builtin_kind(bound).ok()
|
||||
})
|
||||
.chain(data.principal().map(|ref p| p.def_id()));
|
||||
data.auto_traits().chain(data.principal().map(|ref p| p.def_id()));
|
||||
self.out.extend(
|
||||
component_traits.map(|did| { traits::Obligation::new(
|
||||
component_traits.map(|did| traits::Obligation::new(
|
||||
cause.clone(),
|
||||
ty::Predicate::ObjectSafe(did)
|
||||
)})
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
@ -493,7 +489,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
let implicit_bounds =
|
||||
object_region_bounds(self.infcx.tcx,
|
||||
data.principal().unwrap(),
|
||||
data.builtin_bounds);
|
||||
data.auto_traits());
|
||||
|
||||
let explicit_bound = data.region_bound;
|
||||
|
||||
@ -512,18 +508,25 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
/// they declare `trait SomeTrait : 'static`, for example, then
|
||||
/// `'static` would appear in the list. The hard work is done by
|
||||
/// `ty::required_region_bounds`, see that for more information.
|
||||
pub fn object_region_bounds<'a, 'gcx, 'tcx>(
|
||||
pub fn object_region_bounds<'a, 'gcx, 'tcx, I>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
principal: ty::PolyExistentialTraitRef<'tcx>,
|
||||
others: ty::BuiltinBounds)
|
||||
others: I)
|
||||
-> Vec<&'tcx ty::Region>
|
||||
where I: Iterator<Item=DefId>
|
||||
{
|
||||
// Since we don't actually *know* the self type for an object,
|
||||
// this "open(err)" serves as a kind of dummy standin -- basically
|
||||
// a skolemized type.
|
||||
let open_ty = tcx.mk_infer(ty::FreshTy(0));
|
||||
|
||||
let mut predicates = others.to_predicates(tcx, open_ty);
|
||||
let mut predicates = others.map(|d| {
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: d,
|
||||
substs: tcx.mk_substs_trait(open_ty, &[])
|
||||
};
|
||||
trait_ref.to_predicate()
|
||||
}).collect::<Vec<_>>();
|
||||
predicates.push(principal.with_self_ty(tcx, open_ty).to_predicate());
|
||||
|
||||
tcx.required_region_bounds(open_ty, predicates)
|
||||
|
@ -349,13 +349,15 @@ impl<'tcx> fmt::Display for ty::TraitObject<'tcx> {
|
||||
}).collect();
|
||||
|
||||
let tap = ty::Binder(TraitAndProjections(principal, projections));
|
||||
in_binder(f, tcx, &ty::Binder(""), Some(tap))
|
||||
})?;
|
||||
in_binder(f, tcx, &ty::Binder(""), Some(tap))?;
|
||||
|
||||
// Builtin bounds.
|
||||
for bound in &self.builtin_bounds {
|
||||
write!(f, " + {:?}", bound)?;
|
||||
}
|
||||
// Builtin bounds.
|
||||
for did in self.auto_traits() {
|
||||
write!(f, " + {}", tcx.item_path_str(did))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// FIXME: It'd be nice to compute from context when this bound
|
||||
// is implied, but that's non-trivial -- we'd perhaps have to
|
||||
@ -474,10 +476,14 @@ impl<'tcx> fmt::Debug for ty::TraitObject<'tcx> {
|
||||
write!(f, "{}", region_str)?;
|
||||
}
|
||||
|
||||
for bound in &self.builtin_bounds {
|
||||
maybe_continue(f)?;
|
||||
write!(f, "{:?}", bound)?;
|
||||
}
|
||||
ty::tls::with(|tcx| {
|
||||
for did in self.auto_traits() {
|
||||
maybe_continue(f)?;
|
||||
write!(f, " + {}", tcx.item_path_str(did))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
for projection_bound in &self.projection_bounds {
|
||||
maybe_continue(f)?;
|
||||
|
@ -1043,7 +1043,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
trait_segment,
|
||||
&mut projection_bounds);
|
||||
|
||||
let PartitionedBounds { builtin_bounds,
|
||||
let PartitionedBounds { auto_traits,
|
||||
trait_bounds,
|
||||
region_bounds } =
|
||||
partitioned_bounds;
|
||||
@ -1076,7 +1076,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
self.compute_object_lifetime_bound(span,
|
||||
®ion_bounds,
|
||||
existential_principal,
|
||||
builtin_bounds);
|
||||
&auto_traits);
|
||||
|
||||
let region_bound = match region_bound {
|
||||
Some(r) => r,
|
||||
@ -1138,7 +1138,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
let ty = tcx.mk_trait(ty::TraitObject::new(
|
||||
Some(existential_principal),
|
||||
region_bound,
|
||||
builtin_bounds,
|
||||
auto_traits,
|
||||
existential_projections
|
||||
));
|
||||
debug!("trait_object_type: {:?}", ty);
|
||||
@ -1923,16 +1923,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
span: Span,
|
||||
explicit_region_bounds: &[&hir::Lifetime],
|
||||
principal_trait_ref: ty::PolyExistentialTraitRef<'tcx>,
|
||||
builtin_bounds: ty::BuiltinBounds)
|
||||
auto_traits: &[DefId])
|
||||
-> Option<&'tcx ty::Region> // if None, use the default
|
||||
{
|
||||
let tcx = self.tcx();
|
||||
|
||||
debug!("compute_opt_region_bound(explicit_region_bounds={:?}, \
|
||||
principal_trait_ref={:?}, builtin_bounds={:?})",
|
||||
principal_trait_ref={:?}, auto_traits={:?})",
|
||||
explicit_region_bounds,
|
||||
principal_trait_ref,
|
||||
builtin_bounds);
|
||||
auto_traits);
|
||||
|
||||
if explicit_region_bounds.len() > 1 {
|
||||
span_err!(tcx.sess, explicit_region_bounds[1].span, E0226,
|
||||
@ -1953,7 +1953,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
// No explicit region bound specified. Therefore, examine trait
|
||||
// bounds and see if we can derive region bounds from those.
|
||||
let derived_region_bounds =
|
||||
object_region_bounds(tcx, principal_trait_ref, builtin_bounds);
|
||||
object_region_bounds(tcx, principal_trait_ref, auto_traits.into_iter().cloned());
|
||||
|
||||
// If there are no derived region bounds, then report back that we
|
||||
// can find no region bound. The caller will use the default.
|
||||
@ -1980,7 +1980,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||
}
|
||||
|
||||
pub struct PartitionedBounds<'a> {
|
||||
pub builtin_bounds: ty::BuiltinBounds,
|
||||
pub auto_traits: Vec<DefId>,
|
||||
pub trait_bounds: Vec<&'a hir::PolyTraitRef>,
|
||||
pub region_bounds: Vec<&'a hir::Lifetime>,
|
||||
}
|
||||
@ -1992,7 +1992,7 @@ pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
ast_bounds: &'b [hir::TyParamBound])
|
||||
-> PartitionedBounds<'b>
|
||||
{
|
||||
let mut builtin_bounds = ty::BuiltinBounds::empty();
|
||||
let mut auto_traits = Vec::new();
|
||||
let mut region_bounds = Vec::new();
|
||||
let mut trait_bounds = Vec::new();
|
||||
for ast_bound in ast_bounds {
|
||||
@ -2000,8 +2000,7 @@ pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
hir::TraitTyParamBound(ref b, hir::TraitBoundModifier::None) => {
|
||||
match b.trait_ref.path.def {
|
||||
Def::Trait(trait_did) => {
|
||||
if tcx.try_add_builtin_trait(trait_did,
|
||||
&mut builtin_bounds) {
|
||||
if tcx.try_add_builtin_trait(trait_did, &mut auto_traits) {
|
||||
let segments = &b.trait_ref.path.segments;
|
||||
let parameters = &segments[segments.len() - 1].parameters;
|
||||
if !parameters.types().is_empty() {
|
||||
@ -2030,7 +2029,7 @@ pub fn partition_bounds<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
}
|
||||
|
||||
PartitionedBounds {
|
||||
builtin_bounds: builtin_bounds,
|
||||
auto_traits: auto_traits,
|
||||
trait_bounds: trait_bounds,
|
||||
region_bounds: region_bounds,
|
||||
}
|
||||
@ -2105,7 +2104,7 @@ fn report_lifetime_number_error(tcx: TyCtxt, span: Span, number: usize, expected
|
||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||
pub struct Bounds<'tcx> {
|
||||
pub region_bounds: Vec<&'tcx ty::Region>,
|
||||
pub builtin_bounds: ty::BuiltinBounds,
|
||||
pub auto_traits: Vec<DefId>,
|
||||
pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
|
||||
pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
|
||||
}
|
||||
@ -2116,11 +2115,12 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
|
||||
{
|
||||
let mut vec = Vec::new();
|
||||
|
||||
for builtin_bound in &self.builtin_bounds {
|
||||
match tcx.trait_ref_for_builtin_bound(builtin_bound, param_ty) {
|
||||
Ok(trait_ref) => { vec.push(trait_ref.to_predicate()); }
|
||||
Err(ErrorReported) => { }
|
||||
}
|
||||
for trait_did in &self.auto_traits {
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: *trait_did,
|
||||
substs: tcx.mk_substs_trait(param_ty, &[]),
|
||||
};
|
||||
vec.push(trait_ref.to_predicate());
|
||||
}
|
||||
|
||||
for ®ion_bound in &self.region_bounds {
|
||||
|
@ -1586,7 +1586,7 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
// Add the Sized bound, unless the type parameter is marked as `?Sized`.
|
||||
fn add_unsized_bound<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||
bounds: &mut ty::BuiltinBounds,
|
||||
bounds: &mut Vec<DefId>,
|
||||
ast_bounds: &[hir::TyParamBound],
|
||||
span: Span)
|
||||
{
|
||||
@ -1908,13 +1908,13 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||
{
|
||||
let tcx = astconv.tcx();
|
||||
let PartitionedBounds {
|
||||
mut builtin_bounds,
|
||||
mut auto_traits,
|
||||
trait_bounds,
|
||||
region_bounds
|
||||
} = partition_bounds(tcx, span, &ast_bounds);
|
||||
|
||||
if let SizedByDefault::Yes = sized_by_default {
|
||||
add_unsized_bound(astconv, &mut builtin_bounds, ast_bounds, span);
|
||||
add_unsized_bound(astconv, &mut auto_traits, ast_bounds, span);
|
||||
}
|
||||
|
||||
let mut projection_bounds = vec![];
|
||||
@ -1935,7 +1935,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||
|
||||
Bounds {
|
||||
region_bounds: region_bounds,
|
||||
builtin_bounds: builtin_bounds,
|
||||
auto_traits: auto_traits,
|
||||
trait_bounds: trait_bounds,
|
||||
projection_bounds: projection_bounds,
|
||||
}
|
||||
|
@ -1883,8 +1883,28 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
||||
|
||||
let mut typarams = vec![];
|
||||
obj.region_bound.clean(cx).map(|b| typarams.push(RegionBound(b)));
|
||||
for bb in &obj.builtin_bounds {
|
||||
typarams.push(bb.clean(cx));
|
||||
for did in obj.auto_traits() {
|
||||
let tcx = match cx.tcx_opt() {
|
||||
Some(tcx) => tcx,
|
||||
None => {
|
||||
typarams.push(RegionBound(Lifetime::statik()));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let empty = tcx.intern_substs(&[]);
|
||||
let path = external_path(cx, &tcx.item_name(did).as_str(),
|
||||
Some(did), false, vec![], empty);
|
||||
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
||||
let bound = TraitBound(PolyTrait {
|
||||
trait_: ResolvedPath {
|
||||
path: path,
|
||||
typarams: None,
|
||||
did: did,
|
||||
is_generic: false,
|
||||
},
|
||||
lifetimes: vec![]
|
||||
}, hir::TraitBoundModifier::None);
|
||||
typarams.push(bound);
|
||||
}
|
||||
|
||||
let mut bindings = vec![];
|
||||
|
Loading…
x
Reference in New Issue
Block a user