1 //! Code for type-checking closure expressions. 2 3 use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}; 4 5 use rustc_errors::ErrorGuaranteed; 6 use rustc_hir as hir; 7 use rustc_hir::lang_items::LangItem; 8 use rustc_hir_analysis::astconv::AstConv; 9 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; 10 use rustc_infer::infer::{DefineOpaqueTypes, LateBoundRegionConversionTime}; 11 use rustc_infer::infer::{InferOk, InferResult}; 12 use rustc_macros::{TypeFoldable, TypeVisitable}; 13 use rustc_middle::ty::subst::InternalSubsts; 14 use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; 15 use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; 16 use rustc_span::def_id::LocalDefId; 17 use rustc_span::source_map::Span; 18 use rustc_span::sym; 19 use rustc_target::spec::abi::Abi; 20 use rustc_trait_selection::traits; 21 use rustc_trait_selection::traits::error_reporting::ArgKind; 22 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; 23 use std::cmp; 24 use std::iter; 25 use std::ops::ControlFlow; 26 27 /// What signature do we *expect* the closure to have from context? 28 #[derive(Debug, Clone, TypeFoldable, TypeVisitable)] 29 struct ExpectedSig<'tcx> { 30 /// Span that gave us this expectation, if we know that. 31 cause_span: Option<Span>, 32 sig: ty::PolyFnSig<'tcx>, 33 } 34 35 struct ClosureSignatures<'tcx> { 36 /// The signature users of the closure see. 37 bound_sig: ty::PolyFnSig<'tcx>, 38 /// The signature within the function body. 39 /// This mostly differs in the sense that lifetimes are now early bound and any 40 /// opaque types from the signature expectation are overridden in case there are 41 /// explicit hidden types written by the user in the closure signature. 42 liberated_sig: ty::FnSig<'tcx>, 43 } 44 45 impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 46 #[instrument(skip(self, closure), level = "debug")] check_expr_closure( &self, closure: &hir::Closure<'tcx>, expr_span: Span, expected: Expectation<'tcx>, ) -> Ty<'tcx>47 pub fn check_expr_closure( 48 &self, 49 closure: &hir::Closure<'tcx>, 50 expr_span: Span, 51 expected: Expectation<'tcx>, 52 ) -> Ty<'tcx> { 53 trace!("decl = {:#?}", closure.fn_decl); 54 55 // It's always helpful for inference if we know the kind of 56 // closure sooner rather than later, so first examine the expected 57 // type, and see if can glean a closure kind from there. 58 let (expected_sig, expected_kind) = match expected.to_option(self) { 59 Some(ty) => self.deduce_closure_signature(ty), 60 None => (None, None), 61 }; 62 let body = self.tcx.hir().body(closure.body); 63 self.check_closure(closure, expr_span, expected_kind, body, expected_sig) 64 } 65 66 #[instrument(skip(self, closure, body), level = "debug", ret)] check_closure( &self, closure: &hir::Closure<'tcx>, expr_span: Span, opt_kind: Option<ty::ClosureKind>, body: &'tcx hir::Body<'tcx>, expected_sig: Option<ExpectedSig<'tcx>>, ) -> Ty<'tcx>67 fn check_closure( 68 &self, 69 closure: &hir::Closure<'tcx>, 70 expr_span: Span, 71 opt_kind: Option<ty::ClosureKind>, 72 body: &'tcx hir::Body<'tcx>, 73 expected_sig: Option<ExpectedSig<'tcx>>, 74 ) -> Ty<'tcx> { 75 trace!("decl = {:#?}", closure.fn_decl); 76 let expr_def_id = closure.def_id; 77 debug!(?expr_def_id); 78 79 let ClosureSignatures { bound_sig, liberated_sig } = 80 self.sig_of_closure(expr_def_id, closure.fn_decl, body, expected_sig); 81 82 debug!(?bound_sig, ?liberated_sig); 83 84 let mut fcx = FnCtxt::new(self, self.param_env.without_const(), closure.def_id); 85 let generator_types = check_fn( 86 &mut fcx, 87 liberated_sig, 88 closure.fn_decl, 89 expr_def_id, 90 body, 91 closure.movability, 92 // Closure "rust-call" ABI doesn't support unsized params 93 false, 94 ); 95 96 let parent_substs = InternalSubsts::identity_for_item( 97 self.tcx, 98 self.tcx.typeck_root_def_id(expr_def_id.to_def_id()), 99 ); 100 101 let tupled_upvars_ty = self.next_root_ty_var(TypeVariableOrigin { 102 kind: TypeVariableOriginKind::ClosureSynthetic, 103 span: self.tcx.def_span(expr_def_id), 104 }); 105 106 if let Some(GeneratorTypes { resume_ty, yield_ty, interior, movability }) = generator_types 107 { 108 let generator_substs = ty::GeneratorSubsts::new( 109 self.tcx, 110 ty::GeneratorSubstsParts { 111 parent_substs, 112 resume_ty, 113 yield_ty, 114 return_ty: liberated_sig.output(), 115 witness: interior, 116 tupled_upvars_ty, 117 }, 118 ); 119 120 return Ty::new_generator( 121 self.tcx, 122 expr_def_id.to_def_id(), 123 generator_substs.substs, 124 movability, 125 ); 126 } 127 128 // Tuple up the arguments and insert the resulting function type into 129 // the `closures` table. 130 let sig = bound_sig.map_bound(|sig| { 131 self.tcx.mk_fn_sig( 132 [Ty::new_tup(self.tcx, sig.inputs())], 133 sig.output(), 134 sig.c_variadic, 135 sig.unsafety, 136 sig.abi, 137 ) 138 }); 139 140 debug!(?sig, ?opt_kind); 141 142 let closure_kind_ty = match opt_kind { 143 Some(kind) => kind.to_ty(self.tcx), 144 145 // Create a type variable (for now) to represent the closure kind. 146 // It will be unified during the upvar inference phase (`upvar.rs`) 147 None => self.next_root_ty_var(TypeVariableOrigin { 148 // FIXME(eddyb) distinguish closure kind inference variables from the rest. 149 kind: TypeVariableOriginKind::ClosureSynthetic, 150 span: expr_span, 151 }), 152 }; 153 154 let closure_substs = ty::ClosureSubsts::new( 155 self.tcx, 156 ty::ClosureSubstsParts { 157 parent_substs, 158 closure_kind_ty, 159 closure_sig_as_fn_ptr_ty: Ty::new_fn_ptr(self.tcx, sig), 160 tupled_upvars_ty, 161 }, 162 ); 163 164 Ty::new_closure(self.tcx, expr_def_id.to_def_id(), closure_substs.substs) 165 } 166 167 /// Given the expected type, figures out what it can about this closure we 168 /// are about to type check: 169 #[instrument(skip(self), level = "debug")] deduce_closure_signature( &self, expected_ty: Ty<'tcx>, ) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>)170 fn deduce_closure_signature( 171 &self, 172 expected_ty: Ty<'tcx>, 173 ) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) { 174 match *expected_ty.kind() { 175 ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => self 176 .deduce_closure_signature_from_predicates( 177 expected_ty, 178 self.tcx 179 .explicit_item_bounds(def_id) 180 .subst_iter_copied(self.tcx, substs) 181 .map(|(c, s)| (c.as_predicate(), s)), 182 ), 183 ty::Dynamic(ref object_type, ..) => { 184 let sig = object_type.projection_bounds().find_map(|pb| { 185 let pb = pb.with_self_ty(self.tcx, self.tcx.types.trait_object_dummy_self); 186 self.deduce_sig_from_projection(None, pb) 187 }); 188 let kind = object_type 189 .principal_def_id() 190 .and_then(|did| self.tcx.fn_trait_kind_from_def_id(did)); 191 (sig, kind) 192 } 193 ty::Infer(ty::TyVar(vid)) => self.deduce_closure_signature_from_predicates( 194 Ty::new_var(self.tcx, self.root_var(vid)), 195 self.obligations_for_self_ty(vid).map(|obl| (obl.predicate, obl.cause.span)), 196 ), 197 ty::FnPtr(sig) => { 198 let expected_sig = ExpectedSig { cause_span: None, sig }; 199 (Some(expected_sig), Some(ty::ClosureKind::Fn)) 200 } 201 _ => (None, None), 202 } 203 } 204 deduce_closure_signature_from_predicates( &self, expected_ty: Ty<'tcx>, predicates: impl DoubleEndedIterator<Item = (ty::Predicate<'tcx>, Span)>, ) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>)205 fn deduce_closure_signature_from_predicates( 206 &self, 207 expected_ty: Ty<'tcx>, 208 predicates: impl DoubleEndedIterator<Item = (ty::Predicate<'tcx>, Span)>, 209 ) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) { 210 let mut expected_sig = None; 211 let mut expected_kind = None; 212 213 for (pred, span) in traits::elaborate( 214 self.tcx, 215 // Reverse the obligations here, since `elaborate_*` uses a stack, 216 // and we want to keep inference generally in the same order of 217 // the registered obligations. 218 predicates.rev(), 219 ) 220 // We only care about self bounds 221 .filter_only_self() 222 { 223 debug!(?pred); 224 let bound_predicate = pred.kind(); 225 226 // Given a Projection predicate, we can potentially infer 227 // the complete signature. 228 if expected_sig.is_none() 229 && let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj_predicate)) = bound_predicate.skip_binder() 230 { 231 let inferred_sig = self.normalize( 232 span, 233 self.deduce_sig_from_projection( 234 Some(span), 235 bound_predicate.rebind(proj_predicate), 236 ), 237 ); 238 // Make sure that we didn't infer a signature that mentions itself. 239 // This can happen when we elaborate certain supertrait bounds that 240 // mention projections containing the `Self` type. See #105401. 241 struct MentionsTy<'tcx> { 242 expected_ty: Ty<'tcx>, 243 } 244 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MentionsTy<'tcx> { 245 type BreakTy = (); 246 247 fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { 248 if t == self.expected_ty { 249 ControlFlow::Break(()) 250 } else { 251 t.super_visit_with(self) 252 } 253 } 254 } 255 if inferred_sig.visit_with(&mut MentionsTy { expected_ty }).is_continue() { 256 expected_sig = inferred_sig; 257 } 258 } 259 260 // Even if we can't infer the full signature, we may be able to 261 // infer the kind. This can occur when we elaborate a predicate 262 // like `F : Fn<A>`. Note that due to subtyping we could encounter 263 // many viable options, so pick the most restrictive. 264 let trait_def_id = match bound_predicate.skip_binder() { 265 ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { 266 Some(data.projection_ty.trait_def_id(self.tcx)) 267 } 268 ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => Some(data.def_id()), 269 _ => None, 270 }; 271 if let Some(closure_kind) = 272 trait_def_id.and_then(|def_id| self.tcx.fn_trait_kind_from_def_id(def_id)) 273 { 274 expected_kind = Some( 275 expected_kind 276 .map_or_else(|| closure_kind, |current| cmp::min(current, closure_kind)), 277 ); 278 } 279 } 280 281 (expected_sig, expected_kind) 282 } 283 284 /// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce 285 /// everything we need to know about a closure or generator. 286 /// 287 /// The `cause_span` should be the span that caused us to 288 /// have this expected signature, or `None` if we can't readily 289 /// know that. 290 #[instrument(level = "debug", skip(self, cause_span), ret)] deduce_sig_from_projection( &self, cause_span: Option<Span>, projection: ty::PolyProjectionPredicate<'tcx>, ) -> Option<ExpectedSig<'tcx>>291 fn deduce_sig_from_projection( 292 &self, 293 cause_span: Option<Span>, 294 projection: ty::PolyProjectionPredicate<'tcx>, 295 ) -> Option<ExpectedSig<'tcx>> { 296 let tcx = self.tcx; 297 298 let trait_def_id = projection.trait_def_id(tcx); 299 300 let is_fn = tcx.is_fn_trait(trait_def_id); 301 302 let gen_trait = tcx.lang_items().gen_trait(); 303 let is_gen = gen_trait == Some(trait_def_id); 304 305 if !is_fn && !is_gen { 306 debug!("not fn or generator"); 307 return None; 308 } 309 310 // Check that we deduce the signature from the `<_ as std::ops::Generator>::Return` 311 // associated item and not yield. 312 if is_gen && self.tcx.associated_item(projection.projection_def_id()).name != sym::Return { 313 debug!("not `Return` assoc item of `Generator`"); 314 return None; 315 } 316 317 let input_tys = if is_fn { 318 let arg_param_ty = projection.skip_binder().projection_ty.substs.type_at(1); 319 let arg_param_ty = self.resolve_vars_if_possible(arg_param_ty); 320 debug!(?arg_param_ty); 321 322 match arg_param_ty.kind() { 323 &ty::Tuple(tys) => tys, 324 _ => return None, 325 } 326 } else { 327 // Generators with a `()` resume type may be defined with 0 or 1 explicit arguments, 328 // else they must have exactly 1 argument. For now though, just give up in this case. 329 return None; 330 }; 331 332 // Since this is a return parameter type it is safe to unwrap. 333 let ret_param_ty = projection.skip_binder().term.ty().unwrap(); 334 let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty); 335 debug!(?ret_param_ty); 336 337 let sig = projection.rebind(self.tcx.mk_fn_sig( 338 input_tys, 339 ret_param_ty, 340 false, 341 hir::Unsafety::Normal, 342 Abi::Rust, 343 )); 344 345 Some(ExpectedSig { cause_span, sig }) 346 } 347 sig_of_closure( &self, expr_def_id: LocalDefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, expected_sig: Option<ExpectedSig<'tcx>>, ) -> ClosureSignatures<'tcx>348 fn sig_of_closure( 349 &self, 350 expr_def_id: LocalDefId, 351 decl: &hir::FnDecl<'_>, 352 body: &hir::Body<'_>, 353 expected_sig: Option<ExpectedSig<'tcx>>, 354 ) -> ClosureSignatures<'tcx> { 355 if let Some(e) = expected_sig { 356 self.sig_of_closure_with_expectation(expr_def_id, decl, body, e) 357 } else { 358 self.sig_of_closure_no_expectation(expr_def_id, decl, body) 359 } 360 } 361 362 /// If there is no expected signature, then we will convert the 363 /// types that the user gave into a signature. 364 #[instrument(skip(self, expr_def_id, decl, body), level = "debug")] sig_of_closure_no_expectation( &self, expr_def_id: LocalDefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, ) -> ClosureSignatures<'tcx>365 fn sig_of_closure_no_expectation( 366 &self, 367 expr_def_id: LocalDefId, 368 decl: &hir::FnDecl<'_>, 369 body: &hir::Body<'_>, 370 ) -> ClosureSignatures<'tcx> { 371 let bound_sig = self.supplied_sig_of_closure(expr_def_id, decl, body); 372 373 self.closure_sigs(expr_def_id, body, bound_sig) 374 } 375 376 /// Invoked to compute the signature of a closure expression. This 377 /// combines any user-provided type annotations (e.g., `|x: u32| 378 /// -> u32 { .. }`) with the expected signature. 379 /// 380 /// The approach is as follows: 381 /// 382 /// - Let `S` be the (higher-ranked) signature that we derive from the user's annotations. 383 /// - Let `E` be the (higher-ranked) signature that we derive from the expectations, if any. 384 /// - If we have no expectation `E`, then the signature of the closure is `S`. 385 /// - Otherwise, the signature of the closure is E. Moreover: 386 /// - Skolemize the late-bound regions in `E`, yielding `E'`. 387 /// - Instantiate all the late-bound regions bound in the closure within `S` 388 /// with fresh (existential) variables, yielding `S'` 389 /// - Require that `E' = S'` 390 /// - We could use some kind of subtyping relationship here, 391 /// I imagine, but equality is easier and works fine for 392 /// our purposes. 393 /// 394 /// The key intuition here is that the user's types must be valid 395 /// from "the inside" of the closure, but the expectation 396 /// ultimately drives the overall signature. 397 /// 398 /// # Examples 399 /// 400 /// ```ignore (illustrative) 401 /// fn with_closure<F>(_: F) 402 /// where F: Fn(&u32) -> &u32 { .. } 403 /// 404 /// with_closure(|x: &u32| { ... }) 405 /// ``` 406 /// 407 /// Here: 408 /// - E would be `fn(&u32) -> &u32`. 409 /// - S would be `fn(&u32) -> ?T` 410 /// - E' is `&'!0 u32 -> &'!0 u32` 411 /// - S' is `&'?0 u32 -> ?T` 412 /// 413 /// S' can be unified with E' with `['?0 = '!0, ?T = &'!10 u32]`. 414 /// 415 /// # Arguments 416 /// 417 /// - `expr_def_id`: the `LocalDefId` of the closure expression 418 /// - `decl`: the HIR declaration of the closure 419 /// - `body`: the body of the closure 420 /// - `expected_sig`: the expected signature (if any). Note that 421 /// this is missing a binder: that is, there may be late-bound 422 /// regions with depth 1, which are bound then by the closure. 423 #[instrument(skip(self, expr_def_id, decl, body), level = "debug")] sig_of_closure_with_expectation( &self, expr_def_id: LocalDefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, expected_sig: ExpectedSig<'tcx>, ) -> ClosureSignatures<'tcx>424 fn sig_of_closure_with_expectation( 425 &self, 426 expr_def_id: LocalDefId, 427 decl: &hir::FnDecl<'_>, 428 body: &hir::Body<'_>, 429 expected_sig: ExpectedSig<'tcx>, 430 ) -> ClosureSignatures<'tcx> { 431 // Watch out for some surprises and just ignore the 432 // expectation if things don't see to match up with what we 433 // expect. 434 if expected_sig.sig.c_variadic() != decl.c_variadic { 435 return self.sig_of_closure_no_expectation(expr_def_id, decl, body); 436 } else if expected_sig.sig.skip_binder().inputs_and_output.len() != decl.inputs.len() + 1 { 437 return self.sig_of_closure_with_mismatched_number_of_arguments( 438 expr_def_id, 439 decl, 440 body, 441 expected_sig, 442 ); 443 } 444 445 // Create a `PolyFnSig`. Note the oddity that late bound 446 // regions appearing free in `expected_sig` are now bound up 447 // in this binder we are creating. 448 assert!(!expected_sig.sig.skip_binder().has_vars_bound_above(ty::INNERMOST)); 449 let bound_sig = expected_sig.sig.map_bound(|sig| { 450 self.tcx.mk_fn_sig( 451 sig.inputs().iter().cloned(), 452 sig.output(), 453 sig.c_variadic, 454 hir::Unsafety::Normal, 455 Abi::RustCall, 456 ) 457 }); 458 459 // `deduce_expectations_from_expected_type` introduces 460 // late-bound lifetimes defined elsewhere, which we now 461 // anonymize away, so as not to confuse the user. 462 let bound_sig = self.tcx.anonymize_bound_vars(bound_sig); 463 464 let closure_sigs = self.closure_sigs(expr_def_id, body, bound_sig); 465 466 // Up till this point, we have ignored the annotations that the user 467 // gave. This function will check that they unify successfully. 468 // Along the way, it also writes out entries for types that the user 469 // wrote into our typeck results, which are then later used by the privacy 470 // check. 471 match self.merge_supplied_sig_with_expectation(expr_def_id, decl, body, closure_sigs) { 472 Ok(infer_ok) => self.register_infer_ok_obligations(infer_ok), 473 Err(_) => self.sig_of_closure_no_expectation(expr_def_id, decl, body), 474 } 475 } 476 sig_of_closure_with_mismatched_number_of_arguments( &self, expr_def_id: LocalDefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, expected_sig: ExpectedSig<'tcx>, ) -> ClosureSignatures<'tcx>477 fn sig_of_closure_with_mismatched_number_of_arguments( 478 &self, 479 expr_def_id: LocalDefId, 480 decl: &hir::FnDecl<'_>, 481 body: &hir::Body<'_>, 482 expected_sig: ExpectedSig<'tcx>, 483 ) -> ClosureSignatures<'tcx> { 484 let hir = self.tcx.hir(); 485 let expr_map_node = hir.get_by_def_id(expr_def_id); 486 let expected_args: Vec<_> = expected_sig 487 .sig 488 .skip_binder() 489 .inputs() 490 .iter() 491 .map(|ty| ArgKind::from_expected_ty(*ty, None)) 492 .collect(); 493 let (closure_span, closure_arg_span, found_args) = 494 match self.get_fn_like_arguments(expr_map_node) { 495 Some((sp, arg_sp, args)) => (Some(sp), arg_sp, args), 496 None => (None, None, Vec::new()), 497 }; 498 let expected_span = 499 expected_sig.cause_span.unwrap_or_else(|| self.tcx.def_span(expr_def_id)); 500 let guar = self 501 .report_arg_count_mismatch( 502 expected_span, 503 closure_span, 504 expected_args, 505 found_args, 506 true, 507 closure_arg_span, 508 ) 509 .emit(); 510 511 let error_sig = self.error_sig_of_closure(decl, guar); 512 513 self.closure_sigs(expr_def_id, body, error_sig) 514 } 515 516 /// Enforce the user's types against the expectation. See 517 /// `sig_of_closure_with_expectation` for details on the overall 518 /// strategy. 519 #[instrument(level = "debug", skip(self, expr_def_id, decl, body, expected_sigs))] merge_supplied_sig_with_expectation( &self, expr_def_id: LocalDefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, mut expected_sigs: ClosureSignatures<'tcx>, ) -> InferResult<'tcx, ClosureSignatures<'tcx>>520 fn merge_supplied_sig_with_expectation( 521 &self, 522 expr_def_id: LocalDefId, 523 decl: &hir::FnDecl<'_>, 524 body: &hir::Body<'_>, 525 mut expected_sigs: ClosureSignatures<'tcx>, 526 ) -> InferResult<'tcx, ClosureSignatures<'tcx>> { 527 // Get the signature S that the user gave. 528 // 529 // (See comment on `sig_of_closure_with_expectation` for the 530 // meaning of these letters.) 531 let supplied_sig = self.supplied_sig_of_closure(expr_def_id, decl, body); 532 533 debug!(?supplied_sig); 534 535 // FIXME(#45727): As discussed in [this comment][c1], naively 536 // forcing equality here actually results in suboptimal error 537 // messages in some cases. For now, if there would have been 538 // an obvious error, we fallback to declaring the type of the 539 // closure to be the one the user gave, which allows other 540 // error message code to trigger. 541 // 542 // However, I think [there is potential to do even better 543 // here][c2], since in *this* code we have the precise span of 544 // the type parameter in question in hand when we report the 545 // error. 546 // 547 // [c1]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341089706 548 // [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796 549 self.commit_if_ok(|_| { 550 let mut all_obligations = vec![]; 551 let inputs: Vec<_> = iter::zip( 552 decl.inputs, 553 supplied_sig.inputs().skip_binder(), // binder moved to (*) below 554 ) 555 .map(|(hir_ty, &supplied_ty)| { 556 // Instantiate (this part of..) S to S', i.e., with fresh variables. 557 self.instantiate_binder_with_fresh_vars( 558 hir_ty.span, 559 LateBoundRegionConversionTime::FnCall, 560 // (*) binder moved to here 561 supplied_sig.inputs().rebind(supplied_ty), 562 ) 563 }) 564 .collect(); 565 566 // The liberated version of this signature should be a subtype 567 // of the liberated form of the expectation. 568 for ((hir_ty, &supplied_ty), expected_ty) in iter::zip( 569 iter::zip(decl.inputs, &inputs), 570 expected_sigs.liberated_sig.inputs(), // `liberated_sig` is E'. 571 ) { 572 // Check that E' = S'. 573 let cause = self.misc(hir_ty.span); 574 let InferOk { value: (), obligations } = self.at(&cause, self.param_env).eq( 575 DefineOpaqueTypes::Yes, 576 *expected_ty, 577 supplied_ty, 578 )?; 579 all_obligations.extend(obligations); 580 } 581 582 let supplied_output_ty = self.instantiate_binder_with_fresh_vars( 583 decl.output.span(), 584 LateBoundRegionConversionTime::FnCall, 585 supplied_sig.output(), 586 ); 587 let cause = &self.misc(decl.output.span()); 588 let InferOk { value: (), obligations } = self.at(cause, self.param_env).eq( 589 DefineOpaqueTypes::Yes, 590 expected_sigs.liberated_sig.output(), 591 supplied_output_ty, 592 )?; 593 all_obligations.extend(obligations); 594 595 let inputs = inputs.into_iter().map(|ty| self.resolve_vars_if_possible(ty)); 596 597 expected_sigs.liberated_sig = self.tcx.mk_fn_sig( 598 inputs, 599 supplied_output_ty, 600 expected_sigs.liberated_sig.c_variadic, 601 hir::Unsafety::Normal, 602 Abi::RustCall, 603 ); 604 605 Ok(InferOk { value: expected_sigs, obligations: all_obligations }) 606 }) 607 } 608 609 /// If there is no expected signature, then we will convert the 610 /// types that the user gave into a signature. 611 /// 612 /// Also, record this closure signature for later. 613 #[instrument(skip(self, decl, body), level = "debug", ret)] supplied_sig_of_closure( &self, expr_def_id: LocalDefId, decl: &hir::FnDecl<'_>, body: &hir::Body<'_>, ) -> ty::PolyFnSig<'tcx>614 fn supplied_sig_of_closure( 615 &self, 616 expr_def_id: LocalDefId, 617 decl: &hir::FnDecl<'_>, 618 body: &hir::Body<'_>, 619 ) -> ty::PolyFnSig<'tcx> { 620 let astconv: &dyn AstConv<'_> = self; 621 622 trace!("decl = {:#?}", decl); 623 debug!(?body.generator_kind); 624 625 let hir_id = self.tcx.hir().local_def_id_to_hir_id(expr_def_id); 626 let bound_vars = self.tcx.late_bound_vars(hir_id); 627 628 // First, convert the types that the user supplied (if any). 629 let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a)); 630 let supplied_return = match decl.output { 631 hir::FnRetTy::Return(ref output) => astconv.ast_ty_to_ty(&output), 632 hir::FnRetTy::DefaultReturn(_) => match body.generator_kind { 633 // In the case of the async block that we create for a function body, 634 // we expect the return type of the block to match that of the enclosing 635 // function. 636 Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn)) => { 637 debug!("closure is async fn body"); 638 let def_id = self.tcx.hir().body_owner_def_id(body.id()); 639 self.deduce_future_output_from_obligations(expr_def_id, def_id).unwrap_or_else( 640 || { 641 // AFAIK, deducing the future output 642 // always succeeds *except* in error cases 643 // like #65159. I'd like to return Error 644 // here, but I can't because I can't 645 // easily (and locally) prove that we 646 // *have* reported an 647 // error. --nikomatsakis 648 astconv.ty_infer(None, decl.output.span()) 649 }, 650 ) 651 } 652 653 _ => astconv.ty_infer(None, decl.output.span()), 654 }, 655 }; 656 657 let result = ty::Binder::bind_with_vars( 658 self.tcx.mk_fn_sig( 659 supplied_arguments, 660 supplied_return, 661 decl.c_variadic, 662 hir::Unsafety::Normal, 663 Abi::RustCall, 664 ), 665 bound_vars, 666 ); 667 668 let c_result = self.inh.infcx.canonicalize_response(result); 669 self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result); 670 671 // Normalize only after registering in `user_provided_sigs`. 672 self.normalize(self.tcx.hir().span(hir_id), result) 673 } 674 675 /// Invoked when we are translating the generator that results 676 /// from desugaring an `async fn`. Returns the "sugared" return 677 /// type of the `async fn` -- that is, the return type that the 678 /// user specified. The "desugared" return type is an `impl 679 /// Future<Output = T>`, so we do this by searching through the 680 /// obligations to extract the `T`. 681 #[instrument(skip(self), level = "debug", ret)] deduce_future_output_from_obligations( &self, expr_def_id: LocalDefId, body_def_id: LocalDefId, ) -> Option<Ty<'tcx>>682 fn deduce_future_output_from_obligations( 683 &self, 684 expr_def_id: LocalDefId, 685 body_def_id: LocalDefId, 686 ) -> Option<Ty<'tcx>> { 687 let ret_coercion = self.ret_coercion.as_ref().unwrap_or_else(|| { 688 span_bug!(self.tcx.def_span(expr_def_id), "async fn generator outside of a fn") 689 }); 690 691 let ret_ty = ret_coercion.borrow().expected_ty(); 692 let ret_ty = self.inh.infcx.shallow_resolve(ret_ty); 693 694 let get_future_output = |predicate: ty::Predicate<'tcx>, span| { 695 // Search for a pending obligation like 696 // 697 // `<R as Future>::Output = T` 698 // 699 // where R is the return type we are expecting. This type `T` 700 // will be our output. 701 let bound_predicate = predicate.kind(); 702 if let ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj_predicate)) = 703 bound_predicate.skip_binder() 704 { 705 self.deduce_future_output_from_projection( 706 span, 707 bound_predicate.rebind(proj_predicate), 708 ) 709 } else { 710 None 711 } 712 }; 713 714 let output_ty = match *ret_ty.kind() { 715 ty::Infer(ty::TyVar(ret_vid)) => { 716 self.obligations_for_self_ty(ret_vid).find_map(|obligation| { 717 get_future_output(obligation.predicate, obligation.cause.span) 718 })? 719 } 720 ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => self 721 .tcx 722 .explicit_item_bounds(def_id) 723 .subst_iter_copied(self.tcx, substs) 724 .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, 725 ty::Error(_) => return None, 726 ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => self 727 .tcx 728 .explicit_item_bounds(proj.def_id) 729 .subst_iter_copied(self.tcx, proj.substs) 730 .find_map(|(p, s)| get_future_output(p.as_predicate(), s))?, 731 _ => span_bug!( 732 self.tcx.def_span(expr_def_id), 733 "async fn generator return type not an inference variable: {ret_ty}" 734 ), 735 }; 736 737 // async fn that have opaque types in their return type need to redo the conversion to inference variables 738 // as they fetch the still opaque version from the signature. 739 let InferOk { value: output_ty, obligations } = self 740 .replace_opaque_types_with_inference_vars( 741 output_ty, 742 body_def_id, 743 self.tcx.def_span(expr_def_id), 744 self.param_env, 745 ); 746 self.register_predicates(obligations); 747 748 Some(output_ty) 749 } 750 751 /// Given a projection like 752 /// 753 /// `<X as Future>::Output = T` 754 /// 755 /// where `X` is some type that has no late-bound regions, returns 756 /// `Some(T)`. If the projection is for some other trait, returns 757 /// `None`. deduce_future_output_from_projection( &self, cause_span: Span, predicate: ty::PolyProjectionPredicate<'tcx>, ) -> Option<Ty<'tcx>>758 fn deduce_future_output_from_projection( 759 &self, 760 cause_span: Span, 761 predicate: ty::PolyProjectionPredicate<'tcx>, 762 ) -> Option<Ty<'tcx>> { 763 debug!("deduce_future_output_from_projection(predicate={:?})", predicate); 764 765 // We do not expect any bound regions in our predicate, so 766 // skip past the bound vars. 767 let Some(predicate) = predicate.no_bound_vars() else { 768 debug!("deduce_future_output_from_projection: has late-bound regions"); 769 return None; 770 }; 771 772 // Check that this is a projection from the `Future` trait. 773 let trait_def_id = predicate.projection_ty.trait_def_id(self.tcx); 774 let future_trait = self.tcx.require_lang_item(LangItem::Future, Some(cause_span)); 775 if trait_def_id != future_trait { 776 debug!("deduce_future_output_from_projection: not a future"); 777 return None; 778 } 779 780 // The `Future` trait has only one associated item, `Output`, 781 // so check that this is what we see. 782 let output_assoc_item = self.tcx.associated_item_def_ids(future_trait)[0]; 783 if output_assoc_item != predicate.projection_ty.def_id { 784 span_bug!( 785 cause_span, 786 "projecting associated item `{:?}` from future, which is not Output `{:?}`", 787 predicate.projection_ty.def_id, 788 output_assoc_item, 789 ); 790 } 791 792 // Extract the type from the projection. Note that there can 793 // be no bound variables in this type because the "self type" 794 // does not have any regions in it. 795 let output_ty = self.resolve_vars_if_possible(predicate.term); 796 debug!("deduce_future_output_from_projection: output_ty={:?}", output_ty); 797 // This is a projection on a Fn trait so will always be a type. 798 Some(output_ty.ty().unwrap()) 799 } 800 801 /// Converts the types that the user supplied, in case that doing 802 /// so should yield an error, but returns back a signature where 803 /// all parameters are of type `TyErr`. error_sig_of_closure( &self, decl: &hir::FnDecl<'_>, guar: ErrorGuaranteed, ) -> ty::PolyFnSig<'tcx>804 fn error_sig_of_closure( 805 &self, 806 decl: &hir::FnDecl<'_>, 807 guar: ErrorGuaranteed, 808 ) -> ty::PolyFnSig<'tcx> { 809 let astconv: &dyn AstConv<'_> = self; 810 let err_ty = Ty::new_error(self.tcx, guar); 811 812 let supplied_arguments = decl.inputs.iter().map(|a| { 813 // Convert the types that the user supplied (if any), but ignore them. 814 astconv.ast_ty_to_ty(a); 815 err_ty 816 }); 817 818 if let hir::FnRetTy::Return(ref output) = decl.output { 819 astconv.ast_ty_to_ty(&output); 820 } 821 822 let result = ty::Binder::dummy(self.tcx.mk_fn_sig( 823 supplied_arguments, 824 err_ty, 825 decl.c_variadic, 826 hir::Unsafety::Normal, 827 Abi::RustCall, 828 )); 829 830 debug!("supplied_sig_of_closure: result={:?}", result); 831 832 result 833 } 834 closure_sigs( &self, expr_def_id: LocalDefId, body: &hir::Body<'_>, bound_sig: ty::PolyFnSig<'tcx>, ) -> ClosureSignatures<'tcx>835 fn closure_sigs( 836 &self, 837 expr_def_id: LocalDefId, 838 body: &hir::Body<'_>, 839 bound_sig: ty::PolyFnSig<'tcx>, 840 ) -> ClosureSignatures<'tcx> { 841 let liberated_sig = 842 self.tcx().liberate_late_bound_regions(expr_def_id.to_def_id(), bound_sig); 843 let liberated_sig = self.normalize(body.value.span, liberated_sig); 844 ClosureSignatures { bound_sig, liberated_sig } 845 } 846 } 847