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