From f8fe978fab83d6cdb7ccd148a7e2bd5c9caae156 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 19 Mar 2025 17:32:21 +0100 Subject: [PATCH 1/2] remove unnecessary loop --- compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 142078900f0..075dc590b99 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -371,14 +371,8 @@ impl RpitConstraintChecker<'_> { // Use borrowck to get the type with unerased regions. let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types; debug!(?concrete_opaque_types); - for (&def_id, &concrete_type) in concrete_opaque_types { - if def_id != self.def_id { - // Ignore constraints for other opaque types. - continue; - } - + if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) { debug!(?concrete_type, "found constraint"); - if concrete_type.ty != self.found.ty { if let Ok(d) = self.found.build_mismatch_error(&concrete_type, self.tcx) { d.emit(); From cfc78cec79653e0c68e894b28295765a4208639e Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 19 Mar 2025 17:52:53 +0100 Subject: [PATCH 2/2] merge opaque types of nested bodies --- compiler/rustc_borrowck/src/lib.rs | 7 ++- compiler/rustc_borrowck/src/nll.rs | 20 ++++--- compiler/rustc_borrowck/src/opaque_types.rs | 55 +++++++++++++++++++ .../src/region_infer/opaque_types.rs | 37 +++---------- compiler/rustc_borrowck/src/type_check/mod.rs | 10 +++- .../src/collect/type_of/opaque.rs | 6 -- tests/crashes/122904.rs | 12 ---- .../impl-fn-predefined-lifetimes.rs | 3 +- .../impl-fn-predefined-lifetimes.stderr | 18 ++---- tests/ui/impl-trait/issues/issue-86800.rs | 1 - tests/ui/impl-trait/issues/issue-86800.stderr | 23 +------- .../const_generic_type.no_infer.stderr | 19 +------ .../const_generic_type.rs | 1 - .../error-tainting-issue-122904.rs | 18 ++++++ .../error-tainting-issue-122904.stderr | 30 ++++++++++ .../type-alias-impl-trait/hkl_forbidden4.rs | 1 - .../hkl_forbidden4.stderr | 19 +------ .../in-assoc-ty-early-bound2.rs | 2 +- .../in-assoc-ty-early-bound2.stderr | 10 +--- 19 files changed, 146 insertions(+), 146 deletions(-) create mode 100644 compiler/rustc_borrowck/src/opaque_types.rs delete mode 100644 tests/crashes/122904.rs create mode 100644 tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs create mode 100644 tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index ed95545dea4..84b7b8c6a2d 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -73,6 +73,7 @@ mod def_use; mod diagnostics; mod member_constraints; mod nll; +mod opaque_types; mod path_utils; mod place_ext; mod places_conflict; @@ -192,7 +193,7 @@ fn do_mir_borrowck<'tcx>( // Compute non-lexical lifetimes. let nll::NllOutput { regioncx, - opaque_type_values, + concrete_opaque_types, polonius_input, polonius_output, opt_closure_req, @@ -222,7 +223,7 @@ fn do_mir_borrowck<'tcx>( body, ®ioncx, &opt_closure_req, - &opaque_type_values, + &concrete_opaque_types, diags_buffer, ); @@ -357,7 +358,7 @@ fn do_mir_borrowck<'tcx>( let tainted_by_errors = mbcx.emit_errors(); let result = BorrowCheckResult { - concrete_opaque_types: opaque_type_values, + concrete_opaque_types: concrete_opaque_types.into_inner(), closure_requirements: opt_closure_req, used_mut_upvars: mbcx.used_mut_upvars, tainted_by_errors, diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 2031579dfd5..d0bd364425a 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -6,8 +6,6 @@ use std::str::FromStr; use std::{env, io}; use polonius_engine::{Algorithm, Output}; -use rustc_data_structures::fx::FxIndexMap; -use rustc_hir::def_id::LocalDefId; use rustc_index::IndexSlice; use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options}; use rustc_middle::mir::{ @@ -15,7 +13,7 @@ use rustc_middle::mir::{ dump_enabled, dump_mir, }; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_mir_dataflow::ResultsCursor; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::MoveData; @@ -27,6 +25,7 @@ use tracing::{debug, instrument}; use crate::borrow_set::BorrowSet; use crate::consumers::ConsumerOptions; use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors}; +use crate::opaque_types::ConcreteOpaqueTypes; use crate::polonius::PoloniusDiagnosticsContext; use crate::polonius::legacy::{ PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput, @@ -40,7 +39,7 @@ use crate::{BorrowckInferCtxt, polonius, renumber}; /// closure requirements to propagate, and any generated errors. pub(crate) struct NllOutput<'tcx> { pub regioncx: RegionInferenceContext<'tcx>, - pub opaque_type_values: FxIndexMap>, + pub concrete_opaque_types: ConcreteOpaqueTypes<'tcx>, pub polonius_input: Option>, pub polonius_output: Option>, pub opt_closure_req: Option>, @@ -99,6 +98,8 @@ pub(crate) fn compute_regions<'a, 'tcx>( let location_map = Rc::new(DenseLocationMap::new(body)); + let mut concrete_opaque_types = ConcreteOpaqueTypes::default(); + // Run the MIR type-checker. let MirTypeckResults { constraints, @@ -116,6 +117,7 @@ pub(crate) fn compute_regions<'a, 'tcx>( flow_inits, move_data, Rc::clone(&location_map), + &mut concrete_opaque_types, ); // Create the region inference context, taking ownership of the @@ -180,11 +182,11 @@ pub(crate) fn compute_regions<'a, 'tcx>( infcx.set_tainted_by_errors(guar); } - let remapped_opaque_tys = regioncx.infer_opaque_types(infcx, opaque_type_values); + regioncx.infer_opaque_types(infcx, opaque_type_values, &mut concrete_opaque_types); NllOutput { regioncx, - opaque_type_values: remapped_opaque_tys, + concrete_opaque_types, polonius_input: polonius_facts.map(Box::new), polonius_output, opt_closure_req: closure_region_requirements, @@ -300,7 +302,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( body: &Body<'tcx>, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, - opaque_type_values: &FxIndexMap>, + concrete_opaque_types: &ConcreteOpaqueTypes<'tcx>, diagnostics_buffer: &mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, ) { let tcx = infcx.tcx; @@ -343,8 +345,8 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( err }; - if !opaque_type_values.is_empty() { - err.note(format!("Inferred opaque type values:\n{opaque_type_values:#?}")); + if !concrete_opaque_types.is_empty() { + err.note(format!("Inferred opaque type values:\n{concrete_opaque_types:#?}")); } diagnostics_buffer.buffer_non_error(err); diff --git a/compiler/rustc_borrowck/src/opaque_types.rs b/compiler/rustc_borrowck/src/opaque_types.rs new file mode 100644 index 00000000000..5c78814abdd --- /dev/null +++ b/compiler/rustc_borrowck/src/opaque_types.rs @@ -0,0 +1,55 @@ +use rustc_data_structures::fx::FxIndexMap; +use rustc_hir::def_id::LocalDefId; +use rustc_middle::ty::{OpaqueHiddenType, Ty, TyCtxt}; + +#[derive(Debug, Default)] +pub(super) struct ConcreteOpaqueTypes<'tcx> { + concrete_opaque_types: FxIndexMap>, +} + +impl<'tcx> ConcreteOpaqueTypes<'tcx> { + pub(super) fn is_empty(&self) -> bool { + self.concrete_opaque_types.is_empty() + } + + pub(super) fn into_inner(self) -> FxIndexMap> { + self.concrete_opaque_types + } + + /// Insert an opaque type into the list of opaque types defined by this function + /// after mapping the hidden type to the generic parameters of the opaque type + /// definition. + pub(super) fn insert( + &mut self, + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + hidden_ty: OpaqueHiddenType<'tcx>, + ) { + // Sometimes two opaque types are the same only after we remap the generic parameters + // back to the opaque type definition. E.g. we may have `OpaqueType` mapped to + // `(X, Y)` and `OpaqueType` mapped to `(Y, X)`, and those are the same, but we + // only know that once we convert the generic parameters to those of the opaque type. + if let Some(prev) = self.concrete_opaque_types.get_mut(&def_id) { + if prev.ty != hidden_ty.ty { + let (Ok(guar) | Err(guar)) = + prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit()); + prev.ty = Ty::new_error(tcx, guar); + } + // Pick a better span if there is one. + // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. + prev.span = prev.span.substitute_dummy(hidden_ty.span); + } else { + self.concrete_opaque_types.insert(def_id, hidden_ty); + } + } + + pub(super) fn extend_from_nested_body( + &mut self, + tcx: TyCtxt<'tcx>, + nested_body: &FxIndexMap>, + ) { + for (&def_id, &hidden_ty) in nested_body { + self.insert(tcx, def_id, hidden_ty); + } + } +} diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 04839448596..ca8b9fb4e9d 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -15,6 +15,7 @@ use rustc_trait_selection::traits::ObligationCtxt; use tracing::{debug, instrument}; use super::RegionInferenceContext; +use crate::opaque_types::ConcreteOpaqueTypes; use crate::session_diagnostics::{LifetimeMismatchOpaqueParam, NonGenericOpaqueTypeParam}; use crate::universal_regions::RegionClassification; @@ -67,8 +68,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, infcx: &InferCtxt<'tcx>, opaque_ty_decls: FxIndexMap, OpaqueHiddenType<'tcx>>, - ) -> FxIndexMap> { - let mut result: FxIndexMap> = FxIndexMap::default(); + concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>, + ) { let mut decls_modulo_regions: FxIndexMap, (OpaqueTypeKey<'tcx>, Span)> = FxIndexMap::default(); @@ -143,33 +144,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { continue; } } - // Sometimes two opaque types are the same only after we remap the generic parameters - // back to the opaque type definition. E.g. we may have `OpaqueType` mapped to - // `(X, Y)` and `OpaqueType` mapped to `(Y, X)`, and those are the same, but we - // only know that once we convert the generic parameters to those of the opaque type. - if let Some(prev) = result.get_mut(&opaque_type_key.def_id) { - if prev.ty != ty { - let guar = ty.error_reported().err().unwrap_or_else(|| { - let (Ok(e) | Err(e)) = prev - .build_mismatch_error( - &OpaqueHiddenType { ty, span: concrete_type.span }, - infcx.tcx, - ) - .map(|d| d.emit()); - e - }); - prev.ty = Ty::new_error(infcx.tcx, guar); - } - // Pick a better span if there is one. - // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. - prev.span = prev.span.substitute_dummy(concrete_type.span); - } else { - result.insert( - opaque_type_key.def_id, - OpaqueHiddenType { ty, span: concrete_type.span }, - ); - } + concrete_opaque_types.insert( + infcx.tcx, + opaque_type_key.def_id, + OpaqueHiddenType { ty, span: concrete_type.span }, + ); // Check that all opaque types have the same region parameters if they have the same // non-region parameters. This is necessary because within the new solver we perform // various query operations modulo regions, and thus could unsoundly select some impls @@ -193,7 +173,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { }); } } - result } /// Map the regions in the type to named regions. This is similar to what diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 0fda3e31690..f6144a25938 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -45,6 +45,7 @@ use crate::borrow_set::BorrowSet; use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet}; use crate::diagnostics::UniverseInfo; use crate::member_constraints::MemberConstraintSet; +use crate::opaque_types::ConcreteOpaqueTypes; use crate::polonius::legacy::{PoloniusFacts, PoloniusLocationTable}; use crate::polonius::{PoloniusContext, PoloniusLivenessContext}; use crate::region_infer::TypeTest; @@ -111,6 +112,7 @@ pub(crate) fn type_check<'a, 'tcx>( flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, move_data: &MoveData<'tcx>, location_map: Rc, + concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>, ) -> MirTypeckResults<'tcx> { let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body); let mut constraints = MirTypeckRegionConstraints { @@ -165,6 +167,7 @@ pub(crate) fn type_check<'a, 'tcx>( polonius_facts, borrow_set, constraints: &mut constraints, + concrete_opaque_types, polonius_liveness, }; @@ -230,6 +233,7 @@ struct TypeChecker<'a, 'tcx> { polonius_facts: &'a mut Option, borrow_set: &'a BorrowSet<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>, + concrete_opaque_types: &'a mut ConcreteOpaqueTypes<'tcx>, /// When using `-Zpolonius=next`, the liveness helper data used to create polonius constraints. polonius_liveness: Option, } @@ -2499,7 +2503,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { args: GenericArgsRef<'tcx>, locations: Locations, ) -> ty::InstantiatedPredicates<'tcx> { - if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements { + let closure_borrowck_results = tcx.mir_borrowck(def_id); + self.concrete_opaque_types + .extend_from_nested_body(tcx, &closure_borrowck_results.concrete_opaque_types); + + if let Some(closure_requirements) = &closure_borrowck_results.closure_requirements { constraint_conversion::ConstraintConversion::new( self.infcx, self.universal_regions, diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 075dc590b99..3dec1e286b4 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -258,9 +258,6 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> { self.tcx } fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { - if let hir::ExprKind::Closure(closure) = ex.kind { - self.check(closure.def_id); - } intravisit::walk_expr(self, ex); } fn visit_item(&mut self, it: &'tcx Item<'tcx>) { @@ -389,9 +386,6 @@ impl<'tcx> intravisit::Visitor<'tcx> for RpitConstraintChecker<'tcx> { self.tcx } fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { - if let hir::ExprKind::Closure(closure) = ex.kind { - self.check(closure.def_id); - } intravisit::walk_expr(self, ex); } fn visit_item(&mut self, it: &'tcx Item<'tcx>) { diff --git a/tests/crashes/122904.rs b/tests/crashes/122904.rs deleted file mode 100644 index 2068cd9d239..00000000000 --- a/tests/crashes/122904.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #122904 -trait T {} - -type Alias<'a> = impl T; - -struct S; -impl<'a> T for &'a S {} - -#[define_opaque(Alias)] -fn with_positive(fun: impl Fn(Alias<'_>)) { - with_positive(|&n| ()); -} diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs index 2f17c0ff508..776bb7278ce 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs @@ -2,8 +2,7 @@ use std::fmt::Debug; fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { - //~^ ERROR cannot resolve opaque type - //~| WARNING elided lifetime has a name + //~^ WARNING elided lifetime has a name |x| x //~^ ERROR expected generic lifetime parameter, found `'_` } diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr index 91550f0e284..209186db4cc 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr @@ -7,24 +7,14 @@ LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { = note: `#[warn(elided_named_lifetimes)]` on by default error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/impl-fn-predefined-lifetimes.rs:7:9 + --> $DIR/impl-fn-predefined-lifetimes.rs:6:9 | LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { | -- this generic parameter must be used with a generic lifetime parameter -... +LL | LL | |x| x | ^ -error[E0720]: cannot resolve opaque type - --> $DIR/impl-fn-predefined-lifetimes.rs:4:35 - | -LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { - | ^^^^^^^^^^^^^^^ recursive opaque type -... -LL | |x| x - | ----- returning here with type `{closure@$DIR/impl-fn-predefined-lifetimes.rs:7:5: 7:8}` +error: aborting due to 1 previous error; 1 warning emitted -error: aborting due to 2 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0720, E0792. -For more information about an error, try `rustc --explain E0720`. +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs index c1176255f24..9e8ea439dde 100644 --- a/tests/ui/impl-trait/issues/issue-86800.rs +++ b/tests/ui/impl-trait/issues/issue-86800.rs @@ -40,7 +40,6 @@ impl Context { f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>, ) -> TransactionResult { //~^ ERROR expected generic lifetime parameter, found `'_` - //~| ERROR: item does not constrain let mut conn = Connection {}; let mut transaction = TestTransaction { conn: &mut conn }; f(&mut transaction).await diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr index 11e23d97d72..80aa5d75c3c 100644 --- a/tests/ui/impl-trait/issues/issue-86800.stderr +++ b/tests/ui/impl-trait/issues/issue-86800.stderr @@ -24,26 +24,6 @@ note: this opaque type is supposed to be constrained LL | type TransactionFuture<'__, O> = impl '__ + Future>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: item does not constrain `TransactionFuture::{opaque#0}` - --> $DIR/issue-86800.rs:41:31 - | -LL | ) -> TransactionResult { - | _______________________________^ -LL | | -LL | | -LL | | let mut conn = Connection {}; -LL | | let mut transaction = TestTransaction { conn: &mut conn }; -LL | | f(&mut transaction).await -LL | | } - | |_____^ - | - = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` -note: this opaque type is supposed to be constrained - --> $DIR/issue-86800.rs:21:34 - | -LL | type TransactionFuture<'__, O> = impl '__ + Future>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/issue-86800.rs:31:5 | @@ -62,13 +42,12 @@ LL | type TransactionFuture<'__, O> = impl '__ + Future TransactionResult { | _______________________________^ LL | | -LL | | LL | | let mut conn = Connection {}; LL | | let mut transaction = TestTransaction { conn: &mut conn }; LL | | f(&mut transaction).await LL | | } | |_____^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr index ba97bbf89f8..241eccc5f2b 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr +++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr @@ -19,22 +19,5 @@ note: this opaque type is supposed to be constrained LL | type Bar = impl std::fmt::Display; | ^^^^^^^^^^^^^^^^^^^^^^ -error: item does not constrain `Bar::{opaque#0}` - --> $DIR/const_generic_type.rs:8:31 - | -LL | async fn test() { - | _______________________________^ -... | -LL | | let x: u32 = N; -LL | | } - | |_^ - | - = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` -note: this opaque type is supposed to be constrained - --> $DIR/const_generic_type.rs:5:12 - | -LL | type Bar = impl std::fmt::Display; - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.rs b/tests/ui/type-alias-impl-trait/const_generic_type.rs index 5b093be9231..9b38f1449f8 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.rs +++ b/tests/ui/type-alias-impl-trait/const_generic_type.rs @@ -8,7 +8,6 @@ type Bar = impl std::fmt::Display; async fn test() { //~^ ERROR: `Bar` is forbidden as the type of a const generic parameter //[no_infer]~^^ ERROR item does not constrain - //[no_infer]~| ERROR item does not constrain #[cfg(infer)] let x: u32 = N; } diff --git a/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs new file mode 100644 index 00000000000..a2de3957c0b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs @@ -0,0 +1,18 @@ +// We previously didn't taint the borrowck result in this test, +// causing an ICE later on. +#![feature(type_alias_impl_trait)] +trait T {} + +type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S {} + +#[define_opaque(Alias)] +fn with_positive(fun: impl Fn(Alias<'_>)) { + //~^ WARN function cannot return without recursing + with_positive(|&n| ()); + //~^ ERROR cannot move out of a shared reference +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr new file mode 100644 index 00000000000..956ce3e5936 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr @@ -0,0 +1,30 @@ +warning: function cannot return without recursing + --> $DIR/error-tainting-issue-122904.rs:12:1 + | +LL | fn with_positive(fun: impl Fn(Alias<'_>)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | +LL | with_positive(|&n| ()); + | ---------------------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error[E0507]: cannot move out of a shared reference + --> $DIR/error-tainting-issue-122904.rs:14:20 + | +LL | with_positive(|&n| ()); + | ^- + | | + | data moved here + | move occurs because `n` has type `S`, which does not implement the `Copy` trait + | +help: consider removing the borrow + | +LL - with_positive(|&n| ()); +LL + with_positive(|n| ()); + | + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs index 7e010918b29..cbd8150d117 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs @@ -22,7 +22,6 @@ where for<'any> F: FnMut(&'any mut ()) -> FutNothing<'any>, { //~^ ERROR: expected generic lifetime parameter, found `'any` - //~| ERROR item does not constrain } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index 2ca6a199448..2c0be0cbcdc 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -11,21 +11,6 @@ note: this opaque type is supposed to be constrained LL | type FutNothing<'a> = impl 'a + Future; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: item does not constrain `FutNothing::{opaque#0}` - --> $DIR/hkl_forbidden4.rs:23:1 - | -LL | / { -... | -LL | | } - | |_^ - | - = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` -note: this opaque type is supposed to be constrained - --> $DIR/hkl_forbidden4.rs:10:23 - | -LL | type FutNothing<'a> = impl 'a + Future; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: concrete type differs from previous defining opaque type use --> $DIR/hkl_forbidden4.rs:12:1 | @@ -54,10 +39,10 @@ LL | type FutNothing<'a> = impl 'a + Future; | -- this generic parameter must be used with a generic lifetime parameter ... LL | / { -... | +LL | | LL | | } | |_^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs index 7452000b65d..92c8a8f3216 100644 --- a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs +++ b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs @@ -6,7 +6,7 @@ trait Foo { } impl Foo for () { - type Assoc<'a> = impl Sized; //~ ERROR unconstrained opaque type + type Assoc<'a> = impl Sized; fn bar<'a: 'a>() where Self::Assoc<'a>:, diff --git a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr index 1274a8b60de..7ce4517fb1e 100644 --- a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr +++ b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr @@ -9,14 +9,6 @@ LL | fn bar<'a: 'a>() LL | let _: Self::Assoc<'a> = x; | ^^^^^^^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/in-assoc-ty-early-bound2.rs:9:22 - | -LL | type Assoc<'a> = impl Sized; - | ^^^^^^^^^^ - | - = note: `Assoc` must be used in combination with a concrete type within the same impl - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0700`.