Rollup merge of #97183 - oli-obk:tait_ice_async, r=jackh726
wf-check generators fixes #90409 We should not rely on generators being well formed by construction now that they can get used via type alias impl trait (and thus users can choose generic arguments that are invalid). This can cause surprising behaviour if (definitely unsound) transmutes are used, and it's generally saner to just check for well formedness.
This commit is contained in:
commit
881e1c1a8b
compiler/rustc_trait_selection/src/traits
src/test/ui
generic-associated-types
lifetimes
type-alias-impl-trait
@ -295,6 +295,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||||||
/// This is called much less often than `needs_process_obligation`, so we
|
/// This is called much less often than `needs_process_obligation`, so we
|
||||||
/// never inline it.
|
/// never inline it.
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
|
#[instrument(level = "debug", skip(self, pending_obligation))]
|
||||||
fn process_obligation(
|
fn process_obligation(
|
||||||
&mut self,
|
&mut self,
|
||||||
pending_obligation: &mut PendingPredicateObligation<'tcx>,
|
pending_obligation: &mut PendingPredicateObligation<'tcx>,
|
||||||
@ -303,7 +304,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||||||
|
|
||||||
let obligation = &mut pending_obligation.obligation;
|
let obligation = &mut pending_obligation.obligation;
|
||||||
|
|
||||||
debug!(?obligation, "process_obligation pre-resolve");
|
debug!(?obligation, "pre-resolve");
|
||||||
|
|
||||||
if obligation.predicate.has_infer_types_or_consts() {
|
if obligation.predicate.has_infer_types_or_consts() {
|
||||||
obligation.predicate =
|
obligation.predicate =
|
||||||
@ -312,8 +313,6 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||||||
|
|
||||||
let obligation = &pending_obligation.obligation;
|
let obligation = &pending_obligation.obligation;
|
||||||
|
|
||||||
debug!(?obligation, ?obligation.cause, "process_obligation");
|
|
||||||
|
|
||||||
let infcx = self.selcx.infcx();
|
let infcx = self.selcx.infcx();
|
||||||
|
|
||||||
if obligation.predicate.has_projections() {
|
if obligation.predicate.has_projections() {
|
||||||
|
@ -559,7 +559,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Generator(..) => {
|
ty::Generator(did, substs, ..) => {
|
||||||
// Walk ALL the types in the generator: this will
|
// Walk ALL the types in the generator: this will
|
||||||
// include the upvar types as well as the yield
|
// include the upvar types as well as the yield
|
||||||
// type. Note that this is mildly distinct from
|
// type. Note that this is mildly distinct from
|
||||||
@ -567,6 +567,8 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||||||
// about the signature of the closure. We don't
|
// about the signature of the closure. We don't
|
||||||
// have the problem of implied bounds here since
|
// have the problem of implied bounds here since
|
||||||
// generators don't take arguments.
|
// generators don't take arguments.
|
||||||
|
let obligations = self.nominal_obligations(did, substs);
|
||||||
|
self.out.extend(obligations);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Closure(did, substs) => {
|
ty::Closure(did, substs) => {
|
||||||
@ -618,11 +620,9 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ty::Opaque(did, substs) => {
|
ty::Opaque(did, substs) => {
|
||||||
// all of the requirements on type parameters
|
// All of the requirements on type parameters
|
||||||
// should've been checked by the instantiation
|
// have already been checked for `impl Trait` in
|
||||||
// of whatever returned this exact `impl Trait`.
|
// return position. We do need to check type-alias-impl-trait though.
|
||||||
|
|
||||||
// for named opaque `impl Trait` types we still need to check them
|
|
||||||
if ty::is_impl_trait_defn(self.tcx, did).is_none() {
|
if ty::is_impl_trait_defn(self.tcx, did).is_none() {
|
||||||
let obligations = self.nominal_obligations(did, substs);
|
let obligations = self.nominal_obligations(did, substs);
|
||||||
self.out.extend(obligations);
|
self.out.extend(obligations);
|
||||||
@ -684,6 +684,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn nominal_obligations(
|
fn nominal_obligations(
|
||||||
&mut self,
|
&mut self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
@ -698,6 +699,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let predicates = predicates.instantiate(self.tcx, substs);
|
let predicates = predicates.instantiate(self.tcx, substs);
|
||||||
|
trace!("{:#?}", predicates);
|
||||||
debug_assert_eq!(predicates.predicates.len(), origins.len());
|
debug_assert_eq!(predicates.predicates.len(), origins.len());
|
||||||
|
|
||||||
iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev())
|
iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev())
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// check-pass
|
|
||||||
// edition:2018
|
// edition:2018
|
||||||
|
|
||||||
#![feature(generic_associated_types)]
|
#![feature(generic_associated_types)]
|
||||||
@ -34,6 +33,7 @@ where
|
|||||||
|
|
||||||
fn search<'c>(&'c self, _client: &'c ()) -> Self::Future<'c, Self, Criteria> {
|
fn search<'c>(&'c self, _client: &'c ()) -> Self::Future<'c, Self, Criteria> {
|
||||||
async move { todo!() }
|
async move { todo!() }
|
||||||
|
//~^ ERROR: the size for values of type `A` cannot be known at compilation time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
src/test/ui/generic-associated-types/issue-88287.stderr
Normal file
27
src/test/ui/generic-associated-types/issue-88287.stderr
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
error[E0277]: the size for values of type `A` cannot be known at compilation time
|
||||||
|
--> $DIR/issue-88287.rs:35:9
|
||||||
|
|
|
||||||
|
LL | type SearchFutureTy<'f, A, B: 'f>
|
||||||
|
| - this type parameter needs to be `std::marker::Sized`
|
||||||
|
...
|
||||||
|
LL | async move { todo!() }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
note: required by a bound in `<T as SearchableResourceExt<Criteria>>`
|
||||||
|
--> $DIR/issue-88287.rs:25:6
|
||||||
|
|
|
||||||
|
LL | impl<T, Criteria> SearchableResourceExt<Criteria> for T
|
||||||
|
| ^ required by this bound in `<T as SearchableResourceExt<Criteria>>`
|
||||||
|
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||||
|
|
|
||||||
|
LL - A: SearchableResource<B> + ?Sized + 'f,
|
||||||
|
LL + A: SearchableResource<B> + 'f,
|
||||||
|
|
|
||||||
|
help: consider relaxing the implicit `Sized` restriction
|
||||||
|
|
|
||||||
|
LL | T: SearchableResource<Criteria> + ?Sized,
|
||||||
|
| ++++++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
22
src/test/ui/lifetimes/issue-76168-hr-outlives-2.rs
Normal file
22
src/test/ui/lifetimes/issue-76168-hr-outlives-2.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// edition:2018
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
trait Trait<Input> {
|
||||||
|
type Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn walk<F>(filter: F)
|
||||||
|
where
|
||||||
|
for<'a> F: Trait<&'a u32> + 'a,
|
||||||
|
for<'a> <F as Trait<&'a u32>>::Output: 'a,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn walk2<F: 'static>(filter: F)
|
||||||
|
where
|
||||||
|
for<'a> F: Trait<&'a u32> + 'a,
|
||||||
|
for<'a> <F as Trait<&'a u32>>::Output: 'a,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
22
src/test/ui/type-alias-impl-trait/future.rs
Normal file
22
src/test/ui/type-alias-impl-trait/future.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
// edition:2021
|
||||||
|
// compile-flags: --crate-type=lib
|
||||||
|
|
||||||
|
use std::future::Future;
|
||||||
|
|
||||||
|
trait Bar {
|
||||||
|
fn bar(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
type FooFuture<B> = impl Future<Output = ()>;
|
||||||
|
|
||||||
|
fn foo<B: Bar>(bar: B) -> FooFuture<B> {
|
||||||
|
async move { bar.bar() }
|
||||||
|
//~^ ERROR: the trait bound `B: Bar` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mainish(ctx: &mut std::task::Context) {
|
||||||
|
let boom: FooFuture<u32> = unsafe { core::mem::zeroed() };
|
||||||
|
Box::pin(boom).as_mut().poll(ctx);
|
||||||
|
}
|
19
src/test/ui/type-alias-impl-trait/future.stderr
Normal file
19
src/test/ui/type-alias-impl-trait/future.stderr
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
error[E0277]: the trait bound `B: Bar` is not satisfied
|
||||||
|
--> $DIR/future.rs:15:5
|
||||||
|
|
|
||||||
|
LL | async move { bar.bar() }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B`
|
||||||
|
|
|
||||||
|
note: required by a bound in `foo`
|
||||||
|
--> $DIR/future.rs:14:11
|
||||||
|
|
|
||||||
|
LL | fn foo<B: Bar>(bar: B) -> FooFuture<B> {
|
||||||
|
| ^^^ required by this bound in `foo`
|
||||||
|
help: consider restricting type parameter `B`
|
||||||
|
|
|
||||||
|
LL | type FooFuture<B: Bar> = impl Future<Output = ()>;
|
||||||
|
| +++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
x
Reference in New Issue
Block a user