Skip to content

Commit f403260

Browse files
committed
Check generators for well formedness
1 parent 144227d commit f403260

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)