Auto merge of #55032 - oli-obk:the_early_unwrap_gets_the_panic, r=Mark-Simulacrum
Check the invariant for `principal` inside the method r? @Mark-Simulacrum
This commit is contained in:
commit
14f42a732f
|
@ -418,9 +418,7 @@ fn fundamental_ty(tcx: TyCtxt<'_, '_, '_>, ty: Ty<'_>) -> bool {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::Ref(..) => true,
|
ty::Ref(..) => true,
|
||||||
ty::Adt(def, _) => def.is_fundamental(),
|
ty::Adt(def, _) => def.is_fundamental(),
|
||||||
ty::Dynamic(ref data, ..) => {
|
ty::Dynamic(ref data, ..) => tcx.has_attr(data.principal().def_id(), "fundamental"),
|
||||||
data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental"))
|
|
||||||
}
|
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -467,11 +465,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool {
|
||||||
ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
|
ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
|
||||||
ty::Foreign(did) => def_id_is_local(did, in_crate),
|
ty::Foreign(did) => def_id_is_local(did, in_crate),
|
||||||
|
|
||||||
ty::Dynamic(ref tt, ..) => {
|
ty::Dynamic(ref tt, ..) => def_id_is_local(tt.principal().def_id(), in_crate),
|
||||||
tt.principal().map_or(false, |p|
|
|
||||||
def_id_is_local(p.def_id(), in_crate)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::Error => true,
|
ty::Error => true,
|
||||||
|
|
||||||
|
|
|
@ -2088,10 +2088,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match data.principal() {
|
data.principal().with_self_ty(this.tcx(), self_ty)
|
||||||
Some(p) => p.with_self_ty(this.tcx(), self_ty),
|
|
||||||
None => return,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ty::Infer(ty::TyVar(_)) => {
|
ty::Infer(ty::TyVar(_)) => {
|
||||||
debug!("assemble_candidates_from_object_ty: ambiguous");
|
debug!("assemble_candidates_from_object_ty: ambiguous");
|
||||||
|
@ -2183,15 +2180,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
//
|
//
|
||||||
// We always upcast when we can because of reason
|
// We always upcast when we can because of reason
|
||||||
// #2 (region bounds).
|
// #2 (region bounds).
|
||||||
match (data_a.principal(), data_b.principal()) {
|
data_a.principal().def_id() == data_b.principal().def_id()
|
||||||
(Some(a), Some(b)) => {
|
&& data_b.auto_traits()
|
||||||
a.def_id() == b.def_id()
|
// All of a's auto traits need to be in b's auto traits.
|
||||||
&& data_b.auto_traits()
|
.all(|b| data_a.auto_traits().any(|a| a == b))
|
||||||
// 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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// T -> Trait.
|
// T -> Trait.
|
||||||
|
@ -2981,7 +2973,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
.shallow_resolve(*obligation.self_ty().skip_binder());
|
.shallow_resolve(*obligation.self_ty().skip_binder());
|
||||||
let poly_trait_ref = match self_ty.sty {
|
let poly_trait_ref = match self_ty.sty {
|
||||||
ty::Dynamic(ref data, ..) => {
|
ty::Dynamic(ref data, ..) => {
|
||||||
data.principal().unwrap().with_self_ty(self.tcx(), self_ty)
|
data.principal().with_self_ty(self.tcx(), self_ty)
|
||||||
}
|
}
|
||||||
_ => span_bug!(obligation.cause.span, "object candidate with non-object"),
|
_ => span_bug!(obligation.cause.span, "object candidate with non-object"),
|
||||||
};
|
};
|
||||||
|
@ -3244,10 +3236,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
(&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
|
(&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
|
||||||
// See assemble_candidates_for_unsizing for more info.
|
// See assemble_candidates_for_unsizing for more info.
|
||||||
let existential_predicates = data_a.map_bound(|data_a| {
|
let existential_predicates = data_a.map_bound(|data_a| {
|
||||||
let principal = data_a.principal();
|
let iter = iter::once(ty::ExistentialPredicate::Trait(data_a.principal()))
|
||||||
let iter = principal
|
|
||||||
.into_iter()
|
|
||||||
.map(ty::ExistentialPredicate::Trait)
|
|
||||||
.chain(
|
.chain(
|
||||||
data_a
|
data_a
|
||||||
.projection_bounds()
|
.projection_bounds()
|
||||||
|
@ -3285,7 +3274,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
// T -> Trait.
|
// T -> Trait.
|
||||||
(_, &ty::Dynamic(ref data, r)) => {
|
(_, &ty::Dynamic(ref data, r)) => {
|
||||||
let mut object_dids = data.auto_traits()
|
let mut object_dids = data.auto_traits()
|
||||||
.chain(data.principal().map(|p| p.def_id()));
|
.chain(iter::once(data.principal().def_id()));
|
||||||
if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
|
if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
|
||||||
return Err(TraitNotObjectSafe(did));
|
return Err(TraitNotObjectSafe(did));
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,8 +208,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
|
||||||
ty::FnDef(..) => "fn item".into(),
|
ty::FnDef(..) => "fn item".into(),
|
||||||
ty::FnPtr(_) => "fn pointer".into(),
|
ty::FnPtr(_) => "fn pointer".into(),
|
||||||
ty::Dynamic(ref inner, ..) => {
|
ty::Dynamic(ref inner, ..) => {
|
||||||
inner.principal().map_or_else(|| "trait".into(),
|
format!("trait {}", tcx.item_path_str(inner.principal().def_id())).into()
|
||||||
|p| format!("trait {}", tcx.item_path_str(p.def_id())).into())
|
|
||||||
}
|
}
|
||||||
ty::Closure(..) => "closure".into(),
|
ty::Closure(..) => "closure".into(),
|
||||||
ty::Generator(..) => "generator".into(),
|
ty::Generator(..) => "generator".into(),
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType),
|
ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType),
|
||||||
ty::RawPtr(_) => Some(PtrSimplifiedType),
|
ty::RawPtr(_) => Some(PtrSimplifiedType),
|
||||||
ty::Dynamic(ref trait_info, ..) => {
|
ty::Dynamic(ref trait_info, ..) => {
|
||||||
trait_info.principal().map(|p| TraitSimplifiedType(p.def_id()))
|
Some(TraitSimplifiedType(trait_info.principal().def_id()))
|
||||||
}
|
}
|
||||||
ty::Ref(_, ty, _) => {
|
ty::Ref(_, ty, _) => {
|
||||||
// since we introduce auto-refs during method lookup, we
|
// since we introduce auto-refs during method lookup, we
|
||||||
|
|
|
@ -436,7 +436,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::Adt(adt_def, _) => Some(adt_def.did),
|
ty::Adt(adt_def, _) => Some(adt_def.did),
|
||||||
|
|
||||||
ty::Dynamic(data, ..) => data.principal().map(|p| p.def_id()),
|
ty::Dynamic(data, ..) => Some(data.principal().def_id()),
|
||||||
|
|
||||||
ty::Array(subty, _) |
|
ty::Array(subty, _) |
|
||||||
ty::Slice(subty) => characteristic_def_id_of_type(subty),
|
ty::Slice(subty) => characteristic_def_id_of_type(subty),
|
||||||
|
|
|
@ -559,10 +559,10 @@ impl<'a, 'gcx, 'tcx> Binder<ExistentialPredicate<'tcx>> {
|
||||||
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}
|
impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}
|
||||||
|
|
||||||
impl<'tcx> List<ExistentialPredicate<'tcx>> {
|
impl<'tcx> List<ExistentialPredicate<'tcx>> {
|
||||||
pub fn principal(&self) -> Option<ExistentialTraitRef<'tcx>> {
|
pub fn principal(&self) -> ExistentialTraitRef<'tcx> {
|
||||||
match self.get(0) {
|
match self[0] {
|
||||||
Some(&ExistentialPredicate::Trait(tr)) => Some(tr),
|
ExistentialPredicate::Trait(tr) => tr,
|
||||||
_ => None,
|
other => bug!("first predicate is {:?}", other),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,8 +589,8 @@ impl<'tcx> List<ExistentialPredicate<'tcx>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
|
impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
|
||||||
pub fn principal(&self) -> Option<PolyExistentialTraitRef<'tcx>> {
|
pub fn principal(&self) -> PolyExistentialTraitRef<'tcx> {
|
||||||
self.skip_binder().principal().map(Binder::bind)
|
Binder::bind(self.skip_binder().principal())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1825,9 +1825,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||||
}
|
}
|
||||||
Dynamic(ref obj, region) => {
|
Dynamic(ref obj, region) => {
|
||||||
let mut v = vec![region];
|
let mut v = vec![region];
|
||||||
if let Some(p) = obj.principal() {
|
v.extend(obj.principal().skip_binder().substs.regions());
|
||||||
v.extend(p.skip_binder().substs.regions());
|
|
||||||
}
|
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
Adt(_, substs) | Opaque(_, substs) => {
|
Adt(_, substs) | Opaque(_, substs) => {
|
||||||
|
|
|
@ -387,7 +387,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
let cause = self.cause(traits::MiscObligation);
|
let cause = self.cause(traits::MiscObligation);
|
||||||
let component_traits =
|
let component_traits =
|
||||||
data.auto_traits().chain(data.principal().map(|p| p.def_id()));
|
data.auto_traits().chain(once(data.principal().def_id()));
|
||||||
self.out.extend(
|
self.out.extend(
|
||||||
component_traits.map(|did| traits::Obligation::new(
|
component_traits.map(|did| traits::Obligation::new(
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
|
|
|
@ -621,16 +621,16 @@ define_print! {
|
||||||
// Use a type that can't appear in defaults of type parameters.
|
// Use a type that can't appear in defaults of type parameters.
|
||||||
let dummy_self = tcx.mk_infer(ty::FreshTy(0));
|
let dummy_self = tcx.mk_infer(ty::FreshTy(0));
|
||||||
|
|
||||||
if let Some(p) = self.principal() {
|
let principal = tcx
|
||||||
let principal = tcx.lift(&p).expect("could not lift TraitRef for printing")
|
.lift(&self.principal())
|
||||||
.with_self_ty(tcx, dummy_self);
|
.expect("could not lift TraitRef for printing")
|
||||||
let projections = self.projection_bounds().map(|p| {
|
.with_self_ty(tcx, dummy_self);
|
||||||
tcx.lift(&p)
|
let projections = self.projection_bounds().map(|p| {
|
||||||
.expect("could not lift projection for printing")
|
tcx.lift(&p)
|
||||||
.with_self_ty(tcx, dummy_self)
|
.expect("could not lift projection for printing")
|
||||||
}).collect::<Vec<_>>();
|
.with_self_ty(tcx, dummy_self)
|
||||||
cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
|
}).collect::<Vec<_>>();
|
||||||
}
|
cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
|
||||||
|
|
||||||
// Builtin bounds.
|
// Builtin bounds.
|
||||||
for did in self.auto_traits() {
|
for did in self.auto_traits() {
|
||||||
|
|
|
@ -59,7 +59,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
|
||||||
/// Cache instances of monomorphic and polymorphic items
|
/// Cache instances of monomorphic and polymorphic items
|
||||||
pub instances: RefCell<FxHashMap<Instance<'tcx>, &'a Value>>,
|
pub instances: RefCell<FxHashMap<Instance<'tcx>, &'a Value>>,
|
||||||
/// Cache generated vtables
|
/// Cache generated vtables
|
||||||
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>),
|
pub vtables: RefCell<FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>),
|
||||||
&'a Value>>,
|
&'a Value>>,
|
||||||
/// Cache of constant strings,
|
/// Cache of constant strings,
|
||||||
pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'a Value>>,
|
pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'a Value>>,
|
||||||
|
|
|
@ -435,12 +435,7 @@ fn trait_pointer_metadata(
|
||||||
// But it does not describe the trait's methods.
|
// But it does not describe the trait's methods.
|
||||||
|
|
||||||
let containing_scope = match trait_type.sty {
|
let containing_scope = match trait_type.sty {
|
||||||
ty::Dynamic(ref data, ..) => if let Some(principal) = data.principal() {
|
ty::Dynamic(ref data, ..) => Some(get_namespace_for_item(cx, data.principal().def_id())),
|
||||||
let def_id = principal.def_id();
|
|
||||||
Some(get_namespace_for_item(cx, def_id))
|
|
||||||
} else {
|
|
||||||
NO_SCOPE_METADATA
|
|
||||||
},
|
|
||||||
_ => {
|
_ => {
|
||||||
bug!("debuginfo: Unexpected trait-object type in \
|
bug!("debuginfo: Unexpected trait-object type in \
|
||||||
trait_pointer_metadata(): {:?}",
|
trait_pointer_metadata(): {:?}",
|
||||||
|
|
|
@ -116,14 +116,12 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ty::Dynamic(ref trait_data, ..) => {
|
ty::Dynamic(ref trait_data, ..) => {
|
||||||
if let Some(principal) = trait_data.principal() {
|
let principal = cx.tcx.normalize_erasing_late_bound_regions(
|
||||||
let principal = cx.tcx.normalize_erasing_late_bound_regions(
|
ty::ParamEnv::reveal_all(),
|
||||||
ty::ParamEnv::reveal_all(),
|
&trait_data.principal(),
|
||||||
&principal,
|
);
|
||||||
);
|
push_item_name(cx, principal.def_id, false, output);
|
||||||
push_item_name(cx, principal.def_id, false, output);
|
push_type_params(cx, principal.substs, output);
|
||||||
push_type_params(cx, principal.substs, output);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||||
let sig = t.fn_sig(cx.tcx);
|
let sig = t.fn_sig(cx.tcx);
|
||||||
|
|
|
@ -72,7 +72,7 @@ impl<'a, 'tcx> VirtualIndex {
|
||||||
pub fn get_vtable(
|
pub fn get_vtable(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
|
trait_ref: ty::PolyExistentialTraitRef<'tcx>,
|
||||||
) -> &'ll Value {
|
) -> &'ll Value {
|
||||||
let tcx = cx.tcx;
|
let tcx = cx.tcx;
|
||||||
|
|
||||||
|
@ -86,23 +86,19 @@ pub fn get_vtable(
|
||||||
// Not in the cache. Build it.
|
// Not in the cache. Build it.
|
||||||
let nullptr = C_null(Type::i8p(cx));
|
let nullptr = C_null(Type::i8p(cx));
|
||||||
|
|
||||||
|
let methods = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty));
|
||||||
|
let methods = methods.iter().cloned().map(|opt_mth| {
|
||||||
|
opt_mth.map_or(nullptr, |(def_id, substs)| {
|
||||||
|
callee::resolve_and_get_fn(cx, def_id, substs)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
let (size, align) = cx.size_and_align_of(ty);
|
let (size, align) = cx.size_and_align_of(ty);
|
||||||
let mut components: Vec<_> = [
|
let components: Vec<_> = [
|
||||||
callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)),
|
callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)),
|
||||||
C_usize(cx, size.bytes()),
|
C_usize(cx, size.bytes()),
|
||||||
C_usize(cx, align.abi())
|
C_usize(cx, align.abi())
|
||||||
].iter().cloned().collect();
|
].iter().cloned().chain(methods).collect();
|
||||||
|
|
||||||
if let Some(trait_ref) = trait_ref {
|
|
||||||
let trait_ref = trait_ref.with_self_ty(tcx, ty);
|
|
||||||
let methods = tcx.vtable_methods(trait_ref);
|
|
||||||
let methods = methods.iter().cloned().map(|opt_mth| {
|
|
||||||
opt_mth.map_or(nullptr, |(def_id, substs)| {
|
|
||||||
callee::resolve_and_get_fn(cx, def_id, substs)
|
|
||||||
})
|
|
||||||
});
|
|
||||||
components.extend(methods);
|
|
||||||
}
|
|
||||||
|
|
||||||
let vtable_const = C_struct(cx, &components, false);
|
let vtable_const = C_struct(cx, &components, false);
|
||||||
let align = cx.data_layout().pointer_align;
|
let align = cx.data_layout().pointer_align;
|
||||||
|
|
|
@ -327,7 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||||
}
|
}
|
||||||
(_, &ty::Dynamic(ref data, _)) => {
|
(_, &ty::Dynamic(ref data, _)) => {
|
||||||
// Initial cast from sized to dyn trait
|
// Initial cast from sized to dyn trait
|
||||||
let trait_ref = data.principal().unwrap().with_self_ty(
|
let trait_ref = data.principal().with_self_ty(
|
||||||
*self.tcx,
|
*self.tcx,
|
||||||
src_pointee_ty,
|
src_pointee_ty,
|
||||||
);
|
);
|
||||||
|
|
|
@ -907,22 +907,20 @@ fn create_mono_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
!impl_ty.needs_subst() && !impl_ty.has_escaping_regions());
|
!impl_ty.needs_subst() && !impl_ty.has_escaping_regions());
|
||||||
|
|
||||||
if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty {
|
if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty {
|
||||||
if let Some(principal) = trait_ty.principal() {
|
let poly_trait_ref = trait_ty.principal().with_self_ty(tcx, impl_ty);
|
||||||
let poly_trait_ref = principal.with_self_ty(tcx, impl_ty);
|
assert!(!poly_trait_ref.has_escaping_regions());
|
||||||
assert!(!poly_trait_ref.has_escaping_regions());
|
|
||||||
|
|
||||||
// Walk all methods of the trait, including those of its supertraits
|
// Walk all methods of the trait, including those of its supertraits
|
||||||
let methods = tcx.vtable_methods(poly_trait_ref);
|
let methods = tcx.vtable_methods(poly_trait_ref);
|
||||||
let methods = methods.iter().cloned().filter_map(|method| method)
|
let methods = methods.iter().cloned().filter_map(|method| method)
|
||||||
.map(|(def_id, substs)| ty::Instance::resolve(
|
.map(|(def_id, substs)| ty::Instance::resolve(
|
||||||
tcx,
|
tcx,
|
||||||
ty::ParamEnv::reveal_all(),
|
ty::ParamEnv::reveal_all(),
|
||||||
def_id,
|
def_id,
|
||||||
substs).unwrap())
|
substs).unwrap())
|
||||||
.filter(|&instance| should_monomorphize_locally(tcx, &instance))
|
.filter(|&instance| should_monomorphize_locally(tcx, &instance))
|
||||||
.map(|instance| create_fn_mono_item(instance));
|
.map(|instance| create_fn_mono_item(instance));
|
||||||
output.extend(methods);
|
output.extend(methods);
|
||||||
}
|
|
||||||
// Also add the destructor
|
// Also add the destructor
|
||||||
visit_drop_use(tcx, impl_ty, false, output);
|
visit_drop_use(tcx, impl_ty, false, output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,12 +320,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
|
||||||
output.push(']');
|
output.push(']');
|
||||||
},
|
},
|
||||||
ty::Dynamic(ref trait_data, ..) => {
|
ty::Dynamic(ref trait_data, ..) => {
|
||||||
if let Some(principal) = trait_data.principal() {
|
let principal = trait_data.principal();
|
||||||
self.push_def_path(principal.def_id(), output);
|
self.push_def_path(principal.def_id(), output);
|
||||||
self.push_type_params(principal.skip_binder().substs,
|
self.push_type_params(
|
||||||
trait_data.projection_bounds(),
|
principal.skip_binder().substs,
|
||||||
output);
|
trait_data.projection_bounds(),
|
||||||
}
|
output,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
ty::Foreign(did) => self.push_def_path(did, output),
|
ty::Foreign(did) => self.push_def_path(did, output),
|
||||||
ty::FnDef(..) |
|
ty::FnDef(..) |
|
||||||
|
|
|
@ -93,8 +93,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
|
||||||
let ty_def_id = match self.tcx.type_of(item_def_id).sty {
|
let ty_def_id = match self.tcx.type_of(item_def_id).sty {
|
||||||
ty::Adt(adt, _) => adt.did,
|
ty::Adt(adt, _) => adt.did,
|
||||||
ty::Foreign(did) => did,
|
ty::Foreign(did) => did,
|
||||||
ty::Dynamic(ref obj, ..) if obj.principal().is_some() =>
|
ty::Dynamic(ref obj, ..) => obj.principal().def_id(),
|
||||||
obj.principal().unwrap().def_id(),
|
|
||||||
ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id,
|
ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id,
|
||||||
_ => return Some(AccessLevel::Public)
|
_ => return Some(AccessLevel::Public)
|
||||||
};
|
};
|
||||||
|
@ -484,7 +483,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b
|
||||||
let ty_def_id = match ty.sty {
|
let ty_def_id = match ty.sty {
|
||||||
ty::Adt(adt, _) => Some(adt.did),
|
ty::Adt(adt, _) => Some(adt.did),
|
||||||
ty::Foreign(did) => Some(did),
|
ty::Foreign(did) => Some(did),
|
||||||
ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
|
ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()),
|
||||||
ty::Projection(ref proj) => Some(proj.item_def_id),
|
ty::Projection(ref proj) => Some(proj.item_def_id),
|
||||||
ty::FnDef(def_id, ..) |
|
ty::FnDef(def_id, ..) |
|
||||||
ty::Closure(def_id, ..) |
|
ty::Closure(def_id, ..) |
|
||||||
|
@ -1456,7 +1455,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
|
||||||
let ty_def_id = match ty.sty {
|
let ty_def_id = match ty.sty {
|
||||||
ty::Adt(adt, _) => Some(adt.did),
|
ty::Adt(adt, _) => Some(adt.did),
|
||||||
ty::Foreign(did) => Some(did),
|
ty::Foreign(did) => Some(did),
|
||||||
ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
|
ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()),
|
||||||
ty::Projection(ref proj) => {
|
ty::Projection(ref proj) => {
|
||||||
if self.required_visibility == ty::Visibility::Invisible {
|
if self.required_visibility == ty::Visibility::Invisible {
|
||||||
// Conservatively approximate the whole type alias as public without
|
// Conservatively approximate the whole type alias as public without
|
||||||
|
|
|
@ -73,7 +73,7 @@ enum PointerKind<'tcx> {
|
||||||
/// No metadata attached, ie pointer to sized type or foreign type
|
/// No metadata attached, ie pointer to sized type or foreign type
|
||||||
Thin,
|
Thin,
|
||||||
/// A trait object
|
/// A trait object
|
||||||
Vtable(Option<DefId>),
|
Vtable(DefId),
|
||||||
/// Slice
|
/// Slice
|
||||||
Length,
|
Length,
|
||||||
/// The unsize info of this projection
|
/// The unsize info of this projection
|
||||||
|
@ -105,7 +105,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
Ok(match t.sty {
|
Ok(match t.sty {
|
||||||
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
|
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
|
||||||
ty::Dynamic(ref tty, ..) =>
|
ty::Dynamic(ref tty, ..) =>
|
||||||
Some(PointerKind::Vtable(tty.principal().map(|p| p.def_id()))),
|
Some(PointerKind::Vtable(tty.principal().def_id())),
|
||||||
ty::Adt(def, substs) if def.is_struct() => {
|
ty::Adt(def, substs) if def.is_struct() => {
|
||||||
match def.non_enum_variant().fields.last() {
|
match def.non_enum_variant().fields.last() {
|
||||||
None => Some(PointerKind::Thin),
|
None => Some(PointerKind::Thin),
|
||||||
|
|
|
@ -198,9 +198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
self.deduce_sig_from_projection(None, &pb)
|
self.deduce_sig_from_projection(None, &pb)
|
||||||
})
|
})
|
||||||
.next();
|
.next();
|
||||||
let kind = object_type
|
let kind = self.tcx.lang_items().fn_trait_kind(object_type.principal().def_id());
|
||||||
.principal()
|
|
||||||
.and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id()));
|
|
||||||
(sig, kind)
|
(sig, kind)
|
||||||
}
|
}
|
||||||
ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
|
ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
|
||||||
|
|
|
@ -290,7 +290,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
||||||
.include_raw_pointers()
|
.include_raw_pointers()
|
||||||
.filter_map(|(ty, _)|
|
.filter_map(|(ty, _)|
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::Dynamic(ref data, ..) => data.principal().map(|p| closure(self, ty, p)),
|
ty::Dynamic(ref data, ..) => Some(closure(self, ty, data.principal())),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -452,10 +452,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
match self_ty.sty {
|
match self_ty.sty {
|
||||||
ty::Dynamic(ref data, ..) => {
|
ty::Dynamic(ref data, ..) => {
|
||||||
if let Some(p) = data.principal() {
|
let p = data.principal();
|
||||||
self.assemble_inherent_candidates_from_object(self_ty, p);
|
self.assemble_inherent_candidates_from_object(self_ty, p);
|
||||||
self.assemble_inherent_impl_candidates_for_type(p.def_id());
|
self.assemble_inherent_impl_candidates_for_type(p.def_id());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ty::Adt(def, _) => {
|
ty::Adt(def, _) => {
|
||||||
self.assemble_inherent_impl_candidates_for_type(def.did);
|
self.assemble_inherent_impl_candidates_for_type(def.did);
|
||||||
|
|
|
@ -663,8 +663,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
ty::Adt(def, _) => def.did.is_local(),
|
ty::Adt(def, _) => def.did.is_local(),
|
||||||
ty::Foreign(did) => did.is_local(),
|
ty::Foreign(did) => did.is_local(),
|
||||||
|
|
||||||
ty::Dynamic(ref tr, ..) => tr.principal()
|
ty::Dynamic(ref tr, ..) => tr.principal().def_id().is_local(),
|
||||||
.map_or(false, |p| p.def_id().is_local()),
|
|
||||||
|
|
||||||
ty::Param(_) => true,
|
ty::Param(_) => true,
|
||||||
|
|
||||||
|
|
|
@ -108,8 +108,8 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
|
||||||
ty::Foreign(did) => {
|
ty::Foreign(did) => {
|
||||||
self.check_def_id(item, did);
|
self.check_def_id(item, did);
|
||||||
}
|
}
|
||||||
ty::Dynamic(ref data, ..) if data.principal().is_some() => {
|
ty::Dynamic(ref data, ..) => {
|
||||||
self.check_def_id(item, data.principal().unwrap().def_id());
|
self.check_def_id(item, data.principal().def_id());
|
||||||
}
|
}
|
||||||
ty::Char => {
|
ty::Char => {
|
||||||
self.check_primitive_impl(def_id,
|
self.check_primitive_impl(def_id,
|
||||||
|
|
|
@ -181,13 +181,12 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
|
||||||
// This is something like impl Trait1 for Trait2. Illegal
|
// This is something like impl Trait1 for Trait2. Illegal
|
||||||
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
|
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
|
||||||
|
|
||||||
if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) {
|
if !tcx.is_object_safe(data.principal().def_id()) {
|
||||||
// This is an error, but it will be reported by wfcheck. Ignore it here.
|
// This is an error, but it will be reported by wfcheck. Ignore it here.
|
||||||
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
|
// This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
|
||||||
} else {
|
} else {
|
||||||
let mut supertrait_def_ids =
|
let mut supertrait_def_ids =
|
||||||
traits::supertrait_def_ids(tcx,
|
traits::supertrait_def_ids(tcx, data.principal().def_id());
|
||||||
data.principal().unwrap().def_id());
|
|
||||||
if supertrait_def_ids.any(|d| d == trait_def_id) {
|
if supertrait_def_ids.any(|d| d == trait_def_id) {
|
||||||
let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap());
|
let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap());
|
||||||
struct_span_err!(tcx.sess,
|
struct_span_err!(tcx.sess,
|
||||||
|
|
|
@ -203,28 +203,27 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
||||||
debug!("Dynamic");
|
debug!("Dynamic");
|
||||||
debug!("field_ty = {}", &field_ty);
|
debug!("field_ty = {}", &field_ty);
|
||||||
debug!("ty in field = {}", &ty);
|
debug!("ty in field = {}", &ty);
|
||||||
if let Some(ex_trait_ref) = obj.principal() {
|
let ex_trait_ref = obj.principal();
|
||||||
// Here, we are passing the type `usize` as a
|
// Here, we are passing the type `usize` as a
|
||||||
// placeholder value with the function
|
// placeholder value with the function
|
||||||
// `with_self_ty`, since there is no concrete type
|
// `with_self_ty`, since there is no concrete type
|
||||||
// `Self` for a `dyn Trait` at this
|
// `Self` for a `dyn Trait` at this
|
||||||
// stage. Therefore when checking explicit
|
// stage. Therefore when checking explicit
|
||||||
// predicates in `check_explicit_predicates` we
|
// predicates in `check_explicit_predicates` we
|
||||||
// need to ignore checking the explicit_map for
|
// need to ignore checking the explicit_map for
|
||||||
// Self type.
|
// Self type.
|
||||||
let substs = ex_trait_ref
|
let substs = ex_trait_ref
|
||||||
.with_self_ty(tcx, tcx.types.usize)
|
.with_self_ty(tcx, tcx.types.usize)
|
||||||
.skip_binder()
|
.skip_binder()
|
||||||
.substs;
|
.substs;
|
||||||
check_explicit_predicates(
|
check_explicit_predicates(
|
||||||
tcx,
|
tcx,
|
||||||
&ex_trait_ref.skip_binder().def_id,
|
&ex_trait_ref.skip_binder().def_id,
|
||||||
substs,
|
substs,
|
||||||
required_predicates,
|
required_predicates,
|
||||||
explicit_map,
|
explicit_map,
|
||||||
IgnoreSelfTy(true),
|
IgnoreSelfTy(true),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Projection(obj) => {
|
ty::Projection(obj) => {
|
||||||
|
|
|
@ -311,11 +311,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||||
let contra = self.contravariant(variance);
|
let contra = self.contravariant(variance);
|
||||||
self.add_constraints_from_region(current, r, contra);
|
self.add_constraints_from_region(current, r, contra);
|
||||||
|
|
||||||
if let Some(p) = data.principal() {
|
let poly_trait_ref = data
|
||||||
let poly_trait_ref = p.with_self_ty(self.tcx(), self.tcx().types.err);
|
.principal()
|
||||||
self.add_constraints_from_trait_ref(
|
.with_self_ty(self.tcx(), self.tcx().types.err);
|
||||||
current, *poly_trait_ref.skip_binder(), variance);
|
self.add_constraints_from_trait_ref(
|
||||||
}
|
current, *poly_trait_ref.skip_binder(), variance);
|
||||||
|
|
||||||
for projection in data.projection_bounds() {
|
for projection in data.projection_bounds() {
|
||||||
self.add_constraints_from_ty(
|
self.add_constraints_from_ty(
|
||||||
|
|
|
@ -2632,47 +2632,44 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Dynamic(ref obj, ref reg) => {
|
ty::Dynamic(ref obj, ref reg) => {
|
||||||
if let Some(principal) = obj.principal() {
|
let principal = obj.principal();
|
||||||
let did = principal.def_id();
|
let did = principal.def_id();
|
||||||
|
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
||||||
|
|
||||||
|
let mut typarams = vec![];
|
||||||
|
reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b)));
|
||||||
|
for did in obj.auto_traits() {
|
||||||
|
let empty = cx.tcx.intern_substs(&[]);
|
||||||
|
let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
|
||||||
|
Some(did), false, vec![], empty);
|
||||||
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
||||||
|
let bound = GenericBound::TraitBound(PolyTrait {
|
||||||
|
trait_: ResolvedPath {
|
||||||
|
path,
|
||||||
|
typarams: None,
|
||||||
|
did,
|
||||||
|
is_generic: false,
|
||||||
|
},
|
||||||
|
generic_params: Vec::new(),
|
||||||
|
}, hir::TraitBoundModifier::None);
|
||||||
|
typarams.push(bound);
|
||||||
|
}
|
||||||
|
|
||||||
let mut typarams = vec![];
|
let mut bindings = vec![];
|
||||||
reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b)));
|
for pb in obj.projection_bounds() {
|
||||||
for did in obj.auto_traits() {
|
bindings.push(TypeBinding {
|
||||||
let empty = cx.tcx.intern_substs(&[]);
|
name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx),
|
||||||
let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
|
ty: pb.skip_binder().ty.clean(cx)
|
||||||
Some(did), false, vec![], empty);
|
});
|
||||||
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
}
|
||||||
let bound = GenericBound::TraitBound(PolyTrait {
|
|
||||||
trait_: ResolvedPath {
|
|
||||||
path,
|
|
||||||
typarams: None,
|
|
||||||
did,
|
|
||||||
is_generic: false,
|
|
||||||
},
|
|
||||||
generic_params: Vec::new(),
|
|
||||||
}, hir::TraitBoundModifier::None);
|
|
||||||
typarams.push(bound);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut bindings = vec![];
|
let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did),
|
||||||
for pb in obj.projection_bounds() {
|
false, bindings, principal.skip_binder().substs);
|
||||||
bindings.push(TypeBinding {
|
ResolvedPath {
|
||||||
name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx),
|
path,
|
||||||
ty: pb.skip_binder().ty.clean(cx)
|
typarams: Some(typarams),
|
||||||
});
|
did,
|
||||||
}
|
is_generic: false,
|
||||||
|
|
||||||
let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did),
|
|
||||||
false, bindings, principal.skip_binder().substs);
|
|
||||||
ResolvedPath {
|
|
||||||
path,
|
|
||||||
typarams: Some(typarams),
|
|
||||||
did,
|
|
||||||
is_generic: false,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Never
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Tuple(ref t) => Tuple(t.clean(cx)),
|
ty::Tuple(ref t) => Tuple(t.clean(cx)),
|
||||||
|
|
Loading…
Reference in New Issue