1 use super::coercion::CoerceMany;
2 use super::compare_method::check_type_bounds;
3 use super::compare_method::{compare_const_impl, compare_impl_method, compare_ty_impl};
4 use super::*;
5 
6 use rustc_attr as attr;
7 use rustc_errors::{Applicability, ErrorReported};
8 use rustc_hir as hir;
9 use rustc_hir::def_id::{DefId, LocalDefId};
10 use rustc_hir::intravisit::Visitor;
11 use rustc_hir::lang_items::LangItem;
12 use rustc_hir::{def::Res, ItemKind, Node, PathSegment};
13 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
14 use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
15 use rustc_middle::ty::fold::TypeFoldable;
16 use rustc_middle::ty::layout::MAX_SIMD_LANES;
17 use rustc_middle::ty::subst::GenericArgKind;
18 use rustc_middle::ty::util::{Discr, IntTypeExt};
19 use rustc_middle::ty::{self, OpaqueTypeKey, ParamEnv, RegionKind, Ty, TyCtxt};
20 use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
21 use rustc_span::symbol::sym;
22 use rustc_span::{self, MultiSpan, Span};
23 use rustc_target::spec::abi::Abi;
24 use rustc_trait_selection::traits;
25 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
26 use rustc_ty_utils::representability::{self, Representability};
27 
28 use std::iter;
29 use std::ops::ControlFlow;
30 
check_wf_new(tcx: TyCtxt<'_>)31 pub fn check_wf_new(tcx: TyCtxt<'_>) {
32     let visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
33     tcx.hir().par_visit_all_item_likes(&visit);
34 }
35 
check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi)36 pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
37     match tcx.sess.target.is_abi_supported(abi) {
38         Some(true) => (),
39         Some(false) => struct_span_err!(
40             tcx.sess,
41             span,
42             E0570,
43             "`{}` is not a supported ABI for the current target",
44             abi
45         )
46         .emit(),
47         None => {
48             tcx.struct_span_lint_hir(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
49                 lint.build("use of calling convention not supported on this target").emit()
50             });
51         }
52     }
53 
54     // This ABI is only allowed on function pointers
55     if abi == Abi::CCmseNonSecureCall {
56         struct_span_err!(
57             tcx.sess,
58             span,
59             E0781,
60             "the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
61         )
62         .emit()
63     }
64 }
65 
66 /// Helper used for fns and closures. Does the grungy work of checking a function
67 /// body and returns the function context used for that purpose, since in the case of a fn item
68 /// there is still a bit more to do.
69 ///
70 /// * ...
71 /// * inherited: other fields inherited from the enclosing fn (if any)
72 #[instrument(skip(inherited, body), level = "debug")]
check_fn<'a, 'tcx>( inherited: &'a Inherited<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, fn_sig: ty::FnSig<'tcx>, decl: &'tcx hir::FnDecl<'tcx>, fn_id: hir::HirId, body: &'tcx hir::Body<'tcx>, can_be_generator: Option<hir::Movability>, return_type_pre_known: bool, ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>)73 pub(super) fn check_fn<'a, 'tcx>(
74     inherited: &'a Inherited<'a, 'tcx>,
75     param_env: ty::ParamEnv<'tcx>,
76     fn_sig: ty::FnSig<'tcx>,
77     decl: &'tcx hir::FnDecl<'tcx>,
78     fn_id: hir::HirId,
79     body: &'tcx hir::Body<'tcx>,
80     can_be_generator: Option<hir::Movability>,
81     return_type_pre_known: bool,
82 ) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
83     let mut fn_sig = fn_sig;
84 
85     // Create the function context. This is either derived from scratch or,
86     // in the case of closures, based on the outer context.
87     let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
88     fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id));
89     fcx.return_type_pre_known = return_type_pre_known;
90 
91     let tcx = fcx.tcx;
92     let sess = tcx.sess;
93     let hir = tcx.hir();
94 
95     let declared_ret_ty = fn_sig.output();
96 
97     let revealed_ret_ty =
98         fcx.instantiate_opaque_types_from_value(declared_ret_ty, decl.output.span());
99     debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty);
100     fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty)));
101     fcx.ret_type_span = Some(decl.output.span());
102     if let ty::Opaque(..) = declared_ret_ty.kind() {
103         fcx.ret_coercion_impl_trait = Some(declared_ret_ty);
104     }
105     fn_sig = tcx.mk_fn_sig(
106         fn_sig.inputs().iter().cloned(),
107         revealed_ret_ty,
108         fn_sig.c_variadic,
109         fn_sig.unsafety,
110         fn_sig.abi,
111     );
112 
113     let span = body.value.span;
114 
115     fn_maybe_err(tcx, span, fn_sig.abi);
116 
117     if fn_sig.abi == Abi::RustCall {
118         let expected_args = if let ImplicitSelfKind::None = decl.implicit_self { 1 } else { 2 };
119 
120         let err = || {
121             let item = match tcx.hir().get(fn_id) {
122                 Node::Item(hir::Item { kind: ItemKind::Fn(header, ..), .. }) => Some(header),
123                 Node::ImplItem(hir::ImplItem {
124                     kind: hir::ImplItemKind::Fn(header, ..), ..
125                 }) => Some(header),
126                 Node::TraitItem(hir::TraitItem {
127                     kind: hir::TraitItemKind::Fn(header, ..),
128                     ..
129                 }) => Some(header),
130                 // Closures are RustCall, but they tuple their arguments, so shouldn't be checked
131                 Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => None,
132                 node => bug!("Item being checked wasn't a function/closure: {:?}", node),
133             };
134 
135             if let Some(header) = item {
136                 tcx.sess.span_err(header.span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple")
137             }
138         };
139 
140         if fn_sig.inputs().len() != expected_args {
141             err()
142         } else {
143             // FIXME(CraftSpider) Add a check on parameter expansion, so we don't just make the ICE happen later on
144             //   This will probably require wide-scale changes to support a TupleKind obligation
145             //   We can't resolve this without knowing the type of the param
146             if !matches!(fn_sig.inputs()[expected_args - 1].kind(), ty::Tuple(_) | ty::Param(_)) {
147                 err()
148             }
149         }
150     }
151 
152     if body.generator_kind.is_some() && can_be_generator.is_some() {
153         let yield_ty = fcx
154             .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
155         fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
156 
157         // Resume type defaults to `()` if the generator has no argument.
158         let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
159 
160         fcx.resume_yield_tys = Some((resume_ty, yield_ty));
161     }
162 
163     GatherLocalsVisitor::new(&fcx).visit_body(body);
164 
165     // C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
166     // (as it's created inside the body itself, not passed in from outside).
167     let maybe_va_list = if fn_sig.c_variadic {
168         let span = body.params.last().unwrap().span;
169         let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span));
170         let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
171 
172         Some(tcx.type_of(va_list_did).subst(tcx, &[region.into()]))
173     } else {
174         None
175     };
176 
177     // Add formal parameters.
178     let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
179     let inputs_fn = fn_sig.inputs().iter().copied();
180     for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
181         // Check the pattern.
182         let ty_span = try { inputs_hir?.get(idx)?.span };
183         fcx.check_pat_top(&param.pat, param_ty, ty_span, false);
184 
185         // Check that argument is Sized.
186         // The check for a non-trivial pattern is a hack to avoid duplicate warnings
187         // for simple cases like `fn foo(x: Trait)`,
188         // where we would error once on the parameter as a whole, and once on the binding `x`.
189         if param.pat.simple_ident().is_none() && !tcx.features().unsized_fn_params {
190             fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
191         }
192 
193         fcx.write_ty(param.hir_id, param_ty);
194     }
195 
196     inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
197 
198     fcx.in_tail_expr = true;
199     if let ty::Dynamic(..) = declared_ret_ty.kind() {
200         // FIXME: We need to verify that the return type is `Sized` after the return expression has
201         // been evaluated so that we have types available for all the nodes being returned, but that
202         // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
203         // causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
204         // while keeping the current ordering we will ignore the tail expression's type because we
205         // don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
206         // because we will trigger "unreachable expression" lints unconditionally.
207         // Because of all of this, we perform a crude check to know whether the simplest `!Sized`
208         // case that a newcomer might make, returning a bare trait, and in that case we populate
209         // the tail expression's type so that the suggestion will be correct, but ignore all other
210         // possible cases.
211         fcx.check_expr(&body.value);
212         fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
213     } else {
214         fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
215         fcx.check_return_expr(&body.value, false);
216     }
217     fcx.in_tail_expr = false;
218 
219     // We insert the deferred_generator_interiors entry after visiting the body.
220     // This ensures that all nested generators appear before the entry of this generator.
221     // resolve_generator_interiors relies on this property.
222     let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
223         let interior = fcx
224             .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
225         fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
226 
227         let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
228         Some(GeneratorTypes {
229             resume_ty,
230             yield_ty,
231             interior,
232             movability: can_be_generator.unwrap(),
233         })
234     } else {
235         None
236     };
237 
238     // Finalize the return check by taking the LUB of the return types
239     // we saw and assigning it to the expected return type. This isn't
240     // really expected to fail, since the coercions would have failed
241     // earlier when trying to find a LUB.
242     let coercion = fcx.ret_coercion.take().unwrap().into_inner();
243     let mut actual_return_ty = coercion.complete(&fcx);
244     debug!("actual_return_ty = {:?}", actual_return_ty);
245     if let ty::Dynamic(..) = declared_ret_ty.kind() {
246         // We have special-cased the case where the function is declared
247         // `-> dyn Foo` and we don't actually relate it to the
248         // `fcx.ret_coercion`, so just substitute a type variable.
249         actual_return_ty =
250             fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span });
251         debug!("actual_return_ty replaced with {:?}", actual_return_ty);
252     }
253     fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
254 
255     // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
256     if let Some(panic_impl_did) = tcx.lang_items().panic_impl() {
257         if panic_impl_did == hir.local_def_id(fn_id).to_def_id() {
258             if let Some(panic_info_did) = tcx.lang_items().panic_info() {
259                 if *declared_ret_ty.kind() != ty::Never {
260                     sess.span_err(decl.output.span(), "return type should be `!`");
261                 }
262 
263                 let inputs = fn_sig.inputs();
264                 let span = hir.span(fn_id);
265                 if inputs.len() == 1 {
266                     let arg_is_panic_info = match *inputs[0].kind() {
267                         ty::Ref(region, ty, mutbl) => match *ty.kind() {
268                             ty::Adt(ref adt, _) => {
269                                 adt.did == panic_info_did
270                                     && mutbl == hir::Mutability::Not
271                                     && *region != RegionKind::ReStatic
272                             }
273                             _ => false,
274                         },
275                         _ => false,
276                     };
277 
278                     if !arg_is_panic_info {
279                         sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
280                     }
281 
282                     if let Node::Item(item) = hir.get(fn_id) {
283                         if let ItemKind::Fn(_, ref generics, _) = item.kind {
284                             if !generics.params.is_empty() {
285                                 sess.span_err(span, "should have no type parameters");
286                             }
287                         }
288                     }
289                 } else {
290                     let span = sess.source_map().guess_head_span(span);
291                     sess.span_err(span, "function should have one argument");
292                 }
293             } else {
294                 sess.err("language item required, but not found: `panic_info`");
295             }
296         }
297     }
298 
299     // Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
300     if let Some(alloc_error_handler_did) = tcx.lang_items().oom() {
301         if alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id() {
302             if let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() {
303                 if *declared_ret_ty.kind() != ty::Never {
304                     sess.span_err(decl.output.span(), "return type should be `!`");
305                 }
306 
307                 let inputs = fn_sig.inputs();
308                 let span = hir.span(fn_id);
309                 if inputs.len() == 1 {
310                     let arg_is_alloc_layout = match inputs[0].kind() {
311                         ty::Adt(ref adt, _) => adt.did == alloc_layout_did,
312                         _ => false,
313                     };
314 
315                     if !arg_is_alloc_layout {
316                         sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
317                     }
318 
319                     if let Node::Item(item) = hir.get(fn_id) {
320                         if let ItemKind::Fn(_, ref generics, _) = item.kind {
321                             if !generics.params.is_empty() {
322                                 sess.span_err(
323                                     span,
324                                     "`#[alloc_error_handler]` function should have no type \
325                                      parameters",
326                                 );
327                             }
328                         }
329                     }
330                 } else {
331                     let span = sess.source_map().guess_head_span(span);
332                     sess.span_err(span, "function should have one argument");
333                 }
334             } else {
335                 sess.err("language item required, but not found: `alloc_layout`");
336             }
337         }
338     }
339 
340     (fcx, gen_ty)
341 }
342 
check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span)343 fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) {
344     let def = tcx.adt_def(def_id);
345     def.destructor(tcx); // force the destructor to be evaluated
346     check_representable(tcx, span, def_id);
347 
348     if def.repr.simd() {
349         check_simd(tcx, span, def_id);
350     }
351 
352     check_transparent(tcx, span, def);
353     check_packed(tcx, span, def);
354 }
355 
check_union(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span)356 fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) {
357     let def = tcx.adt_def(def_id);
358     def.destructor(tcx); // force the destructor to be evaluated
359     check_representable(tcx, span, def_id);
360     check_transparent(tcx, span, def);
361     check_union_fields(tcx, span, def_id);
362     check_packed(tcx, span, def);
363 }
364 
365 /// Check that the fields of the `union` do not need dropping.
check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool366 fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
367     let item_type = tcx.type_of(item_def_id);
368     if let ty::Adt(def, substs) = item_type.kind() {
369         assert!(def.is_union());
370         let fields = &def.non_enum_variant().fields;
371         let param_env = tcx.param_env(item_def_id);
372         for field in fields {
373             let field_ty = field.ty(tcx, substs);
374             if field_ty.needs_drop(tcx, param_env) {
375                 let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
376                     // We are currently checking the type this field came from, so it must be local.
377                     Some(Node::Field(field)) => (field.span, field.ty.span),
378                     _ => unreachable!("mir field has to correspond to hir field"),
379                 };
380                 struct_span_err!(
381                     tcx.sess,
382                     field_span,
383                     E0740,
384                     "unions may not contain fields that need dropping"
385                 )
386                 .multipart_suggestion_verbose(
387                     "wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped",
388                     vec![
389                         (ty_span.shrink_to_lo(), format!("std::mem::ManuallyDrop<")),
390                         (ty_span.shrink_to_hi(), ">".into()),
391                     ],
392                     Applicability::MaybeIncorrect,
393                 )
394                 .emit();
395                 return false;
396             }
397         }
398     } else {
399         span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind());
400     }
401     true
402 }
403 
404 /// Check that a `static` is inhabited.
check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span)405 fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
406     // Make sure statics are inhabited.
407     // Other parts of the compiler assume that there are no uninhabited places. In principle it
408     // would be enough to check this for `extern` statics, as statics with an initializer will
409     // have UB during initialization if they are uninhabited, but there also seems to be no good
410     // reason to allow any statics to be uninhabited.
411     let ty = tcx.type_of(def_id);
412     let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
413         Ok(l) => l,
414         Err(_) => {
415             // Generic statics are rejected, but we still reach this case.
416             tcx.sess.delay_span_bug(span, "generic static must be rejected");
417             return;
418         }
419     };
420     if layout.abi.is_uninhabited() {
421         tcx.struct_span_lint_hir(
422             UNINHABITED_STATIC,
423             tcx.hir().local_def_id_to_hir_id(def_id),
424             span,
425             |lint| {
426                 lint.build("static of uninhabited type")
427                 .note("uninhabited statics cannot be initialized, and any access would be an immediate error")
428                 .emit();
429             },
430         );
431     }
432 }
433 
434 /// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
435 /// projections that would result in "inheriting lifetimes".
check_opaque<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, substs: SubstsRef<'tcx>, span: Span, origin: &hir::OpaqueTyOrigin, )436 pub(super) fn check_opaque<'tcx>(
437     tcx: TyCtxt<'tcx>,
438     def_id: LocalDefId,
439     substs: SubstsRef<'tcx>,
440     span: Span,
441     origin: &hir::OpaqueTyOrigin,
442 ) {
443     check_opaque_for_inheriting_lifetimes(tcx, def_id, span);
444     if tcx.type_of(def_id).references_error() {
445         return;
446     }
447     if check_opaque_for_cycles(tcx, def_id, substs, span, origin).is_err() {
448         return;
449     }
450     check_opaque_meets_bounds(tcx, def_id, substs, span, origin);
451 }
452 
453 /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
454 /// in "inheriting lifetimes".
455 #[instrument(level = "debug", skip(tcx, span))]
check_opaque_for_inheriting_lifetimes( tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span, )456 pub(super) fn check_opaque_for_inheriting_lifetimes(
457     tcx: TyCtxt<'tcx>,
458     def_id: LocalDefId,
459     span: Span,
460 ) {
461     let item = tcx.hir().expect_item(tcx.hir().local_def_id_to_hir_id(def_id));
462     debug!(?item, ?span);
463 
464     struct FoundParentLifetime;
465     struct FindParentLifetimeVisitor<'tcx>(TyCtxt<'tcx>, &'tcx ty::Generics);
466     impl<'tcx> ty::fold::TypeVisitor<'tcx> for FindParentLifetimeVisitor<'tcx> {
467         type BreakTy = FoundParentLifetime;
468         fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
469             Some(self.0)
470         }
471 
472         fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
473             debug!("FindParentLifetimeVisitor: r={:?}", r);
474             if let RegionKind::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = r {
475                 if *index < self.1.parent_count as u32 {
476                     return ControlFlow::Break(FoundParentLifetime);
477                 } else {
478                     return ControlFlow::CONTINUE;
479                 }
480             }
481 
482             r.super_visit_with(self)
483         }
484 
485         fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
486             if let ty::ConstKind::Unevaluated(..) = c.val {
487                 // FIXME(#72219) We currently don't detect lifetimes within substs
488                 // which would violate this check. Even though the particular substitution is not used
489                 // within the const, this should still be fixed.
490                 return ControlFlow::CONTINUE;
491             }
492             c.super_visit_with(self)
493         }
494     }
495 
496     struct ProhibitOpaqueVisitor<'tcx> {
497         tcx: TyCtxt<'tcx>,
498         opaque_identity_ty: Ty<'tcx>,
499         generics: &'tcx ty::Generics,
500         selftys: Vec<(Span, Option<String>)>,
501     }
502 
503     impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
504         type BreakTy = Ty<'tcx>;
505         fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
506             Some(self.tcx)
507         }
508 
509         fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
510             debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t);
511             if t == self.opaque_identity_ty {
512                 ControlFlow::CONTINUE
513             } else {
514                 t.super_visit_with(&mut FindParentLifetimeVisitor(self.tcx, self.generics))
515                     .map_break(|FoundParentLifetime| t)
516             }
517         }
518     }
519 
520     impl Visitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
521         type Map = rustc_middle::hir::map::Map<'tcx>;
522 
523         fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
524             hir::intravisit::NestedVisitorMap::OnlyBodies(self.tcx.hir())
525         }
526 
527         fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
528             match arg.kind {
529                 hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
530                     [PathSegment { res: Some(Res::SelfTy(_, impl_ref)), .. }] => {
531                         let impl_ty_name =
532                             impl_ref.map(|(def_id, _)| self.tcx.def_path_str(def_id));
533                         self.selftys.push((path.span, impl_ty_name));
534                     }
535                     _ => {}
536                 },
537                 _ => {}
538             }
539             hir::intravisit::walk_ty(self, arg);
540         }
541     }
542 
543     if let ItemKind::OpaqueTy(hir::OpaqueTy {
544         origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
545         ..
546     }) = item.kind
547     {
548         let mut visitor = ProhibitOpaqueVisitor {
549             opaque_identity_ty: tcx.mk_opaque(
550                 def_id.to_def_id(),
551                 InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
552             ),
553             generics: tcx.generics_of(def_id),
554             tcx,
555             selftys: vec![],
556         };
557         let prohibit_opaque = tcx
558             .explicit_item_bounds(def_id)
559             .iter()
560             .try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor));
561         debug!(
562             "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor.opaque_identity_ty={:?}, visitor.generics={:?}",
563             prohibit_opaque, visitor.opaque_identity_ty, visitor.generics
564         );
565 
566         if let Some(ty) = prohibit_opaque.break_value() {
567             visitor.visit_item(&item);
568             let is_async = match item.kind {
569                 ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
570                     matches!(origin, hir::OpaqueTyOrigin::AsyncFn)
571                 }
572                 _ => unreachable!(),
573             };
574 
575             let mut err = struct_span_err!(
576                 tcx.sess,
577                 span,
578                 E0760,
579                 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
580                  a parent scope",
581                 if is_async { "async fn" } else { "impl Trait" },
582             );
583 
584             for (span, name) in visitor.selftys {
585                 err.span_suggestion(
586                     span,
587                     "consider spelling out the type instead",
588                     name.unwrap_or_else(|| format!("{:?}", ty)),
589                     Applicability::MaybeIncorrect,
590                 );
591             }
592             err.emit();
593         }
594     }
595 }
596 
597 /// Checks that an opaque type does not contain cycles.
check_opaque_for_cycles<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, substs: SubstsRef<'tcx>, span: Span, origin: &hir::OpaqueTyOrigin, ) -> Result<(), ErrorReported>598 pub(super) fn check_opaque_for_cycles<'tcx>(
599     tcx: TyCtxt<'tcx>,
600     def_id: LocalDefId,
601     substs: SubstsRef<'tcx>,
602     span: Span,
603     origin: &hir::OpaqueTyOrigin,
604 ) -> Result<(), ErrorReported> {
605     if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() {
606         match origin {
607             hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span),
608             _ => opaque_type_cycle_error(tcx, def_id, span),
609         }
610         Err(ErrorReported)
611     } else {
612         Ok(())
613     }
614 }
615 
616 /// Check that the concrete type behind `impl Trait` actually implements `Trait`.
617 ///
618 /// This is mostly checked at the places that specify the opaque type, but we
619 /// check those cases in the `param_env` of that function, which may have
620 /// bounds not on this opaque type:
621 ///
622 /// type X<T> = impl Clone
623 /// fn f<T: Clone>(t: T) -> X<T> {
624 ///     t
625 /// }
626 ///
627 /// Without this check the above code is incorrectly accepted: we would ICE if
628 /// some tried, for example, to clone an `Option<X<&mut ()>>`.
check_opaque_meets_bounds<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, substs: SubstsRef<'tcx>, span: Span, origin: &hir::OpaqueTyOrigin, )629 fn check_opaque_meets_bounds<'tcx>(
630     tcx: TyCtxt<'tcx>,
631     def_id: LocalDefId,
632     substs: SubstsRef<'tcx>,
633     span: Span,
634     origin: &hir::OpaqueTyOrigin,
635 ) {
636     match origin {
637         // Checked when type checking the function containing them.
638         hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => return,
639         // Can have different predicates to their defining use
640         hir::OpaqueTyOrigin::TyAlias => {}
641     }
642 
643     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
644     let param_env = tcx.param_env(def_id);
645 
646     tcx.infer_ctxt().enter(move |infcx| {
647         let inh = Inherited::new(infcx, def_id);
648         let infcx = &inh.infcx;
649         let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
650 
651         let misc_cause = traits::ObligationCause::misc(span, hir_id);
652 
653         let _ = inh.register_infer_ok_obligations(
654             infcx.instantiate_opaque_types(hir_id, param_env, opaque_ty, span),
655         );
656 
657         let opaque_type_map = infcx.inner.borrow().opaque_types.clone();
658         for (OpaqueTypeKey { def_id, substs }, opaque_defn) in opaque_type_map {
659             match infcx
660                 .at(&misc_cause, param_env)
661                 .eq(opaque_defn.concrete_ty, tcx.type_of(def_id).subst(tcx, substs))
662             {
663                 Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok),
664                 Err(ty_err) => tcx.sess.delay_span_bug(
665                     opaque_defn.definition_span,
666                     &format!(
667                         "could not unify `{}` with revealed type:\n{}",
668                         opaque_defn.concrete_ty, ty_err,
669                     ),
670                 ),
671             }
672         }
673 
674         // Check that all obligations are satisfied by the implementation's
675         // version.
676         let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx);
677         if !errors.is_empty() {
678             infcx.report_fulfillment_errors(&errors, None, false);
679         }
680 
681         // Finally, resolve all regions. This catches wily misuses of
682         // lifetime parameters.
683         let fcx = FnCtxt::new(&inh, param_env, hir_id);
684         fcx.regionck_item(hir_id, span, FxHashSet::default());
685     });
686 }
687 
check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>)688 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
689     debug!(
690         "check_item_type(it.def_id={:?}, it.name={})",
691         it.def_id,
692         tcx.def_path_str(it.def_id.to_def_id())
693     );
694     let _indenter = indenter();
695     match it.kind {
696         // Consts can play a role in type-checking, so they are included here.
697         hir::ItemKind::Static(..) => {
698             tcx.ensure().typeck(it.def_id);
699             maybe_check_static_with_link_section(tcx, it.def_id, it.span);
700             check_static_inhabited(tcx, it.def_id, it.span);
701         }
702         hir::ItemKind::Const(..) => {
703             tcx.ensure().typeck(it.def_id);
704         }
705         hir::ItemKind::Enum(ref enum_definition, _) => {
706             check_enum(tcx, it.span, &enum_definition.variants, it.def_id);
707         }
708         hir::ItemKind::Fn(..) => {} // entirely within check_item_body
709         hir::ItemKind::Impl(ref impl_) => {
710             debug!("ItemKind::Impl {} with id {:?}", it.ident, it.def_id);
711             if let Some(impl_trait_ref) = tcx.impl_trait_ref(it.def_id) {
712                 check_impl_items_against_trait(
713                     tcx,
714                     it.span,
715                     it.def_id,
716                     impl_trait_ref,
717                     &impl_.items,
718                 );
719                 let trait_def_id = impl_trait_ref.def_id;
720                 check_on_unimplemented(tcx, trait_def_id, it);
721             }
722         }
723         hir::ItemKind::Trait(_, _, _, _, ref items) => {
724             check_on_unimplemented(tcx, it.def_id.to_def_id(), it);
725 
726             for item in items.iter() {
727                 let item = tcx.hir().trait_item(item.id);
728                 match item.kind {
729                     hir::TraitItemKind::Fn(ref sig, _) => {
730                         let abi = sig.header.abi;
731                         fn_maybe_err(tcx, item.ident.span, abi);
732                     }
733                     hir::TraitItemKind::Type(.., Some(_default)) => {
734                         let assoc_item = tcx.associated_item(item.def_id);
735                         let trait_substs =
736                             InternalSubsts::identity_for_item(tcx, it.def_id.to_def_id());
737                         let _: Result<_, rustc_errors::ErrorReported> = check_type_bounds(
738                             tcx,
739                             assoc_item,
740                             assoc_item,
741                             item.span,
742                             ty::TraitRef { def_id: it.def_id.to_def_id(), substs: trait_substs },
743                         );
744                     }
745                     _ => {}
746                 }
747             }
748         }
749         hir::ItemKind::Struct(..) => {
750             check_struct(tcx, it.def_id, it.span);
751         }
752         hir::ItemKind::Union(..) => {
753             check_union(tcx, it.def_id, it.span);
754         }
755         hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
756             // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
757             // `async-std` (and `pub async fn` in general).
758             // Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
759             // See https://github.com/rust-lang/rust/issues/75100
760             if !tcx.sess.opts.actually_rustdoc {
761                 let substs = InternalSubsts::identity_for_item(tcx, it.def_id.to_def_id());
762                 check_opaque(tcx, it.def_id, substs, it.span, &origin);
763             }
764         }
765         hir::ItemKind::TyAlias(..) => {
766             let pty_ty = tcx.type_of(it.def_id);
767             let generics = tcx.generics_of(it.def_id);
768             check_type_params_are_used(tcx, &generics, pty_ty);
769         }
770         hir::ItemKind::ForeignMod { abi, items } => {
771             check_abi(tcx, it.hir_id(), it.span, abi);
772 
773             if abi == Abi::RustIntrinsic {
774                 for item in items {
775                     let item = tcx.hir().foreign_item(item.id);
776                     intrinsic::check_intrinsic_type(tcx, item);
777                 }
778             } else if abi == Abi::PlatformIntrinsic {
779                 for item in items {
780                     let item = tcx.hir().foreign_item(item.id);
781                     intrinsic::check_platform_intrinsic_type(tcx, item);
782                 }
783             } else {
784                 for item in items {
785                     let def_id = item.id.def_id;
786                     let generics = tcx.generics_of(def_id);
787                     let own_counts = generics.own_counts();
788                     if generics.params.len() - own_counts.lifetimes != 0 {
789                         let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
790                             (_, 0) => ("type", "types", Some("u32")),
791                             // We don't specify an example value, because we can't generate
792                             // a valid value for any type.
793                             (0, _) => ("const", "consts", None),
794                             _ => ("type or const", "types or consts", None),
795                         };
796                         struct_span_err!(
797                             tcx.sess,
798                             item.span,
799                             E0044,
800                             "foreign items may not have {} parameters",
801                             kinds,
802                         )
803                         .span_label(item.span, &format!("can't have {} parameters", kinds))
804                         .help(
805                             // FIXME: once we start storing spans for type arguments, turn this
806                             // into a suggestion.
807                             &format!(
808                                 "replace the {} parameters with concrete {}{}",
809                                 kinds,
810                                 kinds_pl,
811                                 egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
812                             ),
813                         )
814                         .emit();
815                     }
816 
817                     let item = tcx.hir().foreign_item(item.id);
818                     match item.kind {
819                         hir::ForeignItemKind::Fn(ref fn_decl, _, _) => {
820                             require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span);
821                         }
822                         hir::ForeignItemKind::Static(..) => {
823                             check_static_inhabited(tcx, def_id, item.span);
824                         }
825                         _ => {}
826                     }
827                 }
828             }
829         }
830         _ => { /* nothing to do */ }
831     }
832 }
833 
check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>)834 pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, trait_def_id: DefId, item: &hir::Item<'_>) {
835     // an error would be reported if this fails.
836     let _ = traits::OnUnimplementedDirective::of_item(tcx, trait_def_id, item.def_id.to_def_id());
837 }
838 
check_specialization_validity<'tcx>( tcx: TyCtxt<'tcx>, trait_def: &ty::TraitDef, trait_item: &ty::AssocItem, impl_id: DefId, impl_item: &hir::ImplItem<'_>, )839 pub(super) fn check_specialization_validity<'tcx>(
840     tcx: TyCtxt<'tcx>,
841     trait_def: &ty::TraitDef,
842     trait_item: &ty::AssocItem,
843     impl_id: DefId,
844     impl_item: &hir::ImplItem<'_>,
845 ) {
846     let kind = match impl_item.kind {
847         hir::ImplItemKind::Const(..) => ty::AssocKind::Const,
848         hir::ImplItemKind::Fn(..) => ty::AssocKind::Fn,
849         hir::ImplItemKind::TyAlias(_) => ty::AssocKind::Type,
850     };
851 
852     let ancestors = match trait_def.ancestors(tcx, impl_id) {
853         Ok(ancestors) => ancestors,
854         Err(_) => return,
855     };
856     let mut ancestor_impls = ancestors.skip(1).filter_map(|parent| {
857         if parent.is_from_trait() {
858             None
859         } else {
860             Some((parent, parent.item(tcx, trait_item.ident, kind, trait_def.def_id)))
861         }
862     });
863 
864     let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
865         match parent_item {
866             // Parent impl exists, and contains the parent item we're trying to specialize, but
867             // doesn't mark it `default`.
868             Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
869                 Some(Err(parent_impl.def_id()))
870             }
871 
872             // Parent impl contains item and makes it specializable.
873             Some(_) => Some(Ok(())),
874 
875             // Parent impl doesn't mention the item. This means it's inherited from the
876             // grandparent. In that case, if parent is a `default impl`, inherited items use the
877             // "defaultness" from the grandparent, else they are final.
878             None => {
879                 if tcx.impl_defaultness(parent_impl.def_id()).is_default() {
880                     None
881                 } else {
882                     Some(Err(parent_impl.def_id()))
883                 }
884             }
885         }
886     });
887 
888     // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
889     // item. This is allowed, the item isn't actually getting specialized here.
890     let result = opt_result.unwrap_or(Ok(()));
891 
892     if let Err(parent_impl) = result {
893         report_forbidden_specialization(tcx, impl_item, parent_impl);
894     }
895 }
896 
check_impl_items_against_trait<'tcx>( tcx: TyCtxt<'tcx>, full_impl_span: Span, impl_id: LocalDefId, impl_trait_ref: ty::TraitRef<'tcx>, impl_item_refs: &[hir::ImplItemRef], )897 pub(super) fn check_impl_items_against_trait<'tcx>(
898     tcx: TyCtxt<'tcx>,
899     full_impl_span: Span,
900     impl_id: LocalDefId,
901     impl_trait_ref: ty::TraitRef<'tcx>,
902     impl_item_refs: &[hir::ImplItemRef],
903 ) {
904     // If the trait reference itself is erroneous (so the compilation is going
905     // to fail), skip checking the items here -- the `impl_item` table in `tcx`
906     // isn't populated for such impls.
907     if impl_trait_ref.references_error() {
908         return;
909     }
910 
911     // Negative impls are not expected to have any items
912     match tcx.impl_polarity(impl_id) {
913         ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
914         ty::ImplPolarity::Negative => {
915             if let [first_item_ref, ..] = impl_item_refs {
916                 let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
917                 struct_span_err!(
918                     tcx.sess,
919                     first_item_span,
920                     E0749,
921                     "negative impls cannot have any items"
922                 )
923                 .emit();
924             }
925             return;
926         }
927     }
928 
929     // Locate trait definition and items
930     let trait_def = tcx.trait_def(impl_trait_ref.def_id);
931     let impl_items = impl_item_refs.iter().map(|iiref| tcx.hir().impl_item(iiref.id));
932     let associated_items = tcx.associated_items(impl_trait_ref.def_id);
933 
934     // Check existing impl methods to see if they are both present in trait
935     // and compatible with trait signature
936     for impl_item in impl_items {
937         let ty_impl_item = tcx.associated_item(impl_item.def_id);
938 
939         let mut items =
940             associated_items.filter_by_name(tcx, ty_impl_item.ident, impl_trait_ref.def_id);
941 
942         let (compatible_kind, ty_trait_item) = if let Some(ty_trait_item) = items.next() {
943             let is_compatible = |ty: &&ty::AssocItem| match (ty.kind, &impl_item.kind) {
944                 (ty::AssocKind::Const, hir::ImplItemKind::Const(..)) => true,
945                 (ty::AssocKind::Fn, hir::ImplItemKind::Fn(..)) => true,
946                 (ty::AssocKind::Type, hir::ImplItemKind::TyAlias(..)) => true,
947                 _ => false,
948             };
949 
950             // If we don't have a compatible item, we'll use the first one whose name matches
951             // to report an error.
952             let mut compatible_kind = is_compatible(&ty_trait_item);
953             let mut trait_item = ty_trait_item;
954 
955             if !compatible_kind {
956                 if let Some(ty_trait_item) = items.find(is_compatible) {
957                     compatible_kind = true;
958                     trait_item = ty_trait_item;
959                 }
960             }
961 
962             (compatible_kind, trait_item)
963         } else {
964             continue;
965         };
966 
967         if compatible_kind {
968             match impl_item.kind {
969                 hir::ImplItemKind::Const(..) => {
970                     // Find associated const definition.
971                     compare_const_impl(
972                         tcx,
973                         &ty_impl_item,
974                         impl_item.span,
975                         &ty_trait_item,
976                         impl_trait_ref,
977                     );
978                 }
979                 hir::ImplItemKind::Fn(..) => {
980                     let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
981                     compare_impl_method(
982                         tcx,
983                         &ty_impl_item,
984                         impl_item.span,
985                         &ty_trait_item,
986                         impl_trait_ref,
987                         opt_trait_span,
988                     );
989                 }
990                 hir::ImplItemKind::TyAlias(_) => {
991                     let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id);
992                     compare_ty_impl(
993                         tcx,
994                         &ty_impl_item,
995                         impl_item.span,
996                         &ty_trait_item,
997                         impl_trait_ref,
998                         opt_trait_span,
999                     );
1000                 }
1001             }
1002 
1003             check_specialization_validity(
1004                 tcx,
1005                 trait_def,
1006                 &ty_trait_item,
1007                 impl_id.to_def_id(),
1008                 impl_item,
1009             );
1010         } else {
1011             report_mismatch_error(
1012                 tcx,
1013                 ty_trait_item.def_id,
1014                 impl_trait_ref,
1015                 impl_item,
1016                 &ty_impl_item,
1017             );
1018         }
1019     }
1020 
1021     if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
1022         let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
1023 
1024         // Check for missing items from trait
1025         let mut missing_items = Vec::new();
1026         for trait_item in tcx.associated_items(impl_trait_ref.def_id).in_definition_order() {
1027             let is_implemented = ancestors
1028                 .leaf_def(tcx, trait_item.ident, trait_item.kind)
1029                 .map(|node_item| !node_item.defining_node.is_from_trait())
1030                 .unwrap_or(false);
1031 
1032             if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
1033                 if !trait_item.defaultness.has_value() {
1034                     missing_items.push(*trait_item);
1035                 }
1036             }
1037         }
1038 
1039         if !missing_items.is_empty() {
1040             missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
1041         }
1042     }
1043 }
1044 
1045 #[inline(never)]
1046 #[cold]
report_mismatch_error<'tcx>( tcx: TyCtxt<'tcx>, trait_item_def_id: DefId, impl_trait_ref: ty::TraitRef<'tcx>, impl_item: &hir::ImplItem<'_>, ty_impl_item: &ty::AssocItem, )1047 fn report_mismatch_error<'tcx>(
1048     tcx: TyCtxt<'tcx>,
1049     trait_item_def_id: DefId,
1050     impl_trait_ref: ty::TraitRef<'tcx>,
1051     impl_item: &hir::ImplItem<'_>,
1052     ty_impl_item: &ty::AssocItem,
1053 ) {
1054     let mut err = match impl_item.kind {
1055         hir::ImplItemKind::Const(..) => {
1056             // Find associated const definition.
1057             struct_span_err!(
1058                 tcx.sess,
1059                 impl_item.span,
1060                 E0323,
1061                 "item `{}` is an associated const, which doesn't match its trait `{}`",
1062                 ty_impl_item.ident,
1063                 impl_trait_ref.print_only_trait_path()
1064             )
1065         }
1066 
1067         hir::ImplItemKind::Fn(..) => {
1068             struct_span_err!(
1069                 tcx.sess,
1070                 impl_item.span,
1071                 E0324,
1072                 "item `{}` is an associated method, which doesn't match its trait `{}`",
1073                 ty_impl_item.ident,
1074                 impl_trait_ref.print_only_trait_path()
1075             )
1076         }
1077 
1078         hir::ImplItemKind::TyAlias(_) => {
1079             struct_span_err!(
1080                 tcx.sess,
1081                 impl_item.span,
1082                 E0325,
1083                 "item `{}` is an associated type, which doesn't match its trait `{}`",
1084                 ty_impl_item.ident,
1085                 impl_trait_ref.print_only_trait_path()
1086             )
1087         }
1088     };
1089 
1090     err.span_label(impl_item.span, "does not match trait");
1091     if let Some(trait_span) = tcx.hir().span_if_local(trait_item_def_id) {
1092         err.span_label(trait_span, "item in trait");
1093     }
1094     err.emit();
1095 }
1096 
1097 /// Checks whether a type can be represented in memory. In particular, it
1098 /// identifies types that contain themselves without indirection through a
1099 /// pointer, which would mean their size is unbounded.
check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool1100 pub(super) fn check_representable(tcx: TyCtxt<'_>, sp: Span, item_def_id: LocalDefId) -> bool {
1101     let rty = tcx.type_of(item_def_id);
1102 
1103     // Check that it is possible to represent this type. This call identifies
1104     // (1) types that contain themselves and (2) types that contain a different
1105     // recursive type. It is only necessary to throw an error on those that
1106     // contain themselves. For case 2, there must be an inner type that will be
1107     // caught by case 1.
1108     match representability::ty_is_representable(tcx, rty, sp) {
1109         Representability::SelfRecursive(spans) => {
1110             recursive_type_with_infinite_size_error(tcx, item_def_id.to_def_id(), spans);
1111             return false;
1112         }
1113         Representability::Representable | Representability::ContainsRecursive => (),
1114     }
1115     true
1116 }
1117 
check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId)1118 pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
1119     let t = tcx.type_of(def_id);
1120     if let ty::Adt(def, substs) = t.kind() {
1121         if def.is_struct() {
1122             let fields = &def.non_enum_variant().fields;
1123             if fields.is_empty() {
1124                 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
1125                 return;
1126             }
1127             let e = fields[0].ty(tcx, substs);
1128             if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1129                 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1130                     .span_label(sp, "SIMD elements must have the same type")
1131                     .emit();
1132                 return;
1133             }
1134 
1135             let len = if let ty::Array(_ty, c) = e.kind() {
1136                 c.try_eval_usize(tcx, tcx.param_env(def.did))
1137             } else {
1138                 Some(fields.len() as u64)
1139             };
1140             if let Some(len) = len {
1141                 if len == 0 {
1142                     struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
1143                     return;
1144                 } else if len > MAX_SIMD_LANES {
1145                     struct_span_err!(
1146                         tcx.sess,
1147                         sp,
1148                         E0075,
1149                         "SIMD vector cannot have more than {} elements",
1150                         MAX_SIMD_LANES,
1151                     )
1152                     .emit();
1153                     return;
1154                 }
1155             }
1156 
1157             // Check that we use types valid for use in the lanes of a SIMD "vector register"
1158             // These are scalar types which directly match a "machine" type
1159             // Yes: Integers, floats, "thin" pointers
1160             // No: char, "fat" pointers, compound types
1161             match e.kind() {
1162                 ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
1163                 ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
1164                 ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
1165                 ty::Array(t, _clen)
1166                     if matches!(
1167                         t.kind(),
1168                         ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_)
1169                     ) =>
1170                 { /* struct([f32; 4]) is ok */ }
1171                 _ => {
1172                     struct_span_err!(
1173                         tcx.sess,
1174                         sp,
1175                         E0077,
1176                         "SIMD vector element type should be a \
1177                          primitive scalar (integer/float/pointer) type"
1178                     )
1179                     .emit();
1180                     return;
1181                 }
1182             }
1183         }
1184     }
1185 }
1186 
check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef)1187 pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: &ty::AdtDef) {
1188     let repr = def.repr;
1189     if repr.packed() {
1190         for attr in tcx.get_attrs(def.did).iter() {
1191             for r in attr::find_repr_attrs(&tcx.sess, attr) {
1192                 if let attr::ReprPacked(pack) = r {
1193                     if let Some(repr_pack) = repr.pack {
1194                         if pack as u64 != repr_pack.bytes() {
1195                             struct_span_err!(
1196                                 tcx.sess,
1197                                 sp,
1198                                 E0634,
1199                                 "type has conflicting packed representation hints"
1200                             )
1201                             .emit();
1202                         }
1203                     }
1204                 }
1205             }
1206         }
1207         if repr.align.is_some() {
1208             struct_span_err!(
1209                 tcx.sess,
1210                 sp,
1211                 E0587,
1212                 "type has conflicting packed and align representation hints"
1213             )
1214             .emit();
1215         } else {
1216             if let Some(def_spans) = check_packed_inner(tcx, def.did, &mut vec![]) {
1217                 let mut err = struct_span_err!(
1218                     tcx.sess,
1219                     sp,
1220                     E0588,
1221                     "packed type cannot transitively contain a `#[repr(align)]` type"
1222                 );
1223 
1224                 err.span_note(
1225                     tcx.def_span(def_spans[0].0),
1226                     &format!(
1227                         "`{}` has a `#[repr(align)]` attribute",
1228                         tcx.item_name(def_spans[0].0)
1229                     ),
1230                 );
1231 
1232                 if def_spans.len() > 2 {
1233                     let mut first = true;
1234                     for (adt_def, span) in def_spans.iter().skip(1).rev() {
1235                         let ident = tcx.item_name(*adt_def);
1236                         err.span_note(
1237                             *span,
1238                             &if first {
1239                                 format!(
1240                                     "`{}` contains a field of type `{}`",
1241                                     tcx.type_of(def.did),
1242                                     ident
1243                                 )
1244                             } else {
1245                                 format!("...which contains a field of type `{}`", ident)
1246                             },
1247                         );
1248                         first = false;
1249                     }
1250                 }
1251 
1252                 err.emit();
1253             }
1254         }
1255     }
1256 }
1257 
check_packed_inner( tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec<DefId>, ) -> Option<Vec<(DefId, Span)>>1258 pub(super) fn check_packed_inner(
1259     tcx: TyCtxt<'_>,
1260     def_id: DefId,
1261     stack: &mut Vec<DefId>,
1262 ) -> Option<Vec<(DefId, Span)>> {
1263     if let ty::Adt(def, substs) = tcx.type_of(def_id).kind() {
1264         if def.is_struct() || def.is_union() {
1265             if def.repr.align.is_some() {
1266                 return Some(vec![(def.did, DUMMY_SP)]);
1267             }
1268 
1269             stack.push(def_id);
1270             for field in &def.non_enum_variant().fields {
1271                 if let ty::Adt(def, _) = field.ty(tcx, substs).kind() {
1272                     if !stack.contains(&def.did) {
1273                         if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
1274                             defs.push((def.did, field.ident.span));
1275                             return Some(defs);
1276                         }
1277                     }
1278                 }
1279             }
1280             stack.pop();
1281         }
1282     }
1283 
1284     None
1285 }
1286 
check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef)1287 pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty::AdtDef) {
1288     if !adt.repr.transparent() {
1289         return;
1290     }
1291     let sp = tcx.sess.source_map().guess_head_span(sp);
1292 
1293     if adt.is_union() && !tcx.features().transparent_unions {
1294         feature_err(
1295             &tcx.sess.parse_sess,
1296             sym::transparent_unions,
1297             sp,
1298             "transparent unions are unstable",
1299         )
1300         .emit();
1301     }
1302 
1303     if adt.variants.len() != 1 {
1304         bad_variant_count(tcx, adt, sp, adt.did);
1305         if adt.variants.is_empty() {
1306             // Don't bother checking the fields. No variants (and thus no fields) exist.
1307             return;
1308         }
1309     }
1310 
1311     // For each field, figure out if it's known to be a ZST and align(1)
1312     let field_infos = adt.all_fields().map(|field| {
1313         let ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, field.did));
1314         let param_env = tcx.param_env(field.did);
1315         let layout = tcx.layout_of(param_env.and(ty));
1316         // We are currently checking the type this field came from, so it must be local
1317         let span = tcx.hir().span_if_local(field.did).unwrap();
1318         let zst = layout.map_or(false, |layout| layout.is_zst());
1319         let align1 = layout.map_or(false, |layout| layout.align.abi.bytes() == 1);
1320         (span, zst, align1)
1321     });
1322 
1323     let non_zst_fields =
1324         field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
1325     let non_zst_count = non_zst_fields.clone().count();
1326     if non_zst_count >= 2 {
1327         bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
1328     }
1329     for (span, zst, align1) in field_infos {
1330         if zst && !align1 {
1331             struct_span_err!(
1332                 tcx.sess,
1333                 span,
1334                 E0691,
1335                 "zero-sized field in transparent {} has alignment larger than 1",
1336                 adt.descr(),
1337             )
1338             .span_label(span, "has alignment larger than 1")
1339             .emit();
1340         }
1341     }
1342 }
1343 
1344 #[allow(trivial_numeric_casts)]
check_enum<'tcx>( tcx: TyCtxt<'tcx>, sp: Span, vs: &'tcx [hir::Variant<'tcx>], def_id: LocalDefId, )1345 fn check_enum<'tcx>(
1346     tcx: TyCtxt<'tcx>,
1347     sp: Span,
1348     vs: &'tcx [hir::Variant<'tcx>],
1349     def_id: LocalDefId,
1350 ) {
1351     let def = tcx.adt_def(def_id);
1352     def.destructor(tcx); // force the destructor to be evaluated
1353 
1354     if vs.is_empty() {
1355         let attributes = tcx.get_attrs(def_id.to_def_id());
1356         if let Some(attr) = tcx.sess.find_by_name(&attributes, sym::repr) {
1357             struct_span_err!(
1358                 tcx.sess,
1359                 attr.span,
1360                 E0084,
1361                 "unsupported representation for zero-variant enum"
1362             )
1363             .span_label(sp, "zero-variant enum")
1364             .emit();
1365         }
1366     }
1367 
1368     let repr_type_ty = def.repr.discr_type().to_ty(tcx);
1369     if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1370         if !tcx.features().repr128 {
1371             feature_err(
1372                 &tcx.sess.parse_sess,
1373                 sym::repr128,
1374                 sp,
1375                 "repr with 128-bit type is unstable",
1376             )
1377             .emit();
1378         }
1379     }
1380 
1381     for v in vs {
1382         if let Some(ref e) = v.disr_expr {
1383             tcx.ensure().typeck(tcx.hir().local_def_id(e.hir_id));
1384         }
1385     }
1386 
1387     if tcx.adt_def(def_id).repr.int.is_none() && tcx.features().arbitrary_enum_discriminant {
1388         let is_unit = |var: &hir::Variant<'_>| matches!(var.data, hir::VariantData::Unit(..));
1389 
1390         let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
1391         let has_non_units = vs.iter().any(|var| !is_unit(var));
1392         let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
1393         let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
1394 
1395         if disr_non_unit || (disr_units && has_non_units) {
1396             let mut err =
1397                 struct_span_err!(tcx.sess, sp, E0732, "`#[repr(inttype)]` must be specified");
1398             err.emit();
1399         }
1400     }
1401 
1402     let mut disr_vals: Vec<Discr<'tcx>> = Vec::with_capacity(vs.len());
1403     for ((_, discr), v) in iter::zip(def.discriminants(tcx), vs) {
1404         // Check for duplicate discriminant values
1405         if let Some(i) = disr_vals.iter().position(|&x| x.val == discr.val) {
1406             let variant_did = def.variants[VariantIdx::new(i)].def_id;
1407             let variant_i_hir_id = tcx.hir().local_def_id_to_hir_id(variant_did.expect_local());
1408             let variant_i = tcx.hir().expect_variant(variant_i_hir_id);
1409             let i_span = match variant_i.disr_expr {
1410                 Some(ref expr) => tcx.hir().span(expr.hir_id),
1411                 None => tcx.hir().span(variant_i_hir_id),
1412             };
1413             let span = match v.disr_expr {
1414                 Some(ref expr) => tcx.hir().span(expr.hir_id),
1415                 None => v.span,
1416             };
1417             let display_discr = display_discriminant_value(tcx, v, discr.val);
1418             let display_discr_i = display_discriminant_value(tcx, variant_i, disr_vals[i].val);
1419             struct_span_err!(
1420                 tcx.sess,
1421                 span,
1422                 E0081,
1423                 "discriminant value `{}` already exists",
1424                 discr.val,
1425             )
1426             .span_label(i_span, format!("first use of {}", display_discr_i))
1427             .span_label(span, format!("enum already has {}", display_discr))
1428             .emit();
1429         }
1430         disr_vals.push(discr);
1431     }
1432 
1433     check_representable(tcx, sp, def_id);
1434     check_transparent(tcx, sp, def);
1435 }
1436 
1437 /// Format an enum discriminant value for use in a diagnostic message.
display_discriminant_value<'tcx>( tcx: TyCtxt<'tcx>, variant: &hir::Variant<'_>, evaluated: u128, ) -> String1438 fn display_discriminant_value<'tcx>(
1439     tcx: TyCtxt<'tcx>,
1440     variant: &hir::Variant<'_>,
1441     evaluated: u128,
1442 ) -> String {
1443     if let Some(expr) = &variant.disr_expr {
1444         let body = &tcx.hir().body(expr.body).value;
1445         if let hir::ExprKind::Lit(lit) = &body.kind {
1446             if let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node {
1447                 if evaluated != *lit_value {
1448                     return format!("`{}` (overflowed from `{}`)", evaluated, lit_value);
1449                 }
1450             }
1451         }
1452     }
1453     format!("`{}`", evaluated)
1454 }
1455 
check_type_params_are_used<'tcx>( tcx: TyCtxt<'tcx>, generics: &ty::Generics, ty: Ty<'tcx>, )1456 pub(super) fn check_type_params_are_used<'tcx>(
1457     tcx: TyCtxt<'tcx>,
1458     generics: &ty::Generics,
1459     ty: Ty<'tcx>,
1460 ) {
1461     debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
1462 
1463     assert_eq!(generics.parent, None);
1464 
1465     if generics.own_counts().types == 0 {
1466         return;
1467     }
1468 
1469     let mut params_used = BitSet::new_empty(generics.params.len());
1470 
1471     if ty.references_error() {
1472         // If there is already another error, do not emit
1473         // an error for not using a type parameter.
1474         assert!(tcx.sess.has_errors());
1475         return;
1476     }
1477 
1478     for leaf in ty.walk(tcx) {
1479         if let GenericArgKind::Type(leaf_ty) = leaf.unpack() {
1480             if let ty::Param(param) = leaf_ty.kind() {
1481                 debug!("found use of ty param {:?}", param);
1482                 params_used.insert(param.index);
1483             }
1484         }
1485     }
1486 
1487     for param in &generics.params {
1488         if !params_used.contains(param.index) {
1489             if let ty::GenericParamDefKind::Type { .. } = param.kind {
1490                 let span = tcx.def_span(param.def_id);
1491                 struct_span_err!(
1492                     tcx.sess,
1493                     span,
1494                     E0091,
1495                     "type parameter `{}` is unused",
1496                     param.name,
1497                 )
1498                 .span_label(span, "unused type parameter")
1499                 .emit();
1500             }
1501         }
1502     }
1503 }
1504 
check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId)1505 pub(super) fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
1506     tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
1507 }
1508 
check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId)1509 pub(super) fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
1510     wfcheck::check_item_well_formed(tcx, def_id);
1511 }
1512 
check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId)1513 pub(super) fn check_trait_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
1514     wfcheck::check_trait_item(tcx, def_id);
1515 }
1516 
check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId)1517 pub(super) fn check_impl_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
1518     wfcheck::check_impl_item(tcx, def_id);
1519 }
1520 
async_opaque_type_cycle_error(tcx: TyCtxt<'tcx>, span: Span)1521 fn async_opaque_type_cycle_error(tcx: TyCtxt<'tcx>, span: Span) {
1522     struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing")
1523         .span_label(span, "recursive `async fn`")
1524         .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
1525         .note(
1526             "consider using the `async_recursion` crate: https://crates.io/crates/async_recursion",
1527         )
1528         .emit();
1529 }
1530 
1531 /// Emit an error for recursive opaque types.
1532 ///
1533 /// If this is a return `impl Trait`, find the item's return expressions and point at them. For
1534 /// direct recursion this is enough, but for indirect recursion also point at the last intermediary
1535 /// `impl Trait`.
1536 ///
1537 /// If all the return expressions evaluate to `!`, then we explain that the error will go away
1538 /// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder.
opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span)1539 fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1540     let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
1541 
1542     let mut label = false;
1543     if let Some((hir_id, visitor)) = get_owner_return_paths(tcx, def_id) {
1544         let typeck_results = tcx.typeck(tcx.hir().local_def_id(hir_id));
1545         if visitor
1546             .returns
1547             .iter()
1548             .filter_map(|expr| typeck_results.node_type_opt(expr.hir_id))
1549             .all(|ty| matches!(ty.kind(), ty::Never))
1550         {
1551             let spans = visitor
1552                 .returns
1553                 .iter()
1554                 .filter(|expr| typeck_results.node_type_opt(expr.hir_id).is_some())
1555                 .map(|expr| expr.span)
1556                 .collect::<Vec<Span>>();
1557             let span_len = spans.len();
1558             if span_len == 1 {
1559                 err.span_label(spans[0], "this returned value is of `!` type");
1560             } else {
1561                 let mut multispan: MultiSpan = spans.clone().into();
1562                 for span in spans {
1563                     multispan
1564                         .push_span_label(span, "this returned value is of `!` type".to_string());
1565                 }
1566                 err.span_note(multispan, "these returned values have a concrete \"never\" type");
1567             }
1568             err.help("this error will resolve once the item's body returns a concrete type");
1569         } else {
1570             let mut seen = FxHashSet::default();
1571             seen.insert(span);
1572             err.span_label(span, "recursive opaque type");
1573             label = true;
1574             for (sp, ty) in visitor
1575                 .returns
1576                 .iter()
1577                 .filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t)))
1578                 .filter(|(_, ty)| !matches!(ty.kind(), ty::Never))
1579             {
1580                 struct OpaqueTypeCollector(Vec<DefId>);
1581                 impl<'tcx> ty::fold::TypeVisitor<'tcx> for OpaqueTypeCollector {
1582                     fn tcx_for_anon_const_substs(&self) -> Option<TyCtxt<'tcx>> {
1583                         // Default anon const substs cannot contain opaque types.
1584                         None
1585                     }
1586                     fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
1587                         match *t.kind() {
1588                             ty::Opaque(def, _) => {
1589                                 self.0.push(def);
1590                                 ControlFlow::CONTINUE
1591                             }
1592                             _ => t.super_visit_with(self),
1593                         }
1594                     }
1595                 }
1596                 let mut visitor = OpaqueTypeCollector(vec![]);
1597                 ty.visit_with(&mut visitor);
1598                 for def_id in visitor.0 {
1599                     let ty_span = tcx.def_span(def_id);
1600                     if !seen.contains(&ty_span) {
1601                         err.span_label(ty_span, &format!("returning this opaque type `{}`", ty));
1602                         seen.insert(ty_span);
1603                     }
1604                     err.span_label(sp, &format!("returning here with type `{}`", ty));
1605                 }
1606             }
1607         }
1608     }
1609     if !label {
1610         err.span_label(span, "cannot resolve opaque type");
1611     }
1612     err.emit();
1613 }
1614