opaque types may also be sized

This commit is contained in:
Michael Goulet 2022-02-13 19:57:23 -08:00
parent ef0ba1d2ce
commit 1d834cb657
3 changed files with 37 additions and 13 deletions

View File

@ -2282,19 +2282,18 @@ impl<'tcx> Ty<'tcx> {
ty::Str | ty::Slice(_) => (tcx.types.usize, false),
ty::Dynamic(..) => {
let dyn_metadata = tcx.lang_items().dyn_metadata().unwrap();
(tcx.type_of(dyn_metadata).subst(tcx, &[self.into()]), false)
(tcx.type_of(dyn_metadata).subst(tcx, &[tail.into()]), false)
},
// type parameters only have unit metadata if they're sized, so return true
// to make sure we double check this during confirmation
ty::Param(_) | ty::Projection(_) => (tcx.types.unit, true),
ty::Param(_) | ty::Projection(_) | ty::Opaque(..) => (tcx.types.unit, true),
ty::Opaque(..)
| ty::Infer(ty::TyVar(_))
ty::Infer(ty::TyVar(_))
| ty::Bound(..)
| ty::Placeholder(..)
| ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
bug!("`ptr_metadata_ty` applied to unexpected type: {:?}", self)
bug!("`ptr_metadata_ty` applied to unexpected type: {:?} (tail = {:?})", self, tail)
}
}
}

View File

@ -1439,10 +1439,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,
// type parameters and unnormalized projections have pointer metadata if they're still known to be sized
ty::Param(_) | ty::Projection(..) => tail.is_sized(selcx.tcx().at(obligation.cause.span), obligation.param_env),
// 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
}
ty::Opaque(..)
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
ty::Param(_)
| ty::Projection(..)
| ty::Opaque(..)
| ty::Bound(..)
| ty::Placeholder(..)
| ty::Infer(..)
@ -1451,7 +1459,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
candidate_set.mark_ambiguous();
}
false
},
}
}
}
super::ImplSource::Param(..) => {

View File

@ -1,12 +1,29 @@
// check-pass
// edition:2018
#![feature(ptr_metadata)]
#![feature(type_alias_impl_trait)]
fn a<T>() {
b::<T>();
b::<std::cell::Cell<T>>();
type Opaque = impl std::future::Future;
fn opaque() -> Opaque {
async {}
}
fn b<T: std::ptr::Pointee<Metadata = ()>>() {}
fn a<T>() {
// type parameter T is known to be sized
is_thin::<T>();
// tail of ADT (which is a type param) is known to be sized
is_thin::<std::cell::Cell<T>>();
// opaque type is known to be sized
is_thin::<Opaque>();
}
fn a2<T: Iterator>() {
// associated type is known to be sized
is_thin::<T::Item>();
}
fn is_thin<T: std::ptr::Pointee<Metadata = ()>>() {}
fn main() {}