diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index f26310665f9fa..beb5afe3a1117 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -608,8 +608,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { | ty::Float(..) | ty::Error(_) | ty::Str - | ty::GeneratorWitness(..) - | ty::GeneratorWitnessMIR(..) | ty::Never | ty::Param(_) | ty::Bound(..) @@ -681,6 +679,12 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } } + ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => { + // Unspecified in RFC 1214. + // They are always WF when the gnereator passes typeck/borrowck. + walker.skip_current_subtree(); + } + ty::Generator(did, args, ..) => { // Walk ALL the types in the generator: this will // include the upvar types as well as the yield diff --git a/tests/ui/async-await/generator-wf-check.output_wf.stderr b/tests/ui/async-await/generator-wf-check.output_wf.stderr new file mode 100644 index 0000000000000..14ada6b6f81bb --- /dev/null +++ b/tests/ui/async-await/generator-wf-check.output_wf.stderr @@ -0,0 +1,17 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/generator-wf-check.rs:24:5 + | +LL | / wf(async { +LL | | +LL | | None::> +LL | | }); + | |______^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test_output_wf() { + | +++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/async-await/generator-wf-check.rs b/tests/ui/async-await/generator-wf-check.rs new file mode 100644 index 0000000000000..ab815700d5dd9 --- /dev/null +++ b/tests/ui/async-await/generator-wf-check.rs @@ -0,0 +1,52 @@ +//! Tests if we draw implied bounds from the generator output or witness types, +//! and if so, whether we check these types are WF when checking the generator. + +// edition: 2021 +// revisions: output output_wf witness witness_wf +//[output] check-pass +//[output_wf] check-fail +//[witness] check-fail +//[witness_wf] check-fail + +struct Static(T); + +fn wf(_: T) {} + +#[cfg(output)] +fn test_output() { + async { + None::> + }; +} + +#[cfg(output_wf)] +fn test_output_wf() { + wf(async { + //[output_wf]~^ ERROR `T` may not live long enough + None::> + }); +} + +#[cfg(witness)] +fn test_witness() { + async { + let witness: Option> = None; + //[witness]~^ ERROR `T` may not live long enough + async {}.await; + drop(witness); + //[witness]~^ ERROR `T` may not live long enough + }; +} + +#[cfg(witness_wf)] +fn test_witness_wf() { + wf(async { + let witness: Option> = None; + //[witness_wf]~^ ERROR `T` may not live long enough + async {}.await; + drop(witness); + //[witness_wf]~^ ERROR `T` may not live long enough + }); +} + +fn main() {} diff --git a/tests/ui/async-await/generator-wf-check.witness.stderr b/tests/ui/async-await/generator-wf-check.witness.stderr new file mode 100644 index 0000000000000..b8888f78080ed --- /dev/null +++ b/tests/ui/async-await/generator-wf-check.witness.stderr @@ -0,0 +1,25 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/generator-wf-check.rs:33:22 + | +LL | let witness: Option> = None; + | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test_witness() { + | +++++++++ + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/generator-wf-check.rs:36:9 + | +LL | drop(witness); + | ^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test_witness() { + | +++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/async-await/generator-wf-check.witness_wf.stderr b/tests/ui/async-await/generator-wf-check.witness_wf.stderr new file mode 100644 index 0000000000000..8780c50f4ec36 --- /dev/null +++ b/tests/ui/async-await/generator-wf-check.witness_wf.stderr @@ -0,0 +1,25 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/generator-wf-check.rs:44:22 + | +LL | let witness: Option> = None; + | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test_witness_wf() { + | +++++++++ + +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/generator-wf-check.rs:47:9 + | +LL | drop(witness); + | ^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test_witness_wf() { + | +++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0310`.