diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index da9bdc8b4b0..f9db62e0a3a 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -221,9 +221,17 @@ fn do_mir_borrowck<'a, 'tcx>( // write unit-tests, as well as helping with debugging. nll::dump_mir_results(infcx, MirSource::item(def_id), &body, ®ioncx, &opt_closure_req); - // We also have a `#[rustc_nll]` annotation that causes us to dump + // We also have a `#[rustc_regions]` annotation that causes us to dump // information. - nll::dump_annotation(infcx, &body, def_id, ®ioncx, &opt_closure_req, &mut errors_buffer); + nll::dump_annotation( + infcx, + &body, + def_id, + ®ioncx, + &opt_closure_req, + &opaque_type_values, + &mut errors_buffer, + ); // The various `flow_*` structures can be large. We drop `flow_inits` here // so it doesn't overlap with the others below. This reduces peak memory diff --git a/src/librustc_mir/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs index 4c1ee9582c1..101d1856c38 100644 --- a/src/librustc_mir/borrow_check/nll.rs +++ b/src/librustc_mir/borrow_check/nll.rs @@ -355,6 +355,7 @@ pub(super) fn dump_annotation<'a, 'tcx>( mir_def_id: DefId, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option>, + opaque_type_values: &FxHashMap>, errors_buffer: &mut Vec, ) { let tcx = infcx.tcx; @@ -370,7 +371,7 @@ pub(super) fn dump_annotation<'a, 'tcx>( // viewing the intraprocedural state, the -Zdump-mir output is // better. - if let Some(closure_region_requirements) = closure_region_requirements { + let mut err = if let Some(closure_region_requirements) = closure_region_requirements { let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "external requirements"); regioncx.annotate(tcx, &mut err); @@ -388,13 +389,19 @@ pub(super) fn dump_annotation<'a, 'tcx>( }) .unwrap(); - err.buffer(errors_buffer); + err } else { let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "no external requirements"); regioncx.annotate(tcx, &mut err); - err.buffer(errors_buffer); + err + }; + + if !opaque_type_values.is_empty() { + err.note(&format!("Inferred opaque type values:\n{:#?}", opaque_type_values)); } + + err.buffer(errors_buffer); } fn for_each_region_constraint( diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index b2e8cf9df7c..6c073b3d2c8 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -1226,6 +1226,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { revealed_ty={:?}", output_ty, opaque_type_map, revealed_ty ); + // Make sure that the inferred types are well-formed. I'm + // not entirely sure this is needed (the HIR type check + // didn't do this) but it seems sensible to prevent opaque + // types hiding ill-formed types. + obligations.obligations.push(traits::Obligation::new( + ObligationCause::dummy(), + param_env, + ty::Predicate::WellFormed(revealed_ty), + )); obligations.add( infcx .at(&ObligationCause::dummy(), param_env)