]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Rollup merge of #91641 - dtolnay:cchar-if, r=Mark-Simulacrum
[rust.git] / compiler / rustc_typeck / src / check / fn_ctxt / checks.rs
1 use crate::astconv::AstConv;
2 use crate::check::coercion::CoerceMany;
3 use crate::check::gather_locals::Declaration;
4 use crate::check::method::MethodCallee;
5 use crate::check::Expectation::*;
6 use crate::check::TupleArgumentsFlag::*;
7 use crate::check::{
8     potentially_plural_count, struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt,
9     LocalTy, Needs, TupleArgumentsFlag,
10 };
11
12 use rustc_ast as ast;
13 use rustc_data_structures::sync::Lrc;
14 use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId};
15 use rustc_hir as hir;
16 use rustc_hir::def::{CtorOf, DefKind, Res};
17 use rustc_hir::def_id::DefId;
18 use rustc_hir::{ExprKind, Node, QPath};
19 use rustc_middle::ty::adjustment::AllowTwoPhase;
20 use rustc_middle::ty::fold::TypeFoldable;
21 use rustc_middle::ty::{self, Ty};
22 use rustc_session::Session;
23 use rustc_span::symbol::Ident;
24 use rustc_span::{self, MultiSpan, Span};
25 use rustc_trait_selection::traits::{self, ObligationCauseCode, StatementAsExpression};
26
27 use crate::structured_errors::StructuredDiagnostic;
28 use std::iter;
29 use std::slice;
30
31 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
32     pub(in super::super) fn check_casts(&self) {
33         let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
34         debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len());
35         for cast in deferred_cast_checks.drain(..) {
36             cast.check(self);
37         }
38     }
39
40     pub(in super::super) fn check_method_argument_types(
41         &self,
42         sp: Span,
43         expr: &'tcx hir::Expr<'tcx>,
44         method: Result<MethodCallee<'tcx>, ()>,
45         args_no_rcvr: &'tcx [hir::Expr<'tcx>],
46         tuple_arguments: TupleArgumentsFlag,
47         expected: Expectation<'tcx>,
48     ) -> Ty<'tcx> {
49         let has_error = match method {
50             Ok(method) => method.substs.references_error() || method.sig.references_error(),
51             Err(_) => true,
52         };
53         if has_error {
54             let err_inputs = self.err_args(args_no_rcvr.len());
55
56             let err_inputs = match tuple_arguments {
57                 DontTupleArguments => err_inputs,
58                 TupleArguments => vec![self.tcx.intern_tup(&err_inputs)],
59             };
60
61             self.check_argument_types(
62                 sp,
63                 expr,
64                 &err_inputs,
65                 vec![],
66                 args_no_rcvr,
67                 false,
68                 tuple_arguments,
69                 None,
70             );
71             return self.tcx.ty_error();
72         }
73
74         let method = method.unwrap();
75         // HACK(eddyb) ignore self in the definition (see above).
76         let expected_input_tys = self.expected_inputs_for_expected_output(
77             sp,
78             expected,
79             method.sig.output(),
80             &method.sig.inputs()[1..],
81         );
82         self.check_argument_types(
83             sp,
84             expr,
85             &method.sig.inputs()[1..],
86             expected_input_tys,
87             args_no_rcvr,
88             method.sig.c_variadic,
89             tuple_arguments,
90             Some(method.def_id),
91         );
92         method.sig.output()
93     }
94
95     /// Generic function that factors out common logic from function calls,
96     /// method calls and overloaded operators.
97     pub(in super::super) fn check_argument_types(
98         &self,
99         // Span enclosing the call site
100         call_span: Span,
101         // Expression of the call site
102         call_expr: &'tcx hir::Expr<'tcx>,
103         // Types (as defined in the *signature* of the target function)
104         formal_input_tys: &[Ty<'tcx>],
105         // More specific expected types, after unifying with caller output types
106         expected_input_tys: Vec<Ty<'tcx>>,
107         // The expressions for each provided argument
108         provided_args: &'tcx [hir::Expr<'tcx>],
109         // Whether the function is variadic, for example when imported from C
110         c_variadic: bool,
111         // Whether the arguments have been bundled in a tuple (ex: closures)
112         tuple_arguments: TupleArgumentsFlag,
113         // The DefId for the function being called, for better error messages
114         fn_def_id: Option<DefId>,
115     ) {
116         let tcx = self.tcx;
117         // Grab the argument types, supplying fresh type variables
118         // if the wrong number of arguments were supplied
119         let supplied_arg_count =
120             if tuple_arguments == DontTupleArguments { provided_args.len() } else { 1 };
121
122         // All the input types from the fn signature must outlive the call
123         // so as to validate implied bounds.
124         for (&fn_input_ty, arg_expr) in iter::zip(formal_input_tys, provided_args) {
125             self.register_wf_obligation(fn_input_ty.into(), arg_expr.span, traits::MiscObligation);
126         }
127
128         let expected_arg_count = formal_input_tys.len();
129
130         // expected_count, arg_count, error_code, sugg_unit
131         let mut error: Option<(usize, usize, &str, bool)> = None;
132
133         // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
134         let (formal_input_tys, expected_input_tys) = if tuple_arguments == TupleArguments {
135             let tuple_type = self.structurally_resolved_type(call_span, formal_input_tys[0]);
136             match tuple_type.kind() {
137                 // We expected a tuple and got a tuple
138                 ty::Tuple(arg_types) => {
139                     // Argument length differs
140                     if arg_types.len() != provided_args.len() {
141                         error = Some((arg_types.len(), provided_args.len(), "E0057", false));
142                     }
143                     let expected_input_tys = match expected_input_tys.get(0) {
144                         Some(&ty) => match ty.kind() {
145                             ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).collect(),
146                             _ => vec![],
147                         },
148                         None => vec![],
149                     };
150                     (arg_types.iter().map(|k| k.expect_ty()).collect(), expected_input_tys)
151                 }
152                 _ => {
153                     // Otherwise, there's a mismatch, so clear out what we're expecting, and set
154                     // our input typs to err_args so we don't blow up the error messages
155                     struct_span_err!(
156                         tcx.sess,
157                         call_span,
158                         E0059,
159                         "cannot use call notation; the first type parameter \
160                          for the function trait is neither a tuple nor unit"
161                     )
162                     .emit();
163                     (self.err_args(provided_args.len()), vec![])
164                 }
165             }
166         } else if expected_arg_count == supplied_arg_count {
167             (formal_input_tys.to_vec(), expected_input_tys)
168         } else if c_variadic {
169             if supplied_arg_count >= expected_arg_count {
170                 (formal_input_tys.to_vec(), expected_input_tys)
171             } else {
172                 error = Some((expected_arg_count, supplied_arg_count, "E0060", false));
173                 (self.err_args(supplied_arg_count), vec![])
174             }
175         } else {
176             // is the missing argument of type `()`?
177             let sugg_unit = if expected_input_tys.len() == 1 && supplied_arg_count == 0 {
178                 self.resolve_vars_if_possible(expected_input_tys[0]).is_unit()
179             } else if formal_input_tys.len() == 1 && supplied_arg_count == 0 {
180                 self.resolve_vars_if_possible(formal_input_tys[0]).is_unit()
181             } else {
182                 false
183             };
184             error = Some((expected_arg_count, supplied_arg_count, "E0061", sugg_unit));
185             (self.err_args(supplied_arg_count), vec![])
186         };
187
188         debug!(
189             "check_argument_types: formal_input_tys={:?}",
190             formal_input_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>()
191         );
192
193         // If there is no expectation, expect formal_input_tys.
194         let expected_input_tys = if !expected_input_tys.is_empty() {
195             expected_input_tys
196         } else {
197             formal_input_tys.clone()
198         };
199
200         assert_eq!(expected_input_tys.len(), formal_input_tys.len());
201
202         let provided_arg_count: usize = provided_args.len();
203
204         // Keep track of the fully coerced argument types
205         let mut final_arg_types: Vec<Option<(Ty<'_>, Ty<'_>)>> = vec![None; provided_arg_count];
206
207         // We introduce a helper function to demand that a given argument satisfy a given input
208         // This is more complicated than just checking type equality, as arguments could be coerced
209         // This version writes those types back so further type checking uses the narrowed types
210         let demand_compatible = |idx, final_arg_types: &mut Vec<Option<(Ty<'tcx>, Ty<'tcx>)>>| {
211             let formal_input_ty: Ty<'tcx> = formal_input_tys[idx];
212             let expected_input_ty: Ty<'tcx> = expected_input_tys[idx];
213             let provided_arg = &provided_args[idx];
214
215             debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty);
216
217             // The special-cased logic below has three functions:
218             // 1. Provide as good of an expected type as possible.
219             let expectation = Expectation::rvalue_hint(self, expected_input_ty);
220
221             let checked_ty = self.check_expr_with_expectation(provided_arg, expectation);
222
223             // 2. Coerce to the most detailed type that could be coerced
224             //    to, which is `expected_ty` if `rvalue_hint` returns an
225             //    `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
226             let coerced_ty = expectation.only_has_type(self).unwrap_or(formal_input_ty);
227
228             // Keep track of these for below
229             final_arg_types[idx] = Some((checked_ty, coerced_ty));
230
231             // Cause selection errors caused by resolving a single argument to point at the
232             // argument and not the call. This is otherwise redundant with the `demand_coerce`
233             // call immediately after, but it lets us customize the span pointed to in the
234             // fulfillment error to be more accurate.
235             let coerced_ty =
236                 self.resolve_vars_with_obligations_and_mutate_fulfillment(coerced_ty, |errors| {
237                     self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr);
238                     self.point_at_arg_instead_of_call_if_possible(
239                         errors,
240                         &final_arg_types,
241                         call_expr,
242                         call_span,
243                         provided_args,
244                     );
245                 });
246
247             final_arg_types[idx] = Some((checked_ty, coerced_ty));
248
249             // We're processing function arguments so we definitely want to use
250             // two-phase borrows.
251             self.demand_coerce(&provided_arg, checked_ty, coerced_ty, None, AllowTwoPhase::Yes);
252
253             // 3. Relate the expected type and the formal one,
254             //    if the expected type was used for the coercion.
255             self.demand_suptype(provided_arg.span, formal_input_ty, coerced_ty);
256         };
257
258         // Check the arguments.
259         // We do this in a pretty awful way: first we type-check any arguments
260         // that are not closures, then we type-check the closures. This is so
261         // that we have more information about the types of arguments when we
262         // type-check the functions. This isn't really the right way to do this.
263         for check_closures in [false, true] {
264             // More awful hacks: before we check argument types, try to do
265             // an "opportunistic" trait resolution of any trait bounds on
266             // the call. This helps coercions.
267             if check_closures {
268                 self.select_obligations_where_possible(false, |errors| {
269                     self.point_at_type_arg_instead_of_call_if_possible(errors, call_expr);
270                     self.point_at_arg_instead_of_call_if_possible(
271                         errors,
272                         &final_arg_types,
273                         call_expr,
274                         call_span,
275                         &provided_args,
276                     );
277                 })
278             }
279
280             let minimum_input_count = formal_input_tys.len();
281             for (idx, arg) in provided_args.iter().enumerate() {
282                 // Warn only for the first loop (the "no closures" one).
283                 // Closure arguments themselves can't be diverging, but
284                 // a previous argument can, e.g., `foo(panic!(), || {})`.
285                 if !check_closures {
286                     self.warn_if_unreachable(arg.hir_id, arg.span, "expression");
287                 }
288
289                 // For C-variadic functions, we don't have a declared type for all of
290                 // the arguments hence we only do our usual type checking with
291                 // the arguments who's types we do know. However, we *can* check
292                 // for unreachable expressions (see above).
293                 // FIXME: unreachable warning current isn't emitted
294                 if idx >= minimum_input_count {
295                     continue;
296                 }
297
298                 let is_closure = matches!(arg.kind, ExprKind::Closure(..));
299                 if is_closure != check_closures {
300                     continue;
301                 }
302
303                 demand_compatible(idx, &mut final_arg_types);
304             }
305         }
306
307         // If there was an error in parameter count, emit that here
308         if let Some((expected_count, arg_count, err_code, sugg_unit)) = error {
309             let (span, start_span, args, ctor_of) = match &call_expr.kind {
310                 hir::ExprKind::Call(
311                     hir::Expr {
312                         span,
313                         kind:
314                             hir::ExprKind::Path(hir::QPath::Resolved(
315                                 _,
316                                 hir::Path { res: Res::Def(DefKind::Ctor(of, _), _), .. },
317                             )),
318                         ..
319                     },
320                     args,
321                 ) => (*span, *span, &args[..], Some(of)),
322                 hir::ExprKind::Call(hir::Expr { span, .. }, args) => {
323                     (*span, *span, &args[..], None)
324                 }
325                 hir::ExprKind::MethodCall(path_segment, args, _) => (
326                     path_segment.ident.span,
327                     // `sp` doesn't point at the whole `foo.bar()`, only at `bar`.
328                     path_segment
329                         .args
330                         .and_then(|args| args.args.iter().last())
331                         // Account for `foo.bar::<T>()`.
332                         .map(|arg| {
333                             // Skip the closing `>`.
334                             tcx.sess
335                                 .source_map()
336                                 .next_point(tcx.sess.source_map().next_point(arg.span()))
337                         })
338                         .unwrap_or(path_segment.ident.span),
339                     &args[1..], // Skip the receiver.
340                     None,       // methods are never ctors
341                 ),
342                 k => span_bug!(call_span, "checking argument types on a non-call: `{:?}`", k),
343             };
344             let arg_spans = if provided_args.is_empty() {
345                 // foo()
346                 // ^^^-- supplied 0 arguments
347                 // |
348                 // expected 2 arguments
349                 vec![tcx.sess.source_map().next_point(start_span).with_hi(call_span.hi())]
350             } else {
351                 // foo(1, 2, 3)
352                 // ^^^ -  -  - supplied 3 arguments
353                 // |
354                 // expected 2 arguments
355                 args.iter().map(|arg| arg.span).collect::<Vec<Span>>()
356             };
357             let call_name = match ctor_of {
358                 Some(CtorOf::Struct) => "struct",
359                 Some(CtorOf::Variant) => "enum variant",
360                 None => "function",
361             };
362             let mut err = tcx.sess.struct_span_err_with_code(
363                 span,
364                 &format!(
365                     "this {} takes {}{} but {} {} supplied",
366                     call_name,
367                     if c_variadic { "at least " } else { "" },
368                     potentially_plural_count(expected_count, "argument"),
369                     potentially_plural_count(arg_count, "argument"),
370                     if arg_count == 1 { "was" } else { "were" }
371                 ),
372                 DiagnosticId::Error(err_code.to_owned()),
373             );
374             let label = format!("supplied {}", potentially_plural_count(arg_count, "argument"));
375             for (i, span) in arg_spans.into_iter().enumerate() {
376                 err.span_label(
377                     span,
378                     if arg_count == 0 || i + 1 == arg_count { &label } else { "" },
379                 );
380             }
381             if let Some(def_id) = fn_def_id {
382                 if let Some(def_span) = tcx.def_ident_span(def_id) {
383                     let mut spans: MultiSpan = def_span.into();
384
385                     let params = tcx
386                         .hir()
387                         .get_if_local(def_id)
388                         .and_then(|node| node.body_id())
389                         .into_iter()
390                         .map(|id| tcx.hir().body(id).params)
391                         .flatten();
392
393                     for param in params {
394                         spans.push_span_label(param.span, String::new());
395                     }
396
397                     let def_kind = tcx.def_kind(def_id);
398                     err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id)));
399                 }
400             }
401             if sugg_unit {
402                 let sugg_span = tcx.sess.source_map().end_point(call_expr.span);
403                 // remove closing `)` from the span
404                 let sugg_span = sugg_span.shrink_to_lo();
405                 err.span_suggestion(
406                     sugg_span,
407                     "expected the unit value `()`; create it with empty parentheses",
408                     String::from("()"),
409                     Applicability::MachineApplicable,
410                 );
411             } else {
412                 err.span_label(
413                     span,
414                     format!(
415                         "expected {}{}",
416                         if c_variadic { "at least " } else { "" },
417                         potentially_plural_count(expected_count, "argument")
418                     ),
419                 );
420             }
421             err.emit();
422         }
423
424         // We also need to make sure we at least write the ty of the other
425         // arguments which we skipped above.
426         if c_variadic {
427             fn variadic_error<'tcx>(sess: &Session, span: Span, ty: Ty<'tcx>, cast_ty: &str) {
428                 use crate::structured_errors::MissingCastForVariadicArg;
429
430                 MissingCastForVariadicArg { sess, span, ty, cast_ty }.diagnostic().emit()
431             }
432
433             for arg in provided_args.iter().skip(expected_arg_count) {
434                 let arg_ty = self.check_expr(&arg);
435
436                 // There are a few types which get autopromoted when passed via varargs
437                 // in C but we just error out instead and require explicit casts.
438                 let arg_ty = self.structurally_resolved_type(arg.span, arg_ty);
439                 match arg_ty.kind() {
440                     ty::Float(ty::FloatTy::F32) => {
441                         variadic_error(tcx.sess, arg.span, arg_ty, "c_double");
442                     }
443                     ty::Int(ty::IntTy::I8 | ty::IntTy::I16) | ty::Bool => {
444                         variadic_error(tcx.sess, arg.span, arg_ty, "c_int");
445                     }
446                     ty::Uint(ty::UintTy::U8 | ty::UintTy::U16) => {
447                         variadic_error(tcx.sess, arg.span, arg_ty, "c_uint");
448                     }
449                     ty::FnDef(..) => {
450                         let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
451                         let ptr_ty = self.resolve_vars_if_possible(ptr_ty);
452                         variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
453                     }
454                     _ => {}
455                 }
456             }
457         }
458     }
459
460     // AST fragment checking
461     pub(in super::super) fn check_lit(
462         &self,
463         lit: &hir::Lit,
464         expected: Expectation<'tcx>,
465     ) -> Ty<'tcx> {
466         let tcx = self.tcx;
467
468         match lit.node {
469             ast::LitKind::Str(..) => tcx.mk_static_str(),
470             ast::LitKind::ByteStr(ref v) => {
471                 tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
472             }
473             ast::LitKind::Byte(_) => tcx.types.u8,
474             ast::LitKind::Char(_) => tcx.types.char,
475             ast::LitKind::Int(_, ast::LitIntType::Signed(t)) => tcx.mk_mach_int(ty::int_ty(t)),
476             ast::LitKind::Int(_, ast::LitIntType::Unsigned(t)) => tcx.mk_mach_uint(ty::uint_ty(t)),
477             ast::LitKind::Int(_, ast::LitIntType::Unsuffixed) => {
478                 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
479                     ty::Int(_) | ty::Uint(_) => Some(ty),
480                     ty::Char => Some(tcx.types.u8),
481                     ty::RawPtr(..) => Some(tcx.types.usize),
482                     ty::FnDef(..) | ty::FnPtr(_) => Some(tcx.types.usize),
483                     _ => None,
484                 });
485                 opt_ty.unwrap_or_else(|| self.next_int_var())
486             }
487             ast::LitKind::Float(_, ast::LitFloatType::Suffixed(t)) => {
488                 tcx.mk_mach_float(ty::float_ty(t))
489             }
490             ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) => {
491                 let opt_ty = expected.to_option(self).and_then(|ty| match ty.kind() {
492                     ty::Float(_) => Some(ty),
493                     _ => None,
494                 });
495                 opt_ty.unwrap_or_else(|| self.next_float_var())
496             }
497             ast::LitKind::Bool(_) => tcx.types.bool,
498             ast::LitKind::Err(_) => tcx.ty_error(),
499         }
500     }
501
502     pub fn check_struct_path(
503         &self,
504         qpath: &QPath<'_>,
505         hir_id: hir::HirId,
506     ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
507         let path_span = qpath.span();
508         let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
509         let variant = match def {
510             Res::Err => {
511                 self.set_tainted_by_errors();
512                 return None;
513             }
514             Res::Def(DefKind::Variant, _) => match ty.kind() {
515                 ty::Adt(adt, substs) => Some((adt.variant_of_res(def), adt.did, substs)),
516                 _ => bug!("unexpected type: {:?}", ty),
517             },
518             Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
519             | Res::SelfTy(..) => match ty.kind() {
520                 ty::Adt(adt, substs) if !adt.is_enum() => {
521                     Some((adt.non_enum_variant(), adt.did, substs))
522                 }
523                 _ => None,
524             },
525             _ => bug!("unexpected definition: {:?}", def),
526         };
527
528         if let Some((variant, did, substs)) = variant {
529             debug!("check_struct_path: did={:?} substs={:?}", did, substs);
530             self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
531
532             // Check bounds on type arguments used in the path.
533             self.add_required_obligations(path_span, did, substs);
534
535             Some((variant, ty))
536         } else {
537             match ty.kind() {
538                 ty::Error(_) => {
539                     // E0071 might be caused by a spelling error, which will have
540                     // already caused an error message and probably a suggestion
541                     // elsewhere. Refrain from emitting more unhelpful errors here
542                     // (issue #88844).
543                 }
544                 _ => {
545                     struct_span_err!(
546                         self.tcx.sess,
547                         path_span,
548                         E0071,
549                         "expected struct, variant or union type, found {}",
550                         ty.sort_string(self.tcx)
551                     )
552                     .span_label(path_span, "not a struct")
553                     .emit();
554                 }
555             }
556             None
557         }
558     }
559
560     pub fn check_decl_initializer(
561         &self,
562         hir_id: hir::HirId,
563         pat: &'tcx hir::Pat<'tcx>,
564         init: &'tcx hir::Expr<'tcx>,
565     ) -> Ty<'tcx> {
566         // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed
567         // for #42640 (default match binding modes).
568         //
569         // See #44848.
570         let ref_bindings = pat.contains_explicit_ref_binding();
571
572         let local_ty = self.local_ty(init.span, hir_id).revealed_ty;
573         if let Some(m) = ref_bindings {
574             // Somewhat subtle: if we have a `ref` binding in the pattern,
575             // we want to avoid introducing coercions for the RHS. This is
576             // both because it helps preserve sanity and, in the case of
577             // ref mut, for soundness (issue #23116). In particular, in
578             // the latter case, we need to be clear that the type of the
579             // referent for the reference that results is *equal to* the
580             // type of the place it is referencing, and not some
581             // supertype thereof.
582             let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m));
583             self.demand_eqtype(init.span, local_ty, init_ty);
584             init_ty
585         } else {
586             self.check_expr_coercable_to_type(init, local_ty, None)
587         }
588     }
589
590     pub(in super::super) fn check_decl(&self, decl: Declaration<'tcx>) {
591         // Determine and write the type which we'll check the pattern against.
592         let decl_ty = self.local_ty(decl.span, decl.hir_id).decl_ty;
593         self.write_ty(decl.hir_id, decl_ty);
594
595         // Type check the initializer.
596         if let Some(ref init) = decl.init {
597             let init_ty = self.check_decl_initializer(decl.hir_id, decl.pat, &init);
598             self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, decl_ty, init_ty);
599         }
600
601         // Does the expected pattern type originate from an expression and what is the span?
602         let (origin_expr, ty_span) = match (decl.ty, decl.init) {
603             (Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
604             (_, Some(init)) => (true, Some(init.span)), // No explicit type; so use the scrutinee.
605             _ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
606         };
607
608         // Type check the pattern. Override if necessary to avoid knock-on errors.
609         self.check_pat_top(&decl.pat, decl_ty, ty_span, origin_expr);
610         let pat_ty = self.node_ty(decl.pat.hir_id);
611         self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, decl_ty, pat_ty);
612     }
613
614     /// Type check a `let` statement.
615     pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
616         self.check_decl(local.into());
617     }
618
619     pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>, is_last: bool) {
620         // Don't do all the complex logic below for `DeclItem`.
621         match stmt.kind {
622             hir::StmtKind::Item(..) => return,
623             hir::StmtKind::Local(..) | hir::StmtKind::Expr(..) | hir::StmtKind::Semi(..) => {}
624         }
625
626         self.warn_if_unreachable(stmt.hir_id, stmt.span, "statement");
627
628         // Hide the outer diverging and `has_errors` flags.
629         let old_diverges = self.diverges.replace(Diverges::Maybe);
630         let old_has_errors = self.has_errors.replace(false);
631
632         match stmt.kind {
633             hir::StmtKind::Local(ref l) => {
634                 self.check_decl_local(&l);
635             }
636             // Ignore for now.
637             hir::StmtKind::Item(_) => {}
638             hir::StmtKind::Expr(ref expr) => {
639                 // Check with expected type of `()`.
640                 self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
641                     if expr.can_have_side_effects() {
642                         self.suggest_semicolon_at_end(expr.span, err);
643                     }
644                 });
645             }
646             hir::StmtKind::Semi(ref expr) => {
647                 // All of this is equivalent to calling `check_expr`, but it is inlined out here
648                 // in order to capture the fact that this `match` is the last statement in its
649                 // function. This is done for better suggestions to remove the `;`.
650                 let expectation = match expr.kind {
651                     hir::ExprKind::Match(..) if is_last => IsLast(stmt.span),
652                     _ => NoExpectation,
653                 };
654                 self.check_expr_with_expectation(expr, expectation);
655             }
656         }
657
658         // Combine the diverging and `has_error` flags.
659         self.diverges.set(self.diverges.get() | old_diverges);
660         self.has_errors.set(self.has_errors.get() | old_has_errors);
661     }
662
663     pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) {
664         let unit = self.tcx.mk_unit();
665         let ty = self.check_block_with_expected(blk, ExpectHasType(unit));
666
667         // if the block produces a `!` value, that can always be
668         // (effectively) coerced to unit.
669         if !ty.is_never() {
670             self.demand_suptype(blk.span, unit, ty);
671         }
672     }
673
674     pub(in super::super) fn check_block_with_expected(
675         &self,
676         blk: &'tcx hir::Block<'tcx>,
677         expected: Expectation<'tcx>,
678     ) -> Ty<'tcx> {
679         let prev = self.ps.replace(self.ps.get().recurse(blk));
680
681         // In some cases, blocks have just one exit, but other blocks
682         // can be targeted by multiple breaks. This can happen both
683         // with labeled blocks as well as when we desugar
684         // a `try { ... }` expression.
685         //
686         // Example 1:
687         //
688         //    'a: { if true { break 'a Err(()); } Ok(()) }
689         //
690         // Here we would wind up with two coercions, one from
691         // `Err(())` and the other from the tail expression
692         // `Ok(())`. If the tail expression is omitted, that's a
693         // "forced unit" -- unless the block diverges, in which
694         // case we can ignore the tail expression (e.g., `'a: {
695         // break 'a 22; }` would not force the type of the block
696         // to be `()`).
697         let tail_expr = blk.expr.as_ref();
698         let coerce_to_ty = expected.coercion_target_type(self, blk.span);
699         let coerce = if blk.targeted_by_break {
700             CoerceMany::new(coerce_to_ty)
701         } else {
702             let tail_expr: &[&hir::Expr<'_>] = match tail_expr {
703                 Some(e) => slice::from_ref(e),
704                 None => &[],
705             };
706             CoerceMany::with_coercion_sites(coerce_to_ty, tail_expr)
707         };
708
709         let prev_diverges = self.diverges.get();
710         let ctxt = BreakableCtxt { coerce: Some(coerce), may_break: false };
711
712         let (ctxt, ()) = self.with_breakable_ctxt(blk.hir_id, ctxt, || {
713             for (pos, s) in blk.stmts.iter().enumerate() {
714                 self.check_stmt(s, blk.stmts.len() - 1 == pos);
715             }
716
717             // check the tail expression **without** holding the
718             // `enclosing_breakables` lock below.
719             let tail_expr_ty = tail_expr.map(|t| self.check_expr_with_expectation(t, expected));
720
721             let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
722             let ctxt = enclosing_breakables.find_breakable(blk.hir_id);
723             let coerce = ctxt.coerce.as_mut().unwrap();
724             if let Some(tail_expr_ty) = tail_expr_ty {
725                 let tail_expr = tail_expr.unwrap();
726                 let span = self.get_expr_coercion_span(tail_expr);
727                 let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
728                 coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
729             } else {
730                 // Subtle: if there is no explicit tail expression,
731                 // that is typically equivalent to a tail expression
732                 // of `()` -- except if the block diverges. In that
733                 // case, there is no value supplied from the tail
734                 // expression (assuming there are no other breaks,
735                 // this implies that the type of the block will be
736                 // `!`).
737                 //
738                 // #41425 -- label the implicit `()` as being the
739                 // "found type" here, rather than the "expected type".
740                 if !self.diverges.get().is_always() {
741                     // #50009 -- Do not point at the entire fn block span, point at the return type
742                     // span, as it is the cause of the requirement, and
743                     // `consider_hint_about_removing_semicolon` will point at the last expression
744                     // if it were a relevant part of the error. This improves usability in editors
745                     // that highlight errors inline.
746                     let mut sp = blk.span;
747                     let mut fn_span = None;
748                     if let Some((decl, ident)) = self.get_parent_fn_decl(blk.hir_id) {
749                         let ret_sp = decl.output.span();
750                         if let Some(block_sp) = self.parent_item_span(blk.hir_id) {
751                             // HACK: on some cases (`ui/liveness/liveness-issue-2163.rs`) the
752                             // output would otherwise be incorrect and even misleading. Make sure
753                             // the span we're aiming at correspond to a `fn` body.
754                             if block_sp == blk.span {
755                                 sp = ret_sp;
756                                 fn_span = Some(ident.span);
757                             }
758                         }
759                     }
760                     coerce.coerce_forced_unit(
761                         self,
762                         &self.misc(sp),
763                         &mut |err| {
764                             if let Some(expected_ty) = expected.only_has_type(self) {
765                                 self.consider_hint_about_removing_semicolon(blk, expected_ty, err);
766                                 if expected_ty == self.tcx.types.bool {
767                                     // If this is caused by a missing `let` in a `while let`,
768                                     // silence this redundant error, as we already emit E0070.
769                                     let parent = self.tcx.hir().get_parent_node(blk.hir_id);
770                                     let parent = self.tcx.hir().get_parent_node(parent);
771                                     let parent = self.tcx.hir().get_parent_node(parent);
772                                     let parent = self.tcx.hir().get_parent_node(parent);
773                                     let parent = self.tcx.hir().get_parent_node(parent);
774                                     match self.tcx.hir().find(parent) {
775                                         Some(hir::Node::Expr(hir::Expr {
776                                             kind: hir::ExprKind::Loop(_, _, hir::LoopSource::While, _),
777                                             ..
778                                         })) => {
779                                             err.delay_as_bug();
780                                         }
781                                         _ => {}
782                                     }
783                                 }
784                             }
785                             if let Some(fn_span) = fn_span {
786                                 err.span_label(
787                                     fn_span,
788                                     "implicitly returns `()` as its body has no tail or `return` \
789                                      expression",
790                                 );
791                             }
792                         },
793                         false,
794                     );
795                 }
796             }
797         });
798
799         if ctxt.may_break {
800             // If we can break from the block, then the block's exit is always reachable
801             // (... as long as the entry is reachable) - regardless of the tail of the block.
802             self.diverges.set(prev_diverges);
803         }
804
805         let mut ty = ctxt.coerce.unwrap().complete(self);
806
807         if self.has_errors.get() || ty.references_error() {
808             ty = self.tcx.ty_error()
809         }
810
811         self.write_ty(blk.hir_id, ty);
812
813         self.ps.set(prev);
814         ty
815     }
816
817     /// A common error is to add an extra semicolon:
818     ///
819     /// ```
820     /// fn foo() -> usize {
821     ///     22;
822     /// }
823     /// ```
824     ///
825     /// This routine checks if the final statement in a block is an
826     /// expression with an explicit semicolon whose type is compatible
827     /// with `expected_ty`. If so, it suggests removing the semicolon.
828     fn consider_hint_about_removing_semicolon(
829         &self,
830         blk: &'tcx hir::Block<'tcx>,
831         expected_ty: Ty<'tcx>,
832         err: &mut DiagnosticBuilder<'_>,
833     ) {
834         if let Some((span_semi, boxed)) = self.could_remove_semicolon(blk, expected_ty) {
835             if let StatementAsExpression::NeedsBoxing = boxed {
836                 err.span_suggestion_verbose(
837                     span_semi,
838                     "consider removing this semicolon and boxing the expression",
839                     String::new(),
840                     Applicability::HasPlaceholders,
841                 );
842             } else {
843                 err.span_suggestion_short(
844                     span_semi,
845                     "consider removing this semicolon",
846                     String::new(),
847                     Applicability::MachineApplicable,
848                 );
849             }
850         }
851     }
852
853     fn parent_item_span(&self, id: hir::HirId) -> Option<Span> {
854         let node = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(id));
855         match node {
856             Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })
857             | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body_id), .. }) => {
858                 let body = self.tcx.hir().body(body_id);
859                 if let ExprKind::Block(block, _) = &body.value.kind {
860                     return Some(block.span);
861                 }
862             }
863             _ => {}
864         }
865         None
866     }
867
868     /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
869     fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
870         let parent = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(blk_id));
871         self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
872     }
873
874     /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
875     /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
876     /// when given code like the following:
877     /// ```text
878     /// if false { return 0i32; } else { 1u32 }
879     /// //                               ^^^^ point at this instead of the whole `if` expression
880     /// ```
881     fn get_expr_coercion_span(&self, expr: &hir::Expr<'_>) -> rustc_span::Span {
882         let check_in_progress = |elem: &hir::Expr<'_>| {
883             self.in_progress_typeck_results
884                 .and_then(|typeck_results| typeck_results.borrow().node_type_opt(elem.hir_id))
885                 .and_then(|ty| {
886                     if ty.is_never() {
887                         None
888                     } else {
889                         Some(match elem.kind {
890                             // Point at the tail expression when possible.
891                             hir::ExprKind::Block(block, _) => {
892                                 block.expr.map_or(block.span, |e| e.span)
893                             }
894                             _ => elem.span,
895                         })
896                     }
897                 })
898         };
899
900         if let hir::ExprKind::If(_, _, Some(el)) = expr.kind {
901             if let Some(rslt) = check_in_progress(el) {
902                 return rslt;
903             }
904         }
905
906         if let hir::ExprKind::Match(_, arms, _) = expr.kind {
907             let mut iter = arms.iter().filter_map(|arm| check_in_progress(arm.body));
908             if let Some(span) = iter.next() {
909                 if iter.next().is_none() {
910                     return span;
911                 }
912             }
913         }
914
915         expr.span
916     }
917
918     fn overwrite_local_ty_if_err(
919         &self,
920         hir_id: hir::HirId,
921         pat: &'tcx hir::Pat<'tcx>,
922         decl_ty: Ty<'tcx>,
923         ty: Ty<'tcx>,
924     ) {
925         if ty.references_error() {
926             // Override the types everywhere with `err()` to avoid knock on errors.
927             self.write_ty(hir_id, ty);
928             self.write_ty(pat.hir_id, ty);
929             let local_ty = LocalTy { decl_ty, revealed_ty: ty };
930             self.locals.borrow_mut().insert(hir_id, local_ty);
931             self.locals.borrow_mut().insert(pat.hir_id, local_ty);
932         }
933     }
934
935     // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
936     // The newly resolved definition is written into `type_dependent_defs`.
937     fn finish_resolving_struct_path(
938         &self,
939         qpath: &QPath<'_>,
940         path_span: Span,
941         hir_id: hir::HirId,
942     ) -> (Res, Ty<'tcx>) {
943         match *qpath {
944             QPath::Resolved(ref maybe_qself, ref path) => {
945                 let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself));
946                 let ty = <dyn AstConv<'_>>::res_to_ty(self, self_ty, path, true);
947                 (path.res, ty)
948             }
949             QPath::TypeRelative(ref qself, ref segment) => {
950                 let ty = self.to_ty(qself);
951
952                 let res = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.kind {
953                     path.res
954                 } else {
955                     Res::Err
956                 };
957                 let result = <dyn AstConv<'_>>::associated_path_to_ty(
958                     self, hir_id, path_span, ty, res, segment, true,
959                 );
960                 let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error());
961                 let result = result.map(|(_, kind, def_id)| (kind, def_id));
962
963                 // Write back the new resolution.
964                 self.write_resolution(hir_id, result);
965
966                 (result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)), ty)
967             }
968             QPath::LangItem(lang_item, span, id) => {
969                 self.resolve_lang_item_path(lang_item, span, hir_id, id)
970             }
971         }
972     }
973
974     /// Given a vec of evaluated `FulfillmentError`s and an `fn` call argument expressions, we walk
975     /// the checked and coerced types for each argument to see if any of the `FulfillmentError`s
976     /// reference a type argument. The reason to walk also the checked type is that the coerced type
977     /// can be not easily comparable with predicate type (because of coercion). If the types match
978     /// for either checked or coerced type, and there's only *one* argument that does, we point at
979     /// the corresponding argument's expression span instead of the `fn` call path span.
980     fn point_at_arg_instead_of_call_if_possible(
981         &self,
982         errors: &mut Vec<traits::FulfillmentError<'tcx>>,
983         final_arg_types: &[Option<(Ty<'tcx>, Ty<'tcx>)>],
984         expr: &'tcx hir::Expr<'tcx>,
985         call_sp: Span,
986         args: &'tcx [hir::Expr<'tcx>],
987     ) {
988         // We *do not* do this for desugared call spans to keep good diagnostics when involving
989         // the `?` operator.
990         if call_sp.desugaring_kind().is_some() {
991             return;
992         }
993
994         for error in errors {
995             // Only if the cause is somewhere inside the expression we want try to point at arg.
996             // Otherwise, it means that the cause is somewhere else and we should not change
997             // anything because we can break the correct span.
998             if !call_sp.contains(error.obligation.cause.span) {
999                 continue;
1000             }
1001
1002             // Peel derived obligation, because it's the type that originally
1003             // started this inference chain that matters, not the one we wound
1004             // up with at the end.
1005             fn unpeel_to_top(
1006                 mut code: Lrc<ObligationCauseCode<'_>>,
1007             ) -> Lrc<ObligationCauseCode<'_>> {
1008                 let mut result_code = code.clone();
1009                 loop {
1010                     let parent = match &*code {
1011                         ObligationCauseCode::BuiltinDerivedObligation(c)
1012                         | ObligationCauseCode::ImplDerivedObligation(c)
1013                         | ObligationCauseCode::DerivedObligation(c) => c.parent_code.clone(),
1014                         _ => break,
1015                     };
1016                     result_code = std::mem::replace(&mut code, parent);
1017                 }
1018                 result_code
1019             }
1020             let self_: ty::subst::GenericArg<'_> = match &*unpeel_to_top(error.obligation.cause.clone_code()) {
1021                 ObligationCauseCode::BuiltinDerivedObligation(code) |
1022                 ObligationCauseCode::ImplDerivedObligation(code) |
1023                 ObligationCauseCode::DerivedObligation(code) => {
1024                     code.parent_trait_pred.self_ty().skip_binder().into()
1025                 }
1026                 _ if let ty::PredicateKind::Trait(predicate) =
1027                     error.obligation.predicate.kind().skip_binder() => {
1028                         predicate.self_ty().into()
1029                     }
1030                 _ =>  continue,
1031             };
1032             let self_ = self.resolve_vars_if_possible(self_);
1033
1034             // Collect the argument position for all arguments that could have caused this
1035             // `FulfillmentError`.
1036             let mut referenced_in = final_arg_types
1037                 .iter()
1038                 .enumerate()
1039                 .filter_map(|(i, arg)| match arg {
1040                     Some((checked_ty, coerce_ty)) => Some([(i, *checked_ty), (i, *coerce_ty)]),
1041                     _ => None,
1042                 })
1043                 .flatten()
1044                 .flat_map(|(i, ty)| {
1045                     let ty = self.resolve_vars_if_possible(ty);
1046                     // We walk the argument type because the argument's type could have
1047                     // been `Option<T>`, but the `FulfillmentError` references `T`.
1048                     if ty.walk().any(|arg| arg == self_) { Some(i) } else { None }
1049                 })
1050                 .collect::<Vec<usize>>();
1051
1052             // Both checked and coerced types could have matched, thus we need to remove
1053             // duplicates.
1054
1055             // We sort primitive type usize here and can use unstable sort
1056             referenced_in.sort_unstable();
1057             referenced_in.dedup();
1058
1059             if let (Some(ref_in), None) = (referenced_in.pop(), referenced_in.pop()) {
1060                 // Do not point at the inside of a macro.
1061                 // That would often result in poor error messages.
1062                 if args[ref_in].span.from_expansion() {
1063                     return;
1064                 }
1065                 // We make sure that only *one* argument matches the obligation failure
1066                 // and we assign the obligation's span to its expression's.
1067                 error.obligation.cause.span = args[ref_in].span;
1068                 let parent_code = error.obligation.cause.clone_code();
1069                 *error.obligation.cause.make_mut_code() =
1070                     ObligationCauseCode::FunctionArgumentObligation {
1071                         arg_hir_id: args[ref_in].hir_id,
1072                         call_hir_id: expr.hir_id,
1073                         parent_code,
1074                     };
1075             } else if error.obligation.cause.span == call_sp {
1076                 // Make function calls point at the callee, not the whole thing.
1077                 if let hir::ExprKind::Call(callee, _) = expr.kind {
1078                     error.obligation.cause.span = callee.span;
1079                 }
1080             }
1081         }
1082     }
1083
1084     /// Given a vec of evaluated `FulfillmentError`s and an `fn` call expression, we walk the
1085     /// `PathSegment`s and resolve their type parameters to see if any of the `FulfillmentError`s
1086     /// were caused by them. If they were, we point at the corresponding type argument's span
1087     /// instead of the `fn` call path span.
1088     fn point_at_type_arg_instead_of_call_if_possible(
1089         &self,
1090         errors: &mut Vec<traits::FulfillmentError<'tcx>>,
1091         call_expr: &'tcx hir::Expr<'tcx>,
1092     ) {
1093         if let hir::ExprKind::Call(path, _) = &call_expr.kind {
1094             if let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = &path.kind {
1095                 for error in errors {
1096                     if let ty::PredicateKind::Trait(predicate) =
1097                         error.obligation.predicate.kind().skip_binder()
1098                     {
1099                         // If any of the type arguments in this path segment caused the
1100                         // `FulfillmentError`, point at its span (#61860).
1101                         for arg in path
1102                             .segments
1103                             .iter()
1104                             .filter_map(|seg| seg.args.as_ref())
1105                             .flat_map(|a| a.args.iter())
1106                         {
1107                             if let hir::GenericArg::Type(hir_ty) = &arg {
1108                                 if let hir::TyKind::Path(hir::QPath::TypeRelative(..)) =
1109                                     &hir_ty.kind
1110                                 {
1111                                     // Avoid ICE with associated types. As this is best
1112                                     // effort only, it's ok to ignore the case. It
1113                                     // would trigger in `is_send::<T::AssocType>();`
1114                                     // from `typeck-default-trait-impl-assoc-type.rs`.
1115                                 } else {
1116                                     let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, hir_ty);
1117                                     let ty = self.resolve_vars_if_possible(ty);
1118                                     if ty == predicate.self_ty() {
1119                                         error.obligation.cause.span = hir_ty.span;
1120                                     }
1121                                 }
1122                             }
1123                         }
1124                     }
1125                 }
1126             }
1127         }
1128     }
1129 }