Skip to content

Commit

Permalink
Rollup merge of #133501 - lcnr:post-borrowck-analysis, r=compiler-errors
Browse files Browse the repository at this point in the history
support revealing defined opaque post borrowck

By adding a new `TypingMode::PostBorrowckAnalysis`. Currently only supported with the new solver and I didn't look into the way we replace `ReErased`. ``@compiler-errors`` mentioned that always using existentials may be unsound.

r? ``@compiler-errors``
  • Loading branch information
matthiaskrgr authored Nov 29, 2024
2 parents 95560d6 + 34a8c2d commit 6863327
Show file tree
Hide file tree
Showing 47 changed files with 355 additions and 173 deletions.
3 changes: 2 additions & 1 deletion compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use rustc_infer::infer::{
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::*;
use rustc_middle::query::Providers;
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode};
use rustc_middle::{bug, span_bug};
use rustc_mir_dataflow::impls::{
Expand Down Expand Up @@ -502,7 +503,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
for data in tcx.typeck(def_id).concrete_opaque_types.iter().map(|(k, v)| (*k, *v)) {
// HIR typeck did not infer the regions of the opaque, so we instantiate
// them with fresh inference variables.
let (key, hidden_ty) = tcx.fold_regions(data, |_, _| {
let (key, hidden_ty) = fold_regions(tcx, data, |_, _| {
self.next_nll_region_var_in_universe(
NllRegionVariableOrigin::Existential { from_forall: false },
ty::UniverseIndex::ROOT,
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use rustc_middle::mir::{
TerminatorKind,
};
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, UniverseIndex};
use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_span::Span;
Expand Down Expand Up @@ -1100,7 +1101,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let ty = ty.fold_with(&mut OpaqueFolder { tcx });
let mut failed = false;

let ty = tcx.fold_regions(ty, |r, _depth| {
let ty = fold_regions(tcx, ty, |r, _depth| {
let r_vid = self.to_region_vid(r);
let r_scc = self.constraint_sccs.scc(r_vid);

Expand Down Expand Up @@ -1273,7 +1274,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
tcx.fold_regions(value, |r, _db| {
fold_regions(tcx, value, |r, _db| {
let vid = self.to_region_vid(r);
let scc = self.constraint_sccs.scc(vid);
let repr = self.scc_representative(scc);
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::LocalDefId;
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, TyCtxtInferExt as _};
use rustc_macros::extension;
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{
self, GenericArgKind, GenericArgs, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable,
Expand Down Expand Up @@ -117,7 +118,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
});
debug!(?opaque_type_key, ?arg_regions);

let concrete_type = infcx.tcx.fold_regions(concrete_type, |region, _| {
let concrete_type = fold_regions(infcx.tcx, concrete_type, |region, _| {
arg_regions
.iter()
.find(|&&(arg_vid, _)| self.eval_equal(region.as_var(), arg_vid))
Expand Down Expand Up @@ -204,7 +205,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
tcx.fold_regions(ty, |region, _| match *region {
fold_regions(tcx, ty, |region, _| match *region {
ty::ReVar(vid) => {
let scc = self.constraint_sccs.scc(vid);

Expand Down Expand Up @@ -442,7 +443,7 @@ impl<'tcx> LazyOpaqueTyEnv<'tcx> {
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);

let mut seen = vec![tcx.lifetimes.re_static];
let canonical_args = tcx.fold_regions(args, |r1, _| {
let canonical_args = fold_regions(tcx, args, |r1, _| {
if r1.is_error() {
r1
} else if let Some(&r2) = seen.iter().find(|&&r2| {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_borrowck/src/renumber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use rustc_index::IndexSlice;
use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_middle::mir::visit::{MutVisitor, TyContext};
use rustc_middle::mir::{Body, ConstOperand, Location, Promoted};
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable};
use rustc_span::Symbol;
use tracing::{debug, instrument};
Expand Down Expand Up @@ -68,7 +69,7 @@ impl<'a, 'tcx> RegionRenumberer<'a, 'tcx> {
F: Fn() -> RegionCtxt,
{
let origin = NllRegionVariableOrigin::Existential { from_forall: false };
self.infcx.tcx.fold_regions(value, |_region, _depth| {
fold_regions(self.infcx.tcx, value, |_region, _depth| {
self.infcx.next_nll_region_var(origin, || region_ctxt_fn())
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use rustc_middle::bug;
use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
use rustc_middle::traits::ObligationCause;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_span::Span;
use rustc_trait_selection::traits::ScrubbedTraitError;
Expand Down Expand Up @@ -216,7 +217,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
/// are dealt with during trait solving.
fn replace_placeholders_with_nll<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T {
if value.has_placeholders() {
self.tcx.fold_regions(value, |r, _| match *r {
fold_regions(self.tcx, value, |r, _| match *r {
ty::RePlaceholder(placeholder) => {
self.constraints.placeholder_region(self.infcx, placeholder)
}
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use rustc_middle::mir::*;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
Expand Down Expand Up @@ -213,7 +214,7 @@ pub(crate) fn type_check<'a, 'tcx>(

// Convert all regions to nll vars.
let (opaque_type_key, hidden_type) =
infcx.tcx.fold_regions((opaque_type_key, hidden_type), |region, _| {
fold_regions(infcx.tcx, (opaque_type_key, hidden_type), |region, _| {
match region.kind() {
ty::ReVar(_) => region,
ty::RePlaceholder(placeholder) => {
Expand Down Expand Up @@ -2073,7 +2074,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
);

let is_implicit_coercion = coercion_source == CoercionSource::Implicit;
let unsize_to = tcx.fold_regions(ty, |r, _| {
let unsize_to = fold_regions(tcx, ty, |r, _| {
if let ty::ReVar(_) = r.kind() { tcx.lifetimes.re_erased } else { r }
});
self.prove_trait_ref(
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_borrowck/src/universal_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use rustc_hir::lang_items::LangItem;
use rustc_index::IndexVec;
use rustc_infer::infer::NllRegionVariableOrigin;
use rustc_macros::extension;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::fold::{TypeFoldable, fold_regions};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{
self, GenericArgs, GenericArgsRef, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty,
Expand Down Expand Up @@ -824,7 +824,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
self.infcx.tcx.fold_regions(value, |region, _depth| {
fold_regions(self.infcx.tcx, value, |region, _depth| {
let name = region.get_name_or_anon();
debug!(?region, ?name);

Expand Down Expand Up @@ -906,7 +906,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
tcx.fold_regions(value, |region, _| ty::Region::new_var(tcx, self.to_region_vid(region)))
fold_regions(tcx, value, |region, _| ty::Region::new_var(tcx, self.to_region_vid(region)))
}
}

Expand Down
18 changes: 13 additions & 5 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
use rustc_middle::middle::stability::EvalResult;
use rustc_middle::span_bug;
use rustc_middle::ty::error::TypeErrorToStringExt;
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::fold::{BottomUpFolder, fold_regions};
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
use rustc_middle::ty::{
Expand Down Expand Up @@ -322,8 +322,12 @@ fn check_opaque_meets_bounds<'tcx>(
};
let param_env = tcx.param_env(defining_use_anchor);

// FIXME(#132279): This should eventually use the already defined hidden types.
let infcx = tcx.infer_ctxt().build(TypingMode::analysis_in_body(tcx, defining_use_anchor));
// FIXME(#132279): Once `PostBorrowckAnalysis` is supported in the old solver, this branch should be removed.
let infcx = tcx.infer_ctxt().build(if tcx.next_trait_solver_globally() {
TypingMode::post_borrowck_analysis(tcx, defining_use_anchor)
} else {
TypingMode::analysis_in_body(tcx, defining_use_anchor)
});
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);

let args = match origin {
Expand All @@ -346,7 +350,7 @@ fn check_opaque_meets_bounds<'tcx>(
// FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
// here rather than using ReErased.
let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args);
let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() {
let hidden_ty = fold_regions(tcx, hidden_ty, |re, _dbi| match re.kind() {
ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
_ => re,
});
Expand Down Expand Up @@ -417,7 +421,11 @@ fn check_opaque_meets_bounds<'tcx>(
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;

if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } = origin {
if infcx.next_trait_solver() {
Ok(())
} else if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } =
origin
{
// HACK: this should also fall through to the hidden type check below, but the original
// implementation had a bug where equivalent lifetimes are not identical. This caused us
// to reject existing stable code that is otherwise completely fine. The real fix is to
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::hir::nested_filter;
use rustc_middle::query::Providers;
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::util::{Discr, IntTypeExt};
use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode};
use rustc_middle::{bug, span_bug};
Expand Down Expand Up @@ -1415,7 +1416,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
GenericParamKind::Lifetime { .. } => true,
_ => false,
});
let fn_sig = tcx.fold_regions(fn_sig, |r, _| match *r {
let fn_sig = fold_regions(tcx, fn_sig, |r, _| match *r {
ty::ReErased => {
if has_region_params {
ty::Region::new_error_with_message(
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc_hir as hir;
use rustc_hir::HirId;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::query::plumbing::CyclePlaceholder;
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, Article, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
Expand Down Expand Up @@ -113,7 +114,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
// so no need for ConstArg.
Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), span, .. }) if e.hir_id == hir_id => {
let ty = tcx.typeck(def_id).node_type(tcx.local_def_id_to_hir_id(def_id));
let ty = tcx.fold_regions(ty, |r, _| {
let ty = fold_regions(tcx, ty, |r, _| {
if r.is_erased() { ty::Region::new_error_misc(tcx) } else { r }
});
let (ty, opt_sugg) = if let Some(ty) = ty.make_suggestable(tcx, false, None) {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability::AllowUnstable;
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
use rustc_middle::ty::{
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
Expand Down Expand Up @@ -1569,7 +1570,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
);

let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased);
let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
// FIXME: Don't bother dealing with non-lifetime binders here...
if value.has_escaping_bound_vars() {
return false;
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/hir_wf_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
use rustc_middle::bug;
use rustc_middle::query::Providers;
use rustc_middle::ty::fold::fold_regions;
use rustc_middle::ty::{self, TyCtxt, TypingMode};
use rustc_span::def_id::LocalDefId;
use rustc_trait_selection::traits::{self, ObligationCtxt};
Expand Down Expand Up @@ -75,7 +76,7 @@ fn diagnostic_hir_wf_check<'tcx>(
// This visitor can walk into binders, resulting in the `tcx_ty` to
// potentially reference escaping bound variables. We simply erase
// those here.
let tcx_ty = self.tcx.fold_regions(tcx_ty, |r, _| {
let tcx_ty = fold_regions(self.tcx, tcx_ty, |r, _| {
if r.is_bound() { self.tcx.lifetimes.re_erased } else { r }
});
let cause = traits::ObligationCause::new(
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1574,7 +1574,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// Thus we need to prevent them from trying to match the `&_` autoref
// candidates that get created for `&self` trait methods.
ty::Alias(ty::Opaque, alias_ty)
if self.infcx.can_define_opaque_ty(alias_ty.def_id)
if !self.next_trait_solver()
&& self.infcx.can_define_opaque_ty(alias_ty.def_id)
&& !xform_self_ty.is_ty_var() =>
{
return ProbeResult::NoMatch;
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_hir_typeck/src/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::span_bug;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, fold_regions};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperFoldable};
use rustc_span::Span;
Expand Down Expand Up @@ -827,7 +827,10 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
// no reason to keep regions around. They will be repopulated during MIR
// borrowck, and specifically region constraints will be populated during
// MIR typeck which is run on the new body.
value = tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased);
//
// We're not using `tcx.erase_regions` as that also anonymizes bound variables,
// regressing borrowck diagnostics.
value = fold_regions(tcx, value, |_, _| tcx.lifetimes.re_erased);

// Normalize consts in writeback, because GCE doesn't normalize eagerly.
if tcx.features().generic_const_exprs() {
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_infer/src/infer/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::{DUMMY_SP, ErrorGuaranteed};

use super::{BoundRegionConversionTime, InferCtxt, SubregionOrigin};
use super::{BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin};

impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
type Interner = TyCtxt<'tcx>;
Expand Down Expand Up @@ -87,6 +87,10 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
}

fn next_region_infer(&self) -> ty::Region<'tcx> {
self.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP))
}

fn next_ty_infer(&self) -> Ty<'tcx> {
self.next_ty_var(DUMMY_SP)
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use rustc_data_structures::graph::implementation::{
use rustc_data_structures::intern::Interned;
use rustc_data_structures::unord::UnordSet;
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::fold::{TypeFoldable, fold_regions};
use rustc_middle::ty::{
self, ReBound, ReEarlyParam, ReErased, ReError, ReLateParam, RePlaceholder, ReStatic, ReVar,
Region, RegionVid, Ty, TyCtxt,
Expand Down Expand Up @@ -974,7 +974,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
tcx.fold_regions(value, |r, _db| self.resolve_region(tcx, r))
fold_regions(tcx, value, |r, _db| self.resolve_region(tcx, r))
}

fn value(&self, rid: RegionVid) -> &VarValue<'tcx> {
Expand Down
Loading

0 comments on commit 6863327

Please sign in to comment.