Skip to content
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

Lazy type-alias-impl-trait #92007

Merged
merged 53 commits into from
Feb 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
d49b074
Add roll back infrastructure for opaque type caches
oli-obk Aug 13, 2021
a4c1cec
Add some sanity assertions to make sure we use the opaque types corre…
oli-obk Aug 20, 2021
bbbdcb3
Update some comments
oli-obk Aug 20, 2021
4e1a596
Found suspicious comparison of constants
oli-obk Aug 20, 2021
47a6a24
Add a convenient way to inject rustc flags somewhere late in the boot…
oli-obk Sep 3, 2021
f7abc1b
Expose current span to type equality checking in nll
oli-obk Aug 20, 2021
8d2b598
More sanity checks
oli-obk Aug 20, 2021
0f6e06b
Lazily resolve type-alias-impl-trait defining uses
oli-obk Aug 20, 2021
9110911
bless
oli-obk Jan 25, 2022
7bce50c
Register member constraints on the final merged hidden type
oli-obk Jan 25, 2022
a745797
Stop generating inference vars for nested impl trait and let type equ…
oli-obk Jan 26, 2022
38f50d1
Eagerly merge hidden types.
oli-obk Jan 26, 2022
edaf962
Clean up leftovers from eager hidden type merging
oli-obk Jan 26, 2022
64c5b9a
Add backcompat hack to support
oli-obk Jan 26, 2022
7795f62
Add explanation for early abort in TAIT hidden type computation
oli-obk Jan 26, 2022
77aacc1
Test recursive TAIT declarations
oli-obk Jan 26, 2022
cbfd736
Update an outdated test explanation
oli-obk Jan 26, 2022
5a374dc
Add some tests to show what happens when you compare two opaque types…
oli-obk Jan 26, 2022
3146c96
We're equating hidden types eagerly now
oli-obk Jan 27, 2022
94d6a9a
This can't happen anymore. An opaque type can't end up with itself as…
oli-obk Jan 27, 2022
2247778
Fixup changes that aren't neccessary anymore
oli-obk Jan 27, 2022
e03edd2
Inline a function that is only ever used in one place
oli-obk Jan 27, 2022
fcba8d3
Remove the `Instantiator` now that we don't recurse within it anymore
oli-obk Jan 27, 2022
5b49b8e
Remove unnecessary closure in favour of just passing the argument dir…
oli-obk Jan 27, 2022
d35d1ef
Remove unnecessary field
oli-obk Jan 27, 2022
b45fabd
Inline a function that is only used once
oli-obk Jan 27, 2022
dbda675
Undo a diff
oli-obk Jan 27, 2022
d8c29b3
Simplify diff
oli-obk Jan 27, 2022
d3b534b
manual formatting
oli-obk Jan 27, 2022
dc36b38
Make a comment more obvious
oli-obk Jan 27, 2022
3d4b9b8
Remove some unused arguments and update a comment
oli-obk Jan 27, 2022
c564898
Remove a now-useless field
oli-obk Jan 27, 2022
e4794d9
Undo a change that is now unnecessary
oli-obk Jan 27, 2022
b6d57ec
Hide further opaque type errors if items that could constrain the opa…
oli-obk Jan 27, 2022
7fd9c7e
undo a useless change
oli-obk Jan 27, 2022
5518d19
Guess head span of async blocks
oli-obk Jan 27, 2022
4d2e965
Make a span more useful
oli-obk Jan 27, 2022
29c8732
Make the error for opaque types that have no hidden types a bit infor…
oli-obk Jan 28, 2022
6560d77
Bail out early if there already were errors
oli-obk Jan 28, 2022
59d0bff
Reduce follow-up errors that are not helpful
oli-obk Jan 28, 2022
ee2158f
run rustfmt
oli-obk Jan 31, 2022
ebf2772
Add regression test
oli-obk Feb 1, 2022
7a1ccf9
Avoid an ICE in the presence of HKL
oli-obk Feb 1, 2022
bae04fb
Ensure we error in case of non-higher-kinded lifetimes
oli-obk Feb 1, 2022
7f608eb
Prevent two opaque types in their defining scopes from being defined …
oli-obk Feb 1, 2022
be153f0
Only prevent TAITs from defining each other, RPIT and async are fine,…
oli-obk Feb 2, 2022
d9bb93f
Fix some doctests where the main function returns an opaque type
oli-obk Feb 2, 2022
d526a8d
Clean up opaque type obligations in query results
oli-obk Feb 3, 2022
80c7b61
Add tests for lifetime-swaps, not just type param swaps
oli-obk Feb 3, 2022
6807d37
Add some new tests with amusing diagnostics
oli-obk Feb 3, 2022
7546163
Improve self-referential diagnostic somewhat
oli-obk Feb 3, 2022
c93f571
Print opaque types from type aliases via their path
oli-obk Feb 7, 2022
9822fff
Add a test showing that we don't infer across multiple uses of the sa…
oli-obk Feb 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 3 additions & 2 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,9 @@ fn mir_borrowck<'tcx>(
) -> &'tcx BorrowCheckResult<'tcx> {
let (input_body, promoted) = tcx.mir_promoted(def);
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;

let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(def.did).enter(|infcx| {
let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(hir_owner).enter(|infcx| {
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexVec<_, _> = &promoted.borrow();
do_mir_borrowck(&infcx, input_body, promoted, false).0
Expand All @@ -140,7 +141,7 @@ fn mir_borrowck<'tcx>(
/// If `return_body_with_facts` is true, then return the body with non-erased
/// region ids on which the borrow checking was performed together with Polonius
/// facts.
#[instrument(skip(infcx, input_body, input_promoted), level = "debug")]
#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.with_opt_param().as_local().unwrap()), level = "debug")]
fn do_mir_borrowck<'a, 'tcx>(
infcx: &InferCtxt<'a, 'tcx>,
input_body: &Body<'tcx>,
Expand Down
58 changes: 38 additions & 20 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::vec_map::VecMap;
use rustc_hir::OpaqueTyOrigin;
use rustc_infer::infer::opaque_types::OpaqueTypeDecl;
use rustc_infer::infer::InferCtxt;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
Expand Down Expand Up @@ -54,27 +53,44 @@ impl<'tcx> RegionInferenceContext<'tcx> {
pub(crate) fn infer_opaque_types(
&self,
infcx: &InferCtxt<'_, 'tcx>,
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>,
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (Ty<'tcx>, Span, OpaqueTyOrigin)>,
span: Span,
) -> VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>> {
opaque_ty_decls
.into_iter()
.filter_map(|(opaque_type_key, decl)| {
.map(|(opaque_type_key, (concrete_type, decl_span, origin))| {
let substs = opaque_type_key.substs;
let concrete_type = decl.concrete_ty;
// FIXME: why are the spans in decl_span often DUMMY_SP?
let span = decl_span.substitute_dummy(span);
debug!(?concrete_type, ?substs);

let mut subst_regions = vec![self.universal_regions.fr_static];
let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(vid);
self.definitions[vid].external_name.unwrap_or_else(|| {
infcx
.tcx
.sess
.delay_span_bug(span, "opaque type with non-universal region substs");
infcx.tcx.lifetimes.re_static
})
if let ty::RePlaceholder(..) = region {
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
return region;
}
let vid = self.to_region_vid(region);
trace!(?vid);
let scc = self.constraint_sccs.scc(vid);
trace!(?scc);
match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
}) {
Some(region) => {
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(vid);
region
}
None => {
subst_regions.push(vid);
infcx.tcx.sess.delay_span_bug(
span,
"opaque type with non-universal region substs",
);
infcx.tcx.lifetimes.re_static
}
}
});

subst_regions.sort();
Expand All @@ -100,12 +116,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
span,
);

check_opaque_type_parameter_valid(
infcx.tcx,
(
opaque_type_key,
OpaqueTypeDecl { concrete_ty: remapped_type, ..decl },
if check_opaque_type_parameter_valid(infcx.tcx, opaque_type_key, origin, span) {
remapped_type
} else {
infcx.tcx.ty_error()
},
)
.then_some((opaque_type_key, remapped_type))
})
.collect()
}
Expand Down Expand Up @@ -149,9 +167,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
fn check_opaque_type_parameter_valid(
tcx: TyCtxt<'_>,
opaque_type_key: OpaqueTypeKey<'_>,
decl: OpaqueTypeDecl<'_>,
origin: OpaqueTyOrigin,
span: Span,
) -> bool {
match decl.origin {
match origin {
// No need to check return position impl trait (RPIT)
// because for type and const parameters they are correct
// by construction: we convert
Expand All @@ -177,7 +196,6 @@ fn check_opaque_type_parameter_valid(
// Check these
OpaqueTyOrigin::TyAlias => {}
}
let span = decl.definition_span;
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
for (i, arg) in opaque_type_key.substs.iter().enumerate() {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_borrowck/src/type_check/input_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// Return types are a bit more complex. They may contain opaque `impl Trait` types.
let mir_output_ty = body.local_decls[RETURN_PLACE].ty;
let output_span = body.local_decls[RETURN_PLACE].source_info.span;
if let Err(terr) = self.eq_opaque_type_and_type(
mir_output_ty,
if let Err(terr) = self.eq_types(
normalized_output_ty,
mir_output_ty,
Locations::All(output_span),
ConstraintCategory::BoringNoLocation,
) {
Expand All @@ -169,9 +169,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let user_provided_output_ty = user_provided_sig.output();
let user_provided_output_ty =
self.normalize(user_provided_output_ty, Locations::All(output_span));
if let Err(err) = self.eq_opaque_type_and_type(
mir_output_ty,
if let Err(err) = self.eq_types(
user_provided_output_ty,
mir_output_ty,
Locations::All(output_span),
ConstraintCategory::BoringNoLocation,
) {
Expand Down
Loading