From 218caa410aa38c29984be31a5229b9fa717560ee Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:13 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_borrowck/src/region_infer/mod.rs | 113 ++++++++------------- .../src/region_infer/opaque_types.rs | 26 +++-- compiler/rustc_borrowck/src/region_infer/values.rs | 6 +- 3 files changed, 60 insertions(+), 85 deletions(-) (limited to 'compiler/rustc_borrowck/src/region_infer') diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 90e2b6b69..238172ea3 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -527,6 +527,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.scc_values.region_value_str(scc) } + pub(crate) fn placeholders_contained_in<'a>( + &'a self, + r: RegionVid, + ) -> impl Iterator + 'a { + let scc = self.constraint_sccs.scc(r.to_region_vid()); + self.scc_values.placeholders_contained_in(scc) + } + /// Returns access to the value of `r` for debugging purposes. pub(crate) fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex { let scc = self.constraint_sccs.scc(r.to_region_vid()); @@ -562,7 +570,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mir_def_id = body.source.def_id(); self.propagate_constraints(body); - let mut errors_buffer = RegionErrors::new(); + let mut errors_buffer = RegionErrors::new(infcx.tcx); // If this is a closure, we can propagate unsatisfied // `outlives_requirements` to our creator, so create a vector @@ -680,7 +688,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// enforce the constraint). /// /// The current value of `scc` at the time the method is invoked - /// is considered a *lower bound*. If possible, we will modify + /// is considered a *lower bound*. If possible, we will modify /// the constraint to set it equal to one of the option regions. /// If we make any changes, returns true, else false. #[instrument(skip(self, member_constraint_index), level = "debug")] @@ -747,27 +755,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Otherwise, we need to find the minimum remaining choice, if // any, and take that. debug!("choice_regions remaining are {:#?}", choice_regions); - let min = |r1: ty::RegionVid, r2: ty::RegionVid| -> Option { - let r1_outlives_r2 = self.universal_region_relations.outlives(r1, r2); - let r2_outlives_r1 = self.universal_region_relations.outlives(r2, r1); - match (r1_outlives_r2, r2_outlives_r1) { - (true, true) => Some(r1.min(r2)), - (true, false) => Some(r2), - (false, true) => Some(r1), - (false, false) => None, - } + let Some(&min_choice) = choice_regions.iter().find(|&r1| { + choice_regions.iter().all(|&r2| { + self.universal_region_relations.outlives(r2, *r1) + }) + }) else { + debug!("no choice region outlived by all others"); + return false; }; - let mut min_choice = choice_regions[0]; - for &other_option in &choice_regions[1..] { - debug!(?min_choice, ?other_option,); - match min(min_choice, other_option) { - Some(m) => min_choice = m, - None => { - debug!(?min_choice, ?other_option, "incomparable; no min choice",); - return false; - } - } - } let min_choice_scc = self.constraint_sccs.scc(min_choice); debug!(?min_choice, ?min_choice_scc); @@ -844,7 +839,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { if self.eval_verify_bound( infcx, param_env, - body, generic_ty, type_test.lower_bound, &type_test.verify_bound, @@ -973,16 +967,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { // // This is needed because -- particularly in the case // where `ur` is a local bound -- we are sometimes in a - // position to prove things that our caller cannot. See + // position to prove things that our caller cannot. See // #53570 for an example. - if self.eval_verify_bound( - infcx, - param_env, - body, - generic_ty, - ur, - &type_test.verify_bound, - ) { + if self.eval_verify_bound(infcx, param_env, generic_ty, ur, &type_test.verify_bound) { continue; } @@ -1203,7 +1190,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - body: &Body<'tcx>, generic_ty: Ty<'tcx>, lower_bound: RegionVid, verify_bound: &VerifyBound<'tcx>, @@ -1226,25 +1212,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { } VerifyBound::AnyBound(verify_bounds) => verify_bounds.iter().any(|verify_bound| { - self.eval_verify_bound( - infcx, - param_env, - body, - generic_ty, - lower_bound, - verify_bound, - ) + self.eval_verify_bound(infcx, param_env, generic_ty, lower_bound, verify_bound) }), VerifyBound::AllBounds(verify_bounds) => verify_bounds.iter().all(|verify_bound| { - self.eval_verify_bound( - infcx, - param_env, - body, - generic_ty, - lower_bound, - verify_bound, - ) + self.eval_verify_bound(infcx, param_env, generic_ty, lower_bound, verify_bound) }), } } @@ -1683,26 +1655,29 @@ impl<'tcx> RegionInferenceContext<'tcx> { let longer_fr_scc = self.constraint_sccs.scc(longer_fr); debug!("check_bound_universal_region: longer_fr_scc={:?}", longer_fr_scc,); - // If we have some bound universal region `'a`, then the only - // elements it can contain is itself -- we don't know anything - // else about it! - let Some(error_element) = ({ - self.scc_values.elements_contained_in(longer_fr_scc).find(|element| match element { - RegionElement::Location(_) => true, - RegionElement::RootUniversalRegion(_) => true, - RegionElement::PlaceholderRegion(placeholder1) => placeholder != *placeholder1, - }) - }) else { - return; - }; - debug!("check_bound_universal_region: error_element = {:?}", error_element); + for error_element in self.scc_values.elements_contained_in(longer_fr_scc) { + match error_element { + RegionElement::Location(_) | RegionElement::RootUniversalRegion(_) => {} + // If we have some bound universal region `'a`, then the only + // elements it can contain is itself -- we don't know anything + // else about it! + RegionElement::PlaceholderRegion(placeholder1) => { + if placeholder == placeholder1 { + continue; + } + } + } - // Find the region that introduced this `error_element`. - errors_buffer.push(RegionErrorKind::BoundUniversalRegionError { - longer_fr, - error_element, - placeholder, - }); + errors_buffer.push(RegionErrorKind::BoundUniversalRegionError { + longer_fr, + error_element, + placeholder, + }); + + // Stop after the first error, it gets too noisy otherwise, and does not provide more information. + break; + } + debug!("check_bound_universal_region: all bounds satisfied"); } #[instrument(level = "debug", skip(self, infcx, errors_buffer))] @@ -2068,7 +2043,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // '5: '6 ('6 is the target) // // Some of those regions are unified with `'6` (in the same - // SCC). We want to screen those out. After that point, the + // SCC). We want to screen those out. After that point, the // "closest" constraint we have to the end is going to be the // most likely to be the point where the value escapes -- but // we still want to screen for an "interesting" point to diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 516a08077..db5a67a8b 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -12,6 +12,8 @@ use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::ObligationCtxt; +use crate::session_diagnostics::NonGenericOpaqueTypeParam; + use super::RegionInferenceContext; impl<'tcx> RegionInferenceContext<'tcx> { @@ -235,7 +237,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { /// # Parameters /// /// - `def_id`, the `impl Trait` type - /// - `substs`, the substs used to instantiate this opaque type + /// - `substs`, the substs used to instantiate this opaque type /// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of /// `opaque_defn.concrete_ty` #[instrument(level = "debug", skip(self))] @@ -262,7 +264,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { return self.tcx.ty_error(); } - // Only check this for TAIT. RPIT already supports `src/test/ui/impl-trait/nested-return-type2.rs` + // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs` // on stable and we'd break that. let OpaqueTyOrigin::TyAlias = origin else { return definition_ty; @@ -318,7 +320,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { // This is still required for many(half of the tests in ui/type-alias-impl-trait) // tests to pass - let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); + let _ = infcx.take_opaque_types(); if errors.is_empty() { definition_ty @@ -389,17 +391,13 @@ fn check_opaque_type_parameter_valid( } else { // Prevent `fn foo() -> Foo` from being defining. let opaque_param = opaque_generics.param_at(i, tcx); - tcx.sess - .struct_span_err(span, "non-defining opaque type use in defining scope") - .span_note( - tcx.def_span(opaque_param.def_id), - &format!( - "used non-generic {} `{}` for generic parameter", - opaque_param.kind.descr(), - arg, - ), - ) - .emit(); + let kind = opaque_param.kind.descr(); + tcx.sess.emit_err(NonGenericOpaqueTypeParam { + ty: arg, + kind, + span, + param_span: tcx.def_span(opaque_param.def_id), + }); return false; } } diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 7498ddccf..c3dfeedc2 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -90,12 +90,14 @@ impl RegionValueElements { rustc_index::newtype_index! { /// A single integer representing a `Location` in the MIR control-flow /// graph. Constructed efficiently from `RegionValueElements`. - pub struct PointIndex { DEBUG_FORMAT = "PointIndex({})" } + #[debug_format = "PointIndex({})"] + pub struct PointIndex {} } rustc_index::newtype_index! { /// A single integer representing a `ty::Placeholder`. - pub struct PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" } + #[debug_format = "PlaceholderIndex({})"] + pub struct PlaceholderIndex {} } /// An individual element in a region value -- the value of a -- cgit v1.2.3