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