]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/check/mod.rs
Rollup merge of #87307 - michaelwoerister:pgo-unwind-msvc, r=nagisa
[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::source_map::DUMMY_SP;
122 use rustc_span::symbol::{kw, Ident};
123 use rustc_span::{self, BytePos, MultiSpan, Span};
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             // Gather locals in statics (because of block expressions).
445             GatherLocalsVisitor::new(&fcx).visit_body(body);
446
447             fcx.check_expr_coercable_to_type(&body.value, expected_type, None);
448
449             fcx.write_ty(id, expected_type);
450
451             fcx
452         };
453
454         // All type checking constraints were added, try to fallback unsolved variables.
455         fcx.select_obligations_where_possible(false, |_| {});
456         let mut fallback_has_occurred = false;
457
458         // We do fallback in two passes, to try to generate
459         // better error messages.
460         // The first time, we do *not* replace opaque types.
461         for ty in &fcx.unsolved_variables() {
462             fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::NoOpaque);
463         }
464         // We now see if we can make progress. This might
465         // cause us to unify inference variables for opaque types,
466         // since we may have unified some other type variables
467         // during the first phase of fallback.
468         // This means that we only replace inference variables with their underlying
469         // opaque types as a last resort.
470         //
471         // In code like this:
472         //
473         // ```rust
474         // type MyType = impl Copy;
475         // fn produce() -> MyType { true }
476         // fn bad_produce() -> MyType { panic!() }
477         // ```
478         //
479         // we want to unify the opaque inference variable in `bad_produce`
480         // with the diverging fallback for `panic!` (e.g. `()` or `!`).
481         // This will produce a nice error message about conflicting concrete
482         // types for `MyType`.
483         //
484         // If we had tried to fallback the opaque inference variable to `MyType`,
485         // we will generate a confusing type-check error that does not explicitly
486         // refer to opaque types.
487         fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
488
489         // We now run fallback again, but this time we allow it to replace
490         // unconstrained opaque type variables, in addition to performing
491         // other kinds of fallback.
492         for ty in &fcx.unsolved_variables() {
493             fallback_has_occurred |= fcx.fallback_if_possible(ty, FallbackMode::All);
494         }
495
496         // See if we can make any more progress.
497         fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
498
499         // Even though coercion casts provide type hints, we check casts after fallback for
500         // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
501         fcx.check_casts();
502
503         // Closure and generator analysis may run after fallback
504         // because they don't constrain other type variables.
505         fcx.closure_analyze(body);
506         assert!(fcx.deferred_call_resolutions.borrow().is_empty());
507         fcx.resolve_generator_interiors(def_id.to_def_id());
508
509         for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
510             let ty = fcx.normalize_ty(span, ty);
511             fcx.require_type_is_sized(ty, span, code);
512         }
513
514         fcx.select_all_obligations_or_error();
515
516         if fn_decl.is_some() {
517             fcx.regionck_fn(id, body);
518         } else {
519             fcx.regionck_expr(body);
520         }
521
522         fcx.resolve_type_vars_in_body(body)
523     });
524
525     // Consistency check our TypeckResults instance can hold all ItemLocalIds
526     // it will need to hold.
527     assert_eq!(typeck_results.hir_owner, id.owner);
528
529     typeck_results
530 }
531
532 /// When `check_fn` is invoked on a generator (i.e., a body that
533 /// includes yield), it returns back some information about the yield
534 /// points.
535 struct GeneratorTypes<'tcx> {
536     /// Type of generator argument / values returned by `yield`.
537     resume_ty: Ty<'tcx>,
538
539     /// Type of value that is yielded.
540     yield_ty: Ty<'tcx>,
541
542     /// Types that are captured (see `GeneratorInterior` for more).
543     interior: Ty<'tcx>,
544
545     /// Indicates if the generator is movable or static (immovable).
546     movability: hir::Movability,
547 }
548
549 /// Given a `DefId` for an opaque type in return position, find its parent item's return
550 /// expressions.
551 fn get_owner_return_paths(
552     tcx: TyCtxt<'tcx>,
553     def_id: LocalDefId,
554 ) -> Option<(hir::HirId, ReturnsVisitor<'tcx>)> {
555     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
556     let id = tcx.hir().get_parent_item(hir_id);
557     tcx.hir()
558         .find(id)
559         .map(|n| (id, n))
560         .and_then(|(hir_id, node)| node.body_id().map(|b| (hir_id, b)))
561         .map(|(hir_id, body_id)| {
562             let body = tcx.hir().body(body_id);
563             let mut visitor = ReturnsVisitor::default();
564             visitor.visit_body(body);
565             (hir_id, visitor)
566         })
567 }
568
569 // Forbid defining intrinsics in Rust code,
570 // as they must always be defined by the compiler.
571 fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
572     if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
573         tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
574     }
575 }
576
577 fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId, span: Span) {
578     // Only restricted on wasm32 target for now
579     if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
580         return;
581     }
582
583     // If `#[link_section]` is missing, then nothing to verify
584     let attrs = tcx.codegen_fn_attrs(id);
585     if attrs.link_section.is_none() {
586         return;
587     }
588
589     // For the wasm32 target statics with `#[link_section]` are placed into custom
590     // sections of the final output file, but this isn't link custom sections of
591     // other executable formats. Namely we can only embed a list of bytes,
592     // nothing with pointers to anything else or relocations. If any relocation
593     // show up, reject them here.
594     // `#[link_section]` may contain arbitrary, or even undefined bytes, but it is
595     // the consumer's responsibility to ensure all bytes that have been read
596     // have defined values.
597     match tcx.eval_static_initializer(id.to_def_id()) {
598         Ok(alloc) => {
599             if alloc.relocations().len() != 0 {
600                 let msg = "statics with a custom `#[link_section]` must be a \
601                            simple list of bytes on the wasm target with no \
602                            extra levels of indirection such as references";
603                 tcx.sess.span_err(span, msg);
604             }
605         }
606         Err(_) => {}
607     }
608 }
609
610 fn report_forbidden_specialization(
611     tcx: TyCtxt<'_>,
612     impl_item: &hir::ImplItem<'_>,
613     parent_impl: DefId,
614 ) {
615     let mut err = struct_span_err!(
616         tcx.sess,
617         impl_item.span,
618         E0520,
619         "`{}` specializes an item from a parent `impl`, but \
620          that item is not marked `default`",
621         impl_item.ident
622     );
623     err.span_label(impl_item.span, format!("cannot specialize default item `{}`", impl_item.ident));
624
625     match tcx.span_of_impl(parent_impl) {
626         Ok(span) => {
627             err.span_label(span, "parent `impl` is here");
628             err.note(&format!(
629                 "to specialize, `{}` in the parent `impl` must be marked `default`",
630                 impl_item.ident
631             ));
632         }
633         Err(cname) => {
634             err.note(&format!("parent implementation is in crate `{}`", cname));
635         }
636     }
637
638     err.emit();
639 }
640
641 fn missing_items_err(
642     tcx: TyCtxt<'_>,
643     impl_span: Span,
644     missing_items: &[ty::AssocItem],
645     full_impl_span: Span,
646 ) {
647     let missing_items_msg = missing_items
648         .iter()
649         .map(|trait_item| trait_item.ident.to_string())
650         .collect::<Vec<_>>()
651         .join("`, `");
652
653     let mut err = struct_span_err!(
654         tcx.sess,
655         impl_span,
656         E0046,
657         "not all trait items implemented, missing: `{}`",
658         missing_items_msg
659     );
660     err.span_label(impl_span, format!("missing `{}` in implementation", missing_items_msg));
661
662     // `Span` before impl block closing brace.
663     let hi = full_impl_span.hi() - BytePos(1);
664     // Point at the place right before the closing brace of the relevant `impl` to suggest
665     // adding the associated item at the end of its body.
666     let sugg_sp = full_impl_span.with_lo(hi).with_hi(hi);
667     // Obtain the level of indentation ending in `sugg_sp`.
668     let indentation = tcx.sess.source_map().span_to_margin(sugg_sp).unwrap_or(0);
669     // Make the whitespace that will make the suggestion have the right indentation.
670     let padding: String = " ".repeat(indentation);
671
672     for trait_item in missing_items {
673         let snippet = suggestion_signature(&trait_item, tcx);
674         let code = format!("{}{}\n{}", padding, snippet, padding);
675         let msg = format!("implement the missing item: `{}`", snippet);
676         let appl = Applicability::HasPlaceholders;
677         if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) {
678             err.span_label(span, format!("`{}` from trait", trait_item.ident));
679             err.tool_only_span_suggestion(sugg_sp, &msg, code, appl);
680         } else {
681             err.span_suggestion_hidden(sugg_sp, &msg, code, appl);
682         }
683     }
684     err.emit();
685 }
686
687 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
688 fn bounds_from_generic_predicates<'tcx>(
689     tcx: TyCtxt<'tcx>,
690     predicates: ty::GenericPredicates<'tcx>,
691 ) -> (String, String) {
692     let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
693     let mut projections = vec![];
694     for (predicate, _) in predicates.predicates {
695         debug!("predicate {:?}", predicate);
696         let bound_predicate = predicate.kind();
697         match bound_predicate.skip_binder() {
698             ty::PredicateKind::Trait(trait_predicate, _) => {
699                 let entry = types.entry(trait_predicate.self_ty()).or_default();
700                 let def_id = trait_predicate.def_id();
701                 if Some(def_id) != tcx.lang_items().sized_trait() {
702                     // Type params are `Sized` by default, do not add that restriction to the list
703                     // if it is a positive requirement.
704                     entry.push(trait_predicate.def_id());
705                 }
706             }
707             ty::PredicateKind::Projection(projection_pred) => {
708                 projections.push(bound_predicate.rebind(projection_pred));
709             }
710             _ => {}
711         }
712     }
713     let generics = if types.is_empty() {
714         "".to_string()
715     } else {
716         format!(
717             "<{}>",
718             types
719                 .keys()
720                 .filter_map(|t| match t.kind() {
721                     ty::Param(_) => Some(t.to_string()),
722                     // Avoid suggesting the following:
723                     // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
724                     _ => None,
725                 })
726                 .collect::<Vec<_>>()
727                 .join(", ")
728         )
729     };
730     let mut where_clauses = vec![];
731     for (ty, bounds) in types {
732         for bound in &bounds {
733             where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
734         }
735     }
736     for projection in &projections {
737         let p = projection.skip_binder();
738         // FIXME: this is not currently supported syntax, we should be looking at the `types` and
739         // insert the associated types where they correspond, but for now let's be "lazy" and
740         // propose this instead of the following valid resugaring:
741         // `T: Trait, Trait::Assoc = K` â†’ `T: Trait<Assoc = K>`
742         where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.item_def_id), p.ty));
743     }
744     let where_clauses = if where_clauses.is_empty() {
745         String::new()
746     } else {
747         format!(" where {}", where_clauses.join(", "))
748     };
749     (generics, where_clauses)
750 }
751
752 /// Return placeholder code for the given function.
753 fn fn_sig_suggestion<'tcx>(
754     tcx: TyCtxt<'tcx>,
755     sig: ty::FnSig<'tcx>,
756     ident: Ident,
757     predicates: ty::GenericPredicates<'tcx>,
758     assoc: &ty::AssocItem,
759 ) -> String {
760     let args = sig
761         .inputs()
762         .iter()
763         .enumerate()
764         .map(|(i, ty)| {
765             Some(match ty.kind() {
766                 ty::Param(_) if assoc.fn_has_self_parameter && i == 0 => "self".to_string(),
767                 ty::Ref(reg, ref_ty, mutability) if i == 0 => {
768                     let reg = match &format!("{}", reg)[..] {
769                         "'_" | "" => String::new(),
770                         reg => format!("{} ", reg),
771                     };
772                     if assoc.fn_has_self_parameter {
773                         match ref_ty.kind() {
774                             ty::Param(param) if param.name == kw::SelfUpper => {
775                                 format!("&{}{}self", reg, mutability.prefix_str())
776                             }
777
778                             _ => format!("self: {}", ty),
779                         }
780                     } else {
781                         format!("_: {}", ty)
782                     }
783                 }
784                 _ => {
785                     if assoc.fn_has_self_parameter && i == 0 {
786                         format!("self: {}", ty)
787                     } else {
788                         format!("_: {}", ty)
789                     }
790                 }
791             })
792         })
793         .chain(std::iter::once(if sig.c_variadic { Some("...".to_string()) } else { None }))
794         .filter_map(|arg| arg)
795         .collect::<Vec<String>>()
796         .join(", ");
797     let output = sig.output();
798     let output = if !output.is_unit() { format!(" -> {}", output) } else { String::new() };
799
800     let unsafety = sig.unsafety.prefix_str();
801     let (generics, where_clauses) = bounds_from_generic_predicates(tcx, predicates);
802
803     // FIXME: this is not entirely correct, as the lifetimes from borrowed params will
804     // not be present in the `fn` definition, not will we account for renamed
805     // lifetimes between the `impl` and the `trait`, but this should be good enough to
806     // fill in a significant portion of the missing code, and other subsequent
807     // suggestions can help the user fix the code.
808     format!(
809         "{}fn {}{}({}){}{} {{ todo!() }}",
810         unsafety, ident, generics, args, output, where_clauses
811     )
812 }
813
814 /// Return placeholder code for the given associated item.
815 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
816 /// structured suggestion.
817 fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
818     match assoc.kind {
819         ty::AssocKind::Fn => {
820             // We skip the binder here because the binder would deanonymize all
821             // late-bound regions, and we don't want method signatures to show up
822             // `as for<'r> fn(&'r MyType)`.  Pretty-printing handles late-bound
823             // regions just fine, showing `fn(&MyType)`.
824             fn_sig_suggestion(
825                 tcx,
826                 tcx.fn_sig(assoc.def_id).skip_binder(),
827                 assoc.ident,
828                 tcx.predicates_of(assoc.def_id),
829                 assoc,
830             )
831         }
832         ty::AssocKind::Type => format!("type {} = Type;", assoc.ident),
833         ty::AssocKind::Const => {
834             let ty = tcx.type_of(assoc.def_id);
835             let val = expr::ty_kind_suggestion(ty).unwrap_or("value");
836             format!("const {}: {} = {};", assoc.ident, ty, val)
837         }
838     }
839 }
840
841 /// Emit an error when encountering two or more variants in a transparent enum.
842 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
843     let variant_spans: Vec<_> = adt
844         .variants
845         .iter()
846         .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap())
847         .collect();
848     let msg = format!("needs exactly one variant, but has {}", adt.variants.len(),);
849     let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
850     err.span_label(sp, &msg);
851     if let [start @ .., end] = &*variant_spans {
852         for variant_span in start {
853             err.span_label(*variant_span, "");
854         }
855         err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
856     }
857     err.emit();
858 }
859
860 /// Emit an error when encountering two or more non-zero-sized fields in a transparent
861 /// enum.
862 fn bad_non_zero_sized_fields<'tcx>(
863     tcx: TyCtxt<'tcx>,
864     adt: &'tcx ty::AdtDef,
865     field_count: usize,
866     field_spans: impl Iterator<Item = Span>,
867     sp: Span,
868 ) {
869     let msg = format!("needs at most one non-zero-sized field, but has {}", field_count);
870     let mut err = struct_span_err!(
871         tcx.sess,
872         sp,
873         E0690,
874         "{}transparent {} {}",
875         if adt.is_enum() { "the variant of a " } else { "" },
876         adt.descr(),
877         msg,
878     );
879     err.span_label(sp, &msg);
880     for sp in field_spans {
881         err.span_label(sp, "this field is non-zero-sized");
882     }
883     err.emit();
884 }
885
886 fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) {
887     struct_span_err!(
888         tcx.sess,
889         span,
890         E0533,
891         "expected unit struct, unit variant or constant, found {}{}",
892         res.descr(),
893         tcx.sess
894             .source_map()
895             .span_to_snippet(span)
896             .map_or_else(|_| String::new(), |s| format!(" `{}`", s)),
897     )
898     .emit();
899 }
900
901 /// Controls whether the arguments are tupled. This is used for the call
902 /// operator.
903 ///
904 /// Tupling means that all call-side arguments are packed into a tuple and
905 /// passed as a single parameter. For example, if tupling is enabled, this
906 /// function:
907 ///
908 ///     fn f(x: (isize, isize))
909 ///
910 /// Can be called as:
911 ///
912 ///     f(1, 2);
913 ///
914 /// Instead of:
915 ///
916 ///     f((1, 2));
917 #[derive(Clone, Eq, PartialEq)]
918 enum TupleArgumentsFlag {
919     DontTupleArguments,
920     TupleArguments,
921 }
922
923 /// Controls how we perform fallback for unconstrained
924 /// type variables.
925 enum FallbackMode {
926     /// Do not fallback type variables to opaque types.
927     NoOpaque,
928     /// Perform all possible kinds of fallback, including
929     /// turning type variables to opaque types.
930     All,
931 }
932
933 /// A wrapper for `InferCtxt`'s `in_progress_typeck_results` field.
934 #[derive(Copy, Clone)]
935 struct MaybeInProgressTables<'a, 'tcx> {
936     maybe_typeck_results: Option<&'a RefCell<ty::TypeckResults<'tcx>>>,
937 }
938
939 impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> {
940     fn borrow(self) -> Ref<'a, ty::TypeckResults<'tcx>> {
941         match self.maybe_typeck_results {
942             Some(typeck_results) => typeck_results.borrow(),
943             None => bug!(
944                 "MaybeInProgressTables: inh/fcx.typeck_results.borrow() with no typeck results"
945             ),
946         }
947     }
948
949     fn borrow_mut(self) -> RefMut<'a, ty::TypeckResults<'tcx>> {
950         match self.maybe_typeck_results {
951             Some(typeck_results) => typeck_results.borrow_mut(),
952             None => bug!(
953                 "MaybeInProgressTables: inh/fcx.typeck_results.borrow_mut() with no typeck results"
954             ),
955         }
956     }
957 }
958
959 struct CheckItemTypesVisitor<'tcx> {
960     tcx: TyCtxt<'tcx>,
961 }
962
963 impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
964     fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
965         check_item_type(self.tcx, i);
966     }
967     fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
968     fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
969     fn visit_foreign_item(&mut self, _: &'tcx hir::ForeignItem<'tcx>) {}
970 }
971
972 fn typeck_item_bodies(tcx: TyCtxt<'_>, (): ()) {
973     tcx.par_body_owners(|body_owner_def_id| {
974         tcx.ensure().typeck(body_owner_def_id);
975     });
976 }
977
978 fn fatally_break_rust(sess: &Session) {
979     let handler = sess.diagnostic();
980     handler.span_bug_no_panic(
981         MultiSpan::new(),
982         "It looks like you're trying to break rust; would you like some ICE?",
983     );
984     handler.note_without_error("the compiler expectedly panicked. this is a feature.");
985     handler.note_without_error(
986         "we would appreciate a joke overview: \
987          https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
988     );
989     handler.note_without_error(&format!(
990         "rustc {} running on {}",
991         option_env!("CFG_VERSION").unwrap_or("unknown_version"),
992         config::host_triple(),
993     ));
994 }
995
996 fn potentially_plural_count(count: usize, word: &str) -> String {
997     format!("{} {}{}", count, word, pluralize!(count))
998 }
999
1000 fn has_expected_num_generic_args<'tcx>(
1001     tcx: TyCtxt<'tcx>,
1002     trait_did: Option<DefId>,
1003     expected: usize,
1004 ) -> bool {
1005     trait_did.map_or(true, |trait_did| {
1006         let generics = tcx.generics_of(trait_did);
1007         generics.count() == expected + if generics.has_self { 1 } else { 0 }
1008     })
1009 }