]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/callee.rs
Auto merge of #85481 - lcnr:const-equate, r=matthewjasper
[rust.git] / compiler / rustc_typeck / src / check / callee.rs
1 use super::method::MethodCallee;
2 use super::{Expectation, FnCtxt, TupleArgumentsFlag};
3 use crate::type_error_struct;
4
5 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
6 use rustc_hir as hir;
7 use rustc_hir::def::{Namespace, Res};
8 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
9 use rustc_infer::{
10     infer,
11     traits::{self, Obligation},
12 };
13 use rustc_infer::{
14     infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind},
15     traits::ObligationCause,
16 };
17 use rustc_middle::ty::adjustment::{
18     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
19 };
20 use rustc_middle::ty::subst::SubstsRef;
21 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
22 use rustc_span::symbol::{sym, Ident};
23 use rustc_span::Span;
24 use rustc_target::spec::abi;
25 use rustc_trait_selection::autoderef::Autoderef;
26 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
27 use std::iter;
28
29 /// Checks that it is legal to call methods of the trait corresponding
30 /// to `trait_id` (this only cares about the trait, not the specific
31 /// method that is called).
32 pub fn check_legal_trait_for_method_call(
33     tcx: TyCtxt<'_>,
34     span: Span,
35     receiver: Option<Span>,
36     expr_span: Span,
37     trait_id: DefId,
38 ) {
39     if tcx.lang_items().drop_trait() == Some(trait_id) {
40         let mut err = struct_span_err!(tcx.sess, span, E0040, "explicit use of destructor method");
41         err.span_label(span, "explicit destructor calls not allowed");
42
43         let (sp, suggestion) = receiver
44             .and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok())
45             .filter(|snippet| !snippet.is_empty())
46             .map(|snippet| (expr_span, format!("drop({})", snippet)))
47             .unwrap_or_else(|| (span, "drop".to_string()));
48
49         err.span_suggestion(
50             sp,
51             "consider using `drop` function",
52             suggestion,
53             Applicability::MaybeIncorrect,
54         );
55
56         err.emit();
57     }
58 }
59
60 enum CallStep<'tcx> {
61     Builtin(Ty<'tcx>),
62     DeferredClosure(ty::FnSig<'tcx>),
63     /// E.g., enum variant constructors.
64     Overloaded(MethodCallee<'tcx>),
65 }
66
67 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
68     pub fn check_call(
69         &self,
70         call_expr: &'tcx hir::Expr<'tcx>,
71         callee_expr: &'tcx hir::Expr<'tcx>,
72         arg_exprs: &'tcx [hir::Expr<'tcx>],
73         expected: Expectation<'tcx>,
74     ) -> Ty<'tcx> {
75         let original_callee_ty = self.check_expr(callee_expr);
76         let expr_ty = self.structurally_resolved_type(call_expr.span, original_callee_ty);
77
78         let mut autoderef = self.autoderef(callee_expr.span, expr_ty);
79         let mut result = None;
80         while result.is_none() && autoderef.next().is_some() {
81             result = self.try_overloaded_call_step(call_expr, callee_expr, arg_exprs, &autoderef);
82         }
83         self.register_predicates(autoderef.into_obligations());
84
85         let output = match result {
86             None => {
87                 // this will report an error since original_callee_ty is not a fn
88                 self.confirm_builtin_call(
89                     call_expr,
90                     callee_expr,
91                     original_callee_ty,
92                     arg_exprs,
93                     expected,
94                 )
95             }
96
97             Some(CallStep::Builtin(callee_ty)) => {
98                 self.confirm_builtin_call(call_expr, callee_expr, callee_ty, arg_exprs, expected)
99             }
100
101             Some(CallStep::DeferredClosure(fn_sig)) => {
102                 self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, fn_sig)
103             }
104
105             Some(CallStep::Overloaded(method_callee)) => {
106                 self.confirm_overloaded_call(call_expr, arg_exprs, expected, method_callee)
107             }
108         };
109
110         // we must check that return type of called functions is WF:
111         self.register_wf_obligation(output.into(), call_expr.span, traits::MiscObligation);
112
113         output
114     }
115
116     fn try_overloaded_call_step(
117         &self,
118         call_expr: &'tcx hir::Expr<'tcx>,
119         callee_expr: &'tcx hir::Expr<'tcx>,
120         arg_exprs: &'tcx [hir::Expr<'tcx>],
121         autoderef: &Autoderef<'a, 'tcx>,
122     ) -> Option<CallStep<'tcx>> {
123         let adjusted_ty =
124             self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
125         debug!(
126             "try_overloaded_call_step(call_expr={:?}, adjusted_ty={:?})",
127             call_expr, adjusted_ty
128         );
129
130         // If the callee is a bare function or a closure, then we're all set.
131         match *adjusted_ty.kind() {
132             ty::FnDef(..) | ty::FnPtr(_) => {
133                 let adjustments = self.adjust_steps(autoderef);
134                 self.apply_adjustments(callee_expr, adjustments);
135                 return Some(CallStep::Builtin(adjusted_ty));
136             }
137
138             ty::Closure(def_id, substs) => {
139                 assert_eq!(def_id.krate, LOCAL_CRATE);
140
141                 // Check whether this is a call to a closure where we
142                 // haven't yet decided on whether the closure is fn vs
143                 // fnmut vs fnonce. If so, we have to defer further processing.
144                 if self.closure_kind(substs).is_none() {
145                     let closure_sig = substs.as_closure().sig();
146                     let closure_sig = self
147                         .replace_bound_vars_with_fresh_vars(
148                             call_expr.span,
149                             infer::FnCall,
150                             closure_sig,
151                         )
152                         .0;
153                     let adjustments = self.adjust_steps(autoderef);
154                     self.record_deferred_call_resolution(
155                         def_id,
156                         DeferredCallResolution {
157                             call_expr,
158                             callee_expr,
159                             adjusted_ty,
160                             adjustments,
161                             fn_sig: closure_sig,
162                             closure_substs: substs,
163                         },
164                     );
165                     return Some(CallStep::DeferredClosure(closure_sig));
166                 }
167             }
168
169             // Hack: we know that there are traits implementing Fn for &F
170             // where F:Fn and so forth. In the particular case of types
171             // like `x: &mut FnMut()`, if there is a call `x()`, we would
172             // normally translate to `FnMut::call_mut(&mut x, ())`, but
173             // that winds up requiring `mut x: &mut FnMut()`. A little
174             // over the top. The simplest fix by far is to just ignore
175             // this case and deref again, so we wind up with
176             // `FnMut::call_mut(&mut *x, ())`.
177             ty::Ref(..) if autoderef.step_count() == 0 => {
178                 return None;
179             }
180
181             _ => {}
182         }
183
184         // Now, we look for the implementation of a Fn trait on the object's type.
185         // We first do it with the explicit instruction to look for an impl of
186         // `Fn<Tuple>`, with the tuple `Tuple` having an arity corresponding
187         // to the number of call parameters.
188         // If that fails (or_else branch), we try again without specifying the
189         // shape of the tuple (hence the None). This allows to detect an Fn trait
190         // is implemented, and use this information for diagnostic.
191         self.try_overloaded_call_traits(call_expr, adjusted_ty, Some(arg_exprs))
192             .or_else(|| self.try_overloaded_call_traits(call_expr, adjusted_ty, None))
193             .map(|(autoref, method)| {
194                 let mut adjustments = self.adjust_steps(autoderef);
195                 adjustments.extend(autoref);
196                 self.apply_adjustments(callee_expr, adjustments);
197                 CallStep::Overloaded(method)
198             })
199     }
200
201     fn try_overloaded_call_traits(
202         &self,
203         call_expr: &hir::Expr<'_>,
204         adjusted_ty: Ty<'tcx>,
205         opt_arg_exprs: Option<&'tcx [hir::Expr<'tcx>]>,
206     ) -> Option<(Option<Adjustment<'tcx>>, MethodCallee<'tcx>)> {
207         // Try the options that are least restrictive on the caller first.
208         for &(opt_trait_def_id, method_name, borrow) in &[
209             (self.tcx.lang_items().fn_trait(), Ident::with_dummy_span(sym::call), true),
210             (self.tcx.lang_items().fn_mut_trait(), Ident::with_dummy_span(sym::call_mut), true),
211             (self.tcx.lang_items().fn_once_trait(), Ident::with_dummy_span(sym::call_once), false),
212         ] {
213             let trait_def_id = match opt_trait_def_id {
214                 Some(def_id) => def_id,
215                 None => continue,
216             };
217
218             let opt_input_types = opt_arg_exprs.map(|arg_exprs| {
219                 [self.tcx.mk_tup(arg_exprs.iter().map(|e| {
220                     self.next_ty_var(TypeVariableOrigin {
221                         kind: TypeVariableOriginKind::TypeInference,
222                         span: e.span,
223                     })
224                 }))]
225             });
226             let opt_input_types = opt_input_types.as_ref().map(AsRef::as_ref);
227
228             if let Some(ok) = self.lookup_method_in_trait(
229                 call_expr.span,
230                 method_name,
231                 trait_def_id,
232                 adjusted_ty,
233                 opt_input_types,
234             ) {
235                 let method = self.register_infer_ok_obligations(ok);
236                 let mut autoref = None;
237                 if borrow {
238                     // Check for &self vs &mut self in the method signature. Since this is either
239                     // the Fn or FnMut trait, it should be one of those.
240                     let (region, mutbl) =
241                         if let ty::Ref(r, _, mutbl) = method.sig.inputs()[0].kind() {
242                             (r, mutbl)
243                         } else {
244                             span_bug!(call_expr.span, "input to call/call_mut is not a ref?");
245                         };
246
247                     let mutbl = match mutbl {
248                         hir::Mutability::Not => AutoBorrowMutability::Not,
249                         hir::Mutability::Mut => AutoBorrowMutability::Mut {
250                             // For initial two-phase borrow
251                             // deployment, conservatively omit
252                             // overloaded function call ops.
253                             allow_two_phase_borrow: AllowTwoPhase::No,
254                         },
255                     };
256                     autoref = Some(Adjustment {
257                         kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
258                         target: method.sig.inputs()[0],
259                     });
260                 }
261                 return Some((autoref, method));
262             }
263         }
264
265         None
266     }
267
268     /// Give appropriate suggestion when encountering `||{/* not callable */}()`, where the
269     /// likely intention is to call the closure, suggest `(||{})()`. (#55851)
270     fn identify_bad_closure_def_and_call(
271         &self,
272         err: &mut DiagnosticBuilder<'a>,
273         hir_id: hir::HirId,
274         callee_node: &hir::ExprKind<'_>,
275         callee_span: Span,
276     ) {
277         let hir_id = self.tcx.hir().get_parent_node(hir_id);
278         let parent_node = self.tcx.hir().get(hir_id);
279         if let (
280             hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, _, _, sp, ..), .. }),
281             hir::ExprKind::Block(..),
282         ) = (parent_node, callee_node)
283         {
284             let start = sp.shrink_to_lo();
285             let end = callee_span.shrink_to_hi();
286             err.multipart_suggestion(
287                 "if you meant to create this closure and immediately call it, surround the \
288                 closure with parenthesis",
289                 vec![(start, "(".to_string()), (end, ")".to_string())],
290                 Applicability::MaybeIncorrect,
291             );
292         }
293     }
294
295     fn confirm_builtin_call(
296         &self,
297         call_expr: &'tcx hir::Expr<'tcx>,
298         callee_expr: &'tcx hir::Expr<'tcx>,
299         callee_ty: Ty<'tcx>,
300         arg_exprs: &'tcx [hir::Expr<'tcx>],
301         expected: Expectation<'tcx>,
302     ) -> Ty<'tcx> {
303         let (fn_sig, def_id) = match *callee_ty.kind() {
304             ty::FnDef(def_id, subst) => {
305                 // Unit testing: function items annotated with
306                 // `#[rustc_evaluate_where_clauses]` trigger special output
307                 // to let us test the trait evaluation system.
308                 if self.tcx.has_attr(def_id, sym::rustc_evaluate_where_clauses) {
309                     let predicates = self.tcx.predicates_of(def_id);
310                     let predicates = predicates.instantiate(self.tcx, subst);
311                     for (predicate, predicate_span) in
312                         predicates.predicates.iter().zip(&predicates.spans)
313                     {
314                         let obligation = Obligation::new(
315                             ObligationCause::dummy_with_span(callee_expr.span),
316                             self.param_env,
317                             predicate.clone(),
318                         );
319                         let result = self.infcx.evaluate_obligation(&obligation);
320                         self.tcx
321                             .sess
322                             .struct_span_err(
323                                 callee_expr.span,
324                                 &format!("evaluate({:?}) = {:?}", predicate, result),
325                             )
326                             .span_label(*predicate_span, "predicate")
327                             .emit();
328                     }
329                 }
330                 (callee_ty.fn_sig(self.tcx), Some(def_id))
331             }
332             ty::FnPtr(sig) => (sig, None),
333             ref t => {
334                 let mut unit_variant = None;
335                 if let ty::Adt(adt_def, ..) = t {
336                     if adt_def.is_enum() {
337                         if let hir::ExprKind::Call(expr, _) = call_expr.kind {
338                             unit_variant =
339                                 self.tcx.sess.source_map().span_to_snippet(expr.span).ok();
340                         }
341                     }
342                 }
343
344                 let mut err = type_error_struct!(
345                     self.tcx.sess,
346                     callee_expr.span,
347                     callee_ty,
348                     E0618,
349                     "expected function, found {}",
350                     match unit_variant {
351                         Some(ref path) => format!("enum variant `{}`", path),
352                         None => format!("`{}`", callee_ty),
353                     }
354                 );
355
356                 self.identify_bad_closure_def_and_call(
357                     &mut err,
358                     call_expr.hir_id,
359                     &callee_expr.kind,
360                     callee_expr.span,
361                 );
362
363                 if let Some(ref path) = unit_variant {
364                     err.span_suggestion(
365                         call_expr.span,
366                         &format!(
367                             "`{}` is a unit variant, you need to write it \
368                                  without the parenthesis",
369                             path
370                         ),
371                         path.to_string(),
372                         Applicability::MachineApplicable,
373                     );
374                 }
375
376                 let mut inner_callee_path = None;
377                 let def = match callee_expr.kind {
378                     hir::ExprKind::Path(ref qpath) => {
379                         self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
380                     }
381                     hir::ExprKind::Call(ref inner_callee, _) => {
382                         // If the call spans more than one line and the callee kind is
383                         // itself another `ExprCall`, that's a clue that we might just be
384                         // missing a semicolon (Issue #51055)
385                         let call_is_multiline =
386                             self.tcx.sess.source_map().is_multiline(call_expr.span);
387                         if call_is_multiline {
388                             err.span_suggestion(
389                                 callee_expr.span.shrink_to_hi(),
390                                 "consider using a semicolon here",
391                                 ";".to_owned(),
392                                 Applicability::MaybeIncorrect,
393                             );
394                         }
395                         if let hir::ExprKind::Path(ref inner_qpath) = inner_callee.kind {
396                             inner_callee_path = Some(inner_qpath);
397                             self.typeck_results.borrow().qpath_res(inner_qpath, inner_callee.hir_id)
398                         } else {
399                             Res::Err
400                         }
401                     }
402                     _ => Res::Err,
403                 };
404
405                 err.span_label(call_expr.span, "call expression requires function");
406
407                 if let Some(span) = self.tcx.hir().res_span(def) {
408                     let callee_ty = callee_ty.to_string();
409                     let label = match (unit_variant, inner_callee_path) {
410                         (Some(path), _) => Some(format!("`{}` defined here", path)),
411                         (_, Some(hir::QPath::Resolved(_, path))) => self
412                             .tcx
413                             .sess
414                             .source_map()
415                             .span_to_snippet(path.span)
416                             .ok()
417                             .map(|p| format!("`{}` defined here returns `{}`", p, callee_ty)),
418                         _ => {
419                             match def {
420                                 // Emit a different diagnostic for local variables, as they are not
421                                 // type definitions themselves, but rather variables *of* that type.
422                                 Res::Local(hir_id) => Some(format!(
423                                     "`{}` has type `{}`",
424                                     self.tcx.hir().name(hir_id),
425                                     callee_ty
426                                 )),
427                                 Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => {
428                                     Some(format!(
429                                         "`{}` defined here",
430                                         self.tcx.def_path_str(def_id),
431                                     ))
432                                 }
433                                 _ => Some(format!("`{}` defined here", callee_ty)),
434                             }
435                         }
436                     };
437                     if let Some(label) = label {
438                         err.span_label(span, label);
439                     }
440                 }
441                 err.emit();
442
443                 // This is the "default" function signature, used in case of error.
444                 // In that case, we check each argument against "error" in order to
445                 // set up all the node type bindings.
446                 (
447                     ty::Binder::dummy(self.tcx.mk_fn_sig(
448                         self.err_args(arg_exprs.len()).into_iter(),
449                         self.tcx.ty_error(),
450                         false,
451                         hir::Unsafety::Normal,
452                         abi::Abi::Rust,
453                     )),
454                     None,
455                 )
456             }
457         };
458
459         // Replace any late-bound regions that appear in the function
460         // signature with region variables. We also have to
461         // renormalize the associated types at this point, since they
462         // previously appeared within a `Binder<>` and hence would not
463         // have been normalized before.
464         let fn_sig =
465             self.replace_bound_vars_with_fresh_vars(call_expr.span, infer::FnCall, fn_sig).0;
466         let fn_sig = self.normalize_associated_types_in(call_expr.span, fn_sig);
467
468         // Call the generic checker.
469         let expected_arg_tys = self.expected_inputs_for_expected_output(
470             call_expr.span,
471             expected,
472             fn_sig.output(),
473             fn_sig.inputs(),
474         );
475         self.check_argument_types(
476             call_expr.span,
477             call_expr,
478             fn_sig.inputs(),
479             &expected_arg_tys[..],
480             arg_exprs,
481             fn_sig.c_variadic,
482             TupleArgumentsFlag::DontTupleArguments,
483             def_id,
484         );
485
486         fn_sig.output()
487     }
488
489     fn confirm_deferred_closure_call(
490         &self,
491         call_expr: &'tcx hir::Expr<'tcx>,
492         arg_exprs: &'tcx [hir::Expr<'tcx>],
493         expected: Expectation<'tcx>,
494         fn_sig: ty::FnSig<'tcx>,
495     ) -> Ty<'tcx> {
496         // `fn_sig` is the *signature* of the cosure being called. We
497         // don't know the full details yet (`Fn` vs `FnMut` etc), but we
498         // do know the types expected for each argument and the return
499         // type.
500
501         let expected_arg_tys = self.expected_inputs_for_expected_output(
502             call_expr.span,
503             expected,
504             fn_sig.output(),
505             fn_sig.inputs(),
506         );
507
508         self.check_argument_types(
509             call_expr.span,
510             call_expr,
511             fn_sig.inputs(),
512             &expected_arg_tys,
513             arg_exprs,
514             fn_sig.c_variadic,
515             TupleArgumentsFlag::TupleArguments,
516             None,
517         );
518
519         fn_sig.output()
520     }
521
522     fn confirm_overloaded_call(
523         &self,
524         call_expr: &'tcx hir::Expr<'tcx>,
525         arg_exprs: &'tcx [hir::Expr<'tcx>],
526         expected: Expectation<'tcx>,
527         method_callee: MethodCallee<'tcx>,
528     ) -> Ty<'tcx> {
529         let output_type = self.check_method_argument_types(
530             call_expr.span,
531             call_expr,
532             Ok(method_callee),
533             arg_exprs,
534             TupleArgumentsFlag::TupleArguments,
535             expected,
536         );
537
538         self.write_method_call(call_expr.hir_id, method_callee);
539         output_type
540     }
541 }
542
543 #[derive(Debug)]
544 pub struct DeferredCallResolution<'tcx> {
545     call_expr: &'tcx hir::Expr<'tcx>,
546     callee_expr: &'tcx hir::Expr<'tcx>,
547     adjusted_ty: Ty<'tcx>,
548     adjustments: Vec<Adjustment<'tcx>>,
549     fn_sig: ty::FnSig<'tcx>,
550     closure_substs: SubstsRef<'tcx>,
551 }
552
553 impl<'a, 'tcx> DeferredCallResolution<'tcx> {
554     pub fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) {
555         debug!("DeferredCallResolution::resolve() {:?}", self);
556
557         // we should not be invoked until the closure kind has been
558         // determined by upvar inference
559         assert!(fcx.closure_kind(self.closure_substs).is_some());
560
561         // We may now know enough to figure out fn vs fnmut etc.
562         match fcx.try_overloaded_call_traits(self.call_expr, self.adjusted_ty, None) {
563             Some((autoref, method_callee)) => {
564                 // One problem is that when we get here, we are going
565                 // to have a newly instantiated function signature
566                 // from the call trait. This has to be reconciled with
567                 // the older function signature we had before. In
568                 // principle we *should* be able to fn_sigs(), but we
569                 // can't because of the annoying need for a TypeTrace.
570                 // (This always bites me, should find a way to
571                 // refactor it.)
572                 let method_sig = method_callee.sig;
573
574                 debug!("attempt_resolution: method_callee={:?}", method_callee);
575
576                 for (method_arg_ty, self_arg_ty) in
577                     iter::zip(method_sig.inputs().iter().skip(1), self.fn_sig.inputs())
578                 {
579                     fcx.demand_eqtype(self.call_expr.span, &self_arg_ty, &method_arg_ty);
580                 }
581
582                 fcx.demand_eqtype(self.call_expr.span, method_sig.output(), self.fn_sig.output());
583
584                 let mut adjustments = self.adjustments;
585                 adjustments.extend(autoref);
586                 fcx.apply_adjustments(self.callee_expr, adjustments);
587
588                 fcx.write_method_call(self.call_expr.hir_id, method_callee);
589             }
590             None => {
591                 span_bug!(
592                     self.call_expr.span,
593                     "failed to find an overloaded call trait for closure call"
594                 );
595             }
596         }
597     }
598 }