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