opaque types may also be sized
This commit is contained in:
parent
ef0ba1d2ce
commit
1d834cb657
@ -2282,19 +2282,18 @@ pub fn ptr_metadata_ty(
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(..) => {
|
||||
|
@ -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() {}
|
||||
|
Loading…
Reference in New Issue
Block a user