Rollup merge of #93977 - compiler-errors:sized-generic-metadata, r=wesleywiser
Type params and assoc types have unit metadata if they are sized Extend the logic in `Pointee` projection to ensure that we can satisfy `<T as Pointee>::Metadata = ()` if `T: Sized`. cc: `@SimonSapin` and #93959
This commit is contained in:
commit
774655da5f
5 changed files with 134 additions and 15 deletions
|
@ -1469,6 +1469,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
|
||||
let tail = selcx.tcx().struct_tail_with_normalize(self_ty, |ty| {
|
||||
// We throw away any obligations we get from this, since we normalize
|
||||
// and confirm these obligations once again during confirmation
|
||||
normalize_with_depth(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
|
@ -1485,7 +1487,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Float(_)
|
||||
| ty::Foreign(_)
|
||||
| ty::Str
|
||||
| ty::Array(..)
|
||||
| ty::Slice(_)
|
||||
|
@ -1498,6 +1499,8 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
| ty::Generator(..)
|
||||
| ty::GeneratorWitness(..)
|
||||
| ty::Never
|
||||
// Extern types have unit metadata, according to RFC 2850
|
||||
| ty::Foreign(_)
|
||||
// If returned by `struct_tail_without_normalization` this is a unit struct
|
||||
// without any fields, or not a struct, and therefore is Sized.
|
||||
| ty::Adt(..)
|
||||
|
@ -1506,9 +1509,18 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
// Integers and floats are always Sized, and so have unit type metadata.
|
||||
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
|
||||
|
||||
ty::Projection(..)
|
||||
// type parameters, opaques, and unnormalized projections have pointer
|
||||
// metadata if they're known (e.g. by the param_env) to be sized
|
||||
ty::Param(_) | ty::Projection(..) | ty::Opaque(..)
|
||||
if tail.is_sized(selcx.tcx().at(obligation.cause.span), obligation.param_env) =>
|
||||
{
|
||||
true
|
||||
}
|
||||
|
||||
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
|
||||
ty::Param(_)
|
||||
| ty::Projection(..)
|
||||
| ty::Opaque(..)
|
||||
| ty::Param(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(..)
|
||||
|
@ -1517,7 +1529,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
candidate_set.mark_ambiguous();
|
||||
}
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
super::ImplSource::Param(..) => {
|
||||
|
@ -1727,7 +1739,7 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
|
|||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
|
||||
let mut obligations = vec![];
|
||||
let metadata_ty = self_ty.ptr_metadata_ty(tcx, |ty| {
|
||||
let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| {
|
||||
normalize_with_depth_to(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
|
@ -1737,6 +1749,19 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
|
|||
&mut obligations,
|
||||
)
|
||||
});
|
||||
if check_is_sized {
|
||||
let sized_predicate = ty::Binder::dummy(ty::TraitRef::new(
|
||||
tcx.require_lang_item(LangItem::Sized, None),
|
||||
tcx.mk_substs_trait(self_ty, &[]),
|
||||
))
|
||||
.without_const()
|
||||
.to_predicate(tcx);
|
||||
obligations.push(Obligation::new(
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
sized_predicate,
|
||||
));
|
||||
}
|
||||
|
||||
let substs = tcx.mk_substs([self_ty.into()].iter());
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue