From 1d834cb657d4911535a01af38e974d11d081e9f4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 13 Feb 2022 19:57:23 -0800 Subject: [PATCH] opaque types may also be sized --- compiler/rustc_middle/src/ty/sty.rs | 9 +++---- .../src/traits/project.rs | 16 +++++++++--- src/test/ui/traits/pointee-tail-is-generic.rs | 25 ++++++++++++++++--- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 061520189e9..f64d1e06f6c 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -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) } } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 823b03eab95..26f7d0782c2 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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(..) => { diff --git a/src/test/ui/traits/pointee-tail-is-generic.rs b/src/test/ui/traits/pointee-tail-is-generic.rs index 097881256ba..e0da0fc3861 100644 --- a/src/test/ui/traits/pointee-tail-is-generic.rs +++ b/src/test/ui/traits/pointee-tail-is-generic.rs @@ -1,12 +1,29 @@ // check-pass +// edition:2018 #![feature(ptr_metadata)] +#![feature(type_alias_impl_trait)] -fn a() { - b::(); - b::>(); +type Opaque = impl std::future::Future; + +fn opaque() -> Opaque { + async {} } -fn b>() {} +fn a() { + // type parameter T is known to be sized + is_thin::(); + // tail of ADT (which is a type param) is known to be sized + is_thin::>(); + // opaque type is known to be sized + is_thin::(); +} + +fn a2() { + // associated type is known to be sized + is_thin::(); +} + +fn is_thin>() {} fn main() {}