From aa1653e5be13cdcb818ae1f933bec7ad15e33b70 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 19:00:47 -0400 Subject: [PATCH 1/4] Rename coroutine_stalled_predicates --- compiler/rustc_hir_analysis/src/check/check.rs | 6 +++--- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- compiler/rustc_hir_typeck/src/writeback.rs | 4 ++-- compiler/rustc_middle/src/ty/typeck_results.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 216b89fd4f150..ae3623aa329df 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1552,8 +1552,8 @@ pub(super) fn check_coroutine_obligations( let typeck = tcx.typeck(def_id); let param_env = tcx.param_env(typeck.hir_owner.def_id); - let coroutine_interior_predicates = &typeck.coroutine_interior_predicates[&def_id]; - debug!(?coroutine_interior_predicates); + let coroutine_stalled_predicates = &typeck.coroutine_stalled_predicates[&def_id]; + debug!(?coroutine_stalled_predicates); let infcx = tcx .infer_ctxt() @@ -1566,7 +1566,7 @@ pub(super) fn check_coroutine_obligations( .build(); let mut fulfillment_cx = >::new(&infcx); - for (predicate, cause) in coroutine_interior_predicates { + for (predicate, cause) in coroutine_stalled_predicates { let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate); fulfillment_cx.register_predicate_obligation(&infcx, obligation); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2d5ba447e4e68..1024dec1d9fe8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -579,7 +579,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!(?obligations); self.typeck_results .borrow_mut() - .coroutine_interior_predicates + .coroutine_stalled_predicates .insert(expr_def_id, obligations); } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 6604bf094c14a..73613923e69c2 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -552,11 +552,11 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); self.tcx().with_stable_hashing_context(move |ref hcx| { for (&expr_def_id, predicates) in - fcx_typeck_results.coroutine_interior_predicates.to_sorted(hcx, false).into_iter() + fcx_typeck_results.coroutine_stalled_predicates.to_sorted(hcx, false).into_iter() { let predicates = self.resolve(predicates.clone(), &self.fcx.tcx.def_span(expr_def_id)); - self.typeck_results.coroutine_interior_predicates.insert(expr_def_id, predicates); + self.typeck_results.coroutine_stalled_predicates.insert(expr_def_id, predicates); } }) } diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 995feeaa1487f..aa905466fbc87 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -201,7 +201,7 @@ pub struct TypeckResults<'tcx> { /// Stores the predicates that apply on coroutine witness types. /// formatting modified file tests/ui/coroutine/retain-resume-ref.rs - pub coroutine_interior_predicates: + pub coroutine_stalled_predicates: LocalDefIdMap, ObligationCause<'tcx>)>>, /// We sometimes treat byte string literals (which are of type `&[u8; N]`) @@ -243,7 +243,7 @@ impl<'tcx> TypeckResults<'tcx> { closure_min_captures: Default::default(), closure_fake_reads: Default::default(), rvalue_scopes: Default::default(), - coroutine_interior_predicates: Default::default(), + coroutine_stalled_predicates: Default::default(), treat_byte_string_as_slice: Default::default(), closure_size_eval: Default::default(), offset_of_data: Default::default(), From d29178c2efe7846fdb8c442219d7b70ae83e18e7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 19:44:23 -0400 Subject: [PATCH 2/4] Do check_coroutine_obligations once per typeck root --- .../rustc_hir_analysis/src/check/check.rs | 47 +++--------- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 8 +-- compiler/rustc_hir_typeck/src/writeback.rs | 13 ++-- compiler/rustc_interface/src/passes.rs | 4 +- .../rustc_middle/src/ty/typeck_results.rs | 9 +-- compiler/rustc_mir_transform/src/coroutine.rs | 40 +++++++++++ tests/ui/coroutine/clone-impl.rs | 24 +++++-- tests/ui/coroutine/clone-impl.stderr | 72 +++++++++---------- 8 files changed, 118 insertions(+), 99 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index ae3623aa329df..cb0ed68edff3e 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -10,10 +10,9 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::Node; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; -use rustc_infer::traits::{Obligation, TraitEngineExt as _}; +use rustc_infer::traits::Obligation; use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; use rustc_middle::middle::stability::EvalResult; -use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt}; @@ -26,7 +25,7 @@ use rustc_target::abi::FieldIdx; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; -use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _}; +use rustc_trait_selection::traits::{self}; use rustc_type_ir::fold::TypeFoldable; use std::cell::LazyCell; @@ -1541,55 +1540,31 @@ fn opaque_type_cycle_error( err.emit() } -// FIXME(@lcnr): This should not be computed per coroutine, but instead once for -// each typeck root. pub(super) fn check_coroutine_obligations( tcx: TyCtxt<'_>, def_id: LocalDefId, ) -> Result<(), ErrorGuaranteed> { - debug_assert!(tcx.is_coroutine(def_id.to_def_id())); + debug_assert!(!tcx.is_typeck_child(def_id.to_def_id())); - let typeck = tcx.typeck(def_id); - let param_env = tcx.param_env(typeck.hir_owner.def_id); + let typeck_results = tcx.typeck(def_id); + let param_env = tcx.param_env(def_id); - let coroutine_stalled_predicates = &typeck.coroutine_stalled_predicates[&def_id]; - debug!(?coroutine_stalled_predicates); + debug!(?typeck_results.coroutine_stalled_predicates); let infcx = tcx .infer_ctxt() // typeck writeback gives us predicates with their regions erased. // As borrowck already has checked lifetimes, we do not need to do it again. .ignoring_regions() - // Bind opaque types to type checking root, as they should have been checked by borrowck, - // but may show up in some cases, like when (root) obligations are stalled in the new solver. - .with_opaque_type_inference(typeck.hir_owner.def_id) + .with_opaque_type_inference(def_id) .build(); - let mut fulfillment_cx = >::new(&infcx); - for (predicate, cause) in coroutine_stalled_predicates { - let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate); - fulfillment_cx.register_predicate_obligation(&infcx, obligation); - } - - if (tcx.features().unsized_locals || tcx.features().unsized_fn_params) - && let Some(coroutine) = tcx.mir_coroutine_witnesses(def_id) - { - for field_ty in coroutine.field_tys.iter() { - fulfillment_cx.register_bound( - &infcx, - param_env, - field_ty.ty, - tcx.require_lang_item(hir::LangItem::Sized, Some(field_ty.source_info.span)), - ObligationCause::new( - field_ty.source_info.span, - def_id, - ObligationCauseCode::SizedCoroutineInterior(def_id), - ), - ); - } + let ocx = ObligationCtxt::new(&infcx); + for (predicate, cause) in &typeck_results.coroutine_stalled_predicates { + ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, *predicate)); } - let errors = fulfillment_cx.select_all_or_error(&infcx); + let errors = ocx.select_all_or_error(); debug!(?errors); if !errors.is_empty() { return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 1024dec1d9fe8..14e4236ad7859 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -575,12 +575,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { obligations .extend(self.fulfillment_cx.borrow_mut().drain_unstalled_obligations(&self.infcx)); - let obligations = obligations.into_iter().map(|o| (o.predicate, o.cause)).collect(); - debug!(?obligations); - self.typeck_results - .borrow_mut() - .coroutine_stalled_predicates - .insert(expr_def_id, obligations); + let obligations = obligations.into_iter().map(|o| (o.predicate, o.cause)); + self.typeck_results.borrow_mut().coroutine_stalled_predicates.extend(obligations); } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 73613923e69c2..fa2bbc3dbd3a1 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -550,15 +550,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn visit_coroutine_interior(&mut self) { let fcx_typeck_results = self.fcx.typeck_results.borrow(); assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); - self.tcx().with_stable_hashing_context(move |ref hcx| { - for (&expr_def_id, predicates) in - fcx_typeck_results.coroutine_stalled_predicates.to_sorted(hcx, false).into_iter() - { - let predicates = - self.resolve(predicates.clone(), &self.fcx.tcx.def_span(expr_def_id)); - self.typeck_results.coroutine_stalled_predicates.insert(expr_def_id, predicates); - } - }) + for (predicate, cause) in &fcx_typeck_results.coroutine_stalled_predicates { + let (predicate, cause) = self.resolve((*predicate, cause.clone()), &cause.span); + self.typeck_results.coroutine_stalled_predicates.insert((predicate, cause)); + } } #[instrument(skip(self), level = "debug")] diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 91cef02c7d17d..b593c41a8eafa 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -759,7 +759,9 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { tcx.hir().par_body_owners(|def_id| { if tcx.is_coroutine(def_id.to_def_id()) { tcx.ensure().mir_coroutine_witnesses(def_id); - tcx.ensure().check_coroutine_obligations(def_id); + tcx.ensure().check_coroutine_obligations( + tcx.typeck_root_def_id(def_id.to_def_id()).expect_local(), + ); } }); sess.time("layout_testing", || layout_test::test_layout(tcx)); diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index aa905466fbc87..904d56c516d8e 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -7,10 +7,8 @@ use crate::{ GenericArgs, GenericArgsRef, Ty, UserArgs, }, }; -use rustc_data_structures::{ - fx::FxIndexMap, - unord::{ExtendUnord, UnordItems, UnordSet}, -}; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_data_structures::unord::{ExtendUnord, UnordItems, UnordSet}; use rustc_errors::ErrorGuaranteed; use rustc_hir::{ self as hir, @@ -201,8 +199,7 @@ pub struct TypeckResults<'tcx> { /// Stores the predicates that apply on coroutine witness types. /// formatting modified file tests/ui/coroutine/retain-resume-ref.rs - pub coroutine_stalled_predicates: - LocalDefIdMap, ObligationCause<'tcx>)>>, + pub coroutine_stalled_predicates: FxIndexSet<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>, /// We sometimes treat byte string literals (which are of type `&[u8; N]`) /// as `&[u8]`, depending on the pattern in which they are used. diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index e2a911f0dc7d9..b745d97567d6f 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -80,6 +80,10 @@ use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_target::spec::PanicStrategy; +use rustc_trait_selection::infer::TyCtxtInferExt as _; +use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; +use rustc_trait_selection::traits::ObligationCtxt; +use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode}; use std::{iter, ops}; pub struct StateTransform; @@ -1584,10 +1588,46 @@ pub(crate) fn mir_coroutine_witnesses<'tcx>( let (_, coroutine_layout, _) = compute_layout(liveness_info, body); check_suspend_tys(tcx, &coroutine_layout, body); + check_field_tys_sized(tcx, &coroutine_layout, def_id); Some(coroutine_layout) } +fn check_field_tys_sized<'tcx>( + tcx: TyCtxt<'tcx>, + coroutine_layout: &CoroutineLayout<'tcx>, + def_id: LocalDefId, +) { + // No need to check if unsized_locals/unsized_fn_params is disabled, + // since we will error during typeck. + if !tcx.features().unsized_locals && !tcx.features().unsized_fn_params { + return; + } + + let infcx = tcx.infer_ctxt().ignoring_regions().build(); + let param_env = tcx.param_env(def_id); + + let ocx = ObligationCtxt::new(&infcx); + for field_ty in &coroutine_layout.field_tys { + ocx.register_bound( + ObligationCause::new( + field_ty.source_info.span, + def_id, + ObligationCauseCode::SizedCoroutineInterior(def_id), + ), + param_env, + field_ty.ty, + tcx.require_lang_item(hir::LangItem::Sized, Some(field_ty.source_info.span)), + ); + } + + let errors = ocx.select_all_or_error(); + debug!(?errors); + if !errors.is_empty() { + infcx.err_ctxt().report_fulfillment_errors(errors); + } +} + impl<'tcx> MirPass<'tcx> for StateTransform { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let Some(old_yield_ty) = body.yield_ty() else { diff --git a/tests/ui/coroutine/clone-impl.rs b/tests/ui/coroutine/clone-impl.rs index eed6f851bd028..fffdae632ef7d 100644 --- a/tests/ui/coroutine/clone-impl.rs +++ b/tests/ui/coroutine/clone-impl.rs @@ -6,18 +6,18 @@ struct NonClone; -fn main() { +fn test1() { let copyable: u32 = 123; - let clonable_0: Vec = Vec::new(); - let clonable_1: Vec = Vec::new(); - let non_clonable: NonClone = NonClone; - let gen_copy_0 = move || { yield; drop(copyable); }; check_copy(&gen_copy_0); check_clone(&gen_copy_0); +} + +fn test2() { + let copyable: u32 = 123; let gen_copy_1 = move || { /* let v = vec!['a']; @@ -33,6 +33,10 @@ fn main() { }; check_copy(&gen_copy_1); check_clone(&gen_copy_1); +} + +fn test3() { + let clonable_0: Vec = Vec::new(); let gen_clone_0 = move || { let v = vec!['a']; yield; @@ -43,6 +47,10 @@ fn main() { //~^ ERROR the trait bound `Vec: Copy` is not satisfied //~| ERROR the trait bound `Vec: Copy` is not satisfied check_clone(&gen_clone_0); +} + +fn test4() { + let clonable_1: Vec = Vec::new(); let gen_clone_1 = move || { let v = vec!['a']; /* @@ -59,6 +67,10 @@ fn main() { //~^ ERROR the trait bound `Vec: Copy` is not satisfied //~| ERROR the trait bound `Vec: Copy` is not satisfied check_clone(&gen_clone_1); +} + +fn test5() { + let non_clonable: NonClone = NonClone; let gen_non_clone = move || { yield; drop(non_clonable); @@ -71,3 +83,5 @@ fn main() { fn check_copy(_x: &T) {} fn check_clone(_x: &T) {} + +fn main() {} diff --git a/tests/ui/coroutine/clone-impl.stderr b/tests/ui/coroutine/clone-impl.stderr index 1d4804501d8bc..b454846faac9b 100644 --- a/tests/ui/coroutine/clone-impl.stderr +++ b/tests/ui/coroutine/clone-impl.stderr @@ -1,76 +1,76 @@ -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}` - --> $DIR/clone-impl.rs:42:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}` + --> $DIR/clone-impl.rs:46:5 | LL | let gen_clone_0 = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}` ... LL | check_copy(&gen_clone_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}: Copy` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}: Copy` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:40:14 + --> $DIR/clone-impl.rs:44:14 | LL | drop(clonable_0); | ^^^^^^^^^^ has type `Vec` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:72:18 + --> $DIR/clone-impl.rs:84:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}` - --> $DIR/clone-impl.rs:42:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}` + --> $DIR/clone-impl.rs:46:5 | LL | let gen_clone_0 = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}` ... LL | check_copy(&gen_clone_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:36:23: 36:30}: Copy` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:40:23: 40:30}: Copy` | note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/clone-impl.rs:38:9 + --> $DIR/clone-impl.rs:42:9 | LL | let v = vec!['a']; | - has type `Vec` which does not implement `Copy` LL | yield; | ^^^^^ yield occurs here, with `v` maybe used later note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:72:18 + --> $DIR/clone-impl.rs:84:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}` - --> $DIR/clone-impl.rs:58:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}` + --> $DIR/clone-impl.rs:66:5 | LL | let gen_clone_1 = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}` ... LL | check_copy(&gen_clone_1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}: Copy` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}: Copy` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:56:14 + --> $DIR/clone-impl.rs:64:14 | LL | drop(clonable_1); | ^^^^^^^^^^ has type `Vec` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:72:18 + --> $DIR/clone-impl.rs:84:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}` - --> $DIR/clone-impl.rs:58:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}` + --> $DIR/clone-impl.rs:66:5 | LL | let gen_clone_1 = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}` ... LL | check_copy(&gen_clone_1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:46:23: 46:30}: Copy` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}`, the trait `Copy` is not implemented for `Vec`, which is required by `{coroutine@$DIR/clone-impl.rs:54:23: 54:30}: Copy` | note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/clone-impl.rs:52:9 + --> $DIR/clone-impl.rs:60:9 | LL | let v = vec!['a']; | - has type `Vec` which does not implement `Copy` @@ -78,27 +78,27 @@ LL | let v = vec!['a']; LL | yield; | ^^^^^ yield occurs here, with `v` maybe used later note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:72:18 + --> $DIR/clone-impl.rs:84:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}` - --> $DIR/clone-impl.rs:66:5 +error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}` + --> $DIR/clone-impl.rs:78:5 | LL | let gen_non_clone = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}` ... LL | check_copy(&gen_non_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Copy` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}: Copy` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`, the trait `Copy` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}: Copy` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:64:14 + --> $DIR/clone-impl.rs:76:14 | LL | drop(non_clonable); | ^^^^^^^^^^^^ has type `NonClone` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:72:18 + --> $DIR/clone-impl.rs:84:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` @@ -108,22 +108,22 @@ LL + #[derive(Copy)] LL | struct NonClone; | -error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}` - --> $DIR/clone-impl.rs:68:5 +error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}` + --> $DIR/clone-impl.rs:80:5 | LL | let gen_non_clone = move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}` ... LL | check_clone(&gen_non_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Clone` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:62:25: 62:32}: Clone` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}`, the trait `Clone` is not implemented for `NonClone`, which is required by `{coroutine@$DIR/clone-impl.rs:74:25: 74:32}: Clone` | note: captured value does not implement `Clone` - --> $DIR/clone-impl.rs:64:14 + --> $DIR/clone-impl.rs:76:14 | LL | drop(non_clonable); | ^^^^^^^^^^^^ has type `NonClone` which does not implement `Clone` note: required by a bound in `check_clone` - --> $DIR/clone-impl.rs:73:19 + --> $DIR/clone-impl.rs:85:19 | LL | fn check_clone(_x: &T) {} | ^^^^^ required by this bound in `check_clone` From 06501156d15120ff4a14c8f5b714c8c46563b58d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 19:54:51 -0400 Subject: [PATCH 3/4] redundant ::{self} --- compiler/rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 2 +- compiler/rustc_span/src/source_map.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index cb0ed68edff3e..3fd1cd3910c3f 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -22,10 +22,10 @@ use rustc_middle::ty::{ }; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_target::abi::FieldIdx; +use rustc_trait_selection::traits; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; -use rustc_trait_selection::traits::{self}; use rustc_type_ir::fold::TypeFoldable; use std::cell::LazyCell; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index ce203eae95fd0..b911c76da5e88 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -23,7 +23,7 @@ use rustc_hir::{ }; use rustc_hir_analysis::collect::suggest_impl_trait; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; -use rustc_infer::traits::{self}; +use rustc_infer::traits; use rustc_middle::lint::in_external_macro; use rustc_middle::middle::stability::EvalResult; use rustc_middle::ty::print::with_no_trimmed_paths; diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 93d5f06a16736..d9aa5300ed8cb 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -14,7 +14,7 @@ use rustc_data_structures::sync::{IntoDynSyncSend, MappedReadGuard, ReadGuard, R use rustc_data_structures::unhash::UnhashMap; use std::fs; use std::io::{self, BorrowedBuf, Read}; -use std::path::{self}; +use std::path; #[cfg(test)] mod tests; From a8c9a0bd8167c99557c9d475631c844775883336 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 22:21:42 -0400 Subject: [PATCH 4/4] crash -> test --- tests/crashes/122552.rs | 10 ---------- .../coroutine-in-orphaned-anon-const.rs | 10 ++++++++++ .../coroutine-in-orphaned-anon-const.stderr | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 10 deletions(-) delete mode 100644 tests/crashes/122552.rs create mode 100644 tests/ui/coroutine/coroutine-in-orphaned-anon-const.rs create mode 100644 tests/ui/coroutine/coroutine-in-orphaned-anon-const.stderr diff --git a/tests/crashes/122552.rs b/tests/crashes/122552.rs deleted file mode 100644 index 29566941e22b2..0000000000000 --- a/tests/crashes/122552.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #122552 -//@ edition:2021 - -trait X { - fn line_stream<'a, Repr>() -> Self::LineStreamFut<{ async {} }, Repr>; -} - -struct Y; - -pub fn main() {} diff --git a/tests/ui/coroutine/coroutine-in-orphaned-anon-const.rs b/tests/ui/coroutine/coroutine-in-orphaned-anon-const.rs new file mode 100644 index 0000000000000..07c13239a2ce2 --- /dev/null +++ b/tests/ui/coroutine/coroutine-in-orphaned-anon-const.rs @@ -0,0 +1,10 @@ +//@ edition:2021 + +trait X { + fn test() -> Self::Assoc<{ async {} }>; + //~^ ERROR associated type `Assoc` not found for `Self` + //~| ERROR associated type `Assoc` not found for `Self` + +} + +pub fn main() {} diff --git a/tests/ui/coroutine/coroutine-in-orphaned-anon-const.stderr b/tests/ui/coroutine/coroutine-in-orphaned-anon-const.stderr new file mode 100644 index 0000000000000..864c6556d7990 --- /dev/null +++ b/tests/ui/coroutine/coroutine-in-orphaned-anon-const.stderr @@ -0,0 +1,17 @@ +error[E0220]: associated type `Assoc` not found for `Self` + --> $DIR/coroutine-in-orphaned-anon-const.rs:4:24 + | +LL | fn test() -> Self::Assoc<{ async {} }>; + | ^^^^^ associated type `Assoc` not found + +error[E0220]: associated type `Assoc` not found for `Self` + --> $DIR/coroutine-in-orphaned-anon-const.rs:4:24 + | +LL | fn test() -> Self::Assoc<{ async {} }>; + | ^^^^^ associated type `Assoc` not found + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0220`.