mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-02 19:53:46 +00:00
Use ObligationCtxt in main fn return type check
This commit is contained in:
parent
6f18f0a9d4
commit
da59fa74f0
@ -112,7 +112,6 @@ use rustc_middle::util;
|
|||||||
use rustc_session::config::EntryFnType;
|
use rustc_session::config::EntryFnType;
|
||||||
use rustc_span::{symbol::sym, Span, DUMMY_SP};
|
use rustc_span::{symbol::sym, Span, DUMMY_SP};
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use rustc_trait_selection::infer::InferCtxtExt;
|
|
||||||
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
|
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{
|
||||||
self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt as _,
|
self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt as _,
|
||||||
@ -303,7 +302,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let expected_return_type;
|
let expected_return_type;
|
||||||
if let Some(term_id) = tcx.lang_items().termination() {
|
if let Some(term_did) = tcx.lang_items().termination() {
|
||||||
let return_ty = main_fnsig.output();
|
let return_ty = main_fnsig.output();
|
||||||
let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
|
let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
|
||||||
if !return_ty.bound_vars().is_empty() {
|
if !return_ty.bound_vars().is_empty() {
|
||||||
@ -314,33 +313,17 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
|||||||
}
|
}
|
||||||
let return_ty = return_ty.skip_binder();
|
let return_ty = return_ty.skip_binder();
|
||||||
tcx.infer_ctxt().enter(|infcx| {
|
tcx.infer_ctxt().enter(|infcx| {
|
||||||
|
// Main should have no WC, so empty param env is OK here.
|
||||||
|
let param_env = ty::ParamEnv::empty();
|
||||||
let cause = traits::ObligationCause::new(
|
let cause = traits::ObligationCause::new(
|
||||||
return_ty_span,
|
return_ty_span,
|
||||||
main_diagnostics_hir_id,
|
main_diagnostics_hir_id,
|
||||||
ObligationCauseCode::MainFunctionType,
|
ObligationCauseCode::MainFunctionType,
|
||||||
);
|
);
|
||||||
let mut fulfillment_cx = traits::FulfillmentContext::new();
|
let ocx = traits::ObligationCtxt::new(&infcx);
|
||||||
// normalize any potential projections in the return type, then add
|
let norm_return_ty = ocx.normalize(cause.clone(), param_env, return_ty);
|
||||||
// any possible obligations to the fulfillment context.
|
ocx.register_bound(cause, param_env, norm_return_ty, term_did);
|
||||||
// HACK(ThePuzzlemaker) this feels symptomatic of a problem within
|
let errors = ocx.select_all_or_error();
|
||||||
// checking trait fulfillment, not this here. I'm not sure why it
|
|
||||||
// works in the example in `fn test()` given in #88609? This also
|
|
||||||
// probably isn't the best way to do this.
|
|
||||||
let InferOk { value: norm_return_ty, obligations } = infcx
|
|
||||||
.partially_normalize_associated_types_in(
|
|
||||||
cause.clone(),
|
|
||||||
ty::ParamEnv::empty(),
|
|
||||||
return_ty,
|
|
||||||
);
|
|
||||||
fulfillment_cx.register_predicate_obligations(&infcx, obligations);
|
|
||||||
fulfillment_cx.register_bound(
|
|
||||||
&infcx,
|
|
||||||
ty::ParamEnv::empty(),
|
|
||||||
norm_return_ty,
|
|
||||||
term_id,
|
|
||||||
cause,
|
|
||||||
);
|
|
||||||
let errors = fulfillment_cx.select_all_or_error(&infcx);
|
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
infcx.report_fulfillment_errors(&errors, None, false);
|
infcx.report_fulfillment_errors(&errors, None, false);
|
||||||
error = true;
|
error = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user