Compute generator saved locals on MIR.
This commit is contained in:
parent
400cb9aa41
commit
60e04d1e8c
18 changed files with 392 additions and 19 deletions
|
@ -14,7 +14,7 @@ use rustc_hir::{ItemKind, Node, PathSegment};
|
|||
use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor;
|
||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::{DefiningAnchor, RegionVariableOrigin, TyCtxtInferExt};
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
|
||||
use rustc_lint::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::middle::stability::EvalResult;
|
||||
|
@ -28,7 +28,7 @@ use rustc_span::{self, Span};
|
|||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt, TraitEngine, TraitEngineExt as _};
|
||||
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
|
@ -1460,7 +1460,8 @@ fn opaque_type_cycle_error(
|
|||
for def_id in visitor.opaques {
|
||||
let ty_span = tcx.def_span(def_id);
|
||||
if !seen.contains(&ty_span) {
|
||||
err.span_label(ty_span, &format!("returning this opaque type `{ty}`"));
|
||||
let descr = if ty.is_impl_trait() { "opaque " } else { "" };
|
||||
err.span_label(ty_span, &format!("returning this {descr}type `{ty}`"));
|
||||
seen.insert(ty_span);
|
||||
}
|
||||
err.span_label(sp, &format!("returning here with type `{ty}`"));
|
||||
|
@ -1507,3 +1508,34 @@ fn opaque_type_cycle_error(
|
|||
}
|
||||
err.emit()
|
||||
}
|
||||
|
||||
pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
debug_assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
|
||||
debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Generator));
|
||||
|
||||
let typeck = tcx.typeck(def_id);
|
||||
let param_env = tcx.param_env(def_id);
|
||||
|
||||
let generator_interior_predicates = &typeck.generator_interior_predicates[&def_id];
|
||||
debug!(?generator_interior_predicates);
|
||||
|
||||
let infcx = tcx
|
||||
.infer_ctxt()
|
||||
// typeck writeback gives us predicates with their regions erased.
|
||||
// As borrowck already has checked lifetimes, we do not need to do it again.
|
||||
.ignoring_regions()
|
||||
// Bind opaque types to `def_id` as they should have been checked by borrowck.
|
||||
.with_opaque_type_inference(DefiningAnchor::Bind(def_id))
|
||||
.build();
|
||||
|
||||
let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
|
||||
for (predicate, cause) in generator_interior_predicates {
|
||||
let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate);
|
||||
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
|
||||
}
|
||||
let errors = fulfillment_cx.select_all_or_error(&infcx);
|
||||
debug!(?errors);
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(&errors, None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,6 +105,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
region_scope_tree,
|
||||
collect_return_position_impl_trait_in_trait_tys,
|
||||
compare_impl_const: compare_impl_item::compare_impl_const_raw,
|
||||
check_generator_obligations: check::check_generator_obligations,
|
||||
..*providers
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue