Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 11565b9

Browse files
lcnrcompiler-errors
authored andcommitted
support revealing defined opaque post borrowck
1 parent ebd25ca commit 11565b9

File tree

24 files changed

+241
-63
lines changed

24 files changed

+241
-63
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,12 @@ fn check_opaque_meets_bounds<'tcx>(
322322
};
323323
let param_env = tcx.param_env(defining_use_anchor);
324324

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

329333
let args = match origin {
@@ -417,7 +421,11 @@ fn check_opaque_meets_bounds<'tcx>(
417421
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
418422
ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
419423

420-
if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } = origin {
424+
if infcx.next_trait_solver() {
425+
Ok(())
426+
} else if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } =
427+
origin
428+
{
421429
// HACK: this should also fall through to the hidden type check below, but the original
422430
// implementation had a bug where equivalent lifetimes are not identical. This caused us
423431
// to reject existing stable code that is otherwise completely fine. The real fix is to

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15741574
// Thus we need to prevent them from trying to match the `&_` autoref
15751575
// candidates that get created for `&self` trait methods.
15761576
ty::Alias(ty::Opaque, alias_ty)
1577-
if self.infcx.can_define_opaque_ty(alias_ty.def_id)
1577+
if !self.next_trait_solver()
1578+
&& self.infcx.can_define_opaque_ty(alias_ty.def_id)
15781579
&& !xform_self_ty.is_ty_var() =>
15791580
{
15801581
return ProbeResult::NoMatch;

compiler/rustc_infer/src/infer/context.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
77
use rustc_middle::ty::{self, Ty, TyCtxt};
88
use rustc_span::{DUMMY_SP, ErrorGuaranteed};
99

10-
use super::{BoundRegionConversionTime, InferCtxt, SubregionOrigin};
10+
use super::{BoundRegionConversionTime, InferCtxt, RegionVariableOrigin, SubregionOrigin};
1111

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

90+
fn next_region_infer(&self) -> ty::Region<'tcx> {
91+
self.next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP))
92+
}
93+
9094
fn next_ty_infer(&self) -> Ty<'tcx> {
9195
self.next_ty_var(DUMMY_SP)
9296
}

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -990,11 +990,17 @@ impl<'tcx> InferCtxt<'tcx> {
990990

991991
#[inline(always)]
992992
pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
993+
debug_assert!(!self.next_trait_solver());
993994
match self.typing_mode() {
994995
TypingMode::Analysis { defining_opaque_types } => {
995996
id.into().as_local().is_some_and(|def_id| defining_opaque_types.contains(&def_id))
996997
}
997-
TypingMode::Coherence | TypingMode::PostAnalysis => false,
998+
// FIXME(#132279): This function is quite weird in post-analysis
999+
// and post-borrowck analysis mode. We may need to modify its uses
1000+
// to support PostBorrowckAnalysis in the old solver as well.
1001+
TypingMode::Coherence
1002+
| TypingMode::PostBorrowckAnalysis { .. }
1003+
| TypingMode::PostAnalysis => false,
9981004
}
9991005
}
10001006

@@ -1276,15 +1282,16 @@ impl<'tcx> InferCtxt<'tcx> {
12761282
/// using canonicalization or carrying this inference context around.
12771283
pub fn typing_env(&self, param_env: ty::ParamEnv<'tcx>) -> ty::TypingEnv<'tcx> {
12781284
let typing_mode = match self.typing_mode() {
1279-
ty::TypingMode::Coherence => ty::TypingMode::Coherence,
12801285
// FIXME(#132279): This erases the `defining_opaque_types` as it isn't possible
12811286
// to handle them without proper canonicalization. This means we may cause cycle
12821287
// errors and fail to reveal opaques while inside of bodies. We should rename this
12831288
// function and require explicit comments on all use-sites in the future.
12841289
ty::TypingMode::Analysis { defining_opaque_types: _ } => {
12851290
TypingMode::non_body_analysis()
12861291
}
1287-
ty::TypingMode::PostAnalysis => ty::TypingMode::PostAnalysis,
1292+
mode @ (ty::TypingMode::Coherence
1293+
| ty::TypingMode::PostBorrowckAnalysis { .. }
1294+
| ty::TypingMode::PostAnalysis) => mode,
12881295
};
12891296
ty::TypingEnv { typing_mode, param_env }
12901297
}

compiler/rustc_infer/src/infer/opaque_types/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ impl<'tcx> InferCtxt<'tcx> {
9898
span: Span,
9999
param_env: ty::ParamEnv<'tcx>,
100100
) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, TypeError<'tcx>> {
101+
debug_assert!(!self.next_trait_solver());
101102
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
102103
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
103104
let def_id = def_id.expect_local();
@@ -546,7 +547,9 @@ impl<'tcx> InferCtxt<'tcx> {
546547
);
547548
}
548549
}
549-
ty::TypingMode::PostAnalysis => bug!("insert hidden type post-analysis"),
550+
mode @ (ty::TypingMode::PostBorrowckAnalysis { .. } | ty::TypingMode::PostAnalysis) => {
551+
bug!("insert hidden type in {mode:?}")
552+
}
550553
}
551554

552555
Ok(())

compiler/rustc_middle/src/ty/context.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,14 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
632632
fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::DefiningOpaqueTypes {
633633
self.opaque_types_defined_by(defining_anchor)
634634
}
635+
636+
fn fold_regions<T: TypeFoldable<TyCtxt<'tcx>>>(
637+
self,
638+
value: T,
639+
f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
640+
) -> T {
641+
self.fold_regions(value, f)
642+
}
635643
}
636644

637645
macro_rules! bidirectional_lang_item_map {

compiler/rustc_middle/src/ty/fold.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,11 @@ where
5555

5656
impl<'tcx> TyCtxt<'tcx> {
5757
/// Folds the escaping and free regions in `value` using `f`.
58-
pub fn fold_regions<T>(
58+
pub fn fold_regions<T: TypeFoldable<TyCtxt<'tcx>>>(
5959
self,
6060
value: T,
6161
mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
62-
) -> T
63-
where
64-
T: TypeFoldable<TyCtxt<'tcx>>,
65-
{
62+
) -> T {
6663
value.fold_with(&mut RegionFolder::new(self, &mut f))
6764
}
6865
}

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,9 @@ where
339339

340340
match self.typing_mode() {
341341
TypingMode::Coherence => {}
342-
TypingMode::Analysis { .. } | TypingMode::PostAnalysis => {
342+
TypingMode::Analysis { .. }
343+
| TypingMode::PostBorrowckAnalysis { .. }
344+
| TypingMode::PostAnalysis => {
343345
self.discard_impls_shadowed_by_env(goal, &mut candidates);
344346
}
345347
}

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,12 @@ where
644644
}
645645
}
646646

647+
pub(super) fn next_region_var(&mut self) -> I::Region {
648+
let region = self.delegate.next_region_infer();
649+
self.inspect.add_var_value(region);
650+
region
651+
}
652+
647653
pub(super) fn next_ty_infer(&mut self) -> I::Ty {
648654
let ty = self.delegate.next_ty_infer();
649655
self.inspect.add_var_value(ty);

compiler/rustc_next_trait_solver/src/solve/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ mod trait_goals;
2323

2424
use rustc_type_ir::inherent::*;
2525
pub use rustc_type_ir::solve::*;
26-
use rustc_type_ir::{self as ty, Interner};
26+
use rustc_type_ir::{self as ty, Interner, TypingMode};
2727
use tracing::instrument;
2828

2929
pub use self::eval_ctxt::{EvalCtxt, GenerateProofTree, SolverDelegateEvalExt};
@@ -321,6 +321,19 @@ where
321321
Ok(ct)
322322
}
323323
}
324+
325+
fn opaque_type_is_rigid(&self, def_id: I::DefId) -> bool {
326+
match self.typing_mode() {
327+
// Opaques are never rigid outside of analysis mode.
328+
TypingMode::Coherence | TypingMode::PostAnalysis => false,
329+
// During analysis, opaques are rigid unless they may be defined by
330+
// the current body.
331+
TypingMode::Analysis { defining_opaque_types: non_rigid_opaques }
332+
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: non_rigid_opaques } => {
333+
!def_id.as_local().is_some_and(|def_id| non_rigid_opaques.contains(&def_id))
334+
}
335+
}
336+
}
324337
}
325338

326339
fn response_no_constraints_raw<I: Interner>(

0 commit comments

Comments
 (0)