]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/callee.rs
ad4afb0d1a37b001d8eb9cdddc60e9dbea157c4c
[rust.git] / src / librustc_typeck / check / callee.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use super::{Expectation, FnCtxt, Needs, TupleArgumentsFlag};
12 use super::autoderef::Autoderef;
13 use super::method::MethodCallee;
14
15 use hir::def::Def;
16 use hir::def_id::{DefId, LOCAL_CRATE};
17 use rustc::{infer, traits};
18 use rustc::ty::{self, TyCtxt, TypeFoldable, Ty};
19 use rustc::ty::adjustment::{Adjustment, Adjust, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
20 use rustc_target::spec::abi;
21 use syntax::ast::Ident;
22 use syntax_pos::Span;
23 use errors::Applicability;
24
25 use rustc::hir;
26
27 /// Check that it is legal to call methods of the trait corresponding
28 /// to `trait_id` (this only cares about the trait, not the specific
29 /// method that is called)
30 pub fn check_legal_trait_for_method_call(tcx: TyCtxt, span: Span, trait_id: DefId) {
31     if tcx.lang_items().drop_trait() == Some(trait_id) {
32         struct_span_err!(tcx.sess, span, E0040, "explicit use of destructor method")
33             .span_label(span, "explicit destructor calls not allowed")
34             .emit();
35     }
36 }
37
38 enum CallStep<'tcx> {
39     Builtin(Ty<'tcx>),
40     DeferredClosure(ty::FnSig<'tcx>),
41     /// e.g. enum variant constructors
42     Overloaded(MethodCallee<'tcx>),
43 }
44
45 impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
46     pub fn check_call(&self,
47                       call_expr: &'gcx hir::Expr,
48                       callee_expr: &'gcx hir::Expr,
49                       arg_exprs: &'gcx [hir::Expr],
50                       expected: Expectation<'tcx>)
51                       -> Ty<'tcx> {
52         let original_callee_ty = self.check_expr(callee_expr);
53         let expr_ty = self.structurally_resolved_type(call_expr.span, original_callee_ty);
54
55         let mut autoderef = self.autoderef(callee_expr.span, expr_ty);
56         let mut result = None;
57         while result.is_none() && autoderef.next().is_some() {
58             result = self.try_overloaded_call_step(call_expr, callee_expr, &autoderef);
59         }
60         autoderef.finalize();
61
62         let output = match result {
63             None => {
64                 // this will report an error since original_callee_ty is not a fn
65                 self.confirm_builtin_call(call_expr, original_callee_ty, arg_exprs, expected)
66             }
67
68             Some(CallStep::Builtin(callee_ty)) => {
69                 self.confirm_builtin_call(call_expr, callee_ty, arg_exprs, expected)
70             }
71
72             Some(CallStep::DeferredClosure(fn_sig)) => {
73                 self.confirm_deferred_closure_call(call_expr, arg_exprs, expected, fn_sig)
74             }
75
76             Some(CallStep::Overloaded(method_callee)) => {
77                 self.confirm_overloaded_call(call_expr, arg_exprs, expected, method_callee)
78             }
79         };
80
81         // we must check that return type of called functions is WF:
82         self.register_wf_obligation(output, call_expr.span, traits::MiscObligation);
83
84         output
85     }
86
87     fn try_overloaded_call_step(&self,
88                                 call_expr: &'gcx hir::Expr,
89                                 callee_expr: &'gcx hir::Expr,
90                                 autoderef: &Autoderef<'a, 'gcx, 'tcx>)
91                                 -> Option<CallStep<'tcx>> {
92         let adjusted_ty = autoderef.unambiguous_final_ty();
93         debug!("try_overloaded_call_step(call_expr={:?}, adjusted_ty={:?})",
94                call_expr,
95                adjusted_ty);
96
97         // If the callee is a bare function or a closure, then we're all set.
98         match adjusted_ty.sty {
99             ty::FnDef(..) | ty::FnPtr(_) => {
100                 let adjustments = autoderef.adjust_steps(Needs::None);
101                 self.apply_adjustments(callee_expr, adjustments);
102                 return Some(CallStep::Builtin(adjusted_ty));
103             }
104
105             ty::Closure(def_id, substs) => {
106                 assert_eq!(def_id.krate, LOCAL_CRATE);
107
108                 // Check whether this is a call to a closure where we
109                 // haven't yet decided on whether the closure is fn vs
110                 // fnmut vs fnonce. If so, we have to defer further processing.
111                 if self.closure_kind(def_id, substs).is_none() {
112                     let closure_ty = self.closure_sig(def_id, substs);
113                     let fn_sig = self.replace_bound_vars_with_fresh_vars(
114                         call_expr.span,
115                         infer::FnCall,
116                         &closure_ty
117                     ).0;
118                     let adjustments = autoderef.adjust_steps(Needs::None);
119                     self.record_deferred_call_resolution(def_id, DeferredCallResolution {
120                         call_expr,
121                         callee_expr,
122                         adjusted_ty,
123                         adjustments,
124                         fn_sig,
125                         closure_def_id: def_id,
126                         closure_substs: substs,
127                     });
128                     return Some(CallStep::DeferredClosure(fn_sig));
129                 }
130             }
131
132             // Hack: we know that there are traits implementing Fn for &F
133             // where F:Fn and so forth. In the particular case of types
134             // like `x: &mut FnMut()`, if there is a call `x()`, we would
135             // normally translate to `FnMut::call_mut(&mut x, ())`, but
136             // that winds up requiring `mut x: &mut FnMut()`. A little
137             // over the top. The simplest fix by far is to just ignore
138             // this case and deref again, so we wind up with
139             // `FnMut::call_mut(&mut *x, ())`.
140             ty::Ref(..) if autoderef.step_count() == 0 => {
141                 return None;
142             }
143
144             _ => {}
145         }
146
147         self.try_overloaded_call_traits(call_expr, adjusted_ty).map(|(autoref, method)| {
148             let mut adjustments = autoderef.adjust_steps(Needs::None);
149             adjustments.extend(autoref);
150             self.apply_adjustments(callee_expr, adjustments);
151             CallStep::Overloaded(method)
152         })
153     }
154
155     fn try_overloaded_call_traits(&self,
156                                   call_expr: &hir::Expr,
157                                   adjusted_ty: Ty<'tcx>)
158                                   -> Option<(Option<Adjustment<'tcx>>,
159                                              MethodCallee<'tcx>)> {
160         // Try the options that are least restrictive on the caller first.
161         for &(opt_trait_def_id, method_name, borrow) in
162             &[(self.tcx.lang_items().fn_trait(), Ident::from_str("call"), true),
163               (self.tcx.lang_items().fn_mut_trait(), Ident::from_str("call_mut"), true),
164               (self.tcx.lang_items().fn_once_trait(), Ident::from_str("call_once"), false)] {
165             let trait_def_id = match opt_trait_def_id {
166                 Some(def_id) => def_id,
167                 None => continue,
168             };
169
170             if let Some(ok) = self.lookup_method_in_trait(call_expr.span,
171                                                           method_name,
172                                                           trait_def_id,
173                                                           adjusted_ty,
174                                                           None) {
175                 let method = self.register_infer_ok_obligations(ok);
176                 let mut autoref = None;
177                 if borrow {
178                     if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].sty {
179                         let mutbl = match mutbl {
180                             hir::MutImmutable => AutoBorrowMutability::Immutable,
181                             hir::MutMutable => AutoBorrowMutability::Mutable {
182                                 // For initial two-phase borrow
183                                 // deployment, conservatively omit
184                                 // overloaded function call ops.
185                                 allow_two_phase_borrow: AllowTwoPhase::No,
186                             }
187                         };
188                         autoref = Some(Adjustment {
189                             kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
190                             target: method.sig.inputs()[0]
191                         });
192                     }
193                 }
194                 return Some((autoref, method));
195             }
196         }
197
198         None
199     }
200
201     fn confirm_builtin_call(&self,
202                             call_expr: &hir::Expr,
203                             callee_ty: Ty<'tcx>,
204                             arg_exprs: &'gcx [hir::Expr],
205                             expected: Expectation<'tcx>)
206                             -> Ty<'tcx> {
207         let (fn_sig, def_span) = match callee_ty.sty {
208             ty::FnDef(def_id, _) => {
209                 (callee_ty.fn_sig(self.tcx), self.tcx.hir().span_if_local(def_id))
210             }
211             ty::FnPtr(sig) => (sig, None),
212             ref t => {
213                 let mut unit_variant = None;
214                 if let &ty::Adt(adt_def, ..) = t {
215                     if adt_def.is_enum() {
216                         if let hir::ExprKind::Call(ref expr, _) = call_expr.node {
217                             unit_variant = Some(self.tcx.hir().node_to_pretty_string(expr.id))
218                         }
219                     }
220                 }
221
222                 if let hir::ExprKind::Call(ref callee, _) = call_expr.node {
223                     let mut err = type_error_struct!(
224                         self.tcx.sess,
225                         callee.span,
226                         callee_ty,
227                         E0618,
228                         "expected function, found {}",
229                         match unit_variant {
230                             Some(ref path) => format!("enum variant `{}`", path),
231                             None => format!("`{}`", callee_ty),
232                         });
233
234                     if let Some(ref path) = unit_variant {
235                         err.span_suggestion_with_applicability(
236                             call_expr.span,
237                             &format!("`{}` is a unit variant, you need to write it \
238                                       without the parenthesis", path),
239                             path.to_string(),
240                             Applicability::MachineApplicable
241                         );
242                     }
243
244                     let mut inner_callee_path = None;
245                     let def = match callee.node {
246                         hir::ExprKind::Path(ref qpath) => {
247                             self.tables.borrow().qpath_def(qpath, callee.hir_id)
248                         },
249                         hir::ExprKind::Call(ref inner_callee, _) => {
250                             // If the call spans more than one line and the callee kind is
251                             // itself another `ExprCall`, that's a clue that we might just be
252                             // missing a semicolon (Issue #51055)
253                             let call_is_multiline = self.tcx.sess.source_map()
254                                 .is_multiline(call_expr.span);
255                             if call_is_multiline {
256                                 let span = self.tcx.sess.source_map().next_point(callee.span);
257                                 err.span_suggestion_with_applicability(
258                                     span,
259                                     "try adding a semicolon",
260                                     ";".to_owned(),
261                                     Applicability::MaybeIncorrect
262                                 );
263                             }
264                             if let hir::ExprKind::Path(ref inner_qpath) = inner_callee.node {
265                                 inner_callee_path = Some(inner_qpath);
266                                 self.tables.borrow().qpath_def(inner_qpath, inner_callee.hir_id)
267                             } else {
268                                 Def::Err
269                             }
270                         },
271                         _ => {
272                             Def::Err
273                         }
274                     };
275
276                     err.span_label(call_expr.span, "call expression requires function");
277
278                     let def_span = match def {
279                         Def::Err => None,
280                         Def::Local(id) | Def::Upvar(id, ..) => {
281                             Some(self.tcx.hir().span(id))
282                         }
283                         _ => self.tcx.hir().span_if_local(def.def_id())
284                     };
285                     if let Some(span) = def_span {
286                         let label = match (unit_variant, inner_callee_path) {
287                             (Some(path), _) => format!("`{}` defined here", path),
288                             (_, Some(hir::QPath::Resolved(_, path))) => format!(
289                                 "`{}` defined here returns `{}`", path, callee_ty.to_string()
290                             ),
291                             _ => format!("`{}` defined here", callee_ty.to_string()),
292                         };
293                         err.span_label(span, label);
294                     }
295                     err.emit();
296                 } else {
297                     bug!("call_expr.node should be an ExprKind::Call, got {:?}", call_expr.node);
298                 }
299
300                 // This is the "default" function signature, used in case of error.
301                 // In that case, we check each argument against "error" in order to
302                 // set up all the node type bindings.
303                 (ty::Binder::bind(self.tcx.mk_fn_sig(
304                     self.err_args(arg_exprs.len()).into_iter(),
305                     self.tcx.types.err,
306                     false,
307                     hir::Unsafety::Normal,
308                     abi::Abi::Rust
309                 )), None)
310             }
311         };
312
313         // Replace any late-bound regions that appear in the function
314         // signature with region variables. We also have to
315         // renormalize the associated types at this point, since they
316         // previously appeared within a `Binder<>` and hence would not
317         // have been normalized before.
318         let fn_sig =
319             self.replace_bound_vars_with_fresh_vars(call_expr.span, infer::FnCall, &fn_sig)
320                 .0;
321         let fn_sig = self.normalize_associated_types_in(call_expr.span, &fn_sig);
322
323         // Call the generic checker.
324         let expected_arg_tys =
325             self.expected_inputs_for_expected_output(call_expr.span,
326                                             expected,
327                                             fn_sig.output(),
328                                             fn_sig.inputs());
329         self.check_argument_types(call_expr.span,
330                                   call_expr.span,
331                                   fn_sig.inputs(),
332                                   &expected_arg_tys[..],
333                                   arg_exprs,
334                                   fn_sig.variadic,
335                                   TupleArgumentsFlag::DontTupleArguments,
336                                   def_span);
337
338         fn_sig.output()
339     }
340
341     fn confirm_deferred_closure_call(&self,
342                                      call_expr: &hir::Expr,
343                                      arg_exprs: &'gcx [hir::Expr],
344                                      expected: Expectation<'tcx>,
345                                      fn_sig: ty::FnSig<'tcx>)
346                                      -> Ty<'tcx> {
347         // `fn_sig` is the *signature* of the cosure being called. We
348         // don't know the full details yet (`Fn` vs `FnMut` etc), but we
349         // do know the types expected for each argument and the return
350         // type.
351
352         let expected_arg_tys = self.expected_inputs_for_expected_output(call_expr.span,
353                                                                expected,
354                                                                fn_sig.output().clone(),
355                                                                fn_sig.inputs());
356
357         self.check_argument_types(call_expr.span,
358                                   call_expr.span,
359                                   fn_sig.inputs(),
360                                   &expected_arg_tys,
361                                   arg_exprs,
362                                   fn_sig.variadic,
363                                   TupleArgumentsFlag::TupleArguments,
364                                   None);
365
366         fn_sig.output()
367     }
368
369     fn confirm_overloaded_call(&self,
370                                call_expr: &hir::Expr,
371                                arg_exprs: &'gcx [hir::Expr],
372                                expected: Expectation<'tcx>,
373                                method_callee: MethodCallee<'tcx>)
374                                -> Ty<'tcx> {
375         let output_type = self.check_method_argument_types(call_expr.span,
376                                                            call_expr.span,
377                                                            Ok(method_callee),
378                                                            arg_exprs,
379                                                            TupleArgumentsFlag::TupleArguments,
380                                                            expected);
381
382         self.write_method_call(call_expr.hir_id, method_callee);
383         output_type
384     }
385 }
386
387 #[derive(Debug)]
388 pub struct DeferredCallResolution<'gcx: 'tcx, 'tcx> {
389     call_expr: &'gcx hir::Expr,
390     callee_expr: &'gcx hir::Expr,
391     adjusted_ty: Ty<'tcx>,
392     adjustments: Vec<Adjustment<'tcx>>,
393     fn_sig: ty::FnSig<'tcx>,
394     closure_def_id: DefId,
395     closure_substs: ty::ClosureSubsts<'tcx>,
396 }
397
398 impl<'a, 'gcx, 'tcx> DeferredCallResolution<'gcx, 'tcx> {
399     pub fn resolve(self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) {
400         debug!("DeferredCallResolution::resolve() {:?}", self);
401
402         // we should not be invoked until the closure kind has been
403         // determined by upvar inference
404         assert!(fcx.closure_kind(self.closure_def_id, self.closure_substs).is_some());
405
406         // We may now know enough to figure out fn vs fnmut etc.
407         match fcx.try_overloaded_call_traits(self.call_expr,
408                                              self.adjusted_ty) {
409             Some((autoref, method_callee)) => {
410                 // One problem is that when we get here, we are going
411                 // to have a newly instantiated function signature
412                 // from the call trait. This has to be reconciled with
413                 // the older function signature we had before. In
414                 // principle we *should* be able to fn_sigs(), but we
415                 // can't because of the annoying need for a TypeTrace.
416                 // (This always bites me, should find a way to
417                 // refactor it.)
418                 let method_sig = method_callee.sig;
419
420                 debug!("attempt_resolution: method_callee={:?}", method_callee);
421
422                 for (method_arg_ty, self_arg_ty) in
423                     method_sig.inputs().iter().skip(1).zip(self.fn_sig.inputs()) {
424                     fcx.demand_eqtype(self.call_expr.span, &self_arg_ty, &method_arg_ty);
425                 }
426
427                 fcx.demand_eqtype(self.call_expr.span, method_sig.output(), self.fn_sig.output());
428
429                 let mut adjustments = self.adjustments;
430                 adjustments.extend(autoref);
431                 fcx.apply_adjustments(self.callee_expr, adjustments);
432
433                 fcx.write_method_call(self.call_expr.hir_id,
434                                       method_callee);
435             }
436             None => {
437                 span_bug!(self.call_expr.span,
438                           "failed to find an overloaded call trait for closure call");
439             }
440         }
441     }
442 }