Skip to content

Commit 0f6e06b

Browse files
committed
Lazily resolve type-alias-impl-trait defining uses
by using an opaque type obligation to bubble up comparisons between opaque types and other types Also uses proper obligation causes so that the body id works, because out of some reason nll uses body ids for logic instead of just diagnostics.
1 parent 8d2b598 commit 0f6e06b

File tree

284 files changed

+2645
-2096
lines changed

Some content is hidden

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

284 files changed

+2645
-2096
lines changed

compiler/rustc_borrowck/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,9 @@ fn mir_borrowck<'tcx>(
124124
) -> &'tcx BorrowCheckResult<'tcx> {
125125
let (input_body, promoted) = tcx.mir_promoted(def);
126126
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
127+
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
127128

128-
let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(def.did).enter(|infcx| {
129+
let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(hir_owner).enter(|infcx| {
129130
let input_body: &Body<'_> = &input_body.borrow();
130131
let promoted: &IndexVec<_, _> = &promoted.borrow();
131132
do_mir_borrowck(&infcx, input_body, promoted, false).0
@@ -140,7 +141,7 @@ fn mir_borrowck<'tcx>(
140141
/// If `return_body_with_facts` is true, then return the body with non-erased
141142
/// region ids on which the borrow checking was performed together with Polonius
142143
/// facts.
143-
#[instrument(skip(infcx, input_body, input_promoted), level = "debug")]
144+
#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.with_opt_param().as_local().unwrap()), level = "debug")]
144145
fn do_mir_borrowck<'a, 'tcx>(
145146
infcx: &InferCtxt<'a, 'tcx>,
146147
input_body: &Body<'tcx>,

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use rustc_data_structures::fx::FxHashMap;
22
use rustc_data_structures::vec_map::VecMap;
33
use rustc_hir::OpaqueTyOrigin;
4-
use rustc_infer::infer::opaque_types::OpaqueTypeDecl;
54
use rustc_infer::infer::InferCtxt;
65
use rustc_middle::ty::subst::GenericArgKind;
76
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
@@ -54,27 +53,40 @@ impl<'tcx> RegionInferenceContext<'tcx> {
5453
pub(crate) fn infer_opaque_types(
5554
&self,
5655
infcx: &InferCtxt<'_, 'tcx>,
57-
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>,
56+
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (Ty<'tcx>, Span, OpaqueTyOrigin)>,
5857
span: Span,
5958
) -> VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>> {
6059
opaque_ty_decls
6160
.into_iter()
62-
.filter_map(|(opaque_type_key, decl)| {
61+
.filter_map(|(opaque_type_key, (concrete_type, decl_span, origin))| {
6362
let substs = opaque_type_key.substs;
64-
let concrete_type = decl.concrete_ty;
63+
// FIXME: why are the spans in decl_span often DUMMY_SP?
64+
let span = decl_span.substitute_dummy(span);
6565
debug!(?concrete_type, ?substs);
6666

6767
let mut subst_regions = vec![self.universal_regions.fr_static];
6868
let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
69-
let vid = self.universal_regions.to_region_vid(region);
70-
subst_regions.push(vid);
71-
self.definitions[vid].external_name.unwrap_or_else(|| {
72-
infcx
73-
.tcx
74-
.sess
75-
.delay_span_bug(span, "opaque type with non-universal region substs");
76-
infcx.tcx.lifetimes.re_static
77-
})
69+
let vid = self.to_region_vid(region);
70+
trace!(?vid);
71+
let scc = self.constraint_sccs.scc(vid);
72+
trace!(?scc);
73+
match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
74+
self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
75+
}) {
76+
Some(region) => {
77+
let vid = self.universal_regions.to_region_vid(region);
78+
subst_regions.push(vid);
79+
region
80+
}
81+
None => {
82+
subst_regions.push(vid);
83+
infcx.tcx.sess.delay_span_bug(
84+
span,
85+
"opaque type with non-universal region substs",
86+
);
87+
infcx.tcx.lifetimes.re_static
88+
}
89+
}
7890
});
7991

8092
subst_regions.sort();
@@ -100,12 +112,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
100112
span,
101113
);
102114

103-
check_opaque_type_parameter_valid(
104-
infcx.tcx,
105-
opaque_type_key,
106-
OpaqueTypeDecl { concrete_ty: remapped_type, ..decl },
107-
)
108-
.then_some((opaque_type_key, remapped_type))
115+
check_opaque_type_parameter_valid(infcx.tcx, opaque_type_key, origin, span)
116+
.then_some((opaque_type_key, remapped_type))
109117
})
110118
.collect()
111119
}
@@ -149,9 +157,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
149157
fn check_opaque_type_parameter_valid(
150158
tcx: TyCtxt<'_>,
151159
opaque_type_key: OpaqueTypeKey<'_>,
152-
decl: OpaqueTypeDecl<'_>,
160+
origin: OpaqueTyOrigin,
161+
span: Span,
153162
) -> bool {
154-
match decl.origin {
163+
match origin {
155164
// No need to check return position impl trait (RPIT)
156165
// because for type and const parameters they are correct
157166
// by construction: we convert
@@ -177,7 +186,6 @@ fn check_opaque_type_parameter_valid(
177186
// Check these
178187
OpaqueTyOrigin::TyAlias => {}
179188
}
180-
let span = decl.definition_span;
181189
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
182190
let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
183191
for (i, arg) in opaque_type_key.substs.iter().enumerate() {

compiler/rustc_borrowck/src/type_check/input_output.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
147147
// Return types are a bit more complex. They may contain opaque `impl Trait` types.
148148
let mir_output_ty = body.local_decls[RETURN_PLACE].ty;
149149
let output_span = body.local_decls[RETURN_PLACE].source_info.span;
150-
if let Err(terr) = self.eq_opaque_type_and_type(
151-
mir_output_ty,
150+
if let Err(terr) = self.eq_types(
152151
normalized_output_ty,
152+
mir_output_ty,
153153
Locations::All(output_span),
154154
ConstraintCategory::BoringNoLocation,
155155
) {
@@ -169,9 +169,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
169169
let user_provided_output_ty = user_provided_sig.output();
170170
let user_provided_output_ty =
171171
self.normalize(user_provided_output_ty, Locations::All(output_span));
172-
if let Err(err) = self.eq_opaque_type_and_type(
173-
mir_output_ty,
172+
if let Err(err) = self.eq_types(
174173
user_provided_output_ty,
174+
mir_output_ty,
175175
Locations::All(output_span),
176176
ConstraintCategory::BoringNoLocation,
177177
) {

0 commit comments

Comments
 (0)