Skip to content

Commit

Permalink
This version finally does away with all kinds of universe handling
Browse files Browse the repository at this point in the history
It does so in a preprocessing step that now also removes higher-ranked
concerns from type tests.
  • Loading branch information
amandasystems committed Nov 1, 2024
1 parent 15ca2bb commit 9cbe0a8
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 200 deletions.
9 changes: 5 additions & 4 deletions compiler/rustc_borrowck/src/constraints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc_middle::ty::{RegionVid, TyCtxt, VarianceDiagInfo};
use rustc_span::Span;
use tracing::{debug, instrument};

use crate::region_infer::{PlaceholderTracking, RegionDefinition, RegionTracker, SccAnnotations};
use crate::region_infer::{RegionDefinition, RegionTracker, SccAnnotations};
use crate::type_check::Locations;
use crate::universal_regions::UniversalRegions;

Expand Down Expand Up @@ -134,7 +134,8 @@ impl<'tcx> OutlivesConstraintSet<'tcx> {
&mut self,
universal_regions: &UniversalRegions<'tcx>,
definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>,
) -> (scc::Sccs<RegionVid, ConstraintSccIndex>, PlaceholderTracking) {
) -> (scc::Sccs<RegionVid, ConstraintSccIndex>, IndexVec<ConstraintSccIndex, RegionTracker>)
{
let fr_static = universal_regions.fr_static;
let mut annotations = SccAnnotations::init(definitions);
let sccs = self.compute_sccs(fr_static, definitions.len(), &mut annotations);
Expand Down Expand Up @@ -209,11 +210,11 @@ impl<'tcx> OutlivesConstraintSet<'tcx> {
// We changed the constraint set and so must recompute SCCs.
(
self.compute_sccs(fr_static, definitions.len(), &mut annotations),
PlaceholderTracking::On(annotations.scc_to_annotation),
annotations.scc_to_annotation,
)
} else {
// If we didn't add any back-edges; no more work needs doing
(sccs, PlaceholderTracking::On(annotations.scc_to_annotation))
(sccs, annotations.scc_to_annotation)
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {

// find higher-ranked trait bounds bounded to the generic associated types
let scc = self.regioncx.constraint_sccs().scc(lower_bound);

let placeholder: ty::PlaceholderRegion = self.regioncx.placeholder_representative(scc)?;

let placeholder_id = placeholder.bound.kind.get_id()?.as_local()?;
let gat_hir_id = self.infcx.tcx.local_def_id_to_hir_id(placeholder_id);
let generics_impl =
Expand All @@ -221,7 +223,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let mut hrtb_bounds = vec![];

for pred in generics_impl.predicates {
let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) = pred
let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }): &rustc_hir::WherePredicate<'tcx> = pred
else {
continue;
};
Expand Down Expand Up @@ -329,6 +331,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
span: type_test_span,
});

debug!("This bound caused outlives static: {:?}", type_test.derived_from);

// Add notes and suggestions for the case of 'static lifetime
// implied but not specified when a generic associated types
// are from higher-ranked trait bounds
Expand Down
96 changes: 93 additions & 3 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@ use std::{env, io};

use polonius_engine::{Algorithm, Output};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::graph::scc::Sccs;
use rustc_hir::def_id::LocalDefId;
use rustc_index::IndexSlice;
use rustc_index::{IndexSlice, IndexVec};
use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_infer::infer::region_constraints::RegionVariableInfo;
use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options};
use rustc_middle::mir::{
Body, ClosureOutlivesSubject, ClosureRegionRequirements, PassWhere, Promoted, create_dump_file,
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, OpaqueHiddenType, RegionVid, TyCtxt};
use rustc_mir_dataflow::ResultsCursor;
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
use rustc_mir_dataflow::move_paths::MoveData;
Expand All @@ -25,11 +28,14 @@ use rustc_span::symbol::sym;
use tracing::{debug, instrument};

use crate::borrow_set::BorrowSet;
use crate::constraints::{ConstraintSccIndex, OutlivesConstraintSet};
use crate::consumers::ConsumerOptions;
use crate::diagnostics::RegionErrors;
use crate::facts::{AllFacts, AllFactsExt, RustcFacts};
use crate::location::LocationTable;
use crate::region_infer::RegionInferenceContext;
use crate::region_infer::{
RegionDefinition, RegionInferenceContext, Representative, SccAnnotations, TypeTest,
};
use crate::type_check::{self, MirTypeckRegionConstraints, MirTypeckResults};
use crate::universal_regions::UniversalRegions;
use crate::{BorrowckInferCtxt, polonius, renumber};
Expand Down Expand Up @@ -152,6 +158,15 @@ pub(crate) fn compute_regions<'a, 'tcx>(
infcx.set_tainted_by_errors(guar);
}

let (type_tests, sccs, region_definitions, scc_representatives) =
rewrite_higher_kinded_outlives_as_constraints(
&mut outlives_constraints,
&var_origins,
&universal_regions,
type_tests,
infcx.tcx,
);

let mut regioncx = RegionInferenceContext::new(
infcx,
var_origins,
Expand All @@ -163,6 +178,9 @@ pub(crate) fn compute_regions<'a, 'tcx>(
type_tests,
liveness_constraints,
elements,
sccs,
region_definitions,
scc_representatives,
);

// If requested: dump NLL facts, and run legacy polonius analysis.
Expand Down Expand Up @@ -208,6 +226,78 @@ pub(crate) fn compute_regions<'a, 'tcx>(
}
}

fn rewrite_higher_kinded_outlives_as_constraints<'tcx>(
outlives_constraints: &mut OutlivesConstraintSet<'tcx>,
var_origins: &IndexVec<RegionVid, RegionVariableInfo>,
universal_regions: &UniversalRegions<'tcx>,
type_tests: Vec<TypeTest<'tcx>>,
tcx: TyCtxt<'tcx>,
) -> (
Vec<TypeTest<'tcx>>,
Sccs<ty::RegionVid, ConstraintSccIndex>,
IndexVec<ty::RegionVid, RegionDefinition<'tcx>>,
IndexVec<ConstraintSccIndex, Representative>,
) {
// Create a RegionDefinition for each inference variable. This happens here because
// it allows us to sneak in a cheap check for placeholders. Otherwise, its proper home
// is in `RegionInferenceContext::new()`, probably.
let (definitions, has_placeholders) = {
let mut definitions = IndexVec::with_capacity(var_origins.len());
let mut has_placeholders = false;

for info in var_origins.iter() {
let definition = RegionDefinition::new(info);
has_placeholders |=
matches!(definition.origin, NllRegionVariableOrigin::Placeholder(_));
definitions.push(definition);
}

// Add external names from universal regions in fun function definitions.
for (external_name, variable) in universal_regions.named_universal_regions() {
debug!("region {:?} has external name {:?}", variable, external_name);
definitions[variable].external_name = Some(external_name);
}
(definitions, has_placeholders)
};

if !has_placeholders {
debug!("No placeholder regions found; skipping rewriting logic!");
let mut annotations = SccAnnotations::init(&definitions);
let sccs = outlives_constraints.compute_sccs(
universal_regions.fr_static,
definitions.len(),
&mut annotations,
);
let annotations = annotations.scc_to_annotation;
return (type_tests, sccs, definitions, annotations);
}

debug!("Placeholders present; activating placeholder handling logic!");
let (sccs, scc_annotations) =
outlives_constraints.add_outlives_static(&universal_regions, &definitions);

// Rewrite universe-violating type tests into outlives 'static while we remember
// which universes go where.
let type_tests = type_tests
.into_iter()
.map(|type_test| {
type_test.rewrite_higher_kinded_constraints(
&sccs,
&scc_annotations,
universal_regions,
tcx,
)
})
.collect();

let representatives = scc_annotations
.into_iter()
.map(|rich_annotation| rich_annotation.into_representative())
.collect();

(type_tests, sccs, definitions, representatives)
}

/// `-Zdump-mir=nll` dumps MIR annotated with NLL specific information:
/// - free regions
/// - inferred region values
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_borrowck/src/region_infer/dump_mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
for region in self.regions() {
writeln!(
out,
"| {r:rw$?} | {ui:4?} | {v}",
"| {r:rw$?} | {v}",
r = region,
rw = REGION_WIDTH,
ui = self.region_universe(region),
v = self.region_value_str(region),
)?;
}
Expand Down
Loading

0 comments on commit 9cbe0a8

Please sign in to comment.