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