Skip to content

add TypingMode::Borrowck #138785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 4, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 7 additions & 31 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use rustc_infer::infer::{
};
use rustc_middle::mir::*;
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode, fold_regions};
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode};
use rustc_middle::{bug, span_bug};
use rustc_mir_dataflow::impls::{
EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces,
Expand Down Expand Up @@ -171,12 +171,6 @@ fn do_mir_borrowck<'tcx>(
let free_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted);
let body = &body_owned; // no further changes

// FIXME(-Znext-solver): A bit dubious that we're only registering
// predefined opaques in the typeck root.
if infcx.next_trait_solver() && !infcx.tcx.is_typeck_child(body.source.def_id()) {
infcx.register_predefined_opaques_for_next_solver(def);
}

let location_table = PoloniusLocationTable::new(body);

let move_data = MoveData::gather_moves(body, tcx, |_| true);
Expand Down Expand Up @@ -431,7 +425,12 @@ pub(crate) struct BorrowckInferCtxt<'tcx> {

impl<'tcx> BorrowckInferCtxt<'tcx> {
pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
let infcx = tcx.infer_ctxt().build(TypingMode::analysis_in_body(tcx, def_id));
let typing_mode = if tcx.use_typing_mode_borrowck() {
TypingMode::borrowck(tcx, def_id)
} else {
TypingMode::analysis_in_body(tcx, def_id)
};
let infcx = tcx.infer_ctxt().build(typing_mode);
let param_env = tcx.param_env(def_id);
BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()), param_env }
}
Expand Down Expand Up @@ -478,29 +477,6 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {

next_region
}

/// With the new solver we prepopulate the opaque type storage during
/// MIR borrowck with the hidden types from HIR typeck. This is necessary
/// to avoid ambiguities as earlier goals can rely on the hidden type
/// of an opaque which is only constrained by a later goal.
fn register_predefined_opaques_for_next_solver(&self, def_id: LocalDefId) {
let tcx = self.tcx;
// OK to use the identity arguments for each opaque type key, since
// we remap opaques from HIR typeck back to their definition params.
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) = fold_regions(tcx, data, |_, _| {
self.next_nll_region_var_in_universe(
NllRegionVariableOrigin::Existential { from_forall: false },
ty::UniverseIndex::ROOT,
)
});

let prev = self.register_hidden_type_in_storage(key, hidden_ty);
assert_eq!(prev, None);
}
}
}

impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
Expand Down
18 changes: 13 additions & 5 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use rustc_data_structures::fx::FxIndexMap;
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
use rustc_macros::extension;
use rustc_middle::ty::{
self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, fold_regions,
self, DefiningScopeKind, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable,
TypeVisitableExt, fold_regions,
};
use rustc_span::Span;
use rustc_trait_selection::opaque_types::check_opaque_type_parameter_valid;
Expand Down Expand Up @@ -266,14 +267,21 @@ impl<'tcx> InferCtxt<'tcx> {
return Ty::new_error(self.tcx, e);
}

if let Err(guar) =
check_opaque_type_parameter_valid(self, opaque_type_key, instantiated_ty.span)
{
if let Err(guar) = check_opaque_type_parameter_valid(
self,
opaque_type_key,
instantiated_ty.span,
DefiningScopeKind::MirBorrowck,
) {
return Ty::new_error(self.tcx, guar);
}

let definition_ty = instantiated_ty
.remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false)
.remap_generic_params_to_declaration_params(
opaque_type_key,
self.tcx,
DefiningScopeKind::MirBorrowck,
)
.ty;

if let Err(e) = definition_ty.error_reported() {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers {
type_of: type_of::type_of,
type_of_opaque: type_of::type_of_opaque,
type_of_opaque_hir_typeck: type_of::type_of_opaque_hir_typeck,
type_alias_is_lazy: type_of::type_alias_is_lazy,
item_bounds: item_bounds::item_bounds,
explicit_item_bounds: item_bounds::explicit_item_bounds,
Expand Down
59 changes: 55 additions & 4 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use rustc_hir::{self as hir, AmbigArg, HirId};
use rustc_middle::query::plumbing::CyclePlaceholder;
use rustc_middle::ty::print::with_forced_trimmed_paths;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, fold_regions};
use rustc_middle::ty::{
self, DefiningScopeKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt, fold_regions,
};
use rustc_middle::{bug, span_bug};
use rustc_span::{DUMMY_SP, Ident, Span};

Expand Down Expand Up @@ -324,10 +326,18 @@ pub(super) fn type_of_opaque(
if let Some(def_id) = def_id.as_local() {
Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
opaque::find_opaque_ty_constraints_for_tait(tcx, def_id)
opaque::find_opaque_ty_constraints_for_tait(
tcx,
def_id,
DefiningScopeKind::MirBorrowck,
)
}
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. } => {
opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id)
opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
tcx,
def_id,
DefiningScopeKind::MirBorrowck,
)
}
// Opaque types desugared from `impl Trait`.
hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
Expand All @@ -340,7 +350,12 @@ pub(super) fn type_of_opaque(
"tried to get type of this RPITIT with no definition"
);
}
opaque::find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
opaque::find_opaque_ty_constraints_for_rpit(
tcx,
def_id,
owner,
DefiningScopeKind::MirBorrowck,
)
}
}))
} else {
Expand All @@ -350,6 +365,42 @@ pub(super) fn type_of_opaque(
}
}

pub(super) fn type_of_opaque_hir_typeck(
tcx: TyCtxt<'_>,
def_id: LocalDefId,
) -> ty::EarlyBinder<'_, Ty<'_>> {
ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
opaque::find_opaque_ty_constraints_for_tait(tcx, def_id, DefiningScopeKind::HirTypeck)
}
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. } => {
opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
tcx,
def_id,
DefiningScopeKind::HirTypeck,
)
}
// Opaque types desugared from `impl Trait`.
hir::OpaqueTyOrigin::FnReturn { parent: owner, in_trait_or_impl }
| hir::OpaqueTyOrigin::AsyncFn { parent: owner, in_trait_or_impl } => {
if in_trait_or_impl == Some(hir::RpitContext::Trait)
&& !tcx.defaultness(owner).has_value()
{
span_bug!(
tcx.def_span(def_id),
"tried to get type of this RPITIT with no definition"
);
}
opaque::find_opaque_ty_constraints_for_rpit(
tcx,
def_id,
owner,
DefiningScopeKind::HirTypeck,
)
}
})
}

fn infer_placeholder_type<'tcx>(
cx: &dyn HirTyLowerer<'tcx>,
def_id: LocalDefId,
Expand Down
Loading
Loading