Skip to content

Commit 7139b88

Browse files
committed
Auto merge of rust-lang#138785 - lcnr:typing-mode-borrowck, r=<try>
add `TypingMode::Borrowck` Still not quite ready Based on rust-lang#138492 and rust-lang#138719 r? `@compiler-errors` `@oli-obk`
2 parents 4ac032f + 674c2f4 commit 7139b88

File tree

208 files changed

+1953
-2657
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

208 files changed

+1953
-2657
lines changed

compiler/rustc_ast_passes/src/feature_gate.rs

-1
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
483483
half_open_range_patterns_in_slices,
484484
"half-open range patterns in slices are unstable"
485485
);
486-
gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
487486
gate_all!(associated_const_equality, "associated const equality is incomplete");
488487
gate_all!(yeet_expr, "`do yeet` expression is experimental");
489488
gate_all!(dyn_star, "`dyn*` trait objects are experimental");

compiler/rustc_borrowck/messages.ftl

-7
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,6 @@ borrowck_opaque_type_lifetime_mismatch =
162162
.prev_lifetime_label = lifetime `{$prev}` previously used here
163163
.note = if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
164164
165-
borrowck_opaque_type_non_generic_param =
166-
expected generic {$kind} parameter, found `{$ty}`
167-
.label = {STREQ($ty, "'static") ->
168-
[true] cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
169-
*[other] this generic parameter must be used with a generic {$kind} parameter
170-
}
171-
172165
borrowck_partial_var_move_by_use_in_closure =
173166
variable {$is_partial ->
174167
[true] partially moved

compiler/rustc_borrowck/src/consumers.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! This file provides API for compiler consumers.
22
33
use rustc_hir::def_id::LocalDefId;
4-
use rustc_index::{IndexSlice, IndexVec};
4+
use rustc_index::IndexVec;
55
use rustc_middle::mir::{Body, Promoted};
66
use rustc_middle::ty::TyCtxt;
77

@@ -100,8 +100,5 @@ pub fn get_body_with_borrowck_facts(
100100
def: LocalDefId,
101101
options: ConsumerOptions,
102102
) -> BodyWithBorrowckFacts<'_> {
103-
let (input_body, promoted) = tcx.mir_promoted(def);
104-
let input_body: &Body<'_> = &input_body.borrow();
105-
let promoted: &IndexSlice<_, _> = &promoted.borrow();
106-
*super::do_mir_borrowck(tcx, input_body, promoted, Some(options)).1.unwrap()
103+
*super::do_mir_borrowck(tcx, def, Some(options)).1.unwrap()
107104
}

compiler/rustc_borrowck/src/lib.rs

+13-42
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use rustc_infer::infer::{
3535
};
3636
use rustc_middle::mir::*;
3737
use rustc_middle::query::Providers;
38-
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode, fold_regions};
38+
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt, TypingMode};
3939
use rustc_middle::{bug, span_bug};
4040
use rustc_mir_dataflow::impls::{
4141
EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces,
@@ -73,6 +73,7 @@ mod def_use;
7373
mod diagnostics;
7474
mod member_constraints;
7575
mod nll;
76+
mod opaque_types;
7677
mod path_utils;
7778
mod place_ext;
7879
mod places_conflict;
@@ -102,11 +103,8 @@ pub fn provide(providers: &mut Providers) {
102103
}
103104

104105
fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
105-
let (input_body, promoted) = tcx.mir_promoted(def);
106-
debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
107-
106+
let (input_body, _0) = tcx.mir_promoted(def);
108107
let input_body: &Body<'_> = &input_body.borrow();
109-
110108
if input_body.should_skip() || input_body.tainted_by_errors.is_some() {
111109
debug!("Skipping borrowck because of injected body or tainted body");
112110
// Let's make up a borrowck result! Fun times!
@@ -119,7 +117,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
119117
return tcx.arena.alloc(result);
120118
}
121119

122-
let borrowck_result = do_mir_borrowck(tcx, input_body, &*promoted.borrow(), None).0;
120+
let borrowck_result = do_mir_borrowck(tcx, def, None).0;
123121
debug!("mir_borrowck done");
124122

125123
tcx.arena.alloc(borrowck_result)
@@ -130,15 +128,16 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
130128
/// Use `consumer_options: None` for the default behavior of returning
131129
/// [`BorrowCheckResult`] only. Otherwise, return [`BodyWithBorrowckFacts`] according
132130
/// to the given [`ConsumerOptions`].
133-
#[instrument(skip(tcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")]
131+
#[instrument(skip(tcx), level = "debug")]
134132
fn do_mir_borrowck<'tcx>(
135133
tcx: TyCtxt<'tcx>,
136-
input_body: &Body<'tcx>,
137-
input_promoted: &IndexSlice<Promoted, Body<'tcx>>,
134+
def: LocalDefId,
138135
consumer_options: Option<ConsumerOptions>,
139136
) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
140-
let def = input_body.source.def_id().expect_local();
141137
let infcx = BorrowckInferCtxt::new(tcx, def);
138+
let (input_body, promoted) = tcx.mir_promoted(def);
139+
let input_body: &Body<'_> = &input_body.borrow();
140+
let input_promoted: &IndexSlice<_, _> = &promoted.borrow();
142141
if let Some(e) = input_body.tainted_by_errors {
143142
infcx.set_tainted_by_errors(e);
144143
}
@@ -172,12 +171,6 @@ fn do_mir_borrowck<'tcx>(
172171
let free_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted);
173172
let body = &body_owned; // no further changes
174173

175-
// FIXME(-Znext-solver): A bit dubious that we're only registering
176-
// predefined opaques in the typeck root.
177-
if infcx.next_trait_solver() && !infcx.tcx.is_typeck_child(body.source.def_id()) {
178-
infcx.register_predefined_opaques_for_next_solver(def);
179-
}
180-
181174
let location_table = PoloniusLocationTable::new(body);
182175

183176
let move_data = MoveData::gather_moves(body, tcx, |_| true);
@@ -192,7 +185,7 @@ fn do_mir_borrowck<'tcx>(
192185
// Compute non-lexical lifetimes.
193186
let nll::NllOutput {
194187
regioncx,
195-
opaque_type_values,
188+
concrete_opaque_types,
196189
polonius_input,
197190
polonius_output,
198191
opt_closure_req,
@@ -222,7 +215,7 @@ fn do_mir_borrowck<'tcx>(
222215
body,
223216
&regioncx,
224217
&opt_closure_req,
225-
&opaque_type_values,
218+
&concrete_opaque_types,
226219
diags_buffer,
227220
);
228221

@@ -357,7 +350,7 @@ fn do_mir_borrowck<'tcx>(
357350
let tainted_by_errors = mbcx.emit_errors();
358351

359352
let result = BorrowCheckResult {
360-
concrete_opaque_types: opaque_type_values,
353+
concrete_opaque_types: concrete_opaque_types.into_inner(),
361354
closure_requirements: opt_closure_req,
362355
used_mut_upvars: mbcx.used_mut_upvars,
363356
tainted_by_errors,
@@ -432,7 +425,7 @@ pub(crate) struct BorrowckInferCtxt<'tcx> {
432425

433426
impl<'tcx> BorrowckInferCtxt<'tcx> {
434427
pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
435-
let infcx = tcx.infer_ctxt().build(TypingMode::analysis_in_body(tcx, def_id));
428+
let infcx = tcx.infer_ctxt().build(TypingMode::borrowck(tcx, def_id));
436429
let param_env = tcx.param_env(def_id);
437430
BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()), param_env }
438431
}
@@ -479,28 +472,6 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
479472

480473
next_region
481474
}
482-
483-
/// With the new solver we prepopulate the opaque type storage during
484-
/// MIR borrowck with the hidden types from HIR typeck. This is necessary
485-
/// to avoid ambiguities as earlier goals can rely on the hidden type
486-
/// of an opaque which is only constrained by a later goal.
487-
fn register_predefined_opaques_for_next_solver(&self, def_id: LocalDefId) {
488-
let tcx = self.tcx;
489-
// OK to use the identity arguments for each opaque type key, since
490-
// we remap opaques from HIR typeck back to their definition params.
491-
for data in tcx.typeck(def_id).concrete_opaque_types.iter().map(|(k, v)| (*k, *v)) {
492-
// HIR typeck did not infer the regions of the opaque, so we instantiate
493-
// them with fresh inference variables.
494-
let (key, hidden_ty) = fold_regions(tcx, data, |_, _| {
495-
self.next_nll_region_var_in_universe(
496-
NllRegionVariableOrigin::Existential { from_forall: false },
497-
ty::UniverseIndex::ROOT,
498-
)
499-
});
500-
501-
self.inject_new_hidden_type_unchecked(key, hidden_ty);
502-
}
503-
}
504475
}
505476

506477
impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {

compiler/rustc_borrowck/src/nll.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@ use std::str::FromStr;
66
use std::{env, io};
77

88
use polonius_engine::{Algorithm, Output};
9-
use rustc_data_structures::fx::FxIndexMap;
10-
use rustc_hir::def_id::LocalDefId;
119
use rustc_index::IndexSlice;
1210
use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options};
1311
use rustc_middle::mir::{
1412
Body, ClosureOutlivesSubject, ClosureRegionRequirements, PassWhere, Promoted, create_dump_file,
1513
dump_enabled, dump_mir,
1614
};
1715
use rustc_middle::ty::print::with_no_trimmed_paths;
18-
use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt};
16+
use rustc_middle::ty::{self, TyCtxt};
1917
use rustc_mir_dataflow::ResultsCursor;
2018
use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
2119
use rustc_mir_dataflow::move_paths::MoveData;
@@ -27,6 +25,7 @@ use tracing::{debug, instrument};
2725
use crate::borrow_set::BorrowSet;
2826
use crate::consumers::ConsumerOptions;
2927
use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors};
28+
use crate::opaque_types::ConcreteOpaqueTypes;
3029
use crate::polonius::PoloniusDiagnosticsContext;
3130
use crate::polonius::legacy::{
3231
PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput,
@@ -40,7 +39,7 @@ use crate::{BorrowckInferCtxt, polonius, renumber};
4039
/// closure requirements to propagate, and any generated errors.
4140
pub(crate) struct NllOutput<'tcx> {
4241
pub regioncx: RegionInferenceContext<'tcx>,
43-
pub opaque_type_values: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
42+
pub concrete_opaque_types: ConcreteOpaqueTypes<'tcx>,
4443
pub polonius_input: Option<Box<PoloniusFacts>>,
4544
pub polonius_output: Option<Box<PoloniusOutput>>,
4645
pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
@@ -99,6 +98,8 @@ pub(crate) fn compute_regions<'a, 'tcx>(
9998

10099
let location_map = Rc::new(DenseLocationMap::new(body));
101100

101+
let mut concrete_opaque_types = ConcreteOpaqueTypes::default();
102+
102103
// Run the MIR type-checker.
103104
let MirTypeckResults {
104105
constraints,
@@ -116,6 +117,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
116117
flow_inits,
117118
move_data,
118119
Rc::clone(&location_map),
120+
&mut concrete_opaque_types,
119121
);
120122

121123
// Create the region inference context, taking ownership of the
@@ -180,11 +182,11 @@ pub(crate) fn compute_regions<'a, 'tcx>(
180182
infcx.set_tainted_by_errors(guar);
181183
}
182184

183-
let remapped_opaque_tys = regioncx.infer_opaque_types(infcx, opaque_type_values);
185+
regioncx.infer_opaque_types(infcx, opaque_type_values, &mut concrete_opaque_types);
184186

185187
NllOutput {
186188
regioncx,
187-
opaque_type_values: remapped_opaque_tys,
189+
concrete_opaque_types,
188190
polonius_input: polonius_facts.map(Box::new),
189191
polonius_output,
190192
opt_closure_req: closure_region_requirements,
@@ -300,7 +302,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>(
300302
body: &Body<'tcx>,
301303
regioncx: &RegionInferenceContext<'tcx>,
302304
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
303-
opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
305+
concrete_opaque_types: &ConcreteOpaqueTypes<'tcx>,
304306
diagnostics_buffer: &mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>,
305307
) {
306308
let tcx = infcx.tcx;
@@ -343,8 +345,8 @@ pub(super) fn dump_annotation<'tcx, 'infcx>(
343345
err
344346
};
345347

346-
if !opaque_type_values.is_empty() {
347-
err.note(format!("Inferred opaque type values:\n{opaque_type_values:#?}"));
348+
if !concrete_opaque_types.is_empty() {
349+
err.note(format!("Inferred opaque type values:\n{concrete_opaque_types:#?}"));
348350
}
349351

350352
diagnostics_buffer.buffer_non_error(err);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
use rustc_data_structures::fx::FxIndexMap;
2+
use rustc_hir::def_id::LocalDefId;
3+
use rustc_middle::ty::{OpaqueHiddenType, Ty, TyCtxt};
4+
5+
#[derive(Debug, Default)]
6+
pub(super) struct ConcreteOpaqueTypes<'tcx> {
7+
concrete_opaque_types: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
8+
}
9+
10+
impl<'tcx> ConcreteOpaqueTypes<'tcx> {
11+
pub(super) fn is_empty(&self) -> bool {
12+
self.concrete_opaque_types.is_empty()
13+
}
14+
15+
pub(super) fn into_inner(self) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
16+
self.concrete_opaque_types
17+
}
18+
19+
/// Insert an opaque type into the list of opaque types defined by this function
20+
/// after mapping the hidden type to the generic parameters of the opaque type
21+
/// definition.
22+
pub(super) fn insert(
23+
&mut self,
24+
tcx: TyCtxt<'tcx>,
25+
def_id: LocalDefId,
26+
hidden_ty: OpaqueHiddenType<'tcx>,
27+
) {
28+
// Sometimes two opaque types are the same only after we remap the generic parameters
29+
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to
30+
// `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we
31+
// only know that once we convert the generic parameters to those of the opaque type.
32+
if let Some(prev) = self.concrete_opaque_types.get_mut(&def_id) {
33+
if prev.ty != hidden_ty.ty {
34+
let (Ok(guar) | Err(guar)) =
35+
prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit());
36+
prev.ty = Ty::new_error(tcx, guar);
37+
}
38+
// Pick a better span if there is one.
39+
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
40+
prev.span = prev.span.substitute_dummy(hidden_ty.span);
41+
} else {
42+
self.concrete_opaque_types.insert(def_id, hidden_ty);
43+
}
44+
}
45+
46+
pub(super) fn extend_from_nested_body(
47+
&mut self,
48+
tcx: TyCtxt<'tcx>,
49+
nested_body: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
50+
) {
51+
for (&def_id, &hidden_ty) in nested_body {
52+
self.insert(tcx, def_id, hidden_ty);
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)