Skip to content

Commit 881e1c1

Browse files
authored
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.
2 parents 96c2df8 + f403260 commit 881e1c1

File tree

7 files changed

+101
-10
lines changed

7 files changed

+101
-10
lines changed

compiler/rustc_trait_selection/src/traits/fulfill.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
295295
/// This is called much less often than `needs_process_obligation`, so we
296296
/// never inline it.
297297
#[inline(never)]
298+
#[instrument(level = "debug", skip(self, pending_obligation))]
298299
fn process_obligation(
299300
&mut self,
300301
pending_obligation: &mut PendingPredicateObligation<'tcx>,
@@ -303,7 +304,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
303304

304305
let obligation = &mut pending_obligation.obligation;
305306

306-
debug!(?obligation, "process_obligation pre-resolve");
307+
debug!(?obligation, "pre-resolve");
307308

308309
if obligation.predicate.has_infer_types_or_consts() {
309310
obligation.predicate =
@@ -312,8 +313,6 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
312313

313314
let obligation = &pending_obligation.obligation;
314315

315-
debug!(?obligation, ?obligation.cause, "process_obligation");
316-
317316
let infcx = self.selcx.infcx();
318317

319318
if obligation.predicate.has_projections() {

compiler/rustc_trait_selection/src/traits/wf.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -559,14 +559,16 @@ impl<'tcx> WfPredicates<'tcx> {
559559
}
560560
}
561561

562-
ty::Generator(..) => {
562+
ty::Generator(did, substs, ..) => {
563563
// Walk ALL the types in the generator: this will
564564
// include the upvar types as well as the yield
565565
// type. Note that this is mildly distinct from
566566
// the closure case, where we have to be careful
567567
// about the signature of the closure. We don't
568568
// have the problem of implied bounds here since
569569
// generators don't take arguments.
570+
let obligations = self.nominal_obligations(did, substs);
571+
self.out.extend(obligations);
570572
}
571573

572574
ty::Closure(did, substs) => {
@@ -618,11 +620,9 @@ impl<'tcx> WfPredicates<'tcx> {
618620
}
619621

620622
ty::Opaque(did, substs) => {
621-
// all of the requirements on type parameters
622-
// should've been checked by the instantiation
623-
// of whatever returned this exact `impl Trait`.
624-
625-
// for named opaque `impl Trait` types we still need to check them
623+
// All of the requirements on type parameters
624+
// have already been checked for `impl Trait` in
625+
// return position. We do need to check type-alias-impl-trait though.
626626
if ty::is_impl_trait_defn(self.tcx, did).is_none() {
627627
let obligations = self.nominal_obligations(did, substs);
628628
self.out.extend(obligations);
@@ -684,6 +684,7 @@ impl<'tcx> WfPredicates<'tcx> {
684684
}
685685
}
686686

687+
#[instrument(level = "debug", skip(self))]
687688
fn nominal_obligations(
688689
&mut self,
689690
def_id: DefId,
@@ -698,6 +699,7 @@ impl<'tcx> WfPredicates<'tcx> {
698699
}
699700

700701
let predicates = predicates.instantiate(self.tcx, substs);
702+
trace!("{:#?}", predicates);
701703
debug_assert_eq!(predicates.predicates.len(), origins.len());
702704

703705
iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev())

src/test/ui/generic-associated-types/issue-88287.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// check-pass
21
// edition:2018
32

43
#![feature(generic_associated_types)]
@@ -34,6 +33,7 @@ where
3433

3534
fn search<'c>(&'c self, _client: &'c ()) -> Self::Future<'c, Self, Criteria> {
3635
async move { todo!() }
36+
//~^ ERROR: the size for values of type `A` cannot be known at compilation time
3737
}
3838
}
3939

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0277]: the size for values of type `A` cannot be known at compilation time
2+
--> $DIR/issue-88287.rs:35:9
3+
|
4+
LL | type SearchFutureTy<'f, A, B: 'f>
5+
| - this type parameter needs to be `std::marker::Sized`
6+
...
7+
LL | async move { todo!() }
8+
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
9+
|
10+
note: required by a bound in `<T as SearchableResourceExt<Criteria>>`
11+
--> $DIR/issue-88287.rs:25:6
12+
|
13+
LL | impl<T, Criteria> SearchableResourceExt<Criteria> for T
14+
| ^ required by this bound in `<T as SearchableResourceExt<Criteria>>`
15+
help: consider removing the `?Sized` bound to make the type parameter `Sized`
16+
|
17+
LL - A: SearchableResource<B> + ?Sized + 'f,
18+
LL + A: SearchableResource<B> + 'f,
19+
|
20+
help: consider relaxing the implicit `Sized` restriction
21+
|
22+
LL | T: SearchableResource<Criteria> + ?Sized,
23+
| ++++++++
24+
25+
error: aborting due to previous error
26+
27+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// edition:2018
2+
// check-pass
3+
4+
trait Trait<Input> {
5+
type Output;
6+
}
7+
8+
async fn walk<F>(filter: F)
9+
where
10+
for<'a> F: Trait<&'a u32> + 'a,
11+
for<'a> <F as Trait<&'a u32>>::Output: 'a,
12+
{
13+
}
14+
15+
async fn walk2<F: 'static>(filter: F)
16+
where
17+
for<'a> F: Trait<&'a u32> + 'a,
18+
for<'a> <F as Trait<&'a u32>>::Output: 'a,
19+
{
20+
}
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#![feature(type_alias_impl_trait)]
2+
3+
// edition:2021
4+
// compile-flags: --crate-type=lib
5+
6+
use std::future::Future;
7+
8+
trait Bar {
9+
fn bar(&self);
10+
}
11+
12+
type FooFuture<B> = impl Future<Output = ()>;
13+
14+
fn foo<B: Bar>(bar: B) -> FooFuture<B> {
15+
async move { bar.bar() }
16+
//~^ ERROR: the trait bound `B: Bar` is not satisfied
17+
}
18+
19+
pub fn mainish(ctx: &mut std::task::Context) {
20+
let boom: FooFuture<u32> = unsafe { core::mem::zeroed() };
21+
Box::pin(boom).as_mut().poll(ctx);
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0277]: the trait bound `B: Bar` is not satisfied
2+
--> $DIR/future.rs:15:5
3+
|
4+
LL | async move { bar.bar() }
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `B`
6+
|
7+
note: required by a bound in `foo`
8+
--> $DIR/future.rs:14:11
9+
|
10+
LL | fn foo<B: Bar>(bar: B) -> FooFuture<B> {
11+
| ^^^ required by this bound in `foo`
12+
help: consider restricting type parameter `B`
13+
|
14+
LL | type FooFuture<B: Bar> = impl Future<Output = ()>;
15+
| +++++
16+
17+
error: aborting due to previous error
18+
19+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)