Plumb dyn trait representation through ty::Dynamic

This commit is contained in:
Eric Holk 2022-04-13 16:11:28 -07:00
parent eff35e59c6
commit 6c01273a15
29 changed files with 110 additions and 57 deletions

View File

@ -69,7 +69,7 @@ impl<'a, 'tcx> VirtualIndex {
fn expect_dyn_trait_in_self<'tcx>(ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'tcx> {
for arg in ty.peel_refs().walk() {
if let GenericArgKind::Type(ty) = arg.unpack() {
if let ty::Dynamic(data, _) = ty.kind() {
if let ty::Dynamic(data, _, _) = ty.kind() {
return data.principal().expect("expected principal trait object");
}
}

View File

@ -312,7 +312,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let new_vptr = self.get_vtable_ptr(ty, data_b.principal())?;
self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest)
}
(_, &ty::Dynamic(ref data, _)) => {
(_, &ty::Dynamic(ref data, _, _repr)) => {
// Initial cast from sized to dyn trait
let vtable = self.get_vtable_ptr(src_pointee_ty, data.principal())?;
let ptr = self.read_scalar(src)?;

View File

@ -95,7 +95,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
| ty::Ref(_, _, _)
| ty::FnDef(_, _)
| ty::FnPtr(_)
| ty::Dynamic(_, _)
| ty::Dynamic(_, _, _)
| ty::Closure(_, _)
| ty::Generator(_, _, _)
| ty::GeneratorWitness(_)

View File

@ -48,7 +48,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
| ty::FnPtr(_)
| ty::Never
| ty::Tuple(_)
| ty::Dynamic(_, _) => self.pretty_print_type(ty),
| ty::Dynamic(_, _, _) => self.pretty_print_type(ty),
// Placeholders (all printed as `_` to uniformize them).
ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => {

View File

@ -544,7 +544,7 @@ pub struct TraitObjectVisitor(pub FxHashSet<DefId>);
impl<'tcx> TypeVisitor<'tcx> for TraitObjectVisitor {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
ty::Dynamic(preds, re) if re.is_static() => {
ty::Dynamic(preds, re, _) if re.is_static() => {
if let Some(def_id) = preds.principal_def_id() {
self.0.insert(def_id);
}

View File

@ -222,7 +222,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
}
has_emitted
}
ty::Dynamic(binder, _) => {
ty::Dynamic(binder, _, _) => {
let mut has_emitted = false;
for predicate in binder.iter() {
if let ty::ExistentialPredicate::Trait(ref trait_ref) =

View File

@ -63,7 +63,9 @@ use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx};
use rustc_target::spec::abi;
use rustc_type_ir::sty::TyKind::*;
use rustc_type_ir::{InternAs, InternIteratorElement, Interner, TypeFlags};
use rustc_type_ir::{
InternAs, InternIteratorElement, Interner, TraitObjectRepresentation, TypeFlags,
};
use std::any::Any;
use std::borrow::Borrow;
@ -2545,8 +2547,9 @@ impl<'tcx> TyCtxt<'tcx> {
self,
obj: &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>,
reg: ty::Region<'tcx>,
repr: TraitObjectRepresentation,
) -> Ty<'tcx> {
self.mk_ty(Dynamic(obj, reg))
self.mk_ty(Dynamic(obj, reg, repr))
}
#[inline]

View File

@ -467,7 +467,7 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> {
}
}
Dynamic(dty, _) => {
Dynamic(dty, _, _) => {
for pred in *dty {
match pred.skip_binder() {
ExistentialPredicate::Trait(_) | ExistentialPredicate::Projection(_) => {

View File

@ -171,7 +171,7 @@ impl FlagComputation {
self.add_substs(substs);
}
&ty::Dynamic(obj, r) => {
&ty::Dynamic(obj, r, _) => {
for predicate in obj.iter() {
self.bound_computation(predicate, |computation, predicate| match predicate {
ty::ExistentialPredicate::Trait(tr) => computation.add_substs(tr.substs),

View File

@ -2464,7 +2464,8 @@ where
match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() {
ty::Slice(_) | ty::Str => TyMaybeWithLayout::Ty(tcx.types.usize),
ty::Dynamic(_, _) => {
// FIXME(eholk): Do the right thing with trait object representation
ty::Dynamic(_, _, _repr) => {
TyMaybeWithLayout::Ty(tcx.mk_imm_ref(
tcx.lifetimes.re_static,
tcx.mk_array(tcx.types.usize, 3),

View File

@ -16,6 +16,7 @@ use rustc_session::cstore::{ExternCrate, ExternCrateSource};
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_target::abi::Size;
use rustc_target::spec::abi::Abi;
use rustc_type_ir::TraitObjectRepresentation;
use std::cell::Cell;
use std::char;
@ -619,12 +620,16 @@ pub trait PrettyPrinter<'tcx>:
ty::Adt(def, substs) => {
p!(print_def_path(def.did(), substs));
}
ty::Dynamic(data, r) => {
ty::Dynamic(data, r, repr) => {
let print_r = self.should_print_region(r);
if print_r {
p!("(");
}
p!("dyn ", print(data));
match repr {
TraitObjectRepresentation::Unsized => p!("dyn "),
TraitObjectRepresentation::Sized => p!("dyn* "),
}
p!(print(data));
if print_r {
p!(" + ", print(r), ")");
}

View File

@ -441,7 +441,9 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
(&ty::Foreign(a_id), &ty::Foreign(b_id)) if a_id == b_id => Ok(tcx.mk_foreign(a_id)),
(&ty::Dynamic(a_obj, a_region), &ty::Dynamic(b_obj, b_region)) => {
(&ty::Dynamic(a_obj, a_region, a_repr), &ty::Dynamic(b_obj, b_region, b_repr))
if a_repr == b_repr =>
{
let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| {
relation.relate_with_variance(
ty::Contravariant,
@ -450,7 +452,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
b_region,
)
})?;
Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound))
Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound, a_repr))
}
(&ty::Generator(a_id, a_substs, movability), &ty::Generator(b_id, b_substs, _))

View File

@ -1014,9 +1014,11 @@ impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> {
ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?),
ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?),
ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?),
ty::Dynamic(trait_ty, region) => {
ty::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?)
}
ty::Dynamic(trait_ty, region, representation) => ty::Dynamic(
trait_ty.try_fold_with(folder)?,
region.try_fold_with(folder)?,
representation,
),
ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?),
ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?),
@ -1060,7 +1062,7 @@ impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> {
}
ty::Slice(typ) => typ.visit_with(visitor),
ty::Adt(_, substs) => substs.visit_with(visitor),
ty::Dynamic(ref trait_ty, ref reg) => {
ty::Dynamic(ref trait_ty, ref reg, _) => {
trait_ty.visit_with(visitor)?;
reg.visit_with(visitor)
}

View File

@ -152,7 +152,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
ty::Projection(data) => {
stack.extend(data.substs.iter().rev());
}
ty::Dynamic(obj, lt) => {
ty::Dynamic(obj, lt, _) => {
stack.push(lt.into());
stack.extend(obj.iter().rev().flat_map(|predicate| {
let (substs, opt_ty) = match predicate.skip_binder() {

View File

@ -627,7 +627,7 @@ fn encode_ty<'tcx>(
}
// Trait types
ty::Dynamic(predicates, region) => {
ty::Dynamic(predicates, region, _repr) => {
// u3dynI<element-type1[..element-typeN]>E, where <element-type> is <predicate>, as
// vendor extended type.
let mut s = String::from("u3dynI");

View File

@ -479,7 +479,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
})?;
}
ty::Dynamic(predicates, r) => {
ty::Dynamic(predicates, r, _repr) => {
self.push("D");
self = self.print_dyn_existential(predicates)?;
self = r.print(self)?;

View File

@ -256,7 +256,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
}
}
if let ty::Dynamic(traits, _) = self_ty.kind() {
if let ty::Dynamic(traits, _, _) = self_ty.kind() {
for t in traits.iter() {
if let ty::ExistentialPredicate::Trait(trait_ref) = t.skip_binder() {
flags.push((sym::_Self, Some(self.tcx.def_path_str(trait_ref.def_id))))

View File

@ -1067,7 +1067,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
self_ty: Ty<'tcx>,
object_ty: Ty<'tcx>,
) {
let ty::Dynamic(predicates, _) = object_ty.kind() else { return; };
let ty::Dynamic(predicates, _, _) = object_ty.kind() else { return; };
let self_ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, self_ty);
for predicate in predicates.iter() {
@ -1365,7 +1365,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let trait_pred = self.resolve_vars_if_possible(trait_pred);
let ty = trait_pred.skip_binder().self_ty();
let is_object_safe = match ty.kind() {
ty::Dynamic(predicates, _) => {
ty::Dynamic(predicates, _, _) => {
// If the `dyn Trait` is not object safe, do not suggest `Box<dyn Trait>`.
predicates
.principal_def_id()
@ -1425,7 +1425,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
let mut spans_and_needs_box = vec![];
match liberated_sig.output().kind() {
ty::Dynamic(predicates, _) => {
ty::Dynamic(predicates, _, _) => {
let cause = ObligationCause::misc(ret_ty.span, fn_hir_id);
let param_env = ty::ParamEnv::empty();

View File

@ -21,6 +21,7 @@ use rustc_middle::ty::abstract_const::{walk_abstract_const, AbstractConst};
use rustc_middle::ty::subst::{GenericArg, InternalSubsts, Subst};
use rustc_middle::ty::{
self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor,
TraitObjectRepresentation,
};
use rustc_middle::ty::{Predicate, ToPredicate};
use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
@ -600,7 +601,8 @@ fn object_ty_for_trait<'tcx>(
let existential_predicates = tcx
.mk_poly_existential_predicates(iter::once(trait_predicate).chain(projection_predicates));
let object_ty = tcx.mk_dynamic(existential_predicates, lifetime);
let object_ty =
tcx.mk_dynamic(existential_predicates, lifetime, TraitObjectRepresentation::Unsized);
debug!("object_ty_for_trait: object_ty=`{}`", object_ty);

View File

@ -784,7 +784,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let upcast_trait_ref;
match (source.kind(), target.kind()) {
// TraitA+Kx+'a -> TraitB+Ky+'b (trait upcasting coercion).
(&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
(&ty::Dynamic(ref data_a, r_a, repr_a), &ty::Dynamic(ref data_b, r_b, repr_b))
if repr_a == repr_b =>
{
// See `assemble_candidates_for_unsizing` for more info.
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
let principal_a = data_a.principal().unwrap();
@ -810,7 +812,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map(ty::Binder::dummy),
);
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
let source_trait = tcx.mk_dynamic(existential_predicates, r_b);
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_b);
// Require that the traits involved in this upcast are **equal**;
// only the **lifetime bound** is changed.
@ -888,7 +890,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let mut nested = vec![];
match (source.kind(), target.kind()) {
// Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
(&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
(&ty::Dynamic(ref data_a, r_a, repr_a), &ty::Dynamic(ref data_b, r_b, repr_b))
if repr_a == repr_b =>
{
// See `assemble_candidates_for_unsizing` for more info.
// We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
let iter = data_a
@ -907,7 +911,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map(ty::Binder::dummy),
);
let existential_predicates = tcx.mk_poly_existential_predicates(iter);
let source_trait = tcx.mk_dynamic(existential_predicates, r_b);
let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_b);
// Require that the traits involved in this upcast are **equal**;
// only the **lifetime bound** is changed.
@ -934,7 +938,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
// `T` -> `Trait`
(_, &ty::Dynamic(ref data, r)) => {
(_, &ty::Dynamic(ref data, r, _repr)) => {
let mut object_dids = data.auto_traits().chain(data.principal_def_id());
if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
return Err(TraitNotObjectSafe(did));

View File

@ -639,7 +639,7 @@ impl<'tcx> WfPredicates<'tcx> {
}
}
ty::Dynamic(data, r) => {
ty::Dynamic(data, r, _) => {
// WfObject
//
// Here, we defer WF checking due to higher-ranked

View File

@ -326,7 +326,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
)),
})
}
ty::Dynamic(predicates, region) => chalk_ir::TyKind::Dyn(chalk_ir::DynTy {
ty::Dynamic(predicates, region, _repr) => chalk_ir::TyKind::Dyn(chalk_ir::DynTy {
bounds: predicates.lower_into(interner),
lifetime: region.lower_into(interner),
}),

View File

@ -389,7 +389,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Ty<'_>> {
let self_ty = trait_ref.self_ty();
let self_ty_matches = match self_ty.kind() {
ty::Dynamic(ref data, re) if re.is_static() => data.principal().is_none(),
ty::Dynamic(ref data, re, _) if re.is_static() => data.principal().is_none(),
_ => false,
};

View File

@ -18,6 +18,27 @@ use self::TyKind::*;
use rustc_data_structures::stable_hasher::HashStable;
use rustc_serialize::{Decodable, Decoder, Encodable};
/// Specifies how a trait object is represented.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
pub enum TraitObjectRepresentation {
/// An unsized `dyn Trait` object
Unsized,
/// A sized `dyn* Trait` object
Sized,
}
// Manually implemented because deriving HashStable requires rustc_query_system, which would
// create a cyclic dependency.
impl<CTX> HashStable<CTX> for TraitObjectRepresentation {
fn hash_stable(
&self,
hcx: &mut CTX,
hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
) {
std::mem::discriminant(self).hash_stable(hcx, hasher);
}
}
/// Defines the kinds of types used by the type system.
///
/// Types written by the user start out as `hir::TyKind` and get
@ -95,7 +116,7 @@ pub enum TyKind<I: Interner> {
FnPtr(I::PolyFnSig),
/// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
Dynamic(I::ListBinderExistentialPredicate, I::Region),
Dynamic(I::ListBinderExistentialPredicate, I::Region, TraitObjectRepresentation),
/// The anonymous type of a closure. Used to represent the type of `|a| a`.
///
@ -218,7 +239,7 @@ const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
Ref(_, _, _) => 11,
FnDef(_, _) => 12,
FnPtr(_) => 13,
Dynamic(_, _) => 14,
Dynamic(..) => 14,
Closure(_, _) => 15,
Generator(_, _, _) => 16,
GeneratorWitness(_) => 17,
@ -252,7 +273,7 @@ impl<I: Interner> Clone for TyKind<I> {
Ref(r, t, m) => Ref(r.clone(), t.clone(), m.clone()),
FnDef(d, s) => FnDef(d.clone(), s.clone()),
FnPtr(s) => FnPtr(s.clone()),
Dynamic(p, r) => Dynamic(p.clone(), r.clone()),
Dynamic(p, r, repr) => Dynamic(p.clone(), r.clone(), repr.clone()),
Closure(d, s) => Closure(d.clone(), s.clone()),
Generator(d, s, m) => Generator(d.clone(), s.clone(), m.clone()),
GeneratorWitness(g) => GeneratorWitness(g.clone()),
@ -297,9 +318,10 @@ impl<I: Interner> PartialEq for TyKind<I> {
__self_0 == __arg_1_0 && __self_1 == __arg_1_1
}
(&FnPtr(ref __self_0), &FnPtr(ref __arg_1_0)) => __self_0 == __arg_1_0,
(&Dynamic(ref __self_0, ref __self_1), &Dynamic(ref __arg_1_0, ref __arg_1_1)) => {
__self_0 == __arg_1_0 && __self_1 == __arg_1_1
}
(
&Dynamic(ref __self_0, ref __self_1, ref self_repr),
&Dynamic(ref __arg_1_0, ref __arg_1_1, ref arg_repr),
) => __self_0 == __arg_1_0 && __self_1 == __arg_1_1 && self_repr == arg_repr,
(&Closure(ref __self_0, ref __self_1), &Closure(ref __arg_1_0, ref __arg_1_1)) => {
__self_0 == __arg_1_0 && __self_1 == __arg_1_1
}
@ -384,12 +406,16 @@ impl<I: Interner> Ord for TyKind<I> {
}
}
(&FnPtr(ref __self_0), &FnPtr(ref __arg_1_0)) => Ord::cmp(__self_0, __arg_1_0),
(&Dynamic(ref __self_0, ref __self_1), &Dynamic(ref __arg_1_0, ref __arg_1_1)) => {
match Ord::cmp(__self_0, __arg_1_0) {
Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
(
&Dynamic(ref __self_0, ref __self_1, ref self_repr),
&Dynamic(ref __arg_1_0, ref __arg_1_1, ref arg_repr),
) => match Ord::cmp(__self_0, __arg_1_0) {
Ordering::Equal => match Ord::cmp(__self_1, __arg_1_1) {
Ordering::Equal => Ord::cmp(self_repr, arg_repr),
cmp => cmp,
}
}
},
cmp => cmp,
},
(&Closure(ref __self_0, ref __self_1), &Closure(ref __arg_1_0, ref __arg_1_1)) => {
match Ord::cmp(__self_0, __arg_1_0) {
Ordering::Equal => Ord::cmp(__self_1, __arg_1_1),
@ -492,10 +518,11 @@ impl<I: Interner> hash::Hash for TyKind<I> {
hash::Hash::hash(&tykind_discriminant(self), state);
hash::Hash::hash(__self_0, state)
}
(&Dynamic(ref __self_0, ref __self_1),) => {
(&Dynamic(ref __self_0, ref __self_1, ref repr),) => {
hash::Hash::hash(&tykind_discriminant(self), state);
hash::Hash::hash(__self_0, state);
hash::Hash::hash(__self_1, state)
hash::Hash::hash(__self_1, state);
hash::Hash::hash(repr, state)
}
(&Closure(ref __self_0, ref __self_1),) => {
hash::Hash::hash(&tykind_discriminant(self), state);
@ -570,7 +597,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
Ref(f0, f1, f2) => Formatter::debug_tuple_field3_finish(f, "Ref", f0, f1, f2),
FnDef(f0, f1) => Formatter::debug_tuple_field2_finish(f, "FnDef", f0, f1),
FnPtr(f0) => Formatter::debug_tuple_field1_finish(f, "FnPtr", f0),
Dynamic(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Dynamic", f0, f1),
Dynamic(f0, f1, f2) => Formatter::debug_tuple_field3_finish(f, "Dynamic", f0, f1, f2),
Closure(f0, f1) => Formatter::debug_tuple_field2_finish(f, "Closure", f0, f1),
Generator(f0, f1, f2) => {
Formatter::debug_tuple_field3_finish(f, "Generator", f0, f1, f2)
@ -659,9 +686,10 @@ where
FnPtr(polyfnsig) => e.emit_enum_variant(disc, |e| {
polyfnsig.encode(e);
}),
Dynamic(l, r) => e.emit_enum_variant(disc, |e| {
Dynamic(l, r, repr) => e.emit_enum_variant(disc, |e| {
l.encode(e);
r.encode(e);
repr.encode(e);
}),
Closure(def_id, substs) => e.emit_enum_variant(disc, |e| {
def_id.encode(e);
@ -748,7 +776,7 @@ where
11 => Ref(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
12 => FnDef(Decodable::decode(d), Decodable::decode(d)),
13 => FnPtr(Decodable::decode(d)),
14 => Dynamic(Decodable::decode(d), Decodable::decode(d)),
14 => Dynamic(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
15 => Closure(Decodable::decode(d), Decodable::decode(d)),
16 => Generator(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
17 => GeneratorWitness(Decodable::decode(d)),
@ -845,9 +873,10 @@ where
FnPtr(polyfnsig) => {
polyfnsig.hash_stable(__hcx, __hasher);
}
Dynamic(l, r) => {
Dynamic(l, r, repr) => {
l.hash_stable(__hcx, __hasher);
r.hash_stable(__hcx, __hasher);
repr.hash_stable(__hcx, __hasher);
}
Closure(def_id, substs) => {
def_id.hash_stable(__hcx, __hasher);

View File

@ -31,6 +31,7 @@ use rustc_middle::ty::GenericParamDefKind;
use rustc_middle::ty::{
self, Const, DefIdTree, EarlyBinder, IsSuggestable, Ty, TyCtxt, TypeVisitable,
};
use rustc_middle::ty::{TraitObjectRepresentation};
use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
use rustc_span::edition::Edition;
use rustc_span::lev_distance::find_best_match_for_name;
@ -1572,7 +1573,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
};
debug!("region_bound: {:?}", region_bound);
let ty = tcx.mk_dynamic(existential_predicates, region_bound);
let ty = tcx.mk_dynamic(
existential_predicates,
region_bound,
TraitObjectRepresentation::Unsized, // FIXME: check whether the source syntax was dyn or dyn*
);
debug!("trait_object_type: {:?}", ty);
ty
}

View File

@ -527,7 +527,7 @@ fn check_must_not_suspend_ty<'tcx>(
}
has_emitted
}
ty::Dynamic(binder, _) => {
ty::Dynamic(binder, _, _) => {
let mut has_emitted = false;
for predicate in binder.iter() {
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {

View File

@ -537,7 +537,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
bound_spans.push((self.tcx.def_span(def.did()), msg))
}
// Point at the trait object that couldn't satisfy the bound.
ty::Dynamic(preds, _) => {
ty::Dynamic(preds, _, _) => {
for pred in preds.iter() {
match pred.skip_binder() {
ty::ExistentialPredicate::Trait(tr) => bound_spans

View File

@ -257,7 +257,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_invariant_substs(current, substs, variance);
}
ty::Dynamic(data, r) => {
ty::Dynamic(data, r, _) => {
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
let contra = self.contravariant(variance);
self.add_constraints_from_region(current, r, contra);

View File

@ -1600,7 +1600,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
let path = external_path(cx, did, false, ThinVec::new(), InternalSubsts::empty());
Type::Path { path }
}
ty::Dynamic(obj, ref reg) => {
ty::Dynamic(obj, ref reg, _) => {
// HACK: pick the first `did` as the `did` of the trait object. Someone
// might want to implement "native" support for marker-trait-only
// trait objects.