]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/mod.rs
Allow combining -Cprofile-generate and -Cpanic=unwind when targeting
[rust.git] / compiler / rustc_typeck / src / check / mod.rs
1 /*!
2
3 # typeck: check phase
4
5 Within the check phase of type check, we check each item one at a time
6 (bodies of function expressions are checked as part of the containing
7 function). Inference is used to supply types wherever they are unknown.
8
9 By far the most complex case is checking the body of a function. This
10 can be broken down into several distinct phases:
11
12 - gather: creates type variables to represent the type of each local
13   variable and pattern binding.
14
15 - main: the main pass does the lion's share of the work: it
16   determines the types of all expressions, resolves
17   methods, checks for most invalid conditions, and so forth.  In
18   some cases, where a type is unknown, it may create a type or region
19   variable and use that as the type of an expression.
20
21   In the process of checking, various constraints will be placed on
22   these type variables through the subtyping relationships requested
23   through the `demand` module.  The `infer` module is in charge
24   of resolving those constraints.
25
26 - regionck: after main is complete, the regionck pass goes over all
27   types looking for regions and making sure that they did not escape
28   into places they are not in scope.  This may also influence the
29   final assignments of the various region variables if there is some
30   flexibility.
31
32 - writeback: writes the final types within a function body, replacing
33   type variables with their final inferred types.  These final types
34   are written into the `tcx.node_types` table, which should *never* contain
35   any reference to a type variable.
36
37 ## Intermediate types
38
39 While type checking a function, the intermediate types for the
40 expressions, blocks, and so forth contained within the function are
41 stored in `fcx.node_types` and `fcx.node_substs`.  These types
42 may contain unresolved type variables.  After type checking is
43 complete, the functions in the writeback module are used to take the
44 types from this table, resolve them, and then write them into their
45 permanent home in the type context `tcx`.
46
47 This means that during inferencing you should use `fcx.write_ty()`
48 and `fcx.expr_ty()` / `fcx.node_ty()` to write/obtain the types of
49 nodes within the function.
50
51 The types of top-level items, which never contain unbound type
52 variables, are stored directly into the `tcx` typeck_results.
53
54 N.B., a type variable is not the same thing as a type parameter.  A
55 type variable is an instance of a type parameter. That is,
56 given a generic function `fn foo<T>(t: T)`, while checking the
57 function `foo`, the type `ty_param(0)` refers to the type `T`, which
58 is treated in abstract. However, when `foo()` is called, `T` will be
59 substituted for a fresh type variable `N`.  This variable will
60 eventually be resolved to some concrete type (which might itself be
61 a type parameter).
62
63 */
64
65 pub mod _match;
66 mod autoderef;
67 mod callee;
68 pub mod cast;
69 mod check;
70 mod closure;
71 pub mod coercion;
72 mod compare_method;
73 pub mod demand;
74 mod diverges;
75 pub mod dropck;
76 mod expectation;
77 mod expr;
78 mod fn_ctxt;
79 mod gather_locals;
80 mod generator_interior;
81 mod inherited;
82 pub mod intrinsic;
83 pub mod method;
84 mod op;
85 mod pat;
86 mod place_op;
87 mod regionck;
88 mod upvar;
89 mod wfcheck;
90 pub mod writeback;
91
92 use check::{
93     check_abi, check_fn, check_impl_item_well_formed, check_item_well_formed, check_mod_item_types,
94     check_trait_item_well_formed,
95 };
96 pub use check::{check_item_type, check_wf_new};
97 pub use diverges::Diverges;
98 pub use expectation::Expectation;
99 pub use fn_ctxt::*;
100 pub use inherited::{Inherited, InheritedBuilder};
101
102 use crate::astconv::AstConv;
103 use crate::check::gather_locals::GatherLocalsVisitor;
104 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
105 use rustc_errors::{pluralize, struct_span_err, Applicability};
106 use rustc_hir as hir;
107 use rustc_hir::def::Res;
108 use rustc_hir::def_id::{DefId, LocalDefId};
109 use rustc_hir::intravisit::Visitor;
110 use rustc_hir::itemlikevisit::ItemLikeVisitor;
111 use rustc_hir::{HirIdMap, ImplicitSelfKind, Node};
112 use rustc_index::bit_set::BitSet;
113 use rustc_index::vec::Idx;
114 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
115 use rustc_middle::ty::query::Providers;
116 use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
117 use rustc_middle::ty::{self, Ty, TyCtxt, UserType};
118 use rustc_session::config;
119 use rustc_session::parse::feature_err;
120 use rustc_session::Session;
121 use rustc_span::symbol::{kw, Ident};
122 use rustc_span::{self, BytePos, MultiSpan, Span};
123 use rustc_span::{source_map::DUMMY_SP, sym};
124 use rustc_target::abi::VariantIdx;
125 use rustc_target::spec::abi::Abi;
126 use rustc_trait_selection::traits;
127 use rustc_trait_selection::traits::error_reporting::recursive_type_with_infinite_size_error;
128 use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
129
130 use std::cell::{Ref, RefCell, RefMut};
131
132 use crate::require_c_abi_if_c_variadic;
133 use crate::util::common::indenter;
134
135 use self::coercion::DynamicCoerceMany;
136 pub use self::Expectation::*;
137
138 #[macro_export]
139 macro_rules! type_error_struct {
140     ($session:expr, $span:expr, $typ:expr, $code:ident, $($message:tt)*) => ({
141         if $typ.references_error() {
142             $session.diagnostic().struct_dummy()
143         } else {
144             rustc_errors::struct_span_err!($session, $span, $code, $($message)*)
145         }
146     })
147 }
148
149 /// The type of a local binding, including the revealed type for anon types.
150 #[derive(Copy, Clone, Debug)]
151 pub struct LocalTy<'tcx> {
152     decl_ty: Ty<'tcx>,
153     revealed_ty: Ty<'tcx>,
154 }
155
156 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
157 pub enum Needs {
158     MutPlace,
159     None,
160 }
161
162 impl Needs {
163     fn maybe_mut_place(m: hir::Mutability) -> Self {
164         match m {
165             hir::Mutability::Mut => Needs::MutPlace,
166             hir::Mutability::Not => Needs::None,
167         }
168     }
169 }
170
171 #[derive(Copy, Clone)]
172 pub struct UnsafetyState {
173     pub def: hir::HirId,
174     pub unsafety: hir::Unsafety,
175     from_fn: bool,
176 }
177
178 impl UnsafetyState {
179     pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
180         UnsafetyState { def, unsafety, from_fn: true }
181     }
182
183     pub fn recurse(self, blk: &hir::Block<'_>) -> UnsafetyState {
184         use hir::BlockCheckMode;
185         match self.unsafety {
186             // If this unsafe, then if the outer function was already marked as
187             // unsafe we shouldn't attribute the unsafe'ness to the block. This
188             // way the block can be warned about instead of ignoring this
189             // extraneous block (functions are never warned about).
190             hir::Unsafety::Unsafe if self.from_fn => self,
191
192             unsafety => {
193                 let (unsafety, def) = match blk.rules {
194                     BlockCheckMode::UnsafeBlock(..) => (hir::Unsafety::Unsafe, blk.hir_id),
195                     BlockCheckMode::DefaultBlock => (unsafety, self.def),
196                 };
197                 UnsafetyState { def, unsafety, from_fn: false }
198             }
199         }
200     }
201 }
202
203 #[derive(Debug, Copy, Clone)]
204 pub enum PlaceOp {
205     Deref,
206     Index,
207 }
208
209 pub struct BreakableCtxt<'tcx> {
210     may_break: bool,
211
212     // this is `null` for loops where break with a value is illegal,
213     // such as `while`, `for`, and `while let`
214     coerce: Option<DynamicCoerceMany<'tcx>>,
215 }
216
217 pub struct EnclosingBreakables<'tcx> {
218     stack: Vec<BreakableCtxt<'tcx>>,
219     by_id: HirIdMap<usize>,
220 }
221
222 impl<'tcx> EnclosingBreakables<'tcx> {
223     fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> {
224         self.opt_find_breakable(target_id).unwrap_or_else(|| {
225             bug!("could not find enclosing breakable with id {}", target_id);
226         })
227     }
228
229     fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> {
230         match self.by_id.get(&target_id) {
231             Some(ix) => Some(&mut self.stack[*ix]),
232             None => None,
233         }
234     }
235 }
236
237 pub fn provide(providers: &mut Providers) {
238     method::provide(providers);
239     *providers = Providers {
240         typeck_item_bodies,
241         typeck_const_arg,
242         typeck,
243         diagnostic_only_typeck,
244         has_typeck_results,
245         adt_destructor,
246         used_trait_imports,
247         check_item_well_formed,
248         check_trait_item_well_formed,
249         check_impl_item_well_formed,
250         check_mod_item_types,
251         ..*providers
252     };
253 }
254
255 fn adt_destructor(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::Destructor> {
256     tcx.calculate_dtor(def_id, dropck::check_drop_impl)
257 }
258
259 /// If this `DefId` is a "primary tables entry", returns
260 /// `Some((body_id, header, decl))` with information about
261 /// its body-id, fn-header and fn-decl (if any). Otherwise,
262 /// returns `None`.
263 ///
264 /// If this function returns `Some`, then `typeck_results(def_id)` will
265 /// succeed; if it returns `None`, then `typeck_results(def_id)` may or
266 /// may not succeed. In some cases where this function returns `None`
267 /// (notably closures), `typeck_results(def_id)` would wind up
268 /// redirecting to the owning function.
269 fn primary_body_of(
270     tcx: TyCtxt<'_>,
271     id: hir::HirId,
272 ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnHeader>, Option<&hir::FnDecl<'_>>)> {
273     match tcx.hir().get(id) {
274         Node::Item(item) => match item.kind {
275             hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Static(ref ty, _, body) => {
276                 Some((body, Some(ty), None, None))
277             }
278             hir::ItemKind::Fn(ref sig, .., body) => {
279                 Some((body, None, Some(&sig.header), Some(&sig.decl)))
280             }
281             _ => None,
282         },
283         Node::TraitItem(item) => match item.kind {
284             hir::TraitItemKind::Const(ref ty, Some(body)) => Some((body, Some(ty), None, None)),
285             hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
286                 Some((body, None, Some(&sig.header), Some(&sig.decl)))
287             }
288             _ => None,
289         },
290         Node::ImplItem(item) => match item.kind {
291             hir::ImplItemKind::Const(ref ty, body) => Some((body, Some(ty), None, None)),
292             hir::ImplItemKind::Fn(ref sig, body) => {
293                 Some((body, None, Some(&sig.header), Some(&sig.decl)))
294             }
295             _ => None,
296         },
297         Node::AnonConst(constant) => Some((constant.body, None, None, None)),
298         _ => None,
299     }
300 }
301
302 fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
303     // Closures' typeck results come from their outermost function,
304     // as they are part of the same "inference environment".
305     let outer_def_id = tcx.closure_base_def_id(def_id);
306     if outer_def_id != def_id {
307         return tcx.has_typeck_results(outer_def_id);
308     }
309
310     if let Some(def_id) = def_id.as_local() {
311         let id = tcx.hir().local_def_id_to_hir_id(def_id);
312         primary_body_of(tcx, id).is_some()
313     } else {
314         false
315     }
316 }
317
318 fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &FxHashSet<LocalDefId> {
319     &*tcx.typeck(def_id).used_trait_imports
320 }
321
322 fn typeck_const_arg<'tcx>(
323     tcx: TyCtxt<'tcx>,
324     (did, param_did): (LocalDefId, DefId),
325 ) -> &ty::TypeckResults<'tcx> {
326     let fallback = move || tcx.type_of(param_did);
327     typeck_with_fallback(tcx, did, fallback)
328 }
329
330 fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
331     if let Some(param_did) = tcx.opt_const_param_of(def_id) {
332         tcx.typeck_const_arg((def_id, param_did))
333     } else {
334         let fallback = move || tcx.type_of(def_id.to_def_id());
335         typeck_with_fallback(tcx, def_id, fallback)
336     }
337 }
338
339 /// Used only to get `TypeckResults` for type inference during error recovery.
340 /// Currently only used for type inference of `static`s and `const`s to avoid type cycle errors.
341 fn diagnostic_only_typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> {
342     let fallback = move || {
343         let span = tcx.hir().span(tcx.hir().local_def_id_to_hir_id(def_id));
344         tcx.ty_error_with_message(span, "diagnostic only typeck table used")
345     };
346     typeck_with_fallback(tcx, def_id, fallback)
347 }
348
349 fn typeck_with_fallback<'tcx>(
350     tcx: TyCtxt<'tcx>,
351     def_id: LocalDefId,
352     fallback: impl Fn() -> Ty<'tcx> + 'tcx,
353 ) -> &'tcx ty::TypeckResults<'tcx> {
354     // Closures' typeck results come from their outermost function,
355     // as they are part of the same "inference environment".
356     let outer_def_id = tcx.closure_base_def_id(def_id.to_def_id()).expect_local();
357     if outer_def_id != def_id {
358         return tcx.typeck(outer_def_id);
359     }
360
361     let id = tcx.hir().local_def_id_to_hir_id(def_id);
362     let span = tcx.hir().span(id);
363
364     // Figure out what primary body this item has.
365     let (body_id, body_ty, fn_header, fn_decl) = primary_body_of(tcx, id).unwrap_or_else(|| {
366         span_bug!(span, "can't type-check body of {:?}", def_id);
367     });
368     let body = tcx.hir().body(body_id);
369
370     let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
371         let param_env = tcx.param_env(def_id);
372         let fcx = if let (Some(header), Some(decl)) = (fn_header, fn_decl) {
373             let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
374                 let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
375                 <dyn AstConv<'_>>::ty_of_fn(
376                     &fcx,
377                     id,
378                     header.unsafety,
379                     header.abi,
380                     decl,
381                     &hir::Generics::empty(),
382                     None,
383                     None,
384                 )
385             } else {
386                 tcx.fn_sig(def_id)
387             };
388
389             check_abi(tcx, id, span, fn_sig.abi());
390
391             // Compute the fty from point of view of inside the fn.
392             let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
393             let fn_sig = inh.normalize_associated_types_in(
394                 body.value.span,
395                 body_id.hir_id,
396                 param_env,
397                 fn_sig,
398             );
399
400             let fcx = check_fn(&inh, param_env, fn_sig, decl, id, body, None).0;
401             fcx
402         } else {
403             let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
404             let expected_type = body_ty
405                 .and_then(|ty| match ty.kind {
406                     hir::TyKind::Infer => Some(<dyn AstConv<'_>>::ast_ty_to_ty(&fcx, ty)),
407                     _ => None,
408                 })
409                 .unwrap_or_else(|| match tcx.hir().get(id) {
410                     Node::AnonConst(_) => match tcx.hir().get(tcx.hir().get_parent_node(id)) {
411                         Node::Expr(&hir::Expr {
412                             kind: hir::ExprKind::ConstBlock(ref anon_const),
413                             ..
414                         }) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
415                             kind: TypeVariableOriginKind::TypeInference,
416                             span,
417                         }),
418                         Node::Ty(&hir::Ty {
419                             kind: hir::TyKind::Typeof(ref anon_const), ..
420                         }) if anon_const.hir_id == id => fcx.next_ty_var(TypeVariableOrigin {
421                             kind: TypeVariableOriginKind::TypeInference,
422                             span,
423                         }),
424                         Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
425                         | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. })
426                             if asm.operands.iter().any(|(op, _op_sp)| match op {
427                                 hir::InlineAsmOperand::Const { anon_const } => {
428                                     anon_const.hir_id == id
429                                 }
430                                 _ => false,
431                             }) =>
432                         {
433                             // Inline assembly constants must be integers.
434                             fcx.next_int_var()
435                         }
436                         _ => fallback(),
437                     },
438                     _ => fallback(),
439                 });
440
441             let expected_type = fcx.normalize_associated_types_in(body.value.span, expected_type);
442             fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
443
444             let revealed_ty = fcx.instantiate_opaque_types_from_value(
445                 id,
446                 expected_type,
447                 body.value.span,
448                 Some(sym::impl_trait_in_bindings),
449             );
450
451             // Gather locals in statics (because of block expressions).
452             GatherLocalsVisitor::new(&fcx, id).visit_body(body);
453
454             fcx.check_expr_coercable_to_type(&body.value, revealed_ty, None);
455
456             fcx.write_ty(id, revealed_ty);
457
458             fcx
459         };
460
461         // All type checking constraints were added, try to fallback unsolved variables.
462         fcx.select_obligations_where_possible(false, |_| {});
463         let mut fallback_has_occurred = false;
464
465         // We do fallback in two passes, to try to generate
466         // better error messages.
467         // The first time, we do *not* replace opaque types.
468         for ty in &fcx.unsolved_variables() {
469             fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
470         }
471         // We now see if we can make progress. This might
472         // cause us to unify inference variables for opaque types,
473         // since we may have unified some other type variables
474         // during the first phase of fallback.
475         // This means that we only replace inference variables with their underlying
476         // opaque types as a last resort.
477         //
478         // In code like this:
479         //
480         // ```rust
481         // type MyType = impl Copy;
482         // fn produce() -> MyType { true }
483         // fn bad_produce() -> MyType { panic!() }
484         // ```
485         //
486         // we want to unify the opaque inference variable in `bad_produce`
487         // with the diverging fallback for `panic!` (e.g. `()` or `!`).
488         // This will produce a nice error message about conflicting concrete
489         // types for `MyType`.
490         //
491         // If we had tried to fallback the opaque inference variable to `MyType`,
492         // we will generate a confusing type-check error that does not explicitly
493         // refer to opaque types.
494         fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
495
496         // We now run fallback again, but this time we allow it to replace
497         // unconstrained opaque type variables, in addition to performing
498         // other kinds of fallback.
499         for ty in &fcx.unsolved_variables() {
500             fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
501         }
502
503         // See if we can make any more progress.
504         fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
505
506         // Even though coercion casts provide type hints, we check casts after fallback for
507         // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
508         fcx.check_casts();
509
510         // Closure and generator analysis may run after fallback
511         // because they don't constrain other type variables.
512         fcx.closure_analyze(body);
513         assert!(fcx.deferred_call_resolutions.borrow().is_empty());
514         fcx.resolve_generator_interiors(def_id.to_def_id());
515
516         for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
517             let ty = fcx.normalize_ty(span, ty);
518             fcx.require_type_is_sized(ty, span, code);
519         }
520
521         fcx.select_all_obligations_or_error();
522
523         if fn_decl.is_some() {
524             fcx.regionck_fn(id, body);
525         } else {
526             fcx.regionck_expr(body);
527         }
528
529         fcx.resolve_type_vars_in_body(body)
530     });
531
532     // Consistency check our TypeckResults instance can hold all ItemLocalIds
533     // it will need to hold.
534     assert_eq!(typeck_results.hir_owner, id.owner);
535
536     typeck_results
537 }
538
539 /// When `check_fn` is invoked on a generator (i.e., a body that
540 /// includes yield), it returns back some information about the yield
541 /// points.
542 struct GeneratorTypes<'tcx> {
543     /// Type of generator argument / values returned by `yield`.
544     resume_ty: Ty<'tcx>,
545
546     /// Type of value that is yielded.
547     yield_ty: Ty<'tcx>,
548
549     /// Types that are captured (see `GeneratorInterior` for more).
550     interior: Ty<'tcx>,
551
552     /// Indicates if the generator is movable or static (immovable).
553     movability: hir::Movability,
554 }
555
556 /// Given a `DefId` for an opaque type in return position, find its parent item's return
557 /// expressions.
558 fn get_owner_return_paths(
559     tcx: TyCtxt<'tcx>,
560     def_id: LocalDefId,
561 ) -> Option<(hir::HirId, ReturnsVisitor<'tcx>)> {
562     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
563     let id = tcx.hir().get_parent_item(hir_id);
564     tcx.hir()
565         .find(id)
566         .map(|n| (id, n))
567         .and_then(|(hir_id, node)| node.body_id().map(|b| (hir_id, b)))
568         .map(|(hir_id, body_id)| {
569             let body = tcx.hir().body(body_id);
570             let mut visitor = ReturnsVisitor::default();
571             visitor.visit_body(body);
572             (hir_id, visitor)
573         })
574 }
575
576 /// Emit an error for recursive opaque types in a `let` binding.
577 fn binding_opaque_type_cycle_error(
578     tcx: TyCtxt<'tcx>,
579     def_id: LocalDefId,
580     span: Span,
581     partially_expanded_type: Ty<'tcx>,
582 ) {
583     let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
584     err.span_label(span, "cannot resolve opaque type");
585     // Find the owner that declared this `impl Trait` type.
586     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
587     let mut prev_hir_id = hir_id;
588     let mut hir_id = tcx.hir().get_parent_node(hir_id);
589     while let Some(node) = tcx.hir().find(hir_id) {
590         match node {
591             hir::Node::Local(hir::Local {
592                 pat,
593                 init: None,
594                 ty: Some(ty),
595                 source: hir::LocalSource::Normal,
596                 ..
597             }) => {
598                 err.span_label(pat.span, "this binding might not have a concrete type");
599                 err.span_suggestion_verbose(
600                     ty.span.shrink_to_hi(),
601                     "set the binding to a value for a concrete type to be resolved",
602                     " = /* value */".to_string(),
603                     Applicability::HasPlaceholders,
604                 );
605             }
606             hir::Node::Local(hir::Local {
607                 init: Some(expr),
608                 source: hir::LocalSource::Normal,
609                 ..
610             }) => {
611                 let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
612                 let typeck_results =
613                     tcx.typeck(tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id)));
614                 if let Some(ty) = typeck_results.node_type_opt(expr.hir_id) {
615                     err.span_label(
616                         expr.span,
617                         &format!(
618                             "this is of type `{}`, which doesn't constrain \
619                              `{}` enough to arrive to a concrete type",
620                             ty, partially_expanded_type
621                         ),
622                     );
623                 }
624             }
625             _ => {}
626         }
627         if prev_hir_id == hir_id {
628             break;
629         }
630         prev_hir_id = hir_id;
631         hir_id = tcx.hir().get_parent_node(hir_id);
632     }
633     err.emit();
634 }
635
636 // Forbid defining intrinsics in Rust code,
637 // as they must always be defined by the compiler.
638 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
639     if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
640         tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
641     }
642 }
643
644 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
645     // Only restricted on wasm32 target for now
646     if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
647         return;
648     }
649
650     // If `#[link_section]` is missing, then nothing to verify
651     let attrs = tcx.codegen_fn_attrs(id);
652     if attrs.link_section.is_none() {
653         return;
654     }
655
656     // For the wasm32 target statics with `#[link_section]` are placed into custom
657     // sections of the final output file, but this isn't link custom sections of
658     // other executable formats. Namely we can only embed a list of bytes,
659     // nothing with pointers to anything else or relocations. If any relocation
660     // show up, reject them here.
661     // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
662     // the consumer's responsibility to ensure all bytes that have been read
663     // have defined values.
664     match tcx.eval_static_initializer(id.to_def_id()) {
665         Ok(alloc) => {
666             if alloc.relocations().len() != 0 {
667                 let msg = "statics with a custom `#[link_section]` must be a \
668                            simple list of bytes on the wasm target with no \
669                            extra levels of indirection such as references";
670                 tcx.sess.span_err(span, msg);
671             }
672         }
673         Err(_) => {}
674     }
675 }
676
677 fn report_forbidden_specialization(
678     tcx: TyCtxt<'_>,
679     impl_item: &hir::ImplItem<'_>,
680     parent_impl: DefId,
681 ) {
682     let mut err = struct_span_err!(
683         tcx.sess,
684         impl_item.span,
685         E0520,
686         "`{}` specializes an item from a parent `impl`, but \
687          that item is not marked `default`",
688         impl_item.ident
689     );
690     err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
691
692     match tcx.span_of_impl(parent_impl) {
693         Ok(span) => {
694             err.span_label(span, "parent `impl` is here");
695             err.note(&format!(
696                 "to specialize, `{}` in the parent `impl` must be marked `default`",
697                 impl_item.ident
698             ));
699         }
700         Err(cname) => {
701             err.note(&format!("parent implementation is in crate `{}`", cname));
702         }
703     }
704
705     err.emit();
706 }
707
708 fn missing_items_err(
709     tcx: TyCtxt<'_>,
710     impl_span: Span,
711     missing_items: &[ty::AssocItem],
712     full_impl_span: Span,
713 ) {
714     let missing_items_msg = missing_items
715         .iter()
716         .map(|trait_item| trait_item.ident.to_string())
717         .collect::<Vec<_>>()
718         .join("`, `");
719
720     let mut err = struct_span_err!(
721         tcx.sess,
722         impl_span,
723         E0046,
724         "not all trait items implemented, missing: `{}`",
725         missing_items_msg
726     );
727     err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
728
729     // `Span` before impl block closing brace.
730     let hi = full_impl_span.hi() - BytePos(1);
731     // Point at the place right before the closing brace of the relevant `impl` to suggest
732     // adding the associated item at the end of its body.
733     let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
734     // Obtain the level of indentation ending in `sugg_sp`.
735     let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
736     // Make the whitespace that will make the suggestion have the right indentation.
737     let padding: String = " ".repeat(indentation);
738
739     for trait_item in missing_items {
740         let snippet = suggestion_signature(&trait_item, tcx);
741         let code = format!("{}{}\n{}", padding, snippet, padding);
742         let msg = format!("implement the missing item: `{}`", snippet);
743         let appl = Applicability::HasPlaceholders;
744         if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
745             err.span_label(span, format!("`{}` from trait", trait_item.ident));
746             err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
747         } else {
748             err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
749         }
750     }
751     err.emit();
752 }
753
754 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
755 fn bounds_from_generic_predicates<'tcx>(
756     tcx: TyCtxt<'tcx>,
757     predicates: ty::GenericPredicates<'tcx>,
758 ) -> (String, String) {
759     let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
760     let mut projections = vec![];
761     for (predicate, _) in predicates.predicates {
762         debug!("predicate {:?}", predicate);
763         let bound_predicate = predicate.kind();
764         match bound_predicate.skip_binder() {
765             ty::PredicateKind::Trait(trait_predicate, _) => {
766                 let entry = types.entry(trait_predicate.self_ty()).or_default();
767                 let def_id = trait_predicate.def_id();
768                 if Some(def_id) != tcx.lang_items().sized_trait() {
769                     // Type params are `Sized` by default, do not add that restriction to the list
770                     // if it is a positive requirement.
771                     entry.push(trait_predicate.def_id());
772                 }
773             }
774             ty::PredicateKind::Projection(projection_pred) => {
775                 projections.push(bound_predicate.rebind(projection_pred));
776             }
777             _ => {}
778         }
779     }
780     let generics = if types.is_empty() {
781         "".to_string()
782     } else {
783         format!(
784             "<{}>",
785             types
786                 .keys()
787                 .filter_map(|t| match t.kind() {
788                     ty::Param(_) => Some(t.to_string()),
789                     // Avoid suggesting the following:
790                     // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
791                     _ => None,
792                 })
793                 .collect::<Vec<_>>()
794                 .join(", ")
795         )
796     };
797     let mut where_clauses = vec![];
798     for (ty, bounds) in types {
799         for bound in &bounds {
800             where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
801         }
802     }
803     for projection in &projections {
804         let p = projection.skip_binder();
805         // FIXME: this is not currently supported syntax, we should be looking at the `types` and
806         // insert the associated types where they correspond, but for now let's be "lazy" and
807         // propose this instead of the following valid resugaring:
808         // `T: Trait, Trait::Assoc = K` â†’ `T: Trait<Assoc = K>`
809         where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
810     }
811     let where_clauses = if where_clauses.is_empty() {
812         String::new()
813     } else {
814         format!(" where {}", where_clauses.join(", "))
815     };
816     (generics, where_clauses)
817 }
818
819 /// Return placeholder code for the given function.
820 fn fn_sig_suggestion<'tcx>(
821     tcx: TyCtxt<'tcx>,
822     sig: ty::FnSig<'tcx>,
823     ident: Ident,
824     predicates: ty::GenericPredicates<'tcx>,
825     assoc: &ty::AssocItem,
826 ) -> String {
827     let args = sig
828         .inputs()
829         .iter()
830         .enumerate()
831         .map(|(i, ty)| {
832             Some(match ty.kind() {
833                 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
834                 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
835                     let reg = match &format!("{}", reg)[..] {
836                         "'_" | "" => String::new(),
837                         reg => format!("{} ", reg),
838                     };
839                     if assoc.fn_has_self_parameter {
840                         match ref_ty.kind() {
841                             ty::Param(param) if param.name == kw::SelfUpper => {
842                                 format!("&{}{}self", reg, mutability.prefix_str())
843                             }
844
845                             _ => format!("self: {}", ty),
846                         }
847                     } else {
848                         format!("_: {}", ty)
849                     }
850                 }
851                 _ => {
852                     if assoc.fn_has_self_parameter && i == 0 {
853                         format!("self: {}", ty)
854                     } else {
855                         format!("_: {}", ty)
856                     }
857                 }
858             })
859         })
860         .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
861         .filter_map(|arg| arg)
862         .collect::<Vec<String>>()
863         .join(", ");
864     let output = sig.output();
865     let output = if !output.is_unit() { format!(" -> {}", output) } else { String::new() };
866
867     let unsafety = sig.unsafety.prefix_str();
868     let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
869
870     // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
871     // not be present in the `fn` definition, not will we account for renamed
872     // lifetimes between the `impl` and the `trait`, but this should be good enough to
873     // fill in a significant portion of the missing code, and other subsequent
874     // suggestions can help the user fix the code.
875     format!(
876         "{}fn {}{}({}){}{} {{ todo!() }}",
877         unsafety, ident, generics, args, output, where_clauses
878     )
879 }
880
881 /// Return placeholder code for the given associated item.
882 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
883 /// structured suggestion.
884 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
885     match assoc.kind {
886         ty::AssocKind::Fn => {
887             // We skip the binder here because the binder would deanonymize all
888             // late-bound regions, and we don't want method signatures to show up
889             // `as for<'r> fn(&'r MyType)`.  Pretty-printing handles late-bound
890             // regions just fine, showing `fn(&MyType)`.
891             fn_sig_suggestion(
892                 tcx,
893                 tcx.fn_sig(assoc.def_id).skip_binder(),
894                 assoc.ident,
895                 tcx.predicates_of(assoc.def_id),
896                 assoc,
897             )
898         }
899         ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
900         ty::AssocKind::Const => {
901             let ty = tcx.type_of(assoc.def_id);
902             let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
903             format!("const {}: {} = {};", assoc.ident, ty, val)
904         }
905     }
906 }
907
908 /// Emit an error when encountering two or more variants in a transparent enum.
909 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
910     let variant_spans: Vec<_> = adt
911         .variants
912         .iter()
913         .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
914         .collect();
915     let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
916     let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
917     err.span_label(sp, &msg);
918     if let [start @ .., end] = &*variant_spans {
919         for variant_span in start {
920             err.span_label(*variant_span, "");
921         }
922         err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
923     }
924     err.emit();
925 }
926
927 /// Emit an error when encountering two or more non-zero-sized fields in a transparent
928 /// enum.
929 fn bad_non_zero_sized_fields<'tcx>(
930     tcx: TyCtxt<'tcx>,
931     adt: &'tcx ty::AdtDef,
932     field_count: usize,
933     field_spans: impl Iterator<Item = Span>,
934     sp: Span,
935 ) {
936     let msg = format!("needs at most one non-zero-sized field, but has {}", field_count);
937     let mut err = struct_span_err!(
938         tcx.sess,
939         sp,
940         E0690,
941         "{}transparent {} {}",
942         if adt.is_enum() { "the variant of a " } else { "" },
943         adt.descr(),
944         msg,
945     );
946     err.span_label(sp, &msg);
947     for sp in field_spans {
948         err.span_label(sp, "this field is non-zero-sized");
949     }
950     err.emit();
951 }
952
953 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
954     struct_span_err!(
955         tcx.sess,
956         span,
957         E0533,
958         "expected unit struct, unit variant or constant, found {}{}",
959         res.descr(),
960         tcx.sess
961             .source_map()
962             .span_to_snippet(span)
963             .map_or_else(|_| String::new(), |s| format!(" `{}`", s)),
964     )
965     .emit();
966 }
967
968 /// Controls whether the arguments are tupled. This is used for the call
969 /// operator.
970 ///
971 /// Tupling means that all call-side arguments are packed into a tuple and
972 /// passed as a single parameter. For example, if tupling is enabled, this
973 /// function:
974 ///
975 ///     fn f(x: (isize, isize))
976 ///
977 /// Can be called as:
978 ///
979 ///     f(1, 2);
980 ///
981 /// Instead of:
982 ///
983 ///     f((1, 2));
984 #[derive(Clone, Eq, PartialEq)]
985 enum TupleArgumentsFlag {
986     DontTupleArguments,
987     TupleArguments,
988 }
989
990 /// Controls how we perform fallback for unconstrained
991 /// type variables.
992 enum FallbackMode {
993     /// Do not fallback type variables to opaque types.
994     NoOpaque,
995     /// Perform all possible kinds of fallback, including
996     /// turning type variables to opaque types.
997     All,
998 }
999
1000 /// A wrapper for `InferCtxt`'s `in_progress_typeck_results` field.
1001 #[derive(Copy, Clone)]
1002 struct MaybeInProgressTables<'a, 'tcx> {
1003     maybe_typeck_results: Option<&'a RefCell<ty::TypeckResults<'tcx>>>,
1004 }
1005
1006 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
1007     fn borrow(self) -> Ref<'a, ty::TypeckResults<'tcx>> {
1008         match self.maybe_typeck_results {
1009             Some(typeck_results) => typeck_results.borrow(),
1010             None => bug!(
1011                 "MaybeInProgressTables: inh/fcx.typeck_results.borrow() with no typeck results"
1012             ),
1013         }
1014     }
1015
1016     fn borrow_mut(self) -> RefMut<'a, ty::TypeckResults<'tcx>> {
1017         match self.maybe_typeck_results {
1018             Some(typeck_results) => typeck_results.borrow_mut(),
1019             None => bug!(
1020                 "MaybeInProgressTables: inh/fcx.typeck_results.borrow_mut() with no typeck results"
1021             ),
1022         }
1023     }
1024 }
1025
1026 struct CheckItemTypesVisitor<'tcx> {
1027     tcx: TyCtxt<'tcx>,
1028 }
1029
1030 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
1031     fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
1032         check_item_type(self.tcx, i);
1033     }
1034     fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
1035     fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
1036     fn visit_foreign_item(&mut self, _: &'tcx hir::ForeignItem<'tcx>) {}
1037 }
1038
1039 fn typeck_item_bodies(tcx: TyCtxt<'_>, (): ()) {
1040     tcx.par_body_owners(|body_owner_def_id| {
1041         tcx.ensure().typeck(body_owner_def_id);
1042     });
1043 }
1044
1045 fn fatally_break_rust(sess: &Session) {
1046     let handler = sess.diagnostic();
1047     handler.span_bug_no_panic(
1048         MultiSpan::new(),
1049         "It looks like you're trying to break rust; would you like some ICE?",
1050     );
1051     handler.note_without_error("the compiler expectedly panicked. this is a feature.");
1052     handler.note_without_error(
1053         "we would appreciate a joke overview: \
1054          https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
1055     );
1056     handler.note_without_error(&format!(
1057         "rustc {} running on {}",
1058         option_env!("CFG_VERSION").unwrap_or("unknown_version"),
1059         config::host_triple(),
1060     ));
1061 }
1062
1063 fn potentially_plural_count(count: usize, word: &str) -> String {
1064     format!("{} {}{}", count, word, pluralize!(count))
1065 }
1066
1067 fn has_expected_num_generic_args<'tcx>(
1068     tcx: TyCtxt<'tcx>,
1069     trait_did: Option<DefId>,
1070     expected: usize,
1071 ) -> bool {
1072     trait_did.map_or(true, |trait_did| {
1073         let generics = tcx.generics_of(trait_did);
1074         generics.count() == expected + if generics.has_self { 1 } else { 0 }
1075     })
1076 }