From 9835e2ae736235810b4ea1c162ca5e65c547e770 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 04:49:50 +0200 Subject: Merging upstream version 1.71.1+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_borrowck/src/region_infer/mod.rs | 31 +++++++++++++++++----- .../src/region_infer/opaque_types.rs | 11 +++++--- .../src/region_infer/reverse_sccs.rs | 13 ++++----- compiler/rustc_borrowck/src/region_infer/values.rs | 22 ++++++++++++--- 4 files changed, 56 insertions(+), 21 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 729f3dbff..50b246b14 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -7,12 +7,12 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::scc::Sccs; use rustc_errors::Diagnostic; use rustc_hir::def_id::CRATE_DEF_ID; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; use rustc_middle::mir::{ - Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureOutlivesSubjectTy, + BasicBlock, Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureOutlivesSubjectTy, ClosureRegionRequirements, ConstraintCategory, Local, Location, ReturnConstraint, TerminatorKind, }; @@ -76,7 +76,7 @@ pub struct RegionInferenceContext<'tcx> { /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` exists if /// `B: A`. This is used to compute the universal regions that are required /// to outlive a given SCC. Computed lazily. - rev_scc_graph: Option>, + rev_scc_graph: Option, /// The "R0 member of [R1..Rn]" constraints, indexed by SCC. member_constraints: Rc>, @@ -585,6 +585,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.universal_regions.to_region_vid(r) } + /// Returns an iterator over all the outlives constraints. + pub fn outlives_constraints(&self) -> impl Iterator> + '_ { + self.constraints.outlives().iter().copied() + } + /// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`. pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) { self.universal_regions.annotate(tcx, err) @@ -598,6 +603,20 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.scc_values.contains(scc, p) } + /// Returns the lowest statement index in `start..=end` which is not contained by `r`. + /// + /// Panics if called before `solve()` executes. + pub(crate) fn first_non_contained_inclusive( + &self, + r: RegionVid, + block: BasicBlock, + start: usize, + end: usize, + ) -> Option { + let scc = self.constraint_sccs.scc(r); + self.scc_values.first_non_contained_inclusive(scc, block, start, end) + } + /// Returns access to the value of `r` for debugging purposes. pub(crate) fn region_value_str(&self, r: RegionVid) -> String { let scc = self.constraint_sccs.scc(r); @@ -698,7 +717,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { #[instrument(skip(self, _body), level = "debug")] fn propagate_constraints(&mut self, _body: &Body<'tcx>) { debug!("constraints={:#?}", { - let mut constraints: Vec<_> = self.constraints.outlives().iter().collect(); + let mut constraints: Vec<_> = self.outlives_constraints().collect(); constraints.sort_by_key(|c| (c.sup, c.sub)); constraints .into_iter() @@ -813,9 +832,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { // free region that must outlive the member region `R0` (`UB: // R0`). Therefore, we need only keep an option `O` if `UB: O` // for all UB. - let rev_scc_graph = self.reverse_scc_graph(); + self.compute_reverse_scc_graph(); let universal_region_relations = &self.universal_region_relations; - for ub in rev_scc_graph.upper_bounds(scc) { + for ub in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) { debug!(?ub); choice_regions.retain(|&o_r| universal_region_relations.outlives(ub, o_r)); } diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 2b16655cf..7fc89e89a 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -2,9 +2,10 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LocalDefId; use rustc_hir::OpaqueTyOrigin; +use rustc_infer::infer::InferCtxt; use rustc_infer::infer::TyCtxtInferExt as _; -use rustc_infer::infer::{DefiningAnchor, InferCtxt}; use rustc_infer::traits::{Obligation, ObligationCause}; +use rustc_middle::traits::DefiningAnchor; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; @@ -152,8 +153,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { let guar = ty.error_reported().err().unwrap_or_else(|| { prev.report_mismatch( &OpaqueHiddenType { ty, span: concrete_type.span }, + opaque_type_key.def_id, infcx.tcx, ) + .emit() }); prev.ty = infcx.tcx.ty_error(guar); } @@ -265,7 +268,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { // 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 { + let OpaqueTyOrigin::TyAlias { .. } = origin else { return definition_ty; }; let def_id = opaque_type_key.def_id; @@ -360,7 +363,7 @@ fn check_opaque_type_parameter_valid( // which would error here on all of the `'static` args. OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return Ok(()), // Check these - OpaqueTyOrigin::TyAlias => {} + OpaqueTyOrigin::TyAlias { .. } => {} } let opaque_generics = tcx.generics_of(opaque_type_key.def_id); let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default(); @@ -399,7 +402,7 @@ fn check_opaque_type_parameter_valid( return Err(tcx .sess .struct_span_err(span, "non-defining opaque type use in defining scope") - .span_note(spans, &format!("{} used multiple times", descr)) + .span_note(spans, format!("{} used multiple times", descr)) .emit()); } } diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index 23a59c128..fe56bd54a 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -8,7 +8,6 @@ use rustc_data_structures::graph::vec_graph::VecGraph; use rustc_data_structures::graph::WithSuccessors; use rustc_middle::ty::RegionVid; use std::ops::Range; -use std::rc::Rc; pub(crate) struct ReverseSccGraph { graph: VecGraph, @@ -40,10 +39,10 @@ impl ReverseSccGraph { } impl RegionInferenceContext<'_> { - /// Compute and return the reverse SCC-based constraint graph (lazily). - pub(super) fn reverse_scc_graph(&mut self) -> Rc { - if let Some(g) = &self.rev_scc_graph { - return g.clone(); + /// Compute the reverse SCC-based constraint graph (lazily). + pub(super) fn compute_reverse_scc_graph(&mut self) { + if self.rev_scc_graph.is_some() { + return; } let graph = self.constraint_sccs.reverse(); @@ -63,8 +62,6 @@ impl RegionInferenceContext<'_> { start += group_size; } - let rev_graph = Rc::new(ReverseSccGraph { graph, scc_regions, universal_regions }); - self.rev_scc_graph = Some(rev_graph.clone()); - rev_graph + self.rev_scc_graph = Some(ReverseSccGraph { graph, scc_regions, universal_regions }); } } diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 8132800f1..9290e7479 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -4,8 +4,8 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_index::bit_set::SparseBitMatrix; use rustc_index::interval::IntervalSet; use rustc_index::interval::SparseIntervalMatrix; -use rustc_index::vec::Idx; -use rustc_index::vec::IndexVec; +use rustc_index::Idx; +use rustc_index::IndexVec; use rustc_middle::mir::{BasicBlock, Body, Location}; use rustc_middle::ty::{self, RegionVid}; use std::fmt::Debug; @@ -159,7 +159,7 @@ impl LivenessValues { /// Returns `true` if the region `r` contains the given element. pub(crate) fn contains(&self, row: N, location: Location) -> bool { let index = self.elements.point_from_location(location); - self.points.row(row).map_or(false, |r| r.contains(index)) + self.points.row(row).is_some_and(|r| r.contains(index)) } /// Returns an iterator of all the elements contained by the region `r` @@ -283,6 +283,22 @@ impl RegionValues { elem.contained_in_row(self, r) } + /// Returns the lowest statement index in `start..=end` which is not contained by `r`. + pub(crate) fn first_non_contained_inclusive( + &self, + r: N, + block: BasicBlock, + start: usize, + end: usize, + ) -> Option { + let row = self.points.row(r)?; + let block = self.elements.entry_point(block); + let start = block.plus(start); + let end = block.plus(end); + let first_unset = row.first_unset_in(start..=end)?; + Some(first_unset.index() - block.index()) + } + /// `self[to] |= values[from]`, essentially: that is, take all the /// elements for the region `from` from `values` and add them to /// the region `to` in `self`. -- cgit v1.2.3