diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2021-10-05 12:52:41 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-05 12:52:41 -0700 |
| commit | 960e49e89b3c09baf9197dc9c87f3ca7755a486c (patch) | |
| tree | 7ce87a645176134704f0e0d989ea3e5b021357c5 | |
| parent | 25ec8273855fde2d72ae877b397e054de5300e10 (diff) | |
| parent | 33a28254f21c792cb0bda5427e66efa91b87dd4d (diff) | |
| download | rust-960e49e89b3c09baf9197dc9c87f3ca7755a486c.tar.gz rust-960e49e89b3c09baf9197dc9c87f3ca7755a486c.zip | |
Rollup merge of #88706 - ThePuzzlemaker:issue-88609, r=jackh726
Normalize associated type projections when checking return type of main This fixes #88609. Previously, the return type of `fn main()` would not have any associated type projections within normalized before checking if it implements the standard library trait `std::process::Termination`. This commit appears to fix it. This feels vaguely symptomatic of a problem in the underlying trait solving engine, but I am not sure how I would solve that. I am unsure why the example in #88609 with `assert_impl_termination` and `fn foo()` work, but simply `fn main()` doesn't. The way that I solved this is also probably not the best way to do this, so please let me know if there is a better way to do this. I have added a build-pass regression test for this issue.
| -rw-r--r-- | compiler/rustc_typeck/src/lib.rs | 22 | ||||
| -rw-r--r-- | src/test/ui/typeck/issue-88609.rs | 19 |
2 files changed, 40 insertions, 1 deletions
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index 8ff074e2fe5..65eedd2daaf 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -107,6 +107,7 @@ 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 _, @@ -328,7 +329,26 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { ObligationCauseCode::MainFunctionType, ); let mut fulfillment_cx = traits::FulfillmentContext::new(); - fulfillment_cx.register_bound(&infcx, ty::ParamEnv::empty(), return_ty, term_id, cause); + // 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, + ); if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) { infcx.report_fulfillment_errors(&err, None, false); error = true; diff --git a/src/test/ui/typeck/issue-88609.rs b/src/test/ui/typeck/issue-88609.rs new file mode 100644 index 00000000000..dc459c885fa --- /dev/null +++ b/src/test/ui/typeck/issue-88609.rs @@ -0,0 +1,19 @@ +// Regression test for #88609: +// The return type for `main` is not normalized while checking if it implements +// the trait `std::process::Termination`. + +// build-pass + +trait Same { + type Output; +} + +impl<T> Same for T { + type Output = T; +} + +type Unit = <() as Same>::Output; + +fn main() -> Result<Unit, std::io::Error> { + unimplemented!() +} |
