]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/expr.rs
Rollup merge of #75485 - RalfJung:pin, r=nagisa
[rust.git] / src / librustc_typeck / check / expr.rs
1 //! Type checking expressions.
2 //!
3 //! See `mod.rs` for more context on type checking in general.
4
5 use crate::astconv::AstConv as _;
6 use crate::check::cast;
7 use crate::check::coercion::CoerceMany;
8 use crate::check::fatally_break_rust;
9 use crate::check::method::{probe, MethodError, SelfSource};
10 use crate::check::report_unexpected_variant_res;
11 use crate::check::BreakableCtxt;
12 use crate::check::Diverges;
13 use crate::check::Expectation::{self, ExpectCastableToType, ExpectHasType, NoExpectation};
14 use crate::check::FnCtxt;
15 use crate::check::Needs;
16 use crate::check::TupleArgumentsFlag::DontTupleArguments;
17 use crate::type_error_struct;
18
19 use rustc_ast::ast;
20 use rustc_ast::util::lev_distance::find_best_match_for_name;
21 use rustc_data_structures::fx::FxHashMap;
22 use rustc_data_structures::stack::ensure_sufficient_stack;
23 use rustc_errors::ErrorReported;
24 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId};
25 use rustc_hir as hir;
26 use rustc_hir::def::{CtorKind, DefKind, Res};
27 use rustc_hir::def_id::DefId;
28 use rustc_hir::lang_items;
29 use rustc_hir::{ExprKind, QPath};
30 use rustc_infer::infer;
31 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
32 use rustc_middle::ty;
33 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
34 use rustc_middle::ty::Ty;
35 use rustc_middle::ty::TypeFoldable;
36 use rustc_middle::ty::{AdtKind, Visibility};
37 use rustc_span::hygiene::DesugaringKind;
38 use rustc_span::source_map::Span;
39 use rustc_span::symbol::{kw, sym, Ident, Symbol};
40 use rustc_trait_selection::traits::{self, ObligationCauseCode};
41
42 use std::fmt::Display;
43
44 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
45     fn check_expr_eq_type(&self, expr: &'tcx hir::Expr<'tcx>, expected: Ty<'tcx>) {
46         let ty = self.check_expr_with_hint(expr, expected);
47         self.demand_eqtype(expr.span, expected, ty);
48     }
49
50     pub fn check_expr_has_type_or_error(
51         &self,
52         expr: &'tcx hir::Expr<'tcx>,
53         expected: Ty<'tcx>,
54         extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
55     ) -> Ty<'tcx> {
56         self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected), extend_err)
57     }
58
59     fn check_expr_meets_expectation_or_error(
60         &self,
61         expr: &'tcx hir::Expr<'tcx>,
62         expected: Expectation<'tcx>,
63         extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
64     ) -> Ty<'tcx> {
65         let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
66         let mut ty = self.check_expr_with_expectation(expr, expected);
67
68         // While we don't allow *arbitrary* coercions here, we *do* allow
69         // coercions from ! to `expected`.
70         if ty.is_never() {
71             assert!(
72                 !self.typeck_results.borrow().adjustments().contains_key(expr.hir_id),
73                 "expression with never type wound up being adjusted"
74             );
75             let adj_ty = self.next_diverging_ty_var(TypeVariableOrigin {
76                 kind: TypeVariableOriginKind::AdjustmentType,
77                 span: expr.span,
78             });
79             self.apply_adjustments(
80                 expr,
81                 vec![Adjustment { kind: Adjust::NeverToAny, target: adj_ty }],
82             );
83             ty = adj_ty;
84         }
85
86         if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) {
87             let expr = expr.peel_drop_temps();
88             self.suggest_deref_ref_or_into(&mut err, expr, expected_ty, ty, None);
89             extend_err(&mut err);
90             // Error possibly reported in `check_assign` so avoid emitting error again.
91             err.emit_unless(self.is_assign_to_bool(expr, expected_ty));
92         }
93         ty
94     }
95
96     pub(super) fn check_expr_coercable_to_type(
97         &self,
98         expr: &'tcx hir::Expr<'tcx>,
99         expected: Ty<'tcx>,
100         expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
101     ) -> Ty<'tcx> {
102         let ty = self.check_expr_with_hint(expr, expected);
103         // checks don't need two phase
104         self.demand_coerce(expr, ty, expected, expected_ty_expr, AllowTwoPhase::No)
105     }
106
107     pub(super) fn check_expr_with_hint(
108         &self,
109         expr: &'tcx hir::Expr<'tcx>,
110         expected: Ty<'tcx>,
111     ) -> Ty<'tcx> {
112         self.check_expr_with_expectation(expr, ExpectHasType(expected))
113     }
114
115     fn check_expr_with_expectation_and_needs(
116         &self,
117         expr: &'tcx hir::Expr<'tcx>,
118         expected: Expectation<'tcx>,
119         needs: Needs,
120     ) -> Ty<'tcx> {
121         let ty = self.check_expr_with_expectation(expr, expected);
122
123         // If the expression is used in a place whether mutable place is required
124         // e.g. LHS of assignment, perform the conversion.
125         if let Needs::MutPlace = needs {
126             self.convert_place_derefs_to_mutable(expr);
127         }
128
129         ty
130     }
131
132     pub(super) fn check_expr(&self, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> {
133         self.check_expr_with_expectation(expr, NoExpectation)
134     }
135
136     pub(super) fn check_expr_with_needs(
137         &self,
138         expr: &'tcx hir::Expr<'tcx>,
139         needs: Needs,
140     ) -> Ty<'tcx> {
141         self.check_expr_with_expectation_and_needs(expr, NoExpectation, needs)
142     }
143
144     /// Invariant:
145     /// If an expression has any sub-expressions that result in a type error,
146     /// inspecting that expression's type with `ty.references_error()` will return
147     /// true. Likewise, if an expression is known to diverge, inspecting its
148     /// type with `ty::type_is_bot` will return true (n.b.: since Rust is
149     /// strict, _|_ can appear in the type of an expression that does not,
150     /// itself, diverge: for example, fn() -> _|_.)
151     /// Note that inspecting a type's structure *directly* may expose the fact
152     /// that there are actually multiple representations for `Error`, so avoid
153     /// that when err needs to be handled differently.
154     pub(super) fn check_expr_with_expectation(
155         &self,
156         expr: &'tcx hir::Expr<'tcx>,
157         expected: Expectation<'tcx>,
158     ) -> Ty<'tcx> {
159         debug!(">> type-checking: expr={:?} expected={:?}", expr, expected);
160
161         // True if `expr` is a `Try::from_ok(())` that is a result of desugaring a try block
162         // without the final expr (e.g. `try { return; }`). We don't want to generate an
163         // unreachable_code lint for it since warnings for autogenerated code are confusing.
164         let is_try_block_generated_unit_expr = match expr.kind {
165             ExprKind::Call(_, ref args) if expr.span.is_desugaring(DesugaringKind::TryBlock) => {
166                 args.len() == 1 && args[0].span.is_desugaring(DesugaringKind::TryBlock)
167             }
168
169             _ => false,
170         };
171
172         // Warn for expressions after diverging siblings.
173         if !is_try_block_generated_unit_expr {
174             self.warn_if_unreachable(expr.hir_id, expr.span, "expression");
175         }
176
177         // Hide the outer diverging and has_errors flags.
178         let old_diverges = self.diverges.replace(Diverges::Maybe);
179         let old_has_errors = self.has_errors.replace(false);
180
181         let ty = ensure_sufficient_stack(|| self.check_expr_kind(expr, expected));
182
183         // Warn for non-block expressions with diverging children.
184         match expr.kind {
185             ExprKind::Block(..) | ExprKind::Loop(..) | ExprKind::Match(..) => {}
186             // If `expr` is a result of desugaring the try block and is an ok-wrapped
187             // diverging expression (e.g. it arose from desugaring of `try { return }`),
188             // we skip issuing a warning because it is autogenerated code.
189             ExprKind::Call(..) if expr.span.is_desugaring(DesugaringKind::TryBlock) => {}
190             ExprKind::Call(ref callee, _) => {
191                 self.warn_if_unreachable(expr.hir_id, callee.span, "call")
192             }
193             ExprKind::MethodCall(_, ref span, _, _) => {
194                 self.warn_if_unreachable(expr.hir_id, *span, "call")
195             }
196             _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression"),
197         }
198
199         // Any expression that produces a value of type `!` must have diverged
200         if ty.is_never() {
201             self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
202         }
203
204         // Record the type, which applies it effects.
205         // We need to do this after the warning above, so that
206         // we don't warn for the diverging expression itself.
207         self.write_ty(expr.hir_id, ty);
208
209         // Combine the diverging and has_error flags.
210         self.diverges.set(self.diverges.get() | old_diverges);
211         self.has_errors.set(self.has_errors.get() | old_has_errors);
212
213         debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id));
214         debug!("... {:?}, expected is {:?}", ty, expected);
215
216         ty
217     }
218
219     fn check_expr_kind(
220         &self,
221         expr: &'tcx hir::Expr<'tcx>,
222         expected: Expectation<'tcx>,
223     ) -> Ty<'tcx> {
224         debug!("check_expr_kind(expr={:?}, expected={:?})", expr, expected);
225
226         let tcx = self.tcx;
227         match expr.kind {
228             ExprKind::Box(ref subexpr) => self.check_expr_box(subexpr, expected),
229             ExprKind::Lit(ref lit) => self.check_lit(&lit, expected),
230             ExprKind::Binary(op, ref lhs, ref rhs) => self.check_binop(expr, op, lhs, rhs),
231             ExprKind::Assign(ref lhs, ref rhs, ref span) => {
232                 self.check_expr_assign(expr, expected, lhs, rhs, span)
233             }
234             ExprKind::AssignOp(op, ref lhs, ref rhs) => self.check_binop_assign(expr, op, lhs, rhs),
235             ExprKind::Unary(unop, ref oprnd) => self.check_expr_unary(unop, oprnd, expected, expr),
236             ExprKind::AddrOf(kind, mutbl, ref oprnd) => {
237                 self.check_expr_addr_of(kind, mutbl, oprnd, expected, expr)
238             }
239             ExprKind::Path(ref qpath) => self.check_expr_path(qpath, expr),
240             ExprKind::InlineAsm(asm) => self.check_expr_asm(asm),
241             ExprKind::LlvmInlineAsm(ref asm) => {
242                 for expr in asm.outputs_exprs.iter().chain(asm.inputs_exprs.iter()) {
243                     self.check_expr(expr);
244                 }
245                 tcx.mk_unit()
246             }
247             ExprKind::Break(destination, ref expr_opt) => {
248                 self.check_expr_break(destination, expr_opt.as_deref(), expr)
249             }
250             ExprKind::Continue(destination) => {
251                 if destination.target_id.is_ok() {
252                     tcx.types.never
253                 } else {
254                     // There was an error; make type-check fail.
255                     tcx.ty_error()
256                 }
257             }
258             ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr),
259             ExprKind::Loop(ref body, _, source) => {
260                 self.check_expr_loop(body, source, expected, expr)
261             }
262             ExprKind::Match(ref discrim, ref arms, match_src) => {
263                 self.check_match(expr, &discrim, arms, expected, match_src)
264             }
265             ExprKind::Closure(capture, ref decl, body_id, _, gen) => {
266                 self.check_expr_closure(expr, capture, &decl, body_id, gen, expected)
267             }
268             ExprKind::Block(ref body, _) => self.check_block_with_expected(&body, expected),
269             ExprKind::Call(ref callee, ref args) => self.check_call(expr, &callee, args, expected),
270             ExprKind::MethodCall(ref segment, span, ref args, _) => {
271                 self.check_method_call(expr, segment, span, args, expected)
272             }
273             ExprKind::Cast(ref e, ref t) => self.check_expr_cast(e, t, expr),
274             ExprKind::Type(ref e, ref t) => {
275                 let ty = self.to_ty_saving_user_provided_ty(&t);
276                 self.check_expr_eq_type(&e, ty);
277                 ty
278             }
279             ExprKind::DropTemps(ref e) => self.check_expr_with_expectation(e, expected),
280             ExprKind::Array(ref args) => self.check_expr_array(args, expected, expr),
281             ExprKind::Repeat(ref element, ref count) => {
282                 self.check_expr_repeat(element, count, expected, expr)
283             }
284             ExprKind::Tup(ref elts) => self.check_expr_tuple(elts, expected, expr),
285             ExprKind::Struct(ref qpath, fields, ref base_expr) => {
286                 self.check_expr_struct(expr, expected, qpath, fields, base_expr)
287             }
288             ExprKind::Field(ref base, field) => self.check_field(expr, &base, field),
289             ExprKind::Index(ref base, ref idx) => self.check_expr_index(base, idx, expr),
290             ExprKind::Yield(ref value, ref src) => self.check_expr_yield(value, expr, src),
291             hir::ExprKind::Err => tcx.ty_error(),
292         }
293     }
294
295     fn check_expr_box(&self, expr: &'tcx hir::Expr<'tcx>, expected: Expectation<'tcx>) -> Ty<'tcx> {
296         let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| match ty.kind {
297             ty::Adt(def, _) if def.is_box() => Expectation::rvalue_hint(self, ty.boxed_ty()),
298             _ => NoExpectation,
299         });
300         let referent_ty = self.check_expr_with_expectation(expr, expected_inner);
301         self.tcx.mk_box(referent_ty)
302     }
303
304     fn check_expr_unary(
305         &self,
306         unop: hir::UnOp,
307         oprnd: &'tcx hir::Expr<'tcx>,
308         expected: Expectation<'tcx>,
309         expr: &'tcx hir::Expr<'tcx>,
310     ) -> Ty<'tcx> {
311         let tcx = self.tcx;
312         let expected_inner = match unop {
313             hir::UnOp::UnNot | hir::UnOp::UnNeg => expected,
314             hir::UnOp::UnDeref => NoExpectation,
315         };
316         let mut oprnd_t = self.check_expr_with_expectation(&oprnd, expected_inner);
317
318         if !oprnd_t.references_error() {
319             oprnd_t = self.structurally_resolved_type(expr.span, oprnd_t);
320             match unop {
321                 hir::UnOp::UnDeref => {
322                     if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) {
323                         oprnd_t = ty;
324                     } else {
325                         let mut err = type_error_struct!(
326                             tcx.sess,
327                             expr.span,
328                             oprnd_t,
329                             E0614,
330                             "type `{}` cannot be dereferenced",
331                             oprnd_t,
332                         );
333                         let sp = tcx.sess.source_map().start_point(expr.span);
334                         if let Some(sp) =
335                             tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp)
336                         {
337                             tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp, None);
338                         }
339                         err.emit();
340                         oprnd_t = tcx.ty_error();
341                     }
342                 }
343                 hir::UnOp::UnNot => {
344                     let result = self.check_user_unop(expr, oprnd_t, unop);
345                     // If it's builtin, we can reuse the type, this helps inference.
346                     if !(oprnd_t.is_integral() || oprnd_t.kind == ty::Bool) {
347                         oprnd_t = result;
348                     }
349                 }
350                 hir::UnOp::UnNeg => {
351                     let result = self.check_user_unop(expr, oprnd_t, unop);
352                     // If it's builtin, we can reuse the type, this helps inference.
353                     if !oprnd_t.is_numeric() {
354                         oprnd_t = result;
355                     }
356                 }
357             }
358         }
359         oprnd_t
360     }
361
362     fn check_expr_addr_of(
363         &self,
364         kind: hir::BorrowKind,
365         mutbl: hir::Mutability,
366         oprnd: &'tcx hir::Expr<'tcx>,
367         expected: Expectation<'tcx>,
368         expr: &'tcx hir::Expr<'tcx>,
369     ) -> Ty<'tcx> {
370         let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
371             match ty.kind {
372                 ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => {
373                     if oprnd.is_syntactic_place_expr() {
374                         // Places may legitimately have unsized types.
375                         // For example, dereferences of a fat pointer and
376                         // the last field of a struct can be unsized.
377                         ExpectHasType(ty)
378                     } else {
379                         Expectation::rvalue_hint(self, ty)
380                     }
381                 }
382                 _ => NoExpectation,
383             }
384         });
385         let ty =
386             self.check_expr_with_expectation_and_needs(&oprnd, hint, Needs::maybe_mut_place(mutbl));
387
388         let tm = ty::TypeAndMut { ty, mutbl };
389         match kind {
390             _ if tm.ty.references_error() => self.tcx.ty_error(),
391             hir::BorrowKind::Raw => {
392                 self.check_named_place_expr(oprnd);
393                 self.tcx.mk_ptr(tm)
394             }
395             hir::BorrowKind::Ref => {
396                 // Note: at this point, we cannot say what the best lifetime
397                 // is to use for resulting pointer.  We want to use the
398                 // shortest lifetime possible so as to avoid spurious borrowck
399                 // errors.  Moreover, the longest lifetime will depend on the
400                 // precise details of the value whose address is being taken
401                 // (and how long it is valid), which we don't know yet until
402                 // type inference is complete.
403                 //
404                 // Therefore, here we simply generate a region variable. The
405                 // region inferencer will then select a suitable value.
406                 // Finally, borrowck will infer the value of the region again,
407                 // this time with enough precision to check that the value
408                 // whose address was taken can actually be made to live as long
409                 // as it needs to live.
410                 let region = self.next_region_var(infer::AddrOfRegion(expr.span));
411                 self.tcx.mk_ref(region, tm)
412             }
413         }
414     }
415
416     /// Does this expression refer to a place that either:
417     /// * Is based on a local or static.
418     /// * Contains a dereference
419     /// Note that the adjustments for the children of `expr` should already
420     /// have been resolved.
421     fn check_named_place_expr(&self, oprnd: &'tcx hir::Expr<'tcx>) {
422         let is_named = oprnd.is_place_expr(|base| {
423             // Allow raw borrows if there are any deref adjustments.
424             //
425             // const VAL: (i32,) = (0,);
426             // const REF: &(i32,) = &(0,);
427             //
428             // &raw const VAL.0;            // ERROR
429             // &raw const REF.0;            // OK, same as &raw const (*REF).0;
430             //
431             // This is maybe too permissive, since it allows
432             // `let u = &raw const Box::new((1,)).0`, which creates an
433             // immediately dangling raw pointer.
434             self.typeck_results.borrow().adjustments().get(base.hir_id).map_or(false, |x| {
435                 x.iter().any(|adj| if let Adjust::Deref(_) = adj.kind { true } else { false })
436             })
437         });
438         if !is_named {
439             struct_span_err!(
440                 self.tcx.sess,
441                 oprnd.span,
442                 E0745,
443                 "cannot take address of a temporary"
444             )
445             .span_label(oprnd.span, "temporary value")
446             .emit();
447         }
448     }
449
450     fn check_expr_path(&self, qpath: &hir::QPath<'_>, expr: &'tcx hir::Expr<'tcx>) -> Ty<'tcx> {
451         let tcx = self.tcx;
452         let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span);
453         let ty = match res {
454             Res::Err => {
455                 self.set_tainted_by_errors();
456                 tcx.ty_error()
457             }
458             Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
459                 report_unexpected_variant_res(tcx, res, expr.span);
460                 tcx.ty_error()
461             }
462             _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
463         };
464
465         if let ty::FnDef(..) = ty.kind {
466             let fn_sig = ty.fn_sig(tcx);
467             if !tcx.features().unsized_locals {
468                 // We want to remove some Sized bounds from std functions,
469                 // but don't want to expose the removal to stable Rust.
470                 // i.e., we don't want to allow
471                 //
472                 // ```rust
473                 // drop as fn(str);
474                 // ```
475                 //
476                 // to work in stable even if the Sized bound on `drop` is relaxed.
477                 for i in 0..fn_sig.inputs().skip_binder().len() {
478                     // We just want to check sizedness, so instead of introducing
479                     // placeholder lifetimes with probing, we just replace higher lifetimes
480                     // with fresh vars.
481                     let input = self
482                         .replace_bound_vars_with_fresh_vars(
483                             expr.span,
484                             infer::LateBoundRegionConversionTime::FnCall,
485                             &fn_sig.input(i),
486                         )
487                         .0;
488                     self.require_type_is_sized_deferred(
489                         input,
490                         expr.span,
491                         traits::SizedArgumentType(None),
492                     );
493                 }
494             }
495             // Here we want to prevent struct constructors from returning unsized types.
496             // There were two cases this happened: fn pointer coercion in stable
497             // and usual function call in presence of unsized_locals.
498             // Also, as we just want to check sizedness, instead of introducing
499             // placeholder lifetimes with probing, we just replace higher lifetimes
500             // with fresh vars.
501             let output = self
502                 .replace_bound_vars_with_fresh_vars(
503                     expr.span,
504                     infer::LateBoundRegionConversionTime::FnCall,
505                     &fn_sig.output(),
506                 )
507                 .0;
508             self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
509         }
510
511         // We always require that the type provided as the value for
512         // a type parameter outlives the moment of instantiation.
513         let substs = self.typeck_results.borrow().node_substs(expr.hir_id);
514         self.add_wf_bounds(substs, expr);
515
516         ty
517     }
518
519     fn check_expr_break(
520         &self,
521         destination: hir::Destination,
522         expr_opt: Option<&'tcx hir::Expr<'tcx>>,
523         expr: &'tcx hir::Expr<'tcx>,
524     ) -> Ty<'tcx> {
525         let tcx = self.tcx;
526         if let Ok(target_id) = destination.target_id {
527             let (e_ty, cause);
528             if let Some(ref e) = expr_opt {
529                 // If this is a break with a value, we need to type-check
530                 // the expression. Get an expected type from the loop context.
531                 let opt_coerce_to = {
532                     // We should release `enclosing_breakables` before the `check_expr_with_hint`
533                     // below, so can't move this block of code to the enclosing scope and share
534                     // `ctxt` with the second `encloding_breakables` borrow below.
535                     let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
536                     match enclosing_breakables.opt_find_breakable(target_id) {
537                         Some(ctxt) => ctxt.coerce.as_ref().map(|coerce| coerce.expected_ty()),
538                         None => {
539                             // Avoid ICE when `break` is inside a closure (#65383).
540                             return tcx.ty_error_with_message(
541                                 expr.span,
542                                 "break was outside loop, but no error was emitted",
543                             );
544                         }
545                     }
546                 };
547
548                 // If the loop context is not a `loop { }`, then break with
549                 // a value is illegal, and `opt_coerce_to` will be `None`.
550                 // Just set expectation to error in that case.
551                 let coerce_to = opt_coerce_to.unwrap_or_else(|| tcx.ty_error());
552
553                 // Recurse without `enclosing_breakables` borrowed.
554                 e_ty = self.check_expr_with_hint(e, coerce_to);
555                 cause = self.misc(e.span);
556             } else {
557                 // Otherwise, this is a break *without* a value. That's
558                 // always legal, and is equivalent to `break ()`.
559                 e_ty = tcx.mk_unit();
560                 cause = self.misc(expr.span);
561             }
562
563             // Now that we have type-checked `expr_opt`, borrow
564             // the `enclosing_loops` field and let's coerce the
565             // type of `expr_opt` into what is expected.
566             let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
567             let ctxt = match enclosing_breakables.opt_find_breakable(target_id) {
568                 Some(ctxt) => ctxt,
569                 None => {
570                     // Avoid ICE when `break` is inside a closure (#65383).
571                     return tcx.ty_error_with_message(
572                         expr.span,
573                         "break was outside loop, but no error was emitted",
574                     );
575                 }
576             };
577
578             if let Some(ref mut coerce) = ctxt.coerce {
579                 if let Some(ref e) = expr_opt {
580                     coerce.coerce(self, &cause, e, e_ty);
581                 } else {
582                     assert!(e_ty.is_unit());
583                     let ty = coerce.expected_ty();
584                     coerce.coerce_forced_unit(
585                         self,
586                         &cause,
587                         &mut |mut err| {
588                             self.suggest_mismatched_types_on_tail(
589                                 &mut err, expr, ty, e_ty, cause.span, target_id,
590                             );
591                             if let Some(val) = ty_kind_suggestion(ty) {
592                                 let label = destination
593                                     .label
594                                     .map(|l| format!(" {}", l.ident))
595                                     .unwrap_or_else(String::new);
596                                 err.span_suggestion(
597                                     expr.span,
598                                     "give it a value of the expected type",
599                                     format!("break{} {}", label, val),
600                                     Applicability::HasPlaceholders,
601                                 );
602                             }
603                         },
604                         false,
605                     );
606                 }
607             } else {
608                 // If `ctxt.coerce` is `None`, we can just ignore
609                 // the type of the expression.  This is because
610                 // either this was a break *without* a value, in
611                 // which case it is always a legal type (`()`), or
612                 // else an error would have been flagged by the
613                 // `loops` pass for using break with an expression
614                 // where you are not supposed to.
615                 assert!(expr_opt.is_none() || self.tcx.sess.has_errors());
616             }
617
618             ctxt.may_break = true;
619
620             // the type of a `break` is always `!`, since it diverges
621             tcx.types.never
622         } else {
623             // Otherwise, we failed to find the enclosing loop;
624             // this can only happen if the `break` was not
625             // inside a loop at all, which is caught by the
626             // loop-checking pass.
627             let err = self.tcx.ty_error_with_message(
628                 expr.span,
629                 "break was outside loop, but no error was emitted",
630             );
631
632             // We still need to assign a type to the inner expression to
633             // prevent the ICE in #43162.
634             if let Some(ref e) = expr_opt {
635                 self.check_expr_with_hint(e, err);
636
637                 // ... except when we try to 'break rust;'.
638                 // ICE this expression in particular (see #43162).
639                 if let ExprKind::Path(QPath::Resolved(_, ref path)) = e.kind {
640                     if path.segments.len() == 1 && path.segments[0].ident.name == sym::rust {
641                         fatally_break_rust(self.tcx.sess);
642                     }
643                 }
644             }
645
646             // There was an error; make type-check fail.
647             err
648         }
649     }
650
651     fn check_expr_return(
652         &self,
653         expr_opt: Option<&'tcx hir::Expr<'tcx>>,
654         expr: &'tcx hir::Expr<'tcx>,
655     ) -> Ty<'tcx> {
656         if self.ret_coercion.is_none() {
657             struct_span_err!(
658                 self.tcx.sess,
659                 expr.span,
660                 E0572,
661                 "return statement outside of function body",
662             )
663             .emit();
664         } else if let Some(ref e) = expr_opt {
665             if self.ret_coercion_span.borrow().is_none() {
666                 *self.ret_coercion_span.borrow_mut() = Some(e.span);
667             }
668             self.check_return_expr(e);
669         } else {
670             let mut coercion = self.ret_coercion.as_ref().unwrap().borrow_mut();
671             if self.ret_coercion_span.borrow().is_none() {
672                 *self.ret_coercion_span.borrow_mut() = Some(expr.span);
673             }
674             let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
675             if let Some((fn_decl, _)) = self.get_fn_decl(expr.hir_id) {
676                 coercion.coerce_forced_unit(
677                     self,
678                     &cause,
679                     &mut |db| {
680                         let span = fn_decl.output.span();
681                         if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
682                             db.span_label(
683                                 span,
684                                 format!("expected `{}` because of this return type", snippet),
685                             );
686                         }
687                     },
688                     true,
689                 );
690             } else {
691                 coercion.coerce_forced_unit(self, &cause, &mut |_| (), true);
692             }
693         }
694         self.tcx.types.never
695     }
696
697     pub(super) fn check_return_expr(&self, return_expr: &'tcx hir::Expr<'tcx>) {
698         let ret_coercion = self.ret_coercion.as_ref().unwrap_or_else(|| {
699             span_bug!(return_expr.span, "check_return_expr called outside fn body")
700         });
701
702         let ret_ty = ret_coercion.borrow().expected_ty();
703         let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
704         ret_coercion.borrow_mut().coerce(
705             self,
706             &self.cause(return_expr.span, ObligationCauseCode::ReturnValue(return_expr.hir_id)),
707             return_expr,
708             return_expr_ty,
709         );
710     }
711
712     fn is_destructuring_place_expr(&self, expr: &'tcx hir::Expr<'tcx>) -> bool {
713         match &expr.kind {
714             ExprKind::Array(comps) | ExprKind::Tup(comps) => {
715                 comps.iter().all(|e| self.is_destructuring_place_expr(e))
716             }
717             ExprKind::Struct(_path, fields, rest) => {
718                 rest.as_ref().map(|e| self.is_destructuring_place_expr(e)).unwrap_or(true)
719                     && fields.iter().all(|f| self.is_destructuring_place_expr(&f.expr))
720             }
721             _ => expr.is_syntactic_place_expr(),
722         }
723     }
724
725     pub(crate) fn check_lhs_assignable(
726         &self,
727         lhs: &'tcx hir::Expr<'tcx>,
728         err_code: &'static str,
729         expr_span: &Span,
730     ) {
731         if !lhs.is_syntactic_place_expr() {
732             let mut err = self.tcx.sess.struct_span_err_with_code(
733                 *expr_span,
734                 "invalid left-hand side of assignment",
735                 DiagnosticId::Error(err_code.into()),
736             );
737             err.span_label(lhs.span, "cannot assign to this expression");
738             if self.is_destructuring_place_expr(lhs) {
739                 err.note("destructuring assignments are not currently supported");
740                 err.note("for more information, see https://github.com/rust-lang/rfcs/issues/372");
741             }
742             err.emit();
743         }
744     }
745
746     /// Type check assignment expression `expr` of form `lhs = rhs`.
747     /// The expected type is `()` and is passsed to the function for the purposes of diagnostics.
748     fn check_expr_assign(
749         &self,
750         expr: &'tcx hir::Expr<'tcx>,
751         expected: Expectation<'tcx>,
752         lhs: &'tcx hir::Expr<'tcx>,
753         rhs: &'tcx hir::Expr<'tcx>,
754         span: &Span,
755     ) -> Ty<'tcx> {
756         let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
757         let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs));
758
759         let expected_ty = expected.coercion_target_type(self, expr.span);
760         if expected_ty == self.tcx.types.bool {
761             // The expected type is `bool` but this will result in `()` so we can reasonably
762             // say that the user intended to write `lhs == rhs` instead of `lhs = rhs`.
763             // The likely cause of this is `if foo = bar { .. }`.
764             let actual_ty = self.tcx.mk_unit();
765             let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
766             let msg = "try comparing for equality";
767             let left = self.tcx.sess.source_map().span_to_snippet(lhs.span);
768             let right = self.tcx.sess.source_map().span_to_snippet(rhs.span);
769             if let (Ok(left), Ok(right)) = (left, right) {
770                 let help = format!("{} == {}", left, right);
771                 err.span_suggestion(expr.span, msg, help, Applicability::MaybeIncorrect);
772             } else {
773                 err.help(msg);
774             }
775             err.emit();
776         } else {
777             self.check_lhs_assignable(lhs, "E0070", span);
778         }
779
780         self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized);
781
782         if lhs_ty.references_error() || rhs_ty.references_error() {
783             self.tcx.ty_error()
784         } else {
785             self.tcx.mk_unit()
786         }
787     }
788
789     fn check_expr_loop(
790         &self,
791         body: &'tcx hir::Block<'tcx>,
792         source: hir::LoopSource,
793         expected: Expectation<'tcx>,
794         expr: &'tcx hir::Expr<'tcx>,
795     ) -> Ty<'tcx> {
796         let coerce = match source {
797             // you can only use break with a value from a normal `loop { }`
798             hir::LoopSource::Loop => {
799                 let coerce_to = expected.coercion_target_type(self, body.span);
800                 Some(CoerceMany::new(coerce_to))
801             }
802
803             hir::LoopSource::While | hir::LoopSource::WhileLet | hir::LoopSource::ForLoop => None,
804         };
805
806         let ctxt = BreakableCtxt {
807             coerce,
808             may_break: false, // Will get updated if/when we find a `break`.
809         };
810
811         let (ctxt, ()) = self.with_breakable_ctxt(expr.hir_id, ctxt, || {
812             self.check_block_no_value(&body);
813         });
814
815         if ctxt.may_break {
816             // No way to know whether it's diverging because
817             // of a `break` or an outer `break` or `return`.
818             self.diverges.set(Diverges::Maybe);
819         }
820
821         // If we permit break with a value, then result type is
822         // the LUB of the breaks (possibly ! if none); else, it
823         // is nil. This makes sense because infinite loops
824         // (which would have type !) are only possible iff we
825         // permit break with a value [1].
826         if ctxt.coerce.is_none() && !ctxt.may_break {
827             // [1]
828             self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break");
829         }
830         ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| self.tcx.mk_unit())
831     }
832
833     /// Checks a method call.
834     fn check_method_call(
835         &self,
836         expr: &'tcx hir::Expr<'tcx>,
837         segment: &hir::PathSegment<'_>,
838         span: Span,
839         args: &'tcx [hir::Expr<'tcx>],
840         expected: Expectation<'tcx>,
841     ) -> Ty<'tcx> {
842         let rcvr = &args[0];
843         let rcvr_t = self.check_expr(&rcvr);
844         // no need to check for bot/err -- callee does that
845         let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
846
847         let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) {
848             Ok(method) => {
849                 // We could add a "consider `foo::<params>`" suggestion here, but I wasn't able to
850                 // trigger this codepath causing `structuraly_resolved_type` to emit an error.
851
852                 self.write_method_call(expr.hir_id, method);
853                 Ok(method)
854             }
855             Err(error) => {
856                 if segment.ident.name != kw::Invalid {
857                     self.report_extended_method_error(segment, span, args, rcvr_t, error);
858                 }
859                 Err(())
860             }
861         };
862
863         // Call the generic checker.
864         self.check_method_argument_types(
865             span,
866             expr,
867             method,
868             &args[1..],
869             DontTupleArguments,
870             expected,
871         )
872     }
873
874     fn report_extended_method_error(
875         &self,
876         segment: &hir::PathSegment<'_>,
877         span: Span,
878         args: &'tcx [hir::Expr<'tcx>],
879         rcvr_t: Ty<'tcx>,
880         error: MethodError<'tcx>,
881     ) {
882         let rcvr = &args[0];
883         let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| {
884             if let Some(new_rcvr_t) = new_rcvr_t {
885                 if let Ok(pick) = self.lookup_probe(
886                     span,
887                     segment.ident,
888                     new_rcvr_t,
889                     rcvr,
890                     probe::ProbeScope::AllTraits,
891                 ) {
892                     debug!("try_alt_rcvr: pick candidate {:?}", pick);
893                     // Make sure the method is defined for the *actual* receiver:
894                     // we don't want to treat `Box<Self>` as a receiver if
895                     // it only works because of an autoderef to `&self`
896                     if pick.autoderefs == 0 {
897                         err.span_label(
898                             pick.item.ident.span,
899                             &format!("the method is available for `{}` here", new_rcvr_t),
900                         );
901                     }
902                 }
903             }
904         };
905
906         if let Some(mut err) = self.report_method_error(
907             span,
908             rcvr_t,
909             segment.ident,
910             SelfSource::MethodCall(rcvr),
911             error,
912             Some(args),
913         ) {
914             if let ty::Adt(..) = rcvr_t.kind {
915                 // Try alternative arbitrary self types that could fulfill this call.
916                 // FIXME: probe for all types that *could* be arbitrary self-types, not
917                 // just this list.
918                 try_alt_rcvr(&mut err, self.tcx.mk_lang_item(rcvr_t, lang_items::OwnedBoxLangItem));
919                 try_alt_rcvr(&mut err, self.tcx.mk_lang_item(rcvr_t, lang_items::PinTypeLangItem));
920                 try_alt_rcvr(&mut err, self.tcx.mk_diagnostic_item(rcvr_t, sym::Arc));
921                 try_alt_rcvr(&mut err, self.tcx.mk_diagnostic_item(rcvr_t, sym::Rc));
922             }
923             err.emit();
924         }
925     }
926
927     fn check_expr_cast(
928         &self,
929         e: &'tcx hir::Expr<'tcx>,
930         t: &'tcx hir::Ty<'tcx>,
931         expr: &'tcx hir::Expr<'tcx>,
932     ) -> Ty<'tcx> {
933         // Find the type of `e`. Supply hints based on the type we are casting to,
934         // if appropriate.
935         let t_cast = self.to_ty_saving_user_provided_ty(t);
936         let t_cast = self.resolve_vars_if_possible(&t_cast);
937         let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
938         let t_cast = self.resolve_vars_if_possible(&t_cast);
939
940         // Eagerly check for some obvious errors.
941         if t_expr.references_error() || t_cast.references_error() {
942             self.tcx.ty_error()
943         } else {
944             // Defer other checks until we're done type checking.
945             let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut();
946             match cast::CastCheck::new(self, e, t_expr, t_cast, t.span, expr.span) {
947                 Ok(cast_check) => {
948                     deferred_cast_checks.push(cast_check);
949                     t_cast
950                 }
951                 Err(ErrorReported) => self.tcx.ty_error(),
952             }
953         }
954     }
955
956     fn check_expr_array(
957         &self,
958         args: &'tcx [hir::Expr<'tcx>],
959         expected: Expectation<'tcx>,
960         expr: &'tcx hir::Expr<'tcx>,
961     ) -> Ty<'tcx> {
962         let element_ty = if !args.is_empty() {
963             let coerce_to = expected
964                 .to_option(self)
965                 .and_then(|uty| match uty.kind {
966                     ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
967                     _ => None,
968                 })
969                 .unwrap_or_else(|| {
970                     self.next_ty_var(TypeVariableOrigin {
971                         kind: TypeVariableOriginKind::TypeInference,
972                         span: expr.span,
973                     })
974                 });
975             let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
976             assert_eq!(self.diverges.get(), Diverges::Maybe);
977             for e in args {
978                 let e_ty = self.check_expr_with_hint(e, coerce_to);
979                 let cause = self.misc(e.span);
980                 coerce.coerce(self, &cause, e, e_ty);
981             }
982             coerce.complete(self)
983         } else {
984             self.next_ty_var(TypeVariableOrigin {
985                 kind: TypeVariableOriginKind::TypeInference,
986                 span: expr.span,
987             })
988         };
989         self.tcx.mk_array(element_ty, args.len() as u64)
990     }
991
992     fn check_expr_repeat(
993         &self,
994         element: &'tcx hir::Expr<'tcx>,
995         count: &'tcx hir::AnonConst,
996         expected: Expectation<'tcx>,
997         _expr: &'tcx hir::Expr<'tcx>,
998     ) -> Ty<'tcx> {
999         let tcx = self.tcx;
1000         let count = self.to_const(count);
1001
1002         let uty = match expected {
1003             ExpectHasType(uty) => match uty.kind {
1004                 ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
1005                 _ => None,
1006             },
1007             _ => None,
1008         };
1009
1010         let (element_ty, t) = match uty {
1011             Some(uty) => {
1012                 self.check_expr_coercable_to_type(&element, uty, None);
1013                 (uty, uty)
1014             }
1015             None => {
1016                 let ty = self.next_ty_var(TypeVariableOrigin {
1017                     kind: TypeVariableOriginKind::MiscVariable,
1018                     span: element.span,
1019                 });
1020                 let element_ty = self.check_expr_has_type_or_error(&element, ty, |_| {});
1021                 (element_ty, ty)
1022             }
1023         };
1024
1025         if element_ty.references_error() {
1026             return tcx.ty_error();
1027         }
1028
1029         tcx.mk_ty(ty::Array(t, count))
1030     }
1031
1032     fn check_expr_tuple(
1033         &self,
1034         elts: &'tcx [hir::Expr<'tcx>],
1035         expected: Expectation<'tcx>,
1036         expr: &'tcx hir::Expr<'tcx>,
1037     ) -> Ty<'tcx> {
1038         let flds = expected.only_has_type(self).and_then(|ty| {
1039             let ty = self.resolve_vars_with_obligations(ty);
1040             match ty.kind {
1041                 ty::Tuple(ref flds) => Some(&flds[..]),
1042                 _ => None,
1043             }
1044         });
1045
1046         let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| match flds {
1047             Some(ref fs) if i < fs.len() => {
1048                 let ety = fs[i].expect_ty();
1049                 self.check_expr_coercable_to_type(&e, ety, None);
1050                 ety
1051             }
1052             _ => self.check_expr_with_expectation(&e, NoExpectation),
1053         });
1054         let tuple = self.tcx.mk_tup(elt_ts_iter);
1055         if tuple.references_error() {
1056             self.tcx.ty_error()
1057         } else {
1058             self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized);
1059             tuple
1060         }
1061     }
1062
1063     fn check_expr_struct(
1064         &self,
1065         expr: &hir::Expr<'_>,
1066         expected: Expectation<'tcx>,
1067         qpath: &QPath<'_>,
1068         fields: &'tcx [hir::Field<'tcx>],
1069         base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
1070     ) -> Ty<'tcx> {
1071         // Find the relevant variant
1072         let (variant, adt_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, expr.hir_id)
1073         {
1074             variant_ty
1075         } else {
1076             self.check_struct_fields_on_error(fields, base_expr);
1077             return self.tcx.ty_error();
1078         };
1079
1080         let path_span = match *qpath {
1081             QPath::Resolved(_, ref path) => path.span,
1082             QPath::TypeRelative(ref qself, _) => qself.span,
1083         };
1084
1085         // Prohibit struct expressions when non-exhaustive flag is set.
1086         let adt = adt_ty.ty_adt_def().expect("`check_struct_path` returned non-ADT type");
1087         if !adt.did.is_local() && variant.is_field_list_non_exhaustive() {
1088             struct_span_err!(
1089                 self.tcx.sess,
1090                 expr.span,
1091                 E0639,
1092                 "cannot create non-exhaustive {} using struct expression",
1093                 adt.variant_descr()
1094             )
1095             .emit();
1096         }
1097
1098         let error_happened = self.check_expr_struct_fields(
1099             adt_ty,
1100             expected,
1101             expr.hir_id,
1102             path_span,
1103             variant,
1104             fields,
1105             base_expr.is_none(),
1106         );
1107         if let &Some(ref base_expr) = base_expr {
1108             // If check_expr_struct_fields hit an error, do not attempt to populate
1109             // the fields with the base_expr. This could cause us to hit errors later
1110             // when certain fields are assumed to exist that in fact do not.
1111             if !error_happened {
1112                 self.check_expr_has_type_or_error(base_expr, adt_ty, |_| {});
1113                 match adt_ty.kind {
1114                     ty::Adt(adt, substs) if adt.is_struct() => {
1115                         let fru_field_types = adt
1116                             .non_enum_variant()
1117                             .fields
1118                             .iter()
1119                             .map(|f| {
1120                                 self.normalize_associated_types_in(
1121                                     expr.span,
1122                                     &f.ty(self.tcx, substs),
1123                                 )
1124                             })
1125                             .collect();
1126
1127                         self.typeck_results
1128                             .borrow_mut()
1129                             .fru_field_types_mut()
1130                             .insert(expr.hir_id, fru_field_types);
1131                     }
1132                     _ => {
1133                         struct_span_err!(
1134                             self.tcx.sess,
1135                             base_expr.span,
1136                             E0436,
1137                             "functional record update syntax requires a struct"
1138                         )
1139                         .emit();
1140                     }
1141                 }
1142             }
1143         }
1144         self.require_type_is_sized(adt_ty, expr.span, traits::StructInitializerSized);
1145         adt_ty
1146     }
1147
1148     fn check_expr_struct_fields(
1149         &self,
1150         adt_ty: Ty<'tcx>,
1151         expected: Expectation<'tcx>,
1152         expr_id: hir::HirId,
1153         span: Span,
1154         variant: &'tcx ty::VariantDef,
1155         ast_fields: &'tcx [hir::Field<'tcx>],
1156         check_completeness: bool,
1157     ) -> bool {
1158         let tcx = self.tcx;
1159
1160         let adt_ty_hint = self
1161             .expected_inputs_for_expected_output(span, expected, adt_ty, &[adt_ty])
1162             .get(0)
1163             .cloned()
1164             .unwrap_or(adt_ty);
1165         // re-link the regions that EIfEO can erase.
1166         self.demand_eqtype(span, adt_ty_hint, adt_ty);
1167
1168         let (substs, adt_kind, kind_name) = match &adt_ty.kind {
1169             &ty::Adt(adt, substs) => (substs, adt.adt_kind(), adt.variant_descr()),
1170             _ => span_bug!(span, "non-ADT passed to check_expr_struct_fields"),
1171         };
1172
1173         let mut remaining_fields = variant
1174             .fields
1175             .iter()
1176             .enumerate()
1177             .map(|(i, field)| (field.ident.normalize_to_macros_2_0(), (i, field)))
1178             .collect::<FxHashMap<_, _>>();
1179
1180         let mut seen_fields = FxHashMap::default();
1181
1182         let mut error_happened = false;
1183
1184         // Type-check each field.
1185         for field in ast_fields {
1186             let ident = tcx.adjust_ident(field.ident, variant.def_id);
1187             let field_type = if let Some((i, v_field)) = remaining_fields.remove(&ident) {
1188                 seen_fields.insert(ident, field.span);
1189                 self.write_field_index(field.hir_id, i);
1190
1191                 // We don't look at stability attributes on
1192                 // struct-like enums (yet...), but it's definitely not
1193                 // a bug to have constructed one.
1194                 if adt_kind != AdtKind::Enum {
1195                     tcx.check_stability(v_field.did, Some(expr_id), field.span);
1196                 }
1197
1198                 self.field_ty(field.span, v_field, substs)
1199             } else {
1200                 error_happened = true;
1201                 if let Some(prev_span) = seen_fields.get(&ident) {
1202                     let mut err = struct_span_err!(
1203                         self.tcx.sess,
1204                         field.ident.span,
1205                         E0062,
1206                         "field `{}` specified more than once",
1207                         ident
1208                     );
1209
1210                     err.span_label(field.ident.span, "used more than once");
1211                     err.span_label(*prev_span, format!("first use of `{}`", ident));
1212
1213                     err.emit();
1214                 } else {
1215                     self.report_unknown_field(adt_ty, variant, field, ast_fields, kind_name, span);
1216                 }
1217
1218                 tcx.ty_error()
1219             };
1220
1221             // Make sure to give a type to the field even if there's
1222             // an error, so we can continue type-checking.
1223             self.check_expr_coercable_to_type(&field.expr, field_type, None);
1224         }
1225
1226         // Make sure the programmer specified correct number of fields.
1227         if kind_name == "union" {
1228             if ast_fields.len() != 1 {
1229                 tcx.sess.span_err(span, "union expressions should have exactly one field");
1230             }
1231         } else if check_completeness && !error_happened && !remaining_fields.is_empty() {
1232             let len = remaining_fields.len();
1233
1234             let mut displayable_field_names =
1235                 remaining_fields.keys().map(|ident| ident.as_str()).collect::<Vec<_>>();
1236
1237             displayable_field_names.sort();
1238
1239             let truncated_fields_error = if len <= 3 {
1240                 String::new()
1241             } else {
1242                 format!(" and {} other field{}", (len - 3), if len - 3 == 1 { "" } else { "s" })
1243             };
1244
1245             let remaining_fields_names = displayable_field_names
1246                 .iter()
1247                 .take(3)
1248                 .map(|n| format!("`{}`", n))
1249                 .collect::<Vec<_>>()
1250                 .join(", ");
1251
1252             struct_span_err!(
1253                 tcx.sess,
1254                 span,
1255                 E0063,
1256                 "missing field{} {}{} in initializer of `{}`",
1257                 pluralize!(remaining_fields.len()),
1258                 remaining_fields_names,
1259                 truncated_fields_error,
1260                 adt_ty
1261             )
1262             .span_label(
1263                 span,
1264                 format!("missing {}{}", remaining_fields_names, truncated_fields_error),
1265             )
1266             .emit();
1267         }
1268         error_happened
1269     }
1270
1271     fn check_struct_fields_on_error(
1272         &self,
1273         fields: &'tcx [hir::Field<'tcx>],
1274         base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
1275     ) {
1276         for field in fields {
1277             self.check_expr(&field.expr);
1278         }
1279         if let Some(ref base) = *base_expr {
1280             self.check_expr(&base);
1281         }
1282     }
1283
1284     fn report_unknown_field(
1285         &self,
1286         ty: Ty<'tcx>,
1287         variant: &'tcx ty::VariantDef,
1288         field: &hir::Field<'_>,
1289         skip_fields: &[hir::Field<'_>],
1290         kind_name: &str,
1291         ty_span: Span,
1292     ) {
1293         if variant.recovered {
1294             self.set_tainted_by_errors();
1295             return;
1296         }
1297         let mut err = self.type_error_struct_with_diag(
1298             field.ident.span,
1299             |actual| match ty.kind {
1300                 ty::Adt(adt, ..) if adt.is_enum() => struct_span_err!(
1301                     self.tcx.sess,
1302                     field.ident.span,
1303                     E0559,
1304                     "{} `{}::{}` has no field named `{}`",
1305                     kind_name,
1306                     actual,
1307                     variant.ident,
1308                     field.ident
1309                 ),
1310                 _ => struct_span_err!(
1311                     self.tcx.sess,
1312                     field.ident.span,
1313                     E0560,
1314                     "{} `{}` has no field named `{}`",
1315                     kind_name,
1316                     actual,
1317                     field.ident
1318                 ),
1319             },
1320             ty,
1321         );
1322         match variant.ctor_kind {
1323             CtorKind::Fn => {
1324                 err.span_label(variant.ident.span, format!("`{adt}` defined here", adt = ty));
1325                 err.span_label(field.ident.span, "field does not exist");
1326                 err.span_label(
1327                     ty_span,
1328                     format!(
1329                         "`{adt}` is a tuple {kind_name}, \
1330                          use the appropriate syntax: `{adt}(/* fields */)`",
1331                         adt = ty,
1332                         kind_name = kind_name
1333                     ),
1334                 );
1335             }
1336             _ => {
1337                 // prevent all specified fields from being suggested
1338                 let skip_fields = skip_fields.iter().map(|ref x| x.ident.name);
1339                 if let Some(field_name) =
1340                     Self::suggest_field_name(variant, field.ident.name, skip_fields.collect())
1341                 {
1342                     err.span_suggestion(
1343                         field.ident.span,
1344                         "a field with a similar name exists",
1345                         field_name.to_string(),
1346                         Applicability::MaybeIncorrect,
1347                     );
1348                 } else {
1349                     match ty.kind {
1350                         ty::Adt(adt, ..) => {
1351                             if adt.is_enum() {
1352                                 err.span_label(
1353                                     field.ident.span,
1354                                     format!("`{}::{}` does not have this field", ty, variant.ident),
1355                                 );
1356                             } else {
1357                                 err.span_label(
1358                                     field.ident.span,
1359                                     format!("`{}` does not have this field", ty),
1360                                 );
1361                             }
1362                             let available_field_names = self.available_field_names(variant);
1363                             if !available_field_names.is_empty() {
1364                                 err.note(&format!(
1365                                     "available fields are: {}",
1366                                     self.name_series_display(available_field_names)
1367                                 ));
1368                             }
1369                         }
1370                         _ => bug!("non-ADT passed to report_unknown_field"),
1371                     }
1372                 };
1373             }
1374         }
1375         err.emit();
1376     }
1377
1378     // Return an hint about the closest match in field names
1379     fn suggest_field_name(
1380         variant: &'tcx ty::VariantDef,
1381         field: Symbol,
1382         skip: Vec<Symbol>,
1383     ) -> Option<Symbol> {
1384         let names = variant.fields.iter().filter_map(|field| {
1385             // ignore already set fields and private fields from non-local crates
1386             if skip.iter().any(|&x| x == field.ident.name)
1387                 || (!variant.def_id.is_local() && field.vis != Visibility::Public)
1388             {
1389                 None
1390             } else {
1391                 Some(&field.ident.name)
1392             }
1393         });
1394
1395         find_best_match_for_name(names, field, None)
1396     }
1397
1398     fn available_field_names(&self, variant: &'tcx ty::VariantDef) -> Vec<Symbol> {
1399         variant
1400             .fields
1401             .iter()
1402             .filter(|field| {
1403                 let def_scope = self
1404                     .tcx
1405                     .adjust_ident_and_get_scope(field.ident, variant.def_id, self.body_id)
1406                     .1;
1407                 field.vis.is_accessible_from(def_scope, self.tcx)
1408             })
1409             .map(|field| field.ident.name)
1410             .collect()
1411     }
1412
1413     fn name_series_display(&self, names: Vec<Symbol>) -> String {
1414         // dynamic limit, to never omit just one field
1415         let limit = if names.len() == 6 { 6 } else { 5 };
1416         let mut display =
1417             names.iter().take(limit).map(|n| format!("`{}`", n)).collect::<Vec<_>>().join(", ");
1418         if names.len() > limit {
1419             display = format!("{} ... and {} others", display, names.len() - limit);
1420         }
1421         display
1422     }
1423
1424     // Check field access expressions
1425     fn check_field(
1426         &self,
1427         expr: &'tcx hir::Expr<'tcx>,
1428         base: &'tcx hir::Expr<'tcx>,
1429         field: Ident,
1430     ) -> Ty<'tcx> {
1431         let expr_t = self.check_expr(base);
1432         let expr_t = self.structurally_resolved_type(base.span, expr_t);
1433         let mut private_candidate = None;
1434         let mut autoderef = self.autoderef(expr.span, expr_t);
1435         while let Some((base_t, _)) = autoderef.next() {
1436             match base_t.kind {
1437                 ty::Adt(base_def, substs) if !base_def.is_enum() => {
1438                     debug!("struct named {:?}", base_t);
1439                     let (ident, def_scope) =
1440                         self.tcx.adjust_ident_and_get_scope(field, base_def.did, self.body_id);
1441                     let fields = &base_def.non_enum_variant().fields;
1442                     if let Some(index) =
1443                         fields.iter().position(|f| f.ident.normalize_to_macros_2_0() == ident)
1444                     {
1445                         let field = &fields[index];
1446                         let field_ty = self.field_ty(expr.span, field, substs);
1447                         // Save the index of all fields regardless of their visibility in case
1448                         // of error recovery.
1449                         self.write_field_index(expr.hir_id, index);
1450                         if field.vis.is_accessible_from(def_scope, self.tcx) {
1451                             let adjustments = self.adjust_steps(&autoderef);
1452                             self.apply_adjustments(base, adjustments);
1453                             self.register_predicates(autoderef.into_obligations());
1454
1455                             self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span);
1456                             return field_ty;
1457                         }
1458                         private_candidate = Some((base_def.did, field_ty));
1459                     }
1460                 }
1461                 ty::Tuple(ref tys) => {
1462                     let fstr = field.as_str();
1463                     if let Ok(index) = fstr.parse::<usize>() {
1464                         if fstr == index.to_string() {
1465                             if let Some(field_ty) = tys.get(index) {
1466                                 let adjustments = self.adjust_steps(&autoderef);
1467                                 self.apply_adjustments(base, adjustments);
1468                                 self.register_predicates(autoderef.into_obligations());
1469
1470                                 self.write_field_index(expr.hir_id, index);
1471                                 return field_ty.expect_ty();
1472                             }
1473                         }
1474                     }
1475                 }
1476                 _ => {}
1477             }
1478         }
1479         self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
1480
1481         if let Some((did, field_ty)) = private_candidate {
1482             self.ban_private_field_access(expr, expr_t, field, did);
1483             return field_ty;
1484         }
1485
1486         if field.name == kw::Invalid {
1487         } else if self.method_exists(field, expr_t, expr.hir_id, true) {
1488             self.ban_take_value_of_method(expr, expr_t, field);
1489         } else if !expr_t.is_primitive_ty() {
1490             self.ban_nonexisting_field(field, base, expr, expr_t);
1491         } else {
1492             type_error_struct!(
1493                 self.tcx().sess,
1494                 field.span,
1495                 expr_t,
1496                 E0610,
1497                 "`{}` is a primitive type and therefore doesn't have fields",
1498                 expr_t
1499             )
1500             .emit();
1501         }
1502
1503         self.tcx().ty_error()
1504     }
1505
1506     fn ban_nonexisting_field(
1507         &self,
1508         field: Ident,
1509         base: &'tcx hir::Expr<'tcx>,
1510         expr: &'tcx hir::Expr<'tcx>,
1511         expr_t: Ty<'tcx>,
1512     ) {
1513         let mut err = self.no_such_field_err(field.span, field, expr_t);
1514
1515         match expr_t.peel_refs().kind {
1516             ty::Array(_, len) => {
1517                 self.maybe_suggest_array_indexing(&mut err, expr, base, field, len);
1518             }
1519             ty::RawPtr(..) => {
1520                 self.suggest_first_deref_field(&mut err, expr, base, field);
1521             }
1522             ty::Adt(def, _) if !def.is_enum() => {
1523                 self.suggest_fields_on_recordish(&mut err, def, field);
1524             }
1525             ty::Param(param_ty) => {
1526                 self.point_at_param_definition(&mut err, param_ty);
1527             }
1528             _ => {}
1529         }
1530
1531         if field.name == kw::Await {
1532             // We know by construction that `<expr>.await` is either on Rust 2015
1533             // or results in `ExprKind::Await`. Suggest switching the edition to 2018.
1534             err.note("to `.await` a `Future`, switch to Rust 2018");
1535             err.help("set `edition = \"2018\"` in `Cargo.toml`");
1536             err.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
1537         }
1538
1539         err.emit();
1540     }
1541
1542     fn ban_private_field_access(
1543         &self,
1544         expr: &hir::Expr<'_>,
1545         expr_t: Ty<'tcx>,
1546         field: Ident,
1547         base_did: DefId,
1548     ) {
1549         let struct_path = self.tcx().def_path_str(base_did);
1550         let kind_name = self.tcx().def_kind(base_did).descr(base_did);
1551         let mut err = struct_span_err!(
1552             self.tcx().sess,
1553             field.span,
1554             E0616,
1555             "field `{}` of {} `{}` is private",
1556             field,
1557             kind_name,
1558             struct_path
1559         );
1560         err.span_label(field.span, "private field");
1561         // Also check if an accessible method exists, which is often what is meant.
1562         if self.method_exists(field, expr_t, expr.hir_id, false) && !self.expr_in_place(expr.hir_id)
1563         {
1564             self.suggest_method_call(
1565                 &mut err,
1566                 &format!("a method `{}` also exists, call it with parentheses", field),
1567                 field,
1568                 expr_t,
1569                 expr,
1570             );
1571         }
1572         err.emit();
1573     }
1574
1575     fn ban_take_value_of_method(&self, expr: &hir::Expr<'_>, expr_t: Ty<'tcx>, field: Ident) {
1576         let mut err = type_error_struct!(
1577             self.tcx().sess,
1578             field.span,
1579             expr_t,
1580             E0615,
1581             "attempted to take value of method `{}` on type `{}`",
1582             field,
1583             expr_t
1584         );
1585         err.span_label(field.span, "method, not a field");
1586         if !self.expr_in_place(expr.hir_id) {
1587             self.suggest_method_call(
1588                 &mut err,
1589                 "use parentheses to call the method",
1590                 field,
1591                 expr_t,
1592                 expr,
1593             );
1594         } else {
1595             err.help("methods are immutable and cannot be assigned to");
1596         }
1597
1598         err.emit();
1599     }
1600
1601     fn point_at_param_definition(&self, err: &mut DiagnosticBuilder<'_>, param: ty::ParamTy) {
1602         let generics = self.tcx.generics_of(self.body_id.owner.to_def_id());
1603         let generic_param = generics.type_param(&param, self.tcx);
1604         if let ty::GenericParamDefKind::Type { synthetic: Some(..), .. } = generic_param.kind {
1605             return;
1606         }
1607         let param_def_id = generic_param.def_id;
1608         let param_hir_id = match param_def_id.as_local() {
1609             Some(x) => self.tcx.hir().local_def_id_to_hir_id(x),
1610             None => return,
1611         };
1612         let param_span = self.tcx.hir().span(param_hir_id);
1613         let param_name = self.tcx.hir().ty_param_name(param_hir_id);
1614
1615         err.span_label(param_span, &format!("type parameter '{}' declared here", param_name));
1616     }
1617
1618     fn suggest_fields_on_recordish(
1619         &self,
1620         err: &mut DiagnosticBuilder<'_>,
1621         def: &'tcx ty::AdtDef,
1622         field: Ident,
1623     ) {
1624         if let Some(suggested_field_name) =
1625             Self::suggest_field_name(def.non_enum_variant(), field.name, vec![])
1626         {
1627             err.span_suggestion(
1628                 field.span,
1629                 "a field with a similar name exists",
1630                 suggested_field_name.to_string(),
1631                 Applicability::MaybeIncorrect,
1632             );
1633         } else {
1634             err.span_label(field.span, "unknown field");
1635             let struct_variant_def = def.non_enum_variant();
1636             let field_names = self.available_field_names(struct_variant_def);
1637             if !field_names.is_empty() {
1638                 err.note(&format!(
1639                     "available fields are: {}",
1640                     self.name_series_display(field_names),
1641                 ));
1642             }
1643         }
1644     }
1645
1646     fn maybe_suggest_array_indexing(
1647         &self,
1648         err: &mut DiagnosticBuilder<'_>,
1649         expr: &hir::Expr<'_>,
1650         base: &hir::Expr<'_>,
1651         field: Ident,
1652         len: &ty::Const<'tcx>,
1653     ) {
1654         if let (Some(len), Ok(user_index)) =
1655             (len.try_eval_usize(self.tcx, self.param_env), field.as_str().parse::<u64>())
1656         {
1657             if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
1658                 let help = "instead of using tuple indexing, use array indexing";
1659                 let suggestion = format!("{}[{}]", base, field);
1660                 let applicability = if len < user_index {
1661                     Applicability::MachineApplicable
1662                 } else {
1663                     Applicability::MaybeIncorrect
1664                 };
1665                 err.span_suggestion(expr.span, help, suggestion, applicability);
1666             }
1667         }
1668     }
1669
1670     fn suggest_first_deref_field(
1671         &self,
1672         err: &mut DiagnosticBuilder<'_>,
1673         expr: &hir::Expr<'_>,
1674         base: &hir::Expr<'_>,
1675         field: Ident,
1676     ) {
1677         if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) {
1678             let msg = format!("`{}` is a raw pointer; try dereferencing it", base);
1679             let suggestion = format!("(*{}).{}", base, field);
1680             err.span_suggestion(expr.span, &msg, suggestion, Applicability::MaybeIncorrect);
1681         }
1682     }
1683
1684     fn no_such_field_err<T: Display>(
1685         &self,
1686         span: Span,
1687         field: T,
1688         expr_t: &ty::TyS<'_>,
1689     ) -> DiagnosticBuilder<'_> {
1690         type_error_struct!(
1691             self.tcx().sess,
1692             span,
1693             expr_t,
1694             E0609,
1695             "no field `{}` on type `{}`",
1696             field,
1697             expr_t
1698         )
1699     }
1700
1701     fn check_expr_index(
1702         &self,
1703         base: &'tcx hir::Expr<'tcx>,
1704         idx: &'tcx hir::Expr<'tcx>,
1705         expr: &'tcx hir::Expr<'tcx>,
1706     ) -> Ty<'tcx> {
1707         let base_t = self.check_expr(&base);
1708         let idx_t = self.check_expr(&idx);
1709
1710         if base_t.references_error() {
1711             base_t
1712         } else if idx_t.references_error() {
1713             idx_t
1714         } else {
1715             let base_t = self.structurally_resolved_type(base.span, base_t);
1716             match self.lookup_indexing(expr, base, base_t, idx_t) {
1717                 Some((index_ty, element_ty)) => {
1718                     // two-phase not needed because index_ty is never mutable
1719                     self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);
1720                     element_ty
1721                 }
1722                 None => {
1723                     let mut err = type_error_struct!(
1724                         self.tcx.sess,
1725                         expr.span,
1726                         base_t,
1727                         E0608,
1728                         "cannot index into a value of type `{}`",
1729                         base_t
1730                     );
1731                     // Try to give some advice about indexing tuples.
1732                     if let ty::Tuple(..) = base_t.kind {
1733                         let mut needs_note = true;
1734                         // If the index is an integer, we can show the actual
1735                         // fixed expression:
1736                         if let ExprKind::Lit(ref lit) = idx.kind {
1737                             if let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node {
1738                                 let snip = self.tcx.sess.source_map().span_to_snippet(base.span);
1739                                 if let Ok(snip) = snip {
1740                                     err.span_suggestion(
1741                                         expr.span,
1742                                         "to access tuple elements, use",
1743                                         format!("{}.{}", snip, i),
1744                                         Applicability::MachineApplicable,
1745                                     );
1746                                     needs_note = false;
1747                                 }
1748                             }
1749                         }
1750                         if needs_note {
1751                             err.help(
1752                                 "to access tuple elements, use tuple indexing \
1753                                         syntax (e.g., `tuple.0`)",
1754                             );
1755                         }
1756                     }
1757                     err.emit();
1758                     self.tcx.ty_error()
1759                 }
1760             }
1761         }
1762     }
1763
1764     fn check_expr_yield(
1765         &self,
1766         value: &'tcx hir::Expr<'tcx>,
1767         expr: &'tcx hir::Expr<'tcx>,
1768         src: &'tcx hir::YieldSource,
1769     ) -> Ty<'tcx> {
1770         match self.resume_yield_tys {
1771             Some((resume_ty, yield_ty)) => {
1772                 self.check_expr_coercable_to_type(&value, yield_ty, None);
1773
1774                 resume_ty
1775             }
1776             // Given that this `yield` expression was generated as a result of lowering a `.await`,
1777             // we know that the yield type must be `()`; however, the context won't contain this
1778             // information. Hence, we check the source of the yield expression here and check its
1779             // value's type against `()` (this check should always hold).
1780             None if src.is_await() => {
1781                 self.check_expr_coercable_to_type(&value, self.tcx.mk_unit(), None);
1782                 self.tcx.mk_unit()
1783             }
1784             _ => {
1785                 struct_span_err!(
1786                     self.tcx.sess,
1787                     expr.span,
1788                     E0627,
1789                     "yield expression outside of generator literal"
1790                 )
1791                 .emit();
1792                 self.tcx.mk_unit()
1793             }
1794         }
1795     }
1796
1797     fn check_expr_asm_operand(&self, expr: &'tcx hir::Expr<'tcx>, is_input: bool) {
1798         let needs = if is_input { Needs::None } else { Needs::MutPlace };
1799         let ty = self.check_expr_with_needs(expr, needs);
1800         self.require_type_is_sized(ty, expr.span, traits::InlineAsmSized);
1801
1802         if !is_input && !expr.is_syntactic_place_expr() {
1803             let mut err = self.tcx.sess.struct_span_err(expr.span, "invalid asm output");
1804             err.span_label(expr.span, "cannot assign to this expression");
1805             err.emit();
1806         }
1807
1808         // If this is an input value, we require its type to be fully resolved
1809         // at this point. This allows us to provide helpful coercions which help
1810         // pass the type candidate list in a later pass.
1811         //
1812         // We don't require output types to be resolved at this point, which
1813         // allows them to be inferred based on how they are used later in the
1814         // function.
1815         if is_input {
1816             let ty = self.structurally_resolved_type(expr.span, &ty);
1817             match ty.kind {
1818                 ty::FnDef(..) => {
1819                     let fnptr_ty = self.tcx.mk_fn_ptr(ty.fn_sig(self.tcx));
1820                     self.demand_coerce(expr, ty, fnptr_ty, None, AllowTwoPhase::No);
1821                 }
1822                 ty::Ref(_, base_ty, mutbl) => {
1823                     let ptr_ty = self.tcx.mk_ptr(ty::TypeAndMut { ty: base_ty, mutbl });
1824                     self.demand_coerce(expr, ty, ptr_ty, None, AllowTwoPhase::No);
1825                 }
1826                 _ => {}
1827             }
1828         }
1829     }
1830
1831     fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
1832         for op in asm.operands {
1833             match op {
1834                 hir::InlineAsmOperand::In { expr, .. } | hir::InlineAsmOperand::Const { expr } => {
1835                     self.check_expr_asm_operand(expr, true);
1836                 }
1837                 hir::InlineAsmOperand::Out { expr, .. } => {
1838                     if let Some(expr) = expr {
1839                         self.check_expr_asm_operand(expr, false);
1840                     }
1841                 }
1842                 hir::InlineAsmOperand::InOut { expr, .. } => {
1843                     self.check_expr_asm_operand(expr, false);
1844                 }
1845                 hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
1846                     self.check_expr_asm_operand(in_expr, true);
1847                     if let Some(out_expr) = out_expr {
1848                         self.check_expr_asm_operand(out_expr, false);
1849                     }
1850                 }
1851                 hir::InlineAsmOperand::Sym { expr } => {
1852                     self.check_expr(expr);
1853                 }
1854             }
1855         }
1856         if asm.options.contains(ast::InlineAsmOptions::NORETURN) {
1857             self.tcx.types.never
1858         } else {
1859             self.tcx.mk_unit()
1860         }
1861     }
1862 }
1863
1864 pub(super) fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
1865     Some(match ty.kind {
1866         ty::Bool => "true",
1867         ty::Char => "'a'",
1868         ty::Int(_) | ty::Uint(_) => "42",
1869         ty::Float(_) => "3.14159",
1870         ty::Error(_) | ty::Never => return None,
1871         _ => "value",
1872     })
1873 }