]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_hir_analysis/src/check/check.rs
New upstream version 1.76.0+dfsg1
[rustc.git] / compiler / rustc_hir_analysis / src / check / check.rs
CommitLineData
064997fb 1use crate::check::intrinsicck::InlineAsmCtxt;
4b012472 2use crate::errors::LinkageType;
923072b8 3
9c376795
FG
4use super::compare_impl_item::check_type_bounds;
5use super::compare_impl_item::{compare_impl_method, compare_impl_ty};
1b1a35ee 6use super::*;
1b1a35ee 7use rustc_attr as attr;
781aab86 8use rustc_errors::{ErrorGuaranteed, MultiSpan};
1b1a35ee 9use rustc_hir as hir;
781aab86 10use rustc_hir::def::{CtorKind, DefKind};
4b012472 11use rustc_hir::def_id::LocalModDefId;
781aab86 12use rustc_hir::Node;
49aad941 13use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
9ffffee4 14use rustc_infer::traits::{Obligation, TraitEngineExt as _};
49aad941 15use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
f2b60f7d 16use rustc_middle::middle::stability::EvalResult;
781aab86 17use rustc_middle::traits::{DefiningAnchor, ObligationCauseCode};
add651ee 18use rustc_middle::ty::fold::BottomUpFolder;
5e7ed085 19use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
cdc7bbd5 20use rustc_middle::ty::util::{Discr, IntTypeExt};
add651ee 21use rustc_middle::ty::GenericArgKind;
9ffffee4 22use rustc_middle::ty::{
4b012472 23 AdtDef, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
9ffffee4 24};
136023e0 25use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
1b1a35ee 26use rustc_span::symbol::sym;
353b0b11 27use rustc_target::abi::FieldIdx;
487cf647 28use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective;
2b03887a 29use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
49aad941 30use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
4b012472 31use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
add651ee 32use rustc_type_ir::fold::TypeFoldable;
1b1a35ee 33
29967ef6
XL
34use std::ops::ControlFlow;
35
2b03887a 36pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
136023e0
XL
37 match tcx.sess.target.is_abi_supported(abi) {
38 Some(true) => (),
5e7ed085
FG
39 Some(false) => {
40 struct_span_err!(
41 tcx.sess,
42 span,
43 E0570,
04454e1e 44 "`{abi}` is not a supported ABI for the current target",
5e7ed085
FG
45 )
46 .emit();
47 }
136023e0 48 None => {
2b03887a
FG
49 tcx.struct_span_lint_hir(
50 UNSUPPORTED_CALLING_CONVENTIONS,
51 hir_id,
52 span,
53 "use of calling convention not supported on this target",
4b012472 54 |_| {},
2b03887a 55 );
136023e0 56 }
1b1a35ee 57 }
5869c6ff
XL
58
59 // This ABI is only allowed on function pointers
60 if abi == Abi::CCmseNonSecureCall {
61 struct_span_err!(
62 tcx.sess,
63 span,
64 E0781,
c295e0f8 65 "the `\"C-cmse-nonsecure-call\"` ABI is only allowed on function pointers"
5869c6ff 66 )
5e7ed085 67 .emit();
5869c6ff 68 }
1b1a35ee
XL
69}
70
064997fb 71fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
1b1a35ee 72 let def = tcx.adt_def(def_id);
064997fb 73 let span = tcx.def_span(def_id);
1b1a35ee 74 def.destructor(tcx); // force the destructor to be evaluated
1b1a35ee 75
5e7ed085 76 if def.repr().simd() {
1b1a35ee
XL
77 check_simd(tcx, span, def_id);
78 }
79
487cf647 80 check_transparent(tcx, def);
1b1a35ee
XL
81 check_packed(tcx, span, def);
82}
83
064997fb 84fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
1b1a35ee 85 let def = tcx.adt_def(def_id);
064997fb 86 let span = tcx.def_span(def_id);
1b1a35ee 87 def.destructor(tcx); // force the destructor to be evaluated
487cf647 88 check_transparent(tcx, def);
1b1a35ee
XL
89 check_union_fields(tcx, span, def_id);
90 check_packed(tcx, span, def);
91}
92
29967ef6
XL
93/// Check that the fields of the `union` do not need dropping.
94fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
add651ee
FG
95 let item_type = tcx.type_of(item_def_id).instantiate_identity();
96 if let ty::Adt(def, args) = item_type.kind() {
1b1a35ee 97 assert!(def.is_union());
064997fb
FG
98
99 fn allowed_union_field<'tcx>(
100 ty: Ty<'tcx>,
101 tcx: TyCtxt<'tcx>,
102 param_env: ty::ParamEnv<'tcx>,
064997fb
FG
103 ) -> bool {
104 // We don't just accept all !needs_drop fields, due to semver concerns.
105 match ty.kind() {
106 ty::Ref(..) => true, // references never drop (even mutable refs, which are non-Copy and hence fail the later check)
107 ty::Tuple(tys) => {
108 // allow tuples of allowed types
9c376795 109 tys.iter().all(|ty| allowed_union_field(ty, tcx, param_env))
064997fb
FG
110 }
111 ty::Array(elem, _len) => {
112 // Like `Copy`, we do *not* special-case length 0.
9c376795 113 allowed_union_field(*elem, tcx, param_env)
064997fb
FG
114 }
115 _ => {
353b0b11
FG
116 // Fallback case: allow `ManuallyDrop` and things that are `Copy`,
117 // also no need to report an error if the type is unresolved.
064997fb 118 ty.ty_adt_def().is_some_and(|adt_def| adt_def.is_manually_drop())
2b03887a 119 || ty.is_copy_modulo_regions(tcx, param_env)
353b0b11 120 || ty.references_error()
064997fb
FG
121 }
122 }
123 }
124
1b1a35ee 125 let param_env = tcx.param_env(item_def_id);
064997fb 126 for field in &def.non_enum_variant().fields {
ed00b5ec
FG
127 let Ok(field_ty) = tcx.try_normalize_erasing_regions(param_env, field.ty(tcx, args))
128 else {
4b012472 129 tcx.sess.span_delayed_bug(span, "could not normalize field type");
ed00b5ec
FG
130 continue;
131 };
064997fb 132
9c376795 133 if !allowed_union_field(field_ty, tcx, param_env) {
3c0e092e
XL
134 let (field_span, ty_span) = match tcx.hir().get_if_local(field.did) {
135 // We are currently checking the type this field came from, so it must be local.
136 Some(Node::Field(field)) => (field.span, field.ty.span),
137 _ => unreachable!("mir field has to correspond to hir field"),
138 };
353b0b11 139 tcx.sess.emit_err(errors::InvalidUnionField {
1b1a35ee 140 field_span,
353b0b11
FG
141 sugg: errors::InvalidUnionFieldSuggestion {
142 lo: ty_span.shrink_to_lo(),
143 hi: ty_span.shrink_to_hi(),
144 },
145 note: (),
146 });
1b1a35ee 147 return false;
064997fb
FG
148 } else if field_ty.needs_drop(tcx, param_env) {
149 // This should never happen. But we can get here e.g. in case of name resolution errors.
4b012472
FG
150 tcx.sess
151 .span_delayed_bug(span, "we should never accept maybe-dropping union fields");
1b1a35ee
XL
152 }
153 }
154 } else {
155 span_bug!(span, "unions must be ty::Adt, but got {:?}", item_type.kind());
156 }
157 true
158}
159
29967ef6 160/// Check that a `static` is inhabited.
9c376795 161fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
29967ef6
XL
162 // Make sure statics are inhabited.
163 // Other parts of the compiler assume that there are no uninhabited places. In principle it
164 // would be enough to check this for `extern` statics, as statics with an initializer will
165 // have UB during initialization if they are uninhabited, but there also seems to be no good
166 // reason to allow any statics to be uninhabited.
add651ee 167 let ty = tcx.type_of(def_id).instantiate_identity();
064997fb 168 let span = tcx.def_span(def_id);
29967ef6
XL
169 let layout = match tcx.layout_of(ParamEnv::reveal_all().and(ty)) {
170 Ok(l) => l,
5e7ed085
FG
171 // Foreign statics that overflow their allowed size should emit an error
172 Err(LayoutError::SizeOverflow(_))
9ffffee4
FG
173 if matches!(tcx.def_kind(def_id), DefKind::Static(_)
174 if tcx.def_kind(tcx.local_parent(def_id)) == DefKind::ForeignMod) =>
5e7ed085 175 {
49aad941 176 tcx.sess.emit_err(errors::TooLargeStatic { span });
5e7ed085
FG
177 return;
178 }
179 // Generic statics are rejected, but we still reach this case.
180 Err(e) => {
4b012472 181 tcx.sess.span_delayed_bug(span, format!("{e:?}"));
29967ef6
XL
182 return;
183 }
184 };
185 if layout.abi.is_uninhabited() {
186 tcx.struct_span_lint_hir(
187 UNINHABITED_STATIC,
4b012472 188 tcx.local_def_id_to_hir_id(def_id),
29967ef6 189 span,
2b03887a 190 "static of uninhabited type",
29967ef6 191 |lint| {
2b03887a 192 lint
4b012472 193 .note("uninhabited statics cannot be initialized, and any access would be an immediate error");
29967ef6
XL
194 },
195 );
196 }
197}
198
1b1a35ee
XL
199/// Checks that an opaque type does not contain cycles and does not use `Self` or `T::Foo`
200/// projections that would result in "inheriting lifetimes".
9c376795 201fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
2b03887a
FG
202 let item = tcx.hir().item(id);
203 let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item.kind else {
4b012472 204 tcx.sess.span_delayed_bug(item.span, "expected opaque item");
2b03887a
FG
205 return;
206 };
207
208 // HACK(jynelson): trying to infer the type of `impl trait` breaks documenting
209 // `async-std` (and `pub async fn` in general).
210 // Since rustdoc doesn't care about the concrete type behind `impl Trait`, just don't look at it!
211 // See https://github.com/rust-lang/rust/issues/75100
212 if tcx.sess.opts.actually_rustdoc {
213 return;
214 }
215
add651ee 216 let args = GenericArgs::identity_for_item(tcx, item.owner_id);
2b03887a
FG
217 let span = tcx.def_span(item.owner_id.def_id);
218
add651ee 219 if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
29967ef6
XL
220 return;
221 }
4b012472 222 if check_opaque_for_cycles(tcx, item.owner_id.def_id, args, span, origin).is_err() {
29967ef6
XL
223 return;
224 }
fe692bf9 225
4b012472 226 let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, origin);
1b1a35ee 227}
487cf647 228
1b1a35ee
XL
229/// Checks that an opaque type does not contain cycles.
230pub(super) fn check_opaque_for_cycles<'tcx>(
231 tcx: TyCtxt<'tcx>,
232 def_id: LocalDefId,
add651ee 233 args: GenericArgsRef<'tcx>,
1b1a35ee
XL
234 span: Span,
235 origin: &hir::OpaqueTyOrigin,
5e7ed085 236) -> Result<(), ErrorGuaranteed> {
add651ee 237 if tcx.try_expand_impl_trait_type(def_id.to_def_id(), args).is_err() {
5e7ed085 238 let reported = match origin {
a2a8927a 239 hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span),
1b1a35ee 240 _ => opaque_type_cycle_error(tcx, def_id, span),
5e7ed085
FG
241 };
242 Err(reported)
29967ef6
XL
243 } else {
244 Ok(())
1b1a35ee
XL
245 }
246}
247
29967ef6
XL
248/// Check that the concrete type behind `impl Trait` actually implements `Trait`.
249///
250/// This is mostly checked at the places that specify the opaque type, but we
251/// check those cases in the `param_env` of that function, which may have
252/// bounds not on this opaque type:
253///
2b03887a
FG
254/// ```ignore (illustrative)
255/// type X<T> = impl Clone;
29967ef6
XL
256/// fn f<T: Clone>(t: T) -> X<T> {
257/// t
258/// }
2b03887a 259/// ```
29967ef6
XL
260///
261/// Without this check the above code is incorrectly accepted: we would ICE if
262/// some tried, for example, to clone an `Option<X<&mut ()>>`.
5099ac24 263#[instrument(level = "debug", skip(tcx))]
29967ef6
XL
264fn check_opaque_meets_bounds<'tcx>(
265 tcx: TyCtxt<'tcx>,
266 def_id: LocalDefId,
29967ef6
XL
267 span: Span,
268 origin: &hir::OpaqueTyOrigin,
fe692bf9 269) -> Result<(), ErrorGuaranteed> {
5099ac24
FG
270 let defining_use_anchor = match *origin {
271 hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
49aad941 272 hir::OpaqueTyOrigin::TyAlias { .. } => tcx.impl_trait_parent(def_id),
5099ac24
FG
273 };
274 let param_env = tcx.param_env(defining_use_anchor);
29967ef6 275
2b03887a
FG
276 let infcx = tcx
277 .infer_ctxt()
278 .with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor))
279 .build();
280 let ocx = ObligationCtxt::new(&infcx);
49aad941 281
add651ee
FG
282 let args = match *origin {
283 hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
284 GenericArgs::identity_for_item(tcx, parent).extend_to(
285 tcx,
286 def_id.to_def_id(),
287 |param, _| tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()).into(),
288 )
289 }
290 hir::OpaqueTyOrigin::TyAlias { .. } => GenericArgs::identity_for_item(tcx, def_id),
291 };
292
293 let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
2b03887a 294
ed00b5ec 295 // `ReErased` regions appear in the "parent_args" of closures/coroutines.
2b03887a 296 // We're ignoring them here and replacing them with fresh region variables.
add651ee 297 // See tests in ui/type-alias-impl-trait/closure_{parent_args,wf_outlives}.rs.
2b03887a
FG
298 //
299 // FIXME: Consider wrapping the hidden type in an existential `Binder` and instantiating it
300 // here rather than using ReErased.
add651ee 301 let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args);
2b03887a
FG
302 let hidden_ty = tcx.fold_regions(hidden_ty, |re, _dbi| match re.kind() {
303 ty::ReErased => infcx.next_region_var(RegionVariableOrigin::MiscVariable(span)),
304 _ => re,
305 });
29967ef6 306
9ffffee4 307 let misc_cause = traits::ObligationCause::misc(span, def_id);
29967ef6 308
487cf647
FG
309 match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
310 Ok(()) => {}
2b03887a 311 Err(ty_err) => {
9ffffee4 312 let ty_err = ty_err.to_string(tcx);
4b012472 313 return Err(tcx.sess.span_delayed_bug(
2b03887a 314 span,
49aad941 315 format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"),
fe692bf9 316 ));
2b03887a
FG
317 }
318 }
29967ef6 319
2b03887a
FG
320 // Additionally require the hidden type to be well-formed with only the generics of the opaque type.
321 // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
322 // hidden type is well formed even without those bounds.
fe692bf9
FG
323 let predicate =
324 ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(hidden_ty.into())));
add651ee 325 ocx.register_obligation(Obligation::new(tcx, misc_cause.clone(), param_env, predicate));
2b03887a
FG
326
327 // Check that all obligations are satisfied by the implementation's
328 // version.
329 let errors = ocx.select_all_or_error();
330 if !errors.is_empty() {
ed00b5ec 331 let guar = infcx.err_ctxt().report_fulfillment_errors(errors);
fe692bf9 332 return Err(guar);
2b03887a
FG
333 }
334 match origin {
335 // Checked when type checking the function containing them.
add651ee
FG
336 hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {
337 // HACK: this should also fall through to the hidden type check below, but the original
338 // implementation had a bug where equivalent lifetimes are not identical. This caused us
339 // to reject existing stable code that is otherwise completely fine. The real fix is to
340 // compare the hidden types via our type equivalence/relation infra instead of doing an
341 // identity check.
342 let _ = infcx.take_opaque_types();
343 return Ok(());
344 }
49aad941
FG
345 // Nested opaque types occur only in associated types:
346 // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
347 // They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`.
348 // We don't have to check them here because their well-formedness follows from the WF of
349 // the projection input types in the defining- and use-sites.
350 hir::OpaqueTyOrigin::TyAlias { .. }
351 if tcx.def_kind(tcx.parent(def_id.to_def_id())) == DefKind::OpaqueTy => {}
2b03887a 352 // Can have different predicates to their defining use
49aad941 353 hir::OpaqueTyOrigin::TyAlias { .. } => {
fe692bf9 354 let wf_tys = ocx.assumed_wf_types_and_report_errors(param_env, def_id)?;
49aad941
FG
355 let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, wf_tys);
356 let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
fe692bf9 357 ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
2b03887a
FG
358 }
359 }
add651ee
FG
360 // Check that any hidden types found during wf checking match the hidden types that `type_of` sees.
361 for (mut key, mut ty) in infcx.take_opaque_types() {
362 ty.hidden_type.ty = infcx.resolve_vars_if_possible(ty.hidden_type.ty);
363 key = infcx.resolve_vars_if_possible(key);
364 sanity_check_found_hidden_type(tcx, key, ty.hidden_type)?;
365 }
fe692bf9 366 Ok(())
29967ef6
XL
367}
368
add651ee
FG
369fn sanity_check_found_hidden_type<'tcx>(
370 tcx: TyCtxt<'tcx>,
371 key: ty::OpaqueTypeKey<'tcx>,
372 mut ty: ty::OpaqueHiddenType<'tcx>,
373) -> Result<(), ErrorGuaranteed> {
374 if ty.ty.is_ty_var() {
375 // Nothing was actually constrained.
376 return Ok(());
377 }
378 if let ty::Alias(ty::Opaque, alias) = ty.ty.kind() {
379 if alias.def_id == key.def_id.to_def_id() && alias.args == key.args {
380 // Nothing was actually constrained, this is an opaque usage that was
381 // only discovered to be opaque after inference vars resolved.
382 return Ok(());
383 }
384 }
385 let strip_vars = |ty: Ty<'tcx>| {
386 ty.fold_with(&mut BottomUpFolder {
387 tcx,
388 ty_op: |t| t,
389 ct_op: |c| c,
390 lt_op: |l| match l.kind() {
391 RegionKind::ReVar(_) => tcx.lifetimes.re_erased,
392 _ => l,
393 },
394 })
395 };
396 // Closures frequently end up containing erased lifetimes in their final representation.
397 // These correspond to lifetime variables that never got resolved, so we patch this up here.
398 ty.ty = strip_vars(ty.ty);
399 // Get the hidden type.
400 let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args);
401 let hidden_ty = strip_vars(hidden_ty);
402
403 // If the hidden types differ, emit a type mismatch diagnostic.
404 if hidden_ty == ty.ty {
405 Ok(())
406 } else {
407 let span = tcx.def_span(key.def_id);
408 let other = ty::OpaqueHiddenType { ty: hidden_ty, span };
409 Err(ty.report_mismatch(&other, key.def_id, tcx).emit())
410 }
411}
412
487cf647
FG
413fn is_enum_of_nonnullable_ptr<'tcx>(
414 tcx: TyCtxt<'tcx>,
415 adt_def: AdtDef<'tcx>,
add651ee 416 args: GenericArgsRef<'tcx>,
487cf647
FG
417) -> bool {
418 if adt_def.repr().inhibit_enum_layout_opt() {
419 return false;
420 }
421
422 let [var_one, var_two] = &adt_def.variants().raw[..] else {
423 return false;
424 };
353b0b11 425 let (([], [field]) | ([field], [])) = (&var_one.fields.raw[..], &var_two.fields.raw[..]) else {
487cf647
FG
426 return false;
427 };
add651ee 428 matches!(field.ty(tcx, args).kind(), ty::FnPtr(..) | ty::Ref(..))
487cf647
FG
429}
430
9c376795 431fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
487cf647 432 if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() {
add651ee 433 if match tcx.type_of(def_id).instantiate_identity().kind() {
487cf647 434 ty::RawPtr(_) => false,
add651ee 435 ty::Adt(adt_def, args) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *args),
487cf647
FG
436 _ => true,
437 } {
438 tcx.sess.emit_err(LinkageType { span: tcx.def_span(def_id) });
439 }
440 }
441}
442
9c376795 443fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
1b1a35ee 444 debug!(
6a06907d 445 "check_item_type(it.def_id={:?}, it.name={})",
2b03887a 446 id.owner_id,
49aad941 447 tcx.def_path_str(id.owner_id)
1b1a35ee
XL
448 );
449 let _indenter = indenter();
2b03887a 450 match tcx.def_kind(id.owner_id) {
04454e1e 451 DefKind::Static(..) => {
2b03887a
FG
452 tcx.ensure().typeck(id.owner_id.def_id);
453 maybe_check_static_with_link_section(tcx, id.owner_id.def_id);
454 check_static_inhabited(tcx, id.owner_id.def_id);
487cf647 455 check_static_linkage(tcx, id.owner_id.def_id);
1b1a35ee 456 }
04454e1e 457 DefKind::Const => {
2b03887a 458 tcx.ensure().typeck(id.owner_id.def_id);
1b1a35ee 459 }
04454e1e 460 DefKind::Enum => {
487cf647 461 check_enum(tcx, id.owner_id.def_id);
1b1a35ee 462 }
04454e1e 463 DefKind::Fn => {} // entirely within check_item_body
9ffffee4
FG
464 DefKind::Impl { of_trait } => {
465 if of_trait && let Some(impl_trait_ref) = tcx.impl_trait_ref(id.owner_id) {
5869c6ff
XL
466 check_impl_items_against_trait(
467 tcx,
9ffffee4 468 id.owner_id.def_id,
add651ee 469 impl_trait_ref.instantiate_identity(),
5869c6ff 470 );
9ffffee4 471 check_on_unimplemented(tcx, id);
1b1a35ee
XL
472 }
473 }
04454e1e 474 DefKind::Trait => {
9ffffee4
FG
475 let assoc_items = tcx.associated_items(id.owner_id);
476 check_on_unimplemented(tcx, id);
477
478 for &assoc_item in assoc_items.in_definition_order() {
479 match assoc_item.kind {
480 ty::AssocKind::Fn => {
481 let abi = tcx.fn_sig(assoc_item.def_id).skip_binder().abi();
4b012472 482 forbid_intrinsic_abi(tcx, assoc_item.ident(tcx).span, abi);
29967ef6 483 }
9ffffee4 484 ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
ed00b5ec 485 let trait_args = GenericArgs::identity_for_item(tcx, id.owner_id);
5e7ed085 486 let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
29967ef6
XL
487 tcx,
488 assoc_item,
489 assoc_item,
add651ee 490 ty::TraitRef::new(tcx, id.owner_id.to_def_id(), trait_args),
29967ef6
XL
491 );
492 }
493 _ => {}
1b1a35ee
XL
494 }
495 }
496 }
04454e1e 497 DefKind::Struct => {
2b03887a 498 check_struct(tcx, id.owner_id.def_id);
1b1a35ee 499 }
04454e1e 500 DefKind::Union => {
2b03887a 501 check_union(tcx, id.owner_id.def_id);
1b1a35ee 502 }
04454e1e 503 DefKind::OpaqueTy => {
fe692bf9 504 let origin = tcx.opaque_type_origin(id.owner_id.def_id);
ed00b5ec
FG
505 if let hir::OpaqueTyOrigin::FnReturn(fn_def_id)
506 | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin
4b012472 507 && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
353b0b11
FG
508 && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
509 {
510 // Skip opaques from RPIT in traits with no default body.
511 } else {
512 check_opaque(tcx, id);
513 }
2b03887a 514 }
781aab86 515 DefKind::TyAlias => {
add651ee 516 let pty_ty = tcx.type_of(id.owner_id).instantiate_identity();
2b03887a 517 let generics = tcx.generics_of(id.owner_id);
4b012472 518 check_type_params_are_used(tcx, generics, pty_ty);
1b1a35ee 519 }
04454e1e
FG
520 DefKind::ForeignMod => {
521 let it = tcx.hir().item(id);
522 let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
523 return;
524 };
136023e0 525 check_abi(tcx, it.hir_id(), it.span, abi);
1b1a35ee 526
9ffffee4
FG
527 match abi {
528 Abi::RustIntrinsic => {
529 for item in items {
530 let item = tcx.hir().foreign_item(item.id);
531 intrinsic::check_intrinsic_type(tcx, item);
532 }
1b1a35ee 533 }
9ffffee4
FG
534
535 Abi::PlatformIntrinsic => {
536 for item in items {
537 let item = tcx.hir().foreign_item(item.id);
538 intrinsic::check_platform_intrinsic_type(tcx, item);
1b1a35ee 539 }
9ffffee4 540 }
1b1a35ee 541
9ffffee4
FG
542 _ => {
543 for item in items {
544 let def_id = item.id.owner_id.def_id;
545 let generics = tcx.generics_of(def_id);
546 let own_counts = generics.own_counts();
547 if generics.params.len() - own_counts.lifetimes != 0 {
548 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts)
549 {
550 (_, 0) => ("type", "types", Some("u32")),
551 // We don't specify an example value, because we can't generate
552 // a valid value for any type.
553 (0, _) => ("const", "consts", None),
554 _ => ("type or const", "types or consts", None),
555 };
556 struct_span_err!(
557 tcx.sess,
558 item.span,
559 E0044,
560 "foreign items may not have {kinds} parameters",
561 )
49aad941 562 .span_label(item.span, format!("can't have {kinds} parameters"))
9ffffee4
FG
563 .help(
564 // FIXME: once we start storing spans for type arguments, turn this
565 // into a suggestion.
49aad941 566 format!(
9ffffee4
FG
567 "replace the {} parameters with concrete {}{}",
568 kinds,
569 kinds_pl,
add651ee 570 egs.map(|egs| format!(" like `{egs}`")).unwrap_or_default(),
9ffffee4
FG
571 ),
572 )
573 .emit();
29967ef6 574 }
9ffffee4
FG
575
576 let item = tcx.hir().foreign_item(item.id);
577 match &item.kind {
578 hir::ForeignItemKind::Fn(fn_decl, _, _) => {
579 require_c_abi_if_c_variadic(tcx, fn_decl, abi, item.span);
580 }
581 hir::ForeignItemKind::Static(..) => {
582 check_static_inhabited(tcx, def_id);
583 check_static_linkage(tcx, def_id);
584 }
585 _ => {}
29967ef6 586 }
1b1a35ee
XL
587 }
588 }
589 }
590 }
923072b8
FG
591 DefKind::GlobalAsm => {
592 let it = tcx.hir().item(id);
ed00b5ec
FG
593 let hir::ItemKind::GlobalAsm(asm) = it.kind else {
594 span_bug!(it.span, "DefKind::GlobalAsm but got {:#?}", it)
595 };
9ffffee4 596 InlineAsmCtxt::new_global_asm(tcx).check_asm(asm, id.owner_id.def_id);
923072b8 597 }
04454e1e 598 _ => {}
1b1a35ee
XL
599 }
600}
601
9ffffee4 602pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, item: hir::ItemId) {
1b1a35ee 603 // an error would be reported if this fails.
487cf647 604 let _ = OnUnimplementedDirective::of_item(tcx, item.owner_id.to_def_id());
1b1a35ee
XL
605}
606
607pub(super) fn check_specialization_validity<'tcx>(
608 tcx: TyCtxt<'tcx>,
609 trait_def: &ty::TraitDef,
9ffffee4 610 trait_item: ty::AssocItem,
1b1a35ee 611 impl_id: DefId,
9ffffee4 612 impl_item: DefId,
1b1a35ee 613) {
5e7ed085 614 let Ok(ancestors) = trait_def.ancestors(tcx, impl_id) else { return };
5869c6ff
XL
615 let mut ancestor_impls = ancestors.skip(1).filter_map(|parent| {
616 if parent.is_from_trait() {
617 None
618 } else {
5099ac24 619 Some((parent, parent.item(tcx, trait_item.def_id)))
5869c6ff
XL
620 }
621 });
1b1a35ee
XL
622
623 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
624 match parent_item {
625 // Parent impl exists, and contains the parent item we're trying to specialize, but
626 // doesn't mark it `default`.
627 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
628 Some(Err(parent_impl.def_id()))
629 }
630
631 // Parent impl contains item and makes it specializable.
632 Some(_) => Some(Ok(())),
633
634 // Parent impl doesn't mention the item. This means it's inherited from the
635 // grandparent. In that case, if parent is a `default impl`, inherited items use the
636 // "defaultness" from the grandparent, else they are final.
637 None => {
fe692bf9 638 if tcx.defaultness(parent_impl.def_id()).is_default() {
1b1a35ee
XL
639 None
640 } else {
641 Some(Err(parent_impl.def_id()))
642 }
643 }
644 }
645 });
646
647 // If `opt_result` is `None`, we have only encountered `default impl`s that don't contain the
648 // item. This is allowed, the item isn't actually getting specialized here.
649 let result = opt_result.unwrap_or(Ok(()));
650
651 if let Err(parent_impl) = result {
fe692bf9
FG
652 if !tcx.is_impl_trait_in_trait(impl_item) {
653 report_forbidden_specialization(tcx, impl_item, parent_impl);
654 } else {
4b012472 655 tcx.sess.span_delayed_bug(
fe692bf9 656 DUMMY_SP,
add651ee 657 format!("parent item: {parent_impl:?} not marked as default"),
fe692bf9
FG
658 );
659 }
1b1a35ee
XL
660 }
661}
662
5099ac24 663fn check_impl_items_against_trait<'tcx>(
1b1a35ee 664 tcx: TyCtxt<'tcx>,
1b1a35ee
XL
665 impl_id: LocalDefId,
666 impl_trait_ref: ty::TraitRef<'tcx>,
1b1a35ee 667) {
1b1a35ee
XL
668 // If the trait reference itself is erroneous (so the compilation is going
669 // to fail), skip checking the items here -- the `impl_item` table in `tcx`
670 // isn't populated for such impls.
671 if impl_trait_ref.references_error() {
672 return;
673 }
674
9ffffee4
FG
675 let impl_item_refs = tcx.associated_item_def_ids(impl_id);
676
1b1a35ee
XL
677 // Negative impls are not expected to have any items
678 match tcx.impl_polarity(impl_id) {
679 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
680 ty::ImplPolarity::Negative => {
681 if let [first_item_ref, ..] = impl_item_refs {
9ffffee4 682 let first_item_span = tcx.def_span(first_item_ref);
1b1a35ee
XL
683 struct_span_err!(
684 tcx.sess,
685 first_item_span,
686 E0749,
687 "negative impls cannot have any items"
688 )
689 .emit();
690 }
691 return;
692 }
693 }
694
1b1a35ee 695 let trait_def = tcx.trait_def(impl_trait_ref.def_id);
5869c6ff 696
9ffffee4
FG
697 for &impl_item in impl_item_refs {
698 let ty_impl_item = tcx.associated_item(impl_item);
5099ac24
FG
699 let ty_trait_item = if let Some(trait_item_id) = ty_impl_item.trait_item_def_id {
700 tcx.associated_item(trait_item_id)
5869c6ff 701 } else {
5099ac24 702 // Checked in `associated_item`.
4b012472 703 tcx.sess.span_delayed_bug(tcx.def_span(impl_item), "missing associated item in trait");
5869c6ff
XL
704 continue;
705 };
9ffffee4
FG
706 match ty_impl_item.kind {
707 ty::AssocKind::Const => {
781aab86 708 tcx.ensure().compare_impl_const((
9ffffee4 709 impl_item.expect_local(),
2b03887a
FG
710 ty_impl_item.trait_item_def_id.unwrap(),
711 ));
5099ac24 712 }
9ffffee4
FG
713 ty::AssocKind::Fn => {
714 compare_impl_method(tcx, ty_impl_item, ty_trait_item, impl_trait_ref);
5099ac24 715 }
9ffffee4
FG
716 ty::AssocKind::Type => {
717 compare_impl_ty(tcx, ty_impl_item, ty_trait_item, impl_trait_ref);
1b1a35ee 718 }
1b1a35ee 719 }
5099ac24
FG
720
721 check_specialization_validity(
722 tcx,
723 trait_def,
9ffffee4 724 ty_trait_item,
5099ac24
FG
725 impl_id.to_def_id(),
726 impl_item,
727 );
1b1a35ee
XL
728 }
729
1b1a35ee 730 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
5869c6ff
XL
731 // Check for missing items from trait
732 let mut missing_items = Vec::new();
5099ac24
FG
733
734 let mut must_implement_one_of: Option<&[Ident]> =
735 trait_def.must_implement_one_of.as_deref();
736
737 for &trait_item_id in tcx.associated_item_def_ids(impl_trait_ref.def_id) {
9ffffee4
FG
738 let leaf_def = ancestors.leaf_def(tcx, trait_item_id);
739
740 let is_implemented = leaf_def
741 .as_ref()
49aad941 742 .is_some_and(|node_item| node_item.item.defaultness(tcx).has_value());
1b1a35ee 743
fe692bf9 744 if !is_implemented && tcx.defaultness(impl_id).is_final() {
5099ac24
FG
745 missing_items.push(tcx.associated_item(trait_item_id));
746 }
747
f2b60f7d 748 // true if this item is specifically implemented in this impl
49aad941
FG
749 let is_implemented_here =
750 leaf_def.as_ref().is_some_and(|node_item| !node_item.defining_node.is_from_trait());
f2b60f7d
FG
751
752 if !is_implemented_here {
4b012472 753 let full_impl_span = tcx.hir().span_with_body(tcx.local_def_id_to_hir_id(impl_id));
f2b60f7d
FG
754 match tcx.eval_default_body_stability(trait_item_id, full_impl_span) {
755 EvalResult::Deny { feature, reason, issue, .. } => default_body_is_unstable(
756 tcx,
757 full_impl_span,
758 trait_item_id,
759 feature,
760 reason,
761 issue,
762 ),
5099ac24 763
f2b60f7d
FG
764 // Unmarked default bodies are considered stable (at least for now).
765 EvalResult::Allow | EvalResult::Unmarked => {}
766 }
767 }
768
769 if let Some(required_items) = &must_implement_one_of {
5099ac24
FG
770 if is_implemented_here {
771 let trait_item = tcx.associated_item(trait_item_id);
772 if required_items.contains(&trait_item.ident(tcx)) {
773 must_implement_one_of = None;
774 }
1b1a35ee
XL
775 }
776 }
9ffffee4
FG
777
778 if let Some(leaf_def) = &leaf_def
779 && !leaf_def.is_final()
780 && let def_id = leaf_def.item.def_id
781 && tcx.impl_method_has_trait_impl_trait_tys(def_id)
782 {
783 let def_kind = tcx.def_kind(def_id);
784 let descr = tcx.def_kind_descr(def_kind, def_id);
785 let (msg, feature) = if tcx.asyncness(def_id).is_async() {
786 (
787 format!("async {descr} in trait cannot be specialized"),
ed00b5ec 788 "async functions in traits",
9ffffee4
FG
789 )
790 } else {
791 (
792 format!(
793 "{descr} with return-position `impl Trait` in trait cannot be specialized"
794 ),
ed00b5ec 795 "return position `impl Trait` in traits",
9ffffee4
FG
796 )
797 };
798 tcx.sess
799 .struct_span_err(tcx.def_span(def_id), msg)
800 .note(format!(
801 "specialization behaves in inconsistent and \
ed00b5ec 802 surprising ways with {feature}, \
9ffffee4
FG
803 and for now is disallowed"
804 ))
805 .emit();
806 }
1b1a35ee 807 }
5869c6ff
XL
808
809 if !missing_items.is_empty() {
4b012472 810 let full_impl_span = tcx.hir().span_with_body(tcx.local_def_id_to_hir_id(impl_id));
49aad941 811 missing_items_err(tcx, impl_id, &missing_items, full_impl_span);
5869c6ff 812 }
5869c6ff 813
5099ac24 814 if let Some(missing_items) = must_implement_one_of {
5099ac24 815 let attr_span = tcx
04454e1e 816 .get_attr(impl_trait_ref.def_id, sym::rustc_must_implement_one_of)
5099ac24 817 .map(|attr| attr.span);
5869c6ff 818
064997fb
FG
819 missing_items_must_implement_one_of_err(
820 tcx,
821 tcx.def_span(impl_id),
822 missing_items,
823 attr_span,
824 );
5869c6ff 825 }
1b1a35ee
XL
826 }
827}
828
1b1a35ee 829pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
add651ee
FG
830 let t = tcx.type_of(def_id).instantiate_identity();
831 if let ty::Adt(def, args) = t.kind()
04454e1e
FG
832 && def.is_struct()
833 {
834 let fields = &def.non_enum_variant().fields;
835 if fields.is_empty() {
836 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
837 return;
838 }
add651ee
FG
839 let e = fields[FieldIdx::from_u32(0)].ty(tcx, args);
840 if !fields.iter().all(|f| f.ty(tcx, args) == e) {
04454e1e
FG
841 struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
842 .span_label(sp, "SIMD elements must have the same type")
843 .emit();
844 return;
845 }
846
847 let len = if let ty::Array(_ty, c) = e.kind() {
9ffffee4 848 c.try_eval_target_usize(tcx, tcx.param_env(def.did()))
04454e1e
FG
849 } else {
850 Some(fields.len() as u64)
851 };
852 if let Some(len) = len {
853 if len == 0 {
1b1a35ee
XL
854 struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit();
855 return;
04454e1e
FG
856 } else if len > MAX_SIMD_LANES {
857 struct_span_err!(
858 tcx.sess,
859 sp,
860 E0075,
861 "SIMD vector cannot have more than {MAX_SIMD_LANES} elements",
862 )
863 .emit();
1b1a35ee
XL
864 return;
865 }
04454e1e 866 }
6a06907d 867
04454e1e
FG
868 // Check that we use types valid for use in the lanes of a SIMD "vector register"
869 // These are scalar types which directly match a "machine" type
870 // Yes: Integers, floats, "thin" pointers
871 // No: char, "fat" pointers, compound types
872 match e.kind() {
873 ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
874 ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_) => (), // struct(u8, u8, u8, u8) is ok
875 ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
876 ty::Array(t, _clen)
ed00b5ec 877 if matches!(t.kind(), ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_)) =>
04454e1e
FG
878 { /* struct([f32; 4]) is ok */ }
879 _ => {
880 struct_span_err!(
881 tcx.sess,
882 sp,
883 E0077,
884 "SIMD vector element type should be a \
885 primitive scalar (integer/float/pointer) type"
886 )
887 .emit();
888 return;
1b1a35ee
XL
889 }
890 }
891 }
892}
893
5e7ed085
FG
894pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
895 let repr = def.repr();
1b1a35ee 896 if repr.packed() {
04454e1e 897 for attr in tcx.get_attrs(def.did(), sym::repr) {
4b012472 898 for r in attr::parse_repr_attr(tcx.sess, attr) {
5e7ed085 899 if let attr::ReprPacked(pack) = r
ed00b5ec
FG
900 && let Some(repr_pack) = repr.pack
901 && pack as u64 != repr_pack.bytes()
902 {
903 struct_span_err!(
904 tcx.sess,
905 sp,
906 E0634,
907 "type has conflicting packed representation hints"
908 )
909 .emit();
910 }
1b1a35ee
XL
911 }
912 }
913 if repr.align.is_some() {
914 struct_span_err!(
915 tcx.sess,
916 sp,
917 E0587,
918 "type has conflicting packed and align representation hints"
919 )
920 .emit();
921 } else {
5e7ed085 922 if let Some(def_spans) = check_packed_inner(tcx, def.did(), &mut vec![]) {
1b1a35ee
XL
923 let mut err = struct_span_err!(
924 tcx.sess,
925 sp,
926 E0588,
927 "packed type cannot transitively contain a `#[repr(align)]` type"
928 );
929
930 err.span_note(
931 tcx.def_span(def_spans[0].0),
49aad941 932 format!("`{}` has a `#[repr(align)]` attribute", tcx.item_name(def_spans[0].0)),
1b1a35ee
XL
933 );
934
935 if def_spans.len() > 2 {
936 let mut first = true;
937 for (adt_def, span) in def_spans.iter().skip(1).rev() {
938 let ident = tcx.item_name(*adt_def);
939 err.span_note(
940 *span,
49aad941 941 if first {
1b1a35ee
XL
942 format!(
943 "`{}` contains a field of type `{}`",
add651ee 944 tcx.type_of(def.did()).instantiate_identity(),
1b1a35ee
XL
945 ident
946 )
947 } else {
04454e1e 948 format!("...which contains a field of type `{ident}`")
1b1a35ee
XL
949 },
950 );
951 first = false;
952 }
953 }
954
955 err.emit();
956 }
957 }
958 }
959}
960
961pub(super) fn check_packed_inner(
962 tcx: TyCtxt<'_>,
963 def_id: DefId,
964 stack: &mut Vec<DefId>,
965) -> Option<Vec<(DefId, Span)>> {
add651ee 966 if let ty::Adt(def, args) = tcx.type_of(def_id).instantiate_identity().kind() {
1b1a35ee 967 if def.is_struct() || def.is_union() {
5e7ed085
FG
968 if def.repr().align.is_some() {
969 return Some(vec![(def.did(), DUMMY_SP)]);
1b1a35ee
XL
970 }
971
972 stack.push(def_id);
973 for field in &def.non_enum_variant().fields {
add651ee 974 if let ty::Adt(def, _) = field.ty(tcx, args).kind()
04454e1e
FG
975 && !stack.contains(&def.did())
976 && let Some(mut defs) = check_packed_inner(tcx, def.did(), stack)
977 {
978 defs.push((def.did(), field.ident(tcx).span));
979 return Some(defs);
1b1a35ee
XL
980 }
981 }
982 stack.pop();
983 }
984 }
985
986 None
987}
988
487cf647 989pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) {
5e7ed085 990 if !adt.repr().transparent() {
1b1a35ee
XL
991 return;
992 }
1b1a35ee
XL
993
994 if adt.is_union() && !tcx.features().transparent_unions {
995 feature_err(
996 &tcx.sess.parse_sess,
997 sym::transparent_unions,
487cf647 998 tcx.def_span(adt.did()),
1b1a35ee
XL
999 "transparent unions are unstable",
1000 )
1001 .emit();
1002 }
1003
5e7ed085 1004 if adt.variants().len() != 1 {
487cf647 1005 bad_variant_count(tcx, adt, tcx.def_span(adt.did()), adt.did());
9c376795
FG
1006 // Don't bother checking the fields.
1007 return;
1b1a35ee
XL
1008 }
1009
781aab86
FG
1010 // For each field, figure out if it's known to have "trivial" layout (i.e., is a 1-ZST), with
1011 // "known" respecting #[non_exhaustive] attributes.
1b1a35ee 1012 let field_infos = adt.all_fields().map(|field| {
add651ee 1013 let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did));
1b1a35ee
XL
1014 let param_env = tcx.param_env(field.did);
1015 let layout = tcx.layout_of(param_env.and(ty));
1016 // We are currently checking the type this field came from, so it must be local
1017 let span = tcx.hir().span_if_local(field.did).unwrap();
781aab86
FG
1018 let trivial = layout.is_ok_and(|layout| layout.is_1zst());
1019 if !trivial {
1020 return (span, trivial, None);
064997fb 1021 }
781aab86 1022 // Even some 1-ZST fields are not allowed though, if they have `non_exhaustive`.
064997fb
FG
1023
1024 fn check_non_exhaustive<'tcx>(
1025 tcx: TyCtxt<'tcx>,
1026 t: Ty<'tcx>,
add651ee 1027 ) -> ControlFlow<(&'static str, DefId, GenericArgsRef<'tcx>, bool)> {
064997fb
FG
1028 match t.kind() {
1029 ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)),
1030 ty::Array(ty, _) => check_non_exhaustive(tcx, *ty),
1031 ty::Adt(def, subst) => {
1032 if !def.did().is_local() {
1033 let non_exhaustive = def.is_variant_list_non_exhaustive()
1034 || def
1035 .variants()
1036 .iter()
1037 .any(ty::VariantDef::is_field_list_non_exhaustive);
1038 let has_priv = def.all_fields().any(|f| !f.vis.is_public());
1039 if non_exhaustive || has_priv {
1040 return ControlFlow::Break((
1041 def.descr(),
1042 def.did(),
1043 subst,
1044 non_exhaustive,
1045 ));
1046 }
1047 }
1048 def.all_fields()
1049 .map(|field| field.ty(tcx, subst))
1050 .try_for_each(|t| check_non_exhaustive(tcx, t))
1051 }
1052 _ => ControlFlow::Continue(()),
1053 }
1054 }
1055
781aab86 1056 (span, trivial, check_non_exhaustive(tcx, ty).break_value())
1b1a35ee
XL
1057 });
1058
781aab86 1059 let non_trivial_fields = field_infos
064997fb 1060 .clone()
781aab86
FG
1061 .filter_map(|(span, trivial, _non_exhaustive)| if !trivial { Some(span) } else { None });
1062 let non_trivial_count = non_trivial_fields.clone().count();
1063 if non_trivial_count >= 2 {
1064 bad_non_zero_sized_fields(
1065 tcx,
1066 adt,
1067 non_trivial_count,
1068 non_trivial_fields,
1069 tcx.def_span(adt.did()),
1070 );
1071 return;
1b1a35ee 1072 }
781aab86
FG
1073 let mut prev_non_exhaustive_1zst = false;
1074 for (span, _trivial, non_exhaustive_1zst) in field_infos {
1075 if let Some((descr, def_id, args, non_exhaustive)) = non_exhaustive_1zst {
1076 // If there are any non-trivial fields, then there can be no non-exhaustive 1-zsts.
1077 // Otherwise, it's only an issue if there's >1 non-exhaustive 1-zst.
1078 if non_trivial_count > 0 || prev_non_exhaustive_1zst {
1079 tcx.struct_span_lint_hir(
1080 REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS,
4b012472 1081 tcx.local_def_id_to_hir_id(adt.did().expect_local()),
add651ee 1082 span,
781aab86
FG
1083 "zero-sized fields in `repr(transparent)` cannot \
1084 contain external non-exhaustive types",
1085 |lint| {
1086 let note = if non_exhaustive {
1087 "is marked with `#[non_exhaustive]`"
1088 } else {
1089 "contains private fields"
1090 };
1091 let field_ty = tcx.def_path_str_with_args(def_id, args);
1092 lint.note(format!(
1093 "this {descr} contains `{field_ty}`, which {note}, \
1094 and makes it not a breaking change to become \
1095 non-zero-sized in the future."
4b012472 1096 ));
781aab86
FG
1097 },
1098 )
add651ee 1099 } else {
781aab86 1100 prev_non_exhaustive_1zst = true;
add651ee 1101 }
064997fb 1102 }
1b1a35ee
XL
1103 }
1104}
1105
1106#[allow(trivial_numeric_casts)]
9c376795 1107fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
1b1a35ee
XL
1108 let def = tcx.adt_def(def_id);
1109 def.destructor(tcx); // force the destructor to be evaluated
1110
487cf647 1111 if def.variants().is_empty() {
353b0b11 1112 if let Some(attr) = tcx.get_attrs(def_id, sym::repr).next() {
1b1a35ee
XL
1113 struct_span_err!(
1114 tcx.sess,
1115 attr.span,
1116 E0084,
1117 "unsupported representation for zero-variant enum"
1118 )
487cf647 1119 .span_label(tcx.def_span(def_id), "zero-variant enum")
1b1a35ee
XL
1120 .emit();
1121 }
1122 }
1123
5e7ed085 1124 let repr_type_ty = def.repr().discr_type().to_ty(tcx);
1b1a35ee
XL
1125 if repr_type_ty == tcx.types.i128 || repr_type_ty == tcx.types.u128 {
1126 if !tcx.features().repr128 {
1127 feature_err(
1128 &tcx.sess.parse_sess,
1129 sym::repr128,
487cf647 1130 tcx.def_span(def_id),
1b1a35ee
XL
1131 "repr with 128-bit type is unstable",
1132 )
1133 .emit();
1134 }
1135 }
1136
487cf647
FG
1137 for v in def.variants() {
1138 if let ty::VariantDiscr::Explicit(discr_def_id) = v.discr {
1139 tcx.ensure().typeck(discr_def_id.expect_local());
1b1a35ee
XL
1140 }
1141 }
1142
487cf647
FG
1143 if def.repr().int.is_none() {
1144 let is_unit = |var: &ty::VariantDef| matches!(var.ctor_kind(), Some(CtorKind::Const));
1145 let has_disr = |var: &ty::VariantDef| matches!(var.discr, ty::VariantDiscr::Explicit(_));
1b1a35ee 1146
487cf647 1147 let has_non_units = def.variants().iter().any(|var| !is_unit(var));
4b012472
FG
1148 let disr_units = def.variants().iter().any(|var| is_unit(var) && has_disr(var));
1149 let disr_non_unit = def.variants().iter().any(|var| !is_unit(var) && has_disr(var));
1b1a35ee
XL
1150
1151 if disr_non_unit || (disr_units && has_non_units) {
487cf647
FG
1152 let mut err = struct_span_err!(
1153 tcx.sess,
1154 tcx.def_span(def_id),
1155 E0732,
1156 "`#[repr(inttype)]` must be specified"
1157 );
1b1a35ee
XL
1158 err.emit();
1159 }
1160 }
1161
487cf647
FG
1162 detect_discriminant_duplicate(tcx, def);
1163 check_transparent(tcx, def);
1b1a35ee
XL
1164}
1165
f2b60f7d 1166/// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal
487cf647 1167fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) {
f2b60f7d
FG
1168 // Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate.
1169 // Here `idx` refers to the order of which the discriminant appears, and its index in `vs`
487cf647
FG
1170 let report = |dis: Discr<'tcx>, idx, err: &mut Diagnostic| {
1171 let var = adt.variant(idx); // HIR for the duplicate discriminant
1172 let (span, display_discr) = match var.discr {
1173 ty::VariantDiscr::Explicit(discr_def_id) => {
f2b60f7d 1174 // In the case the discriminant is both a duplicate and overflowed, let the user know
ed00b5ec 1175 if let hir::Node::AnonConst(expr) =
4b012472 1176 tcx.hir_node_by_def_id(discr_def_id.expect_local())
487cf647 1177 && let hir::ExprKind::Lit(lit) = &tcx.hir().body(expr.body).value.kind
f2b60f7d
FG
1178 && let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
1179 && *lit_value != dis.val
1180 {
487cf647 1181 (tcx.def_span(discr_def_id), format!("`{dis}` (overflowed from `{lit_value}`)"))
f2b60f7d 1182 } else {
487cf647
FG
1183 // Otherwise, format the value as-is
1184 (tcx.def_span(discr_def_id), format!("`{dis}`"))
f2b60f7d
FG
1185 }
1186 }
487cf647
FG
1187 // This should not happen.
1188 ty::VariantDiscr::Relative(0) => (tcx.def_span(var.def_id), format!("`{dis}`")),
1189 ty::VariantDiscr::Relative(distance_to_explicit) => {
f2b60f7d
FG
1190 // At this point we know this discriminant is a duplicate, and was not explicitly
1191 // assigned by the user. Here we iterate backwards to fetch the HIR for the last
1192 // explicitly assigned discriminant, and letting the user know that this was the
1193 // increment startpoint, and how many steps from there leading to the duplicate
487cf647
FG
1194 if let Some(explicit_idx) =
1195 idx.as_u32().checked_sub(distance_to_explicit).map(VariantIdx::from_u32)
f2b60f7d 1196 {
487cf647
FG
1197 let explicit_variant = adt.variant(explicit_idx);
1198 let ve_ident = var.name;
1199 let ex_ident = explicit_variant.name;
1200 let sp = if distance_to_explicit > 1 { "variants" } else { "variant" };
f2b60f7d
FG
1201
1202 err.span_label(
487cf647
FG
1203 tcx.def_span(explicit_variant.def_id),
1204 format!(
1205 "discriminant for `{ve_ident}` incremented from this startpoint \
1206 (`{ex_ident}` + {distance_to_explicit} {sp} later \
1207 => `{ve_ident}` = {dis})"
1208 ),
f2b60f7d
FG
1209 );
1210 }
1211
487cf647 1212 (tcx.def_span(var.def_id), format!("`{dis}`"))
f2b60f7d
FG
1213 }
1214 };
1215
1216 err.span_label(span, format!("{display_discr} assigned here"));
1217 };
1218
487cf647
FG
1219 let mut discrs = adt.discriminants(tcx).collect::<Vec<_>>();
1220
f2b60f7d
FG
1221 // Here we loop through the discriminants, comparing each discriminant to another.
1222 // When a duplicate is detected, we instantiate an error and point to both
1223 // initial and duplicate value. The duplicate discriminant is then discarded by swapping
1224 // it with the last element and decrementing the `vec.len` (which is why we have to evaluate
1225 // `discrs.len()` anew every iteration, and why this could be tricky to do in a functional
1226 // style as we are mutating `discrs` on the fly).
1227 let mut i = 0;
1228 while i < discrs.len() {
487cf647 1229 let var_i_idx = discrs[i].0;
f2b60f7d
FG
1230 let mut error: Option<DiagnosticBuilder<'_, _>> = None;
1231
1232 let mut o = i + 1;
1233 while o < discrs.len() {
487cf647 1234 let var_o_idx = discrs[o].0;
f2b60f7d
FG
1235
1236 if discrs[i].1.val == discrs[o].1.val {
1237 let err = error.get_or_insert_with(|| {
1238 let mut ret = struct_span_err!(
1239 tcx.sess,
487cf647 1240 tcx.def_span(adt.did()),
f2b60f7d
FG
1241 E0081,
1242 "discriminant value `{}` assigned more than once",
1243 discrs[i].1,
1244 );
1245
487cf647 1246 report(discrs[i].1, var_i_idx, &mut ret);
f2b60f7d
FG
1247
1248 ret
1249 });
1250
487cf647 1251 report(discrs[o].1, var_o_idx, err);
f2b60f7d
FG
1252
1253 // Safe to unwrap here, as we wouldn't reach this point if `discrs` was empty
1254 discrs[o] = *discrs.last().unwrap();
1255 discrs.pop();
1256 } else {
1257 o += 1;
1258 }
94222f64 1259 }
923072b8 1260
f2b60f7d
FG
1261 if let Some(mut e) = error {
1262 e.emit();
1263 }
1264
1265 i += 1;
1266 }
94222f64
XL
1267}
1268
1b1a35ee
XL
1269pub(super) fn check_type_params_are_used<'tcx>(
1270 tcx: TyCtxt<'tcx>,
1271 generics: &ty::Generics,
1272 ty: Ty<'tcx>,
1273) {
1274 debug!("check_type_params_are_used(generics={:?}, ty={:?})", generics, ty);
1275
1276 assert_eq!(generics.parent, None);
1277
1278 if generics.own_counts().types == 0 {
1279 return;
1280 }
1281
1282 let mut params_used = BitSet::new_empty(generics.params.len());
1283
1284 if ty.references_error() {
1285 // If there is already another error, do not emit
1286 // an error for not using a type parameter.
5e7ed085 1287 assert!(tcx.sess.has_errors().is_some());
1b1a35ee
XL
1288 return;
1289 }
1290
5099ac24 1291 for leaf in ty.walk() {
04454e1e
FG
1292 if let GenericArgKind::Type(leaf_ty) = leaf.unpack()
1293 && let ty::Param(param) = leaf_ty.kind()
1294 {
1295 debug!("found use of ty param {:?}", param);
1296 params_used.insert(param.index);
1b1a35ee
XL
1297 }
1298 }
1299
1300 for param in &generics.params {
04454e1e
FG
1301 if !params_used.contains(param.index)
1302 && let ty::GenericParamDefKind::Type { .. } = param.kind
1303 {
1304 let span = tcx.def_span(param.def_id);
ed00b5ec
FG
1305 struct_span_err!(tcx.sess, span, E0091, "type parameter `{}` is unused", param.name,)
1306 .span_label(span, "unused type parameter")
1307 .emit();
1b1a35ee
XL
1308 }
1309 }
1310}
1311
add651ee 1312pub(super) fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
04454e1e
FG
1313 let module = tcx.hir_module_items(module_def_id);
1314 for id in module.items() {
1315 check_item_type(tcx, id);
1316 }
add651ee
FG
1317 if module_def_id == LocalModDefId::CRATE_DEF_ID {
1318 super::entry::check_for_entry_fn(tcx);
1319 }
1b1a35ee
XL
1320}
1321
5e7ed085 1322fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed {
1b1a35ee
XL
1323 struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing")
1324 .span_label(span, "recursive `async fn`")
1325 .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`")
6a06907d
XL
1326 .note(
1327 "consider using the `async_recursion` crate: https://crates.io/crates/async_recursion",
1328 )
5e7ed085 1329 .emit()
1b1a35ee
XL
1330}
1331
1332/// Emit an error for recursive opaque types.
1333///
1334/// If this is a return `impl Trait`, find the item's return expressions and point at them. For
1335/// direct recursion this is enough, but for indirect recursion also point at the last intermediary
1336/// `impl Trait`.
1337///
1338/// If all the return expressions evaluate to `!`, then we explain that the error will go away
1339/// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder.
9c376795
FG
1340fn opaque_type_cycle_error(
1341 tcx: TyCtxt<'_>,
1342 opaque_def_id: LocalDefId,
1343 span: Span,
1344) -> ErrorGuaranteed {
1b1a35ee
XL
1345 let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
1346
1347 let mut label = false;
9c376795 1348 if let Some((def_id, visitor)) = get_owner_return_paths(tcx, opaque_def_id) {
5099ac24 1349 let typeck_results = tcx.typeck(def_id);
1b1a35ee
XL
1350 if visitor
1351 .returns
1352 .iter()
1353 .filter_map(|expr| typeck_results.node_type_opt(expr.hir_id))
1354 .all(|ty| matches!(ty.kind(), ty::Never))
1355 {
1356 let spans = visitor
1357 .returns
1358 .iter()
1359 .filter(|expr| typeck_results.node_type_opt(expr.hir_id).is_some())
1360 .map(|expr| expr.span)
1361 .collect::<Vec<Span>>();
1362 let span_len = spans.len();
1363 if span_len == 1 {
1364 err.span_label(spans[0], "this returned value is of `!` type");
1365 } else {
1366 let mut multispan: MultiSpan = spans.clone().into();
1367 for span in spans {
064997fb 1368 multispan.push_span_label(span, "this returned value is of `!` type");
1b1a35ee
XL
1369 }
1370 err.span_note(multispan, "these returned values have a concrete \"never\" type");
1371 }
1372 err.help("this error will resolve once the item's body returns a concrete type");
1373 } else {
1374 let mut seen = FxHashSet::default();
1375 seen.insert(span);
1376 err.span_label(span, "recursive opaque type");
1377 label = true;
1378 for (sp, ty) in visitor
1379 .returns
1380 .iter()
1381 .filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t)))
1382 .filter(|(_, ty)| !matches!(ty.kind(), ty::Never))
1383 {
9c376795
FG
1384 #[derive(Default)]
1385 struct OpaqueTypeCollector {
1386 opaques: Vec<DefId>,
1387 closures: Vec<DefId>,
1388 }
9ffffee4 1389 impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
fc512014 1390 fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
1b1a35ee 1391 match *t.kind() {
9c376795
FG
1392 ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
1393 self.opaques.push(def);
1394 ControlFlow::Continue(())
1395 }
ed00b5ec 1396 ty::Closure(def_id, ..) | ty::Coroutine(def_id, ..) => {
9c376795
FG
1397 self.closures.push(def_id);
1398 t.super_visit_with(self)
1b1a35ee
XL
1399 }
1400 _ => t.super_visit_with(self),
1401 }
1402 }
1403 }
9c376795
FG
1404
1405 let mut visitor = OpaqueTypeCollector::default();
1b1a35ee 1406 ty.visit_with(&mut visitor);
9c376795 1407 for def_id in visitor.opaques {
1b1a35ee
XL
1408 let ty_span = tcx.def_span(def_id);
1409 if !seen.contains(&ty_span) {
9ffffee4 1410 let descr = if ty.is_impl_trait() { "opaque " } else { "" };
49aad941 1411 err.span_label(ty_span, format!("returning this {descr}type `{ty}`"));
1b1a35ee
XL
1412 seen.insert(ty_span);
1413 }
49aad941 1414 err.span_label(sp, format!("returning here with type `{ty}`"));
1b1a35ee 1415 }
9c376795
FG
1416
1417 for closure_def_id in visitor.closures {
fe692bf9
FG
1418 let Some(closure_local_did) = closure_def_id.as_local() else {
1419 continue;
1420 };
9c376795
FG
1421 let typeck_results = tcx.typeck(closure_local_did);
1422
1423 let mut label_match = |ty: Ty<'_>, span| {
1424 for arg in ty.walk() {
1425 if let ty::GenericArgKind::Type(ty) = arg.unpack()
ed00b5ec
FG
1426 && let ty::Alias(
1427 ty::Opaque,
1428 ty::AliasTy { def_id: captured_def_id, .. },
1429 ) = *ty.kind()
9c376795
FG
1430 && captured_def_id == opaque_def_id.to_def_id()
1431 {
1432 err.span_label(
1433 span,
1434 format!(
1435 "{} captures itself here",
9ffffee4 1436 tcx.def_descr(closure_def_id)
9c376795
FG
1437 ),
1438 );
1439 }
1440 }
1441 };
1442
1443 // Label any closure upvars that capture the opaque
1444 for capture in typeck_results.closure_min_captures_flattened(closure_local_did)
1445 {
1446 label_match(capture.place.ty(), capture.get_path_span(tcx));
1447 }
ed00b5ec 1448 // Label any coroutine locals that capture the opaque
4b012472 1449 if tcx.is_coroutine(closure_def_id)
ed00b5ec 1450 && let Some(coroutine_layout) = tcx.mir_coroutine_witnesses(closure_def_id)
353b0b11 1451 {
ed00b5ec 1452 for interior_ty in &coroutine_layout.field_tys {
353b0b11
FG
1453 label_match(interior_ty.ty, interior_ty.source_info.span);
1454 }
1455 }
9c376795 1456 }
1b1a35ee
XL
1457 }
1458 }
1459 }
1460 if !label {
1461 err.span_label(span, "cannot resolve opaque type");
1462 }
5e7ed085 1463 err.emit()
1b1a35ee 1464}
9ffffee4 1465
4b012472
FG
1466pub(super) fn check_coroutine_obligations(
1467 tcx: TyCtxt<'_>,
1468 def_id: LocalDefId,
1469) -> Result<(), ErrorGuaranteed> {
1470 debug_assert!(tcx.is_coroutine(def_id.to_def_id()));
9ffffee4
FG
1471
1472 let typeck = tcx.typeck(def_id);
1473 let param_env = tcx.param_env(def_id);
1474
ed00b5ec
FG
1475 let coroutine_interior_predicates = &typeck.coroutine_interior_predicates[&def_id];
1476 debug!(?coroutine_interior_predicates);
9ffffee4
FG
1477
1478 let infcx = tcx
1479 .infer_ctxt()
1480 // typeck writeback gives us predicates with their regions erased.
1481 // As borrowck already has checked lifetimes, we do not need to do it again.
1482 .ignoring_regions()
4b012472
FG
1483 // Bind opaque types to type checking root, as they should have been checked by borrowck,
1484 // but may show up in some cases, like when (root) obligations are stalled in the new solver.
1485 .with_opaque_type_inference(DefiningAnchor::Bind(typeck.hir_owner.def_id))
9ffffee4
FG
1486 .build();
1487
fe692bf9 1488 let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);
ed00b5ec 1489 for (predicate, cause) in coroutine_interior_predicates {
9ffffee4
FG
1490 let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate);
1491 fulfillment_cx.register_predicate_obligation(&infcx, obligation);
1492 }
781aab86
FG
1493
1494 if (tcx.features().unsized_locals || tcx.features().unsized_fn_params)
ed00b5ec 1495 && let Some(coroutine) = tcx.mir_coroutine_witnesses(def_id)
781aab86 1496 {
ed00b5ec 1497 for field_ty in coroutine.field_tys.iter() {
781aab86
FG
1498 fulfillment_cx.register_bound(
1499 &infcx,
1500 param_env,
1501 field_ty.ty,
1502 tcx.require_lang_item(hir::LangItem::Sized, Some(field_ty.source_info.span)),
1503 ObligationCause::new(
1504 field_ty.source_info.span,
1505 def_id,
ed00b5ec 1506 ObligationCauseCode::SizedCoroutineInterior(def_id),
781aab86
FG
1507 ),
1508 );
1509 }
1510 }
1511
9ffffee4
FG
1512 let errors = fulfillment_cx.select_all_or_error(&infcx);
1513 debug!(?errors);
1514 if !errors.is_empty() {
4b012472 1515 return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
9ffffee4 1516 }
4b012472
FG
1517
1518 // Check that any hidden types found when checking these stalled coroutine obligations
1519 // are valid.
1520 for (key, ty) in infcx.take_opaque_types() {
1521 let hidden_type = infcx.resolve_vars_if_possible(ty.hidden_type);
1522 let key = infcx.resolve_vars_if_possible(key);
1523 sanity_check_found_hidden_type(tcx, key, hidden_type)?;
1524 }
1525
1526 Ok(())
9ffffee4 1527}