about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-07-26 03:18:45 +0000
committerMichael Goulet <michael@errs.io>2022-08-04 13:42:12 +0000
commitda59fa74f0eaf790f74a893d000c81d87d97ba6e (patch)
tree5df7a663adb1dcd10ee3faca335c26ce2fd74f25
parent6f18f0a9d4548bc87afff1e4c0fe9081c35002c2 (diff)
Use ObligationCtxt in main fn return type check
-rw-r--r--compiler/rustc_typeck/src/lib.rs31
1 files changed, 7 insertions, 24 deletions
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 706b9ee40aa..04c54589d68 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -112,7 +112,6 @@ use rustc_middle::util;
 use rustc_session::config::EntryFnType;
 use rustc_span::{symbol::sym, Span, DUMMY_SP};
 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::{
     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;
-    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_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span);
         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();
         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(
                 return_ty_span,
                 main_diagnostics_hir_id,
                 ObligationCauseCode::MainFunctionType,
             );
-            let mut fulfillment_cx = traits::FulfillmentContext::new();
-            // normalize any potential projections in the return type, then add
-            // any possible obligations to the fulfillment context.
-            // HACK(ThePuzzlemaker) this feels symptomatic of a problem within
-            // 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);
+            let ocx = traits::ObligationCtxt::new(&infcx);
+            let norm_return_ty = ocx.normalize(cause.clone(), param_env, return_ty);
+            ocx.register_bound(cause, param_env, norm_return_ty, term_did);
+            let errors = ocx.select_all_or_error();
             if !errors.is_empty() {
                 infcx.report_fulfillment_errors(&errors, None, false);
                 error = true;