1 //! This module contains code to equate the input/output types appearing 2 //! in the MIR with the expected input/output types from the function 3 //! signature. This requires a bit of processing, as the expected types 4 //! are supplied to us before normalization and may contain opaque 5 //! `impl Trait` instances. In contrast, the input/output types found in 6 //! the MIR (specifically, in the special local variables for the 7 //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and 8 //! contain revealed `impl Trait` values). 9 10 use rustc_infer::infer::LateBoundRegionConversionTime; 11 use rustc_middle::mir::*; 12 use rustc_middle::ty::{self, Ty}; 13 use rustc_span::Span; 14 15 use crate::universal_regions::UniversalRegions; 16 17 use super::{Locations, TypeChecker}; 18 19 impl<'a, 'tcx> TypeChecker<'a, 'tcx> { 20 /// Check explicit closure signature annotation, 21 /// e.g., `|x: FxIndexMap<_, &'static u32>| ...`. 22 #[instrument(skip(self, body), level = "debug")] check_signature_annotation(&mut self, body: &Body<'tcx>)23 pub(super) fn check_signature_annotation(&mut self, body: &Body<'tcx>) { 24 let mir_def_id = body.source.def_id().expect_local(); 25 if !self.tcx().is_closure(mir_def_id.to_def_id()) { 26 return; 27 } 28 let user_provided_poly_sig = self.tcx().closure_user_provided_sig(mir_def_id); 29 30 // Instantiate the canonicalized variables from user-provided signature 31 // (e.g., the `_` in the code above) with fresh variables. 32 // Then replace the bound items in the fn sig with fresh variables, 33 // so that they represent the view from "inside" the closure. 34 let user_provided_sig = self 35 .instantiate_canonical_with_fresh_inference_vars(body.span, &user_provided_poly_sig); 36 let user_provided_sig = self.infcx.instantiate_binder_with_fresh_vars( 37 body.span, 38 LateBoundRegionConversionTime::FnCall, 39 user_provided_sig, 40 ); 41 42 for (&user_ty, arg_decl) in user_provided_sig.inputs().iter().zip( 43 // In MIR, closure args begin with an implicit `self`. Skip it! 44 body.args_iter().skip(1).map(|local| &body.local_decls[local]), 45 ) { 46 self.ascribe_user_type_skip_wf( 47 arg_decl.ty, 48 ty::UserType::Ty(user_ty), 49 arg_decl.source_info.span, 50 ); 51 } 52 53 // If the user explicitly annotated the output type, enforce it. 54 let output_decl = &body.local_decls[RETURN_PLACE]; 55 self.ascribe_user_type_skip_wf( 56 output_decl.ty, 57 ty::UserType::Ty(user_provided_sig.output()), 58 output_decl.source_info.span, 59 ); 60 } 61 62 #[instrument(skip(self, body, universal_regions), level = "debug")] equate_inputs_and_outputs( &mut self, body: &Body<'tcx>, universal_regions: &UniversalRegions<'tcx>, normalized_inputs_and_output: &[Ty<'tcx>], )63 pub(super) fn equate_inputs_and_outputs( 64 &mut self, 65 body: &Body<'tcx>, 66 universal_regions: &UniversalRegions<'tcx>, 67 normalized_inputs_and_output: &[Ty<'tcx>], 68 ) { 69 let (&normalized_output_ty, normalized_input_tys) = 70 normalized_inputs_and_output.split_last().unwrap(); 71 72 debug!(?normalized_output_ty); 73 debug!(?normalized_input_tys); 74 75 // Equate expected input tys with those in the MIR. 76 for (argument_index, &normalized_input_ty) in normalized_input_tys.iter().enumerate() { 77 if argument_index + 1 >= body.local_decls.len() { 78 self.tcx() 79 .sess 80 .delay_span_bug(body.span, "found more normalized_input_ty than local_decls"); 81 break; 82 } 83 84 // In MIR, argument N is stored in local N+1. 85 let local = Local::from_usize(argument_index + 1); 86 87 let mir_input_ty = body.local_decls[local].ty; 88 89 let mir_input_span = body.local_decls[local].source_info.span; 90 self.equate_normalized_input_or_output( 91 normalized_input_ty, 92 mir_input_ty, 93 mir_input_span, 94 ); 95 } 96 97 debug!( 98 "equate_inputs_and_outputs: body.yield_ty {:?}, universal_regions.yield_ty {:?}", 99 body.yield_ty(), 100 universal_regions.yield_ty 101 ); 102 103 // We will not have a universal_regions.yield_ty if we yield (by accident) 104 // outside of a generator and return an `impl Trait`, so emit a delay_span_bug 105 // because we don't want to panic in an assert here if we've already got errors. 106 if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() { 107 self.tcx().sess.delay_span_bug( 108 body.span, 109 format!( 110 "Expected body to have yield_ty ({:?}) iff we have a UR yield_ty ({:?})", 111 body.yield_ty(), 112 universal_regions.yield_ty, 113 ), 114 ); 115 } 116 117 if let (Some(mir_yield_ty), Some(ur_yield_ty)) = 118 (body.yield_ty(), universal_regions.yield_ty) 119 { 120 let yield_span = body.local_decls[RETURN_PLACE].source_info.span; 121 self.equate_normalized_input_or_output(ur_yield_ty, mir_yield_ty, yield_span); 122 } 123 124 // Return types are a bit more complex. They may contain opaque `impl Trait` types. 125 let mir_output_ty = body.local_decls[RETURN_PLACE].ty; 126 let output_span = body.local_decls[RETURN_PLACE].source_info.span; 127 self.equate_normalized_input_or_output(normalized_output_ty, mir_output_ty, output_span); 128 } 129 130 #[instrument(skip(self), level = "debug")] equate_normalized_input_or_output(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, span: Span)131 fn equate_normalized_input_or_output(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, span: Span) { 132 if let Err(_) = 133 self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation) 134 { 135 // FIXME(jackh726): This is a hack. It's somewhat like 136 // `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd 137 // like to normalize *before* inserting into `local_decls`, but 138 // doing so ends up causing some other trouble. 139 let b = self.normalize(b, Locations::All(span)); 140 141 // Note: if we have to introduce new placeholders during normalization above, then we won't have 142 // added those universes to the universe info, which we would want in `relate_tys`. 143 if let Err(terr) = 144 self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation) 145 { 146 span_mirbug!( 147 self, 148 Location::START, 149 "equate_normalized_input_or_output: `{:?}=={:?}` failed with `{:?}`", 150 a, 151 b, 152 terr 153 ); 154 } 155 } 156 } 157 } 158