Skip to content

Commit 4396cec

Browse files
committed
Auto merge of #109753 - compiler-errors:replenish-region-constraints, r=aliemjay
Clone region var origins instead of taking them in borrowck Fixes an issue with the new solver where reporting a borrow-checker error ICEs because it calls `InferCtxt::evaluate_obligation`. This also removes a handful of unnecessary `tcx.infer_ctxt().build()` calls that are only there to mitigate this same exact issue, but with the old solver. Fixes compiler-errors/next-solver-hir-issues#12. ---- This implements `@aliemjay's` solution where we just don't *take* the region constraints, but clone them. This potentially makes it easier to write a bug about taking region constraints twice or never at all, but again, not many folks are touching this code.
2 parents 39cf520 + 964600b commit 4396cec

File tree

6 files changed

+43
-33
lines changed

6 files changed

+43
-33
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use rustc_hir as hir;
1010
use rustc_hir::def::{DefKind, Res};
1111
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
1212
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem};
13-
use rustc_infer::infer::TyCtxtInferExt;
1413
use rustc_infer::traits::ObligationCause;
1514
use rustc_middle::hir::nested_filter::OnlyBodies;
1615
use rustc_middle::mir::tcx::PlaceTy;
@@ -643,11 +642,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
643642
let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
644643
return false;
645644
};
646-
// Regions are already solved, so we must use a fresh InferCtxt,
647-
// but the type has region variables, so erase those.
648-
tcx.infer_ctxt()
649-
.build()
650-
.type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env)
645+
self.infcx
646+
.type_implements_trait(default_trait, [ty], param_env)
651647
.must_apply_modulo_regions()
652648
};
653649

@@ -740,13 +736,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
740736
fn suggest_cloning(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) {
741737
let tcx = self.infcx.tcx;
742738
// Try to find predicates on *generic params* that would allow copying `ty`
743-
let infcx = tcx.infer_ctxt().build();
744-
745739
if let Some(clone_trait_def) = tcx.lang_items().clone_trait()
746-
&& infcx
740+
&& self.infcx
747741
.type_implements_trait(
748742
clone_trait_def,
749-
[tcx.erase_regions(ty)],
743+
[ty],
750744
self.param_env,
751745
)
752746
.must_apply_modulo_regions()
@@ -770,12 +764,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
770764
.and_then(|def_id| tcx.hir().get_generics(def_id))
771765
else { return; };
772766
// Try to find predicates on *generic params* that would allow copying `ty`
773-
let infcx = tcx.infer_ctxt().build();
774-
let ocx = ObligationCtxt::new(&infcx);
767+
let ocx = ObligationCtxt::new(&self.infcx);
775768
let copy_did = tcx.require_lang_item(LangItem::Copy, Some(span));
776769
let cause = ObligationCause::misc(span, self.mir_def_id());
777770

778-
ocx.register_bound(cause, self.param_env, infcx.tcx.erase_regions(ty), copy_did);
771+
ocx.register_bound(cause, self.param_env, ty, copy_did);
779772
let errors = ocx.select_all_or_error();
780773

781774
// Only emit suggestion if all required predicates are on generic
@@ -2219,7 +2212,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
22192212
let tcx = self.infcx.tcx;
22202213

22212214
let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
2222-
let return_ty = tcx.erase_regions(return_ty);
22232215

22242216
// to avoid panics
22252217
if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator)

compiler/rustc_borrowck/src/diagnostics/mod.rs

+11-16
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_hir as hir;
1010
use rustc_hir::def::{CtorKind, Namespace};
1111
use rustc_hir::GeneratorKind;
1212
use rustc_index::vec::IndexSlice;
13-
use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt};
13+
use rustc_infer::infer::LateBoundRegionConversionTime;
1414
use rustc_middle::mir::tcx::PlaceTy;
1515
use rustc_middle::mir::{
1616
AggregateKind, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place,
@@ -1042,15 +1042,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10421042
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
10431043
let ty = moved_place.ty(self.body, tcx).ty;
10441044
let suggest = match tcx.get_diagnostic_item(sym::IntoIterator) {
1045-
Some(def_id) => {
1046-
let infcx = self.infcx.tcx.infer_ctxt().build();
1047-
type_known_to_meet_bound_modulo_regions(
1048-
&infcx,
1049-
self.param_env,
1050-
tcx.mk_imm_ref(tcx.lifetimes.re_erased, tcx.erase_regions(ty)),
1051-
def_id,
1052-
)
1053-
}
1045+
Some(def_id) => type_known_to_meet_bound_modulo_regions(
1046+
&self.infcx,
1047+
self.param_env,
1048+
tcx.mk_imm_ref(tcx.lifetimes.re_erased, ty),
1049+
def_id,
1050+
),
10541051
_ => false,
10551052
};
10561053
if suggest {
@@ -1094,20 +1091,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10941091
is_partial,
10951092
is_loop_message,
10961093
});
1097-
let infcx = tcx.infer_ctxt().build();
10981094
// Erase and shadow everything that could be passed to the new infcx.
1099-
let ty = tcx.erase_regions(moved_place.ty(self.body, tcx).ty);
1100-
let method_substs = tcx.erase_regions(method_substs);
1095+
let ty = moved_place.ty(self.body, tcx).ty;
11011096

11021097
if let ty::Adt(def, substs) = ty.kind()
11031098
&& Some(def.did()) == tcx.lang_items().pin_type()
11041099
&& let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind()
1105-
&& let self_ty = infcx.instantiate_binder_with_fresh_vars(
1100+
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
11061101
fn_call_span,
11071102
LateBoundRegionConversionTime::FnCall,
11081103
tcx.fn_sig(method_did).subst(tcx, method_substs).input(0),
11091104
)
1110-
&& infcx.can_eq(self.param_env, ty, self_ty)
1105+
&& self.infcx.can_eq(self.param_env, ty, self_ty)
11111106
{
11121107
err.eager_subdiagnostic(
11131108
&self.infcx.tcx.sess.parse_sess.span_diagnostic,
@@ -1123,7 +1118,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11231118
self.param_env,
11241119
ty::Binder::dummy(trait_ref),
11251120
)
1126-
&& infcx.predicate_must_hold_modulo_regions(&o)
1121+
&& self.infcx.predicate_must_hold_modulo_regions(&o)
11271122
{
11281123
err.span_suggestion_verbose(
11291124
fn_call_span.shrink_to_lo(),

compiler/rustc_borrowck/src/nll.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
235235
// Create the region inference context, taking ownership of the
236236
// region inference data that was contained in `infcx`, and the
237237
// base constraints generated by the type-check.
238-
let var_origins = infcx.take_region_var_origins();
238+
let var_origins = infcx.get_region_var_origins();
239239
let MirTypeckRegionConstraints {
240240
placeholder_indices,
241241
placeholder_index_to_region: _,

compiler/rustc_infer/src/infer/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1228,11 +1228,11 @@ impl<'tcx> InferCtxt<'tcx> {
12281228
/// hence that `resolve_regions_and_report_errors` can never be
12291229
/// called. This is used only during NLL processing to "hand off" ownership
12301230
/// of the set of region variables into the NLL region context.
1231-
pub fn take_region_var_origins(&self) -> VarInfos {
1231+
pub fn get_region_var_origins(&self) -> VarInfos {
12321232
let mut inner = self.inner.borrow_mut();
12331233
let (var_infos, data) = inner
12341234
.region_constraint_storage
1235-
.take()
1235+
.clone()
12361236
.expect("regions already resolved")
12371237
.with_log(&mut inner.undo_log)
12381238
.into_infos_and_data();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// compile-flags: -Ztrait-solver=next
2+
3+
use std::collections::HashMap;
4+
5+
fn foo() -> &'static HashMap<i32, i32>
6+
{
7+
&HashMap::new()
8+
//~^ ERROR cannot return reference to temporary value
9+
}
10+
11+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0515]: cannot return reference to temporary value
2+
--> $DIR/borrowck-error.rs:7:5
3+
|
4+
LL | &HashMap::new()
5+
| ^--------------
6+
| ||
7+
| |temporary value created here
8+
| returns a reference to data owned by the current function
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0515`.

0 commit comments

Comments
 (0)