1use std::cell::LazyCell;
2use std::ops::ControlFlow;
3
4use rustc_abi::{ExternAbi, FieldIdx, ScalableElt};
5use rustc_data_structures::unord::{UnordMap, UnordSet};
6use rustc_errors::codes::*;
7use rustc_errors::{EmissionGuarantee, MultiSpan};
8use rustc_hir as hir;
9use rustc_hir::attrs::AttributeKind;
10use rustc_hir::attrs::ReprAttr::ReprPacked;
11use rustc_hir::def::{CtorKind, DefKind};
12use rustc_hir::{LangItem, Node, attrs, find_attr, intravisit};
13use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
14use rustc_infer::traits::{Obligation, ObligationCauseCode, WellFormedLoc};
15use rustc_lint_defs::builtin::{REPR_TRANSPARENT_NON_ZST_FIELDS, UNSUPPORTED_CALLING_CONVENTIONS};
16use rustc_middle::hir::nested_filter;
17use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
18use rustc_middle::middle::stability::EvalResult;
19use rustc_middle::ty::error::TypeErrorToStringExt;
20use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
21use rustc_middle::ty::util::Discr;
22use rustc_middle::ty::{
23 AdtDef, BottomUpFolder, FnSig, GenericArgKind, RegionKind, TypeFoldable, TypeSuperVisitable,
24 TypeVisitable, TypeVisitableExt, fold_regions,
25};
26use rustc_session::lint::builtin::UNINHABITED_STATIC;
27use rustc_span::source_map::Spanned;
28use rustc_target::spec::{AbiMap, AbiMapping};
29use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
30use rustc_trait_selection::error_reporting::traits::on_unimplemented::OnUnimplementedDirective;
31use rustc_trait_selection::traits;
32use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
33use tracing::{debug, instrument};
34use ty::TypingMode;
35
36use super::compare_impl_item::check_type_bounds;
37use super::*;
38use crate::check::wfcheck::{
39 check_associated_item, check_trait_item, check_variances_for_type_defn, check_where_clauses,
40 enter_wf_checking_ctxt,
41};
42
43fn add_abi_diag_help<T: EmissionGuarantee>(abi: ExternAbi, diag: &mut Diag<'_, T>) {
44 if let ExternAbi::Cdecl { unwind } = abi {
45 let c_abi = ExternAbi::C { unwind };
46 diag.help(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("use `extern {0}` instead", c_abi))
})format!("use `extern {c_abi}` instead",));
47 } else if let ExternAbi::Stdcall { unwind } = abi {
48 let c_abi = ExternAbi::C { unwind };
49 let system_abi = ExternAbi::System { unwind };
50 diag.help(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("if you need `extern {0}` on win32 and `extern {1}` everywhere else, use `extern {2}`",
abi, c_abi, system_abi))
})format!(
51 "if you need `extern {abi}` on win32 and `extern {c_abi}` everywhere else, \
52 use `extern {system_abi}`"
53 ));
54 }
55}
56
57pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: ExternAbi) {
58 match AbiMap::from_target(&tcx.sess.target).canonize_abi(abi, false) {
63 AbiMapping::Direct(..) => (),
64 AbiMapping::Invalid => {
66 tcx.dcx().span_delayed_bug(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} should be rejected in ast_lowering",
abi))
})format!("{abi} should be rejected in ast_lowering"));
67 }
68 AbiMapping::Deprecated(..) => {
69 tcx.node_span_lint(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| {
70 lint.primary_message(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} is not a supported ABI for the current target",
abi))
})format!(
71 "{abi} is not a supported ABI for the current target"
72 ));
73 add_abi_diag_help(abi, lint);
74 });
75 }
76 }
77}
78
79pub fn check_custom_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, fn_sig: FnSig<'_>, fn_sig_span: Span) {
80 if fn_sig.abi == ExternAbi::Custom {
81 if !{
{
'done:
{
for i in tcx.get_all_attrs(def_id) {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::Naked(_)) => {
break 'done Some(());
}
_ => {}
}
}
None
}
}.is_some()
}find_attr!(tcx.get_all_attrs(def_id), AttributeKind::Naked(_)) {
83 tcx.dcx().emit_err(crate::errors::AbiCustomClothedFunction {
84 span: fn_sig_span,
85 naked_span: tcx.def_span(def_id).shrink_to_lo(),
86 });
87 }
88 }
89}
90
91fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
92 let def = tcx.adt_def(def_id);
93 let span = tcx.def_span(def_id);
94 def.destructor(tcx); if let Some(scalable) = def.repr().scalable {
97 check_scalable_vector(tcx, span, def_id, scalable);
98 } else if def.repr().simd() {
99 check_simd(tcx, span, def_id);
100 }
101
102 check_transparent(tcx, def);
103 check_packed(tcx, span, def);
104}
105
106fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
107 let def = tcx.adt_def(def_id);
108 let span = tcx.def_span(def_id);
109 def.destructor(tcx); check_transparent(tcx, def);
111 check_union_fields(tcx, span, def_id);
112 check_packed(tcx, span, def);
113}
114
115fn allowed_union_or_unsafe_field<'tcx>(
116 tcx: TyCtxt<'tcx>,
117 ty: Ty<'tcx>,
118 typing_env: ty::TypingEnv<'tcx>,
119 span: Span,
120) -> bool {
121 if ty.is_trivially_pure_clone_copy() {
126 return true;
127 }
128 let def_id = tcx
131 .lang_items()
132 .get(LangItem::BikeshedGuaranteedNoDrop)
133 .unwrap_or_else(|| tcx.require_lang_item(LangItem::Copy, span));
134 let Ok(ty) = tcx.try_normalize_erasing_regions(typing_env, ty) else {
135 tcx.dcx().span_delayed_bug(span, "could not normalize field type");
136 return true;
137 };
138 let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
139 infcx.predicate_must_hold_modulo_regions(&Obligation::new(
140 tcx,
141 ObligationCause::dummy_with_span(span),
142 param_env,
143 ty::TraitRef::new(tcx, def_id, [ty]),
144 ))
145}
146
147fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> bool {
149 let def = tcx.adt_def(item_def_id);
150 if !def.is_union() {
::core::panicking::panic("assertion failed: def.is_union()")
};assert!(def.is_union());
151
152 let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
153 let args = ty::GenericArgs::identity_for_item(tcx, item_def_id);
154
155 for field in &def.non_enum_variant().fields {
156 if !allowed_union_or_unsafe_field(tcx, field.ty(tcx, args), typing_env, span) {
157 let (field_span, ty_span) = match tcx.hir_get_if_local(field.did) {
158 Some(Node::Field(field)) => (field.span, field.ty.span),
160 _ => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("mir field has to correspond to hir field")));
}unreachable!("mir field has to correspond to hir field"),
161 };
162 tcx.dcx().emit_err(errors::InvalidUnionField {
163 field_span,
164 sugg: errors::InvalidUnionFieldSuggestion {
165 lo: ty_span.shrink_to_lo(),
166 hi: ty_span.shrink_to_hi(),
167 },
168 note: (),
169 });
170 return false;
171 }
172 }
173
174 true
175}
176
177fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
179 let ty = tcx.type_of(def_id).instantiate_identity();
185 let span = tcx.def_span(def_id);
186 let layout = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) {
187 Ok(l) => l,
188 Err(LayoutError::SizeOverflow(_))
190 if #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(def_id) {
DefKind::Static { .. } if
tcx.def_kind(tcx.local_parent(def_id)) == DefKind::ForeignMod => true,
_ => false,
}matches!(tcx.def_kind(def_id), DefKind::Static{ .. }
191 if tcx.def_kind(tcx.local_parent(def_id)) == DefKind::ForeignMod) =>
192 {
193 tcx.dcx().emit_err(errors::TooLargeStatic { span });
194 return;
195 }
196 Err(e @ LayoutError::InvalidSimd { .. }) => {
198 let ty_span = tcx.ty_span(def_id);
199 tcx.dcx().emit_err(Spanned { span: ty_span, node: e.into_diagnostic() });
200 return;
201 }
202 Err(e) => {
204 tcx.dcx().span_delayed_bug(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0:?}", e))
})format!("{e:?}"));
205 return;
206 }
207 };
208 if layout.is_uninhabited() {
209 tcx.node_span_lint(
210 UNINHABITED_STATIC,
211 tcx.local_def_id_to_hir_id(def_id),
212 span,
213 |lint| {
214 lint.primary_message("static of uninhabited type");
215 lint
216 .note("uninhabited statics cannot be initialized, and any access would be an immediate error");
217 },
218 );
219 }
220}
221
222fn check_opaque(tcx: TyCtxt<'_>, def_id: LocalDefId) {
225 let hir::OpaqueTy { origin, .. } = *tcx.hir_expect_opaque_ty(def_id);
226
227 if tcx.sess.opts.actually_rustdoc {
232 return;
233 }
234
235 if tcx.type_of(def_id).instantiate_identity().references_error() {
236 return;
237 }
238 if check_opaque_for_cycles(tcx, def_id).is_err() {
239 return;
240 }
241
242 let _ = check_opaque_meets_bounds(tcx, def_id, origin);
243}
244
245pub(super) fn check_opaque_for_cycles<'tcx>(
247 tcx: TyCtxt<'tcx>,
248 def_id: LocalDefId,
249) -> Result<(), ErrorGuaranteed> {
250 let args = GenericArgs::identity_for_item(tcx, def_id);
251
252 if tcx.try_expand_impl_trait_type(def_id.to_def_id(), args).is_err() {
255 let reported = opaque_type_cycle_error(tcx, def_id);
256 return Err(reported);
257 }
258
259 Ok(())
260}
261
262#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("check_opaque_meets_bounds",
"rustc_hir_analysis::check::check", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/check/check.rs"),
::tracing_core::__macro_support::Option::Some(277u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::check::check"),
::tracing_core::field::FieldSet::new(&["def_id", "origin"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&origin)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Result<(), ErrorGuaranteed> =
loop {};
return __tracing_attr_fake_return;
}
{
let (span, definition_def_id) =
if let Some((span, def_id)) =
best_definition_site_of_opaque(tcx, def_id, origin) {
(span, Some(def_id))
} else { (tcx.def_span(def_id), None) };
let defining_use_anchor =
match origin {
hir::OpaqueTyOrigin::FnReturn { parent, .. } |
hir::OpaqueTyOrigin::AsyncFn { parent, .. } |
hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent,
};
let param_env = tcx.param_env(defining_use_anchor);
let infcx =
tcx.infer_ctxt().build(if tcx.next_trait_solver_globally() {
TypingMode::post_borrowck_analysis(tcx, defining_use_anchor)
} else {
TypingMode::analysis_in_body(tcx, defining_use_anchor)
});
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let args =
match origin {
hir::OpaqueTyOrigin::FnReturn { parent, .. } |
hir::OpaqueTyOrigin::AsyncFn { parent, .. } |
hir::OpaqueTyOrigin::TyAlias { parent, .. } =>
GenericArgs::identity_for_item(tcx,
parent).extend_to(tcx, def_id.to_def_id(),
|param, _|
{
tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into()
}),
};
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
let hidden_ty =
tcx.type_of(def_id.to_def_id()).instantiate(tcx, args);
let hidden_ty =
fold_regions(tcx, hidden_ty,
|re, _dbi|
match re.kind() {
ty::ReErased =>
infcx.next_region_var(RegionVariableOrigin::Misc(span)),
_ => re,
});
for (predicate, pred_span) in
tcx.explicit_item_bounds(def_id).iter_instantiated_copied(tcx,
args) {
let predicate =
predicate.fold_with(&mut BottomUpFolder {
tcx,
ty_op: |ty| if ty == opaque_ty { hidden_ty } else { ty },
lt_op: |lt| lt,
ct_op: |ct| ct,
});
ocx.register_obligation(Obligation::new(tcx,
ObligationCause::new(span, def_id,
ObligationCauseCode::OpaqueTypeBound(pred_span,
definition_def_id)), param_env, predicate));
}
let misc_cause = ObligationCause::misc(span, def_id);
match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
Ok(()) => {}
Err(ty_err) => {
let ty_err = ty_err.to_string(tcx);
let guar =
tcx.dcx().span_delayed_bug(span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("could not unify `{0}` with revealed type:\n{1}",
hidden_ty, ty_err))
}));
return Err(guar);
}
}
let predicate =
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(hidden_ty.into())));
ocx.register_obligation(Obligation::new(tcx, misc_cause.clone(),
param_env, predicate));
let errors = ocx.evaluate_obligations_error_on_ambiguity();
if !errors.is_empty() {
let guar = infcx.err_ctxt().report_fulfillment_errors(errors);
return Err(guar);
}
let wf_tys =
ocx.assumed_wf_types_and_report_errors(param_env,
defining_use_anchor)?;
ocx.resolve_regions_and_report_errors(defining_use_anchor,
param_env, wf_tys)?;
if infcx.next_trait_solver() {
Ok(())
} else if let hir::OpaqueTyOrigin::FnReturn { .. } |
hir::OpaqueTyOrigin::AsyncFn { .. } = origin {
let _ = infcx.take_opaque_types();
Ok(())
} else {
for (mut key, mut ty) in infcx.take_opaque_types() {
ty.ty = infcx.resolve_vars_if_possible(ty.ty);
key = infcx.resolve_vars_if_possible(key);
sanity_check_found_hidden_type(tcx, key, ty)?;
}
Ok(())
}
}
}
}#[instrument(level = "debug", skip(tcx))]
278fn check_opaque_meets_bounds<'tcx>(
279 tcx: TyCtxt<'tcx>,
280 def_id: LocalDefId,
281 origin: hir::OpaqueTyOrigin<LocalDefId>,
282) -> Result<(), ErrorGuaranteed> {
283 let (span, definition_def_id) =
284 if let Some((span, def_id)) = best_definition_site_of_opaque(tcx, def_id, origin) {
285 (span, Some(def_id))
286 } else {
287 (tcx.def_span(def_id), None)
288 };
289
290 let defining_use_anchor = match origin {
291 hir::OpaqueTyOrigin::FnReturn { parent, .. }
292 | hir::OpaqueTyOrigin::AsyncFn { parent, .. }
293 | hir::OpaqueTyOrigin::TyAlias { parent, .. } => parent,
294 };
295 let param_env = tcx.param_env(defining_use_anchor);
296
297 let infcx = tcx.infer_ctxt().build(if tcx.next_trait_solver_globally() {
299 TypingMode::post_borrowck_analysis(tcx, defining_use_anchor)
300 } else {
301 TypingMode::analysis_in_body(tcx, defining_use_anchor)
302 });
303 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
304
305 let args = match origin {
306 hir::OpaqueTyOrigin::FnReturn { parent, .. }
307 | hir::OpaqueTyOrigin::AsyncFn { parent, .. }
308 | hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item(
309 tcx, parent,
310 )
311 .extend_to(tcx, def_id.to_def_id(), |param, _| {
312 tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into()
313 }),
314 };
315
316 let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
317
318 let hidden_ty = tcx.type_of(def_id.to_def_id()).instantiate(tcx, args);
325 let hidden_ty = fold_regions(tcx, hidden_ty, |re, _dbi| match re.kind() {
326 ty::ReErased => infcx.next_region_var(RegionVariableOrigin::Misc(span)),
327 _ => re,
328 });
329
330 for (predicate, pred_span) in
334 tcx.explicit_item_bounds(def_id).iter_instantiated_copied(tcx, args)
335 {
336 let predicate = predicate.fold_with(&mut BottomUpFolder {
337 tcx,
338 ty_op: |ty| if ty == opaque_ty { hidden_ty } else { ty },
339 lt_op: |lt| lt,
340 ct_op: |ct| ct,
341 });
342
343 ocx.register_obligation(Obligation::new(
344 tcx,
345 ObligationCause::new(
346 span,
347 def_id,
348 ObligationCauseCode::OpaqueTypeBound(pred_span, definition_def_id),
349 ),
350 param_env,
351 predicate,
352 ));
353 }
354
355 let misc_cause = ObligationCause::misc(span, def_id);
356 match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
360 Ok(()) => {}
361 Err(ty_err) => {
362 let ty_err = ty_err.to_string(tcx);
368 let guar = tcx.dcx().span_delayed_bug(
369 span,
370 format!("could not unify `{hidden_ty}` with revealed type:\n{ty_err}"),
371 );
372 return Err(guar);
373 }
374 }
375
376 let predicate =
380 ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(hidden_ty.into())));
381 ocx.register_obligation(Obligation::new(tcx, misc_cause.clone(), param_env, predicate));
382
383 let errors = ocx.evaluate_obligations_error_on_ambiguity();
386 if !errors.is_empty() {
387 let guar = infcx.err_ctxt().report_fulfillment_errors(errors);
388 return Err(guar);
389 }
390
391 let wf_tys = ocx.assumed_wf_types_and_report_errors(param_env, defining_use_anchor)?;
392 ocx.resolve_regions_and_report_errors(defining_use_anchor, param_env, wf_tys)?;
393
394 if infcx.next_trait_solver() {
395 Ok(())
396 } else if let hir::OpaqueTyOrigin::FnReturn { .. } | hir::OpaqueTyOrigin::AsyncFn { .. } =
397 origin
398 {
399 let _ = infcx.take_opaque_types();
405 Ok(())
406 } else {
407 for (mut key, mut ty) in infcx.take_opaque_types() {
409 ty.ty = infcx.resolve_vars_if_possible(ty.ty);
410 key = infcx.resolve_vars_if_possible(key);
411 sanity_check_found_hidden_type(tcx, key, ty)?;
412 }
413 Ok(())
414 }
415}
416
417fn best_definition_site_of_opaque<'tcx>(
418 tcx: TyCtxt<'tcx>,
419 opaque_def_id: LocalDefId,
420 origin: hir::OpaqueTyOrigin<LocalDefId>,
421) -> Option<(Span, LocalDefId)> {
422 struct TaitConstraintLocator<'tcx> {
423 opaque_def_id: LocalDefId,
424 tcx: TyCtxt<'tcx>,
425 }
426 impl<'tcx> TaitConstraintLocator<'tcx> {
427 fn check(&self, item_def_id: LocalDefId) -> ControlFlow<(Span, LocalDefId)> {
428 if !self.tcx.has_typeck_results(item_def_id) {
429 return ControlFlow::Continue(());
430 }
431
432 let opaque_types_defined_by = self.tcx.opaque_types_defined_by(item_def_id);
433 if !opaque_types_defined_by.contains(&self.opaque_def_id) {
435 return ControlFlow::Continue(());
436 }
437
438 if let Some(hidden_ty) = self
439 .tcx
440 .mir_borrowck(item_def_id)
441 .ok()
442 .and_then(|opaque_types| opaque_types.get(&self.opaque_def_id))
443 {
444 ControlFlow::Break((hidden_ty.span, item_def_id))
445 } else {
446 ControlFlow::Continue(())
447 }
448 }
449 }
450 impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> {
451 type NestedFilter = nested_filter::All;
452 type Result = ControlFlow<(Span, LocalDefId)>;
453 fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
454 self.tcx
455 }
456 fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> Self::Result {
457 intravisit::walk_expr(self, ex)
458 }
459 fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) -> Self::Result {
460 self.check(it.owner_id.def_id)?;
461 intravisit::walk_item(self, it)
462 }
463 fn visit_impl_item(&mut self, it: &'tcx hir::ImplItem<'tcx>) -> Self::Result {
464 self.check(it.owner_id.def_id)?;
465 intravisit::walk_impl_item(self, it)
466 }
467 fn visit_trait_item(&mut self, it: &'tcx hir::TraitItem<'tcx>) -> Self::Result {
468 self.check(it.owner_id.def_id)?;
469 intravisit::walk_trait_item(self, it)
470 }
471 fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) -> Self::Result {
472 intravisit::walk_foreign_item(self, it)
473 }
474 }
475
476 let mut locator = TaitConstraintLocator { tcx, opaque_def_id };
477 match origin {
478 hir::OpaqueTyOrigin::FnReturn { parent, .. }
479 | hir::OpaqueTyOrigin::AsyncFn { parent, .. } => locator.check(parent).break_value(),
480 hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty: true } => {
481 let impl_def_id = tcx.local_parent(parent);
482 for assoc in tcx.associated_items(impl_def_id).in_definition_order() {
483 match assoc.kind {
484 ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => {
485 if let ControlFlow::Break(span) = locator.check(assoc.def_id.expect_local())
486 {
487 return Some(span);
488 }
489 }
490 ty::AssocKind::Type { .. } => {}
491 }
492 }
493
494 None
495 }
496 hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. } => {
497 tcx.hir_walk_toplevel_module(&mut locator).break_value()
498 }
499 }
500}
501
502fn sanity_check_found_hidden_type<'tcx>(
503 tcx: TyCtxt<'tcx>,
504 key: ty::OpaqueTypeKey<'tcx>,
505 mut ty: ty::ProvisionalHiddenType<'tcx>,
506) -> Result<(), ErrorGuaranteed> {
507 if ty.ty.is_ty_var() {
508 return Ok(());
510 }
511 if let ty::Alias(ty::Opaque, alias) = ty.ty.kind() {
512 if alias.def_id == key.def_id.to_def_id() && alias.args == key.args {
513 return Ok(());
516 }
517 }
518 let erase_re_vars = |ty: Ty<'tcx>| {
519 fold_regions(tcx, ty, |r, _| match r.kind() {
520 RegionKind::ReVar(_) => tcx.lifetimes.re_erased,
521 _ => r,
522 })
523 };
524 ty.ty = erase_re_vars(ty.ty);
527 let hidden_ty = tcx.type_of(key.def_id).instantiate(tcx, key.args);
529 let hidden_ty = erase_re_vars(hidden_ty);
530
531 if hidden_ty == ty.ty {
533 Ok(())
534 } else {
535 let span = tcx.def_span(key.def_id);
536 let other = ty::ProvisionalHiddenType { ty: hidden_ty, span };
537 Err(ty.build_mismatch_error(&other, tcx)?.emit())
538 }
539}
540
541fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) {
550 let hir::OpaqueTy { bounds, .. } = *tcx.hir_node_by_def_id(opaque_def_id).expect_opaque_ty();
551 let Some(precise_capturing_args) = bounds.iter().find_map(|bound| match *bound {
552 hir::GenericBound::Use(bounds, ..) => Some(bounds),
553 _ => None,
554 }) else {
555 return;
557 };
558
559 let mut expected_captures = UnordSet::default();
560 let mut shadowed_captures = UnordSet::default();
561 let mut seen_params = UnordMap::default();
562 let mut prev_non_lifetime_param = None;
563 for arg in precise_capturing_args {
564 let (hir_id, ident) = match *arg {
565 hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
566 hir_id,
567 ident,
568 ..
569 }) => {
570 if prev_non_lifetime_param.is_none() {
571 prev_non_lifetime_param = Some(ident);
572 }
573 (hir_id, ident)
574 }
575 hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, ident, .. }) => {
576 if let Some(prev_non_lifetime_param) = prev_non_lifetime_param {
577 tcx.dcx().emit_err(errors::LifetimesMustBeFirst {
578 lifetime_span: ident.span,
579 name: ident.name,
580 other_span: prev_non_lifetime_param.span,
581 });
582 }
583 (hir_id, ident)
584 }
585 };
586
587 let ident = ident.normalize_to_macros_2_0();
588 if let Some(span) = seen_params.insert(ident, ident.span) {
589 tcx.dcx().emit_err(errors::DuplicatePreciseCapture {
590 name: ident.name,
591 first_span: span,
592 second_span: ident.span,
593 });
594 }
595
596 match tcx.named_bound_var(hir_id) {
597 Some(ResolvedArg::EarlyBound(def_id)) => {
598 expected_captures.insert(def_id.to_def_id());
599
600 if let DefKind::LifetimeParam = tcx.def_kind(def_id)
606 && let Some(def_id) = tcx
607 .map_opaque_lifetime_to_parent_lifetime(def_id)
608 .opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id()))
609 {
610 shadowed_captures.insert(def_id);
611 }
612 }
613 _ => {
614 tcx.dcx()
615 .span_delayed_bug(tcx.hir_span(hir_id), "parameter should have been resolved");
616 }
617 }
618 }
619
620 let variances = tcx.variances_of(opaque_def_id);
621 let mut def_id = Some(opaque_def_id.to_def_id());
622 while let Some(generics) = def_id {
623 let generics = tcx.generics_of(generics);
624 def_id = generics.parent;
625
626 for param in &generics.own_params {
627 if expected_captures.contains(¶m.def_id) {
628 match (&variances[param.index as usize], &ty::Invariant) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::Some(format_args!("precise captured param should be invariant")));
}
}
};assert_eq!(
629 variances[param.index as usize],
630 ty::Invariant,
631 "precise captured param should be invariant"
632 );
633 continue;
634 }
635 if shadowed_captures.contains(¶m.def_id) {
639 continue;
640 }
641
642 match param.kind {
643 ty::GenericParamDefKind::Lifetime => {
644 let use_span = tcx.def_span(param.def_id);
645 let opaque_span = tcx.def_span(opaque_def_id);
646 if variances[param.index as usize] == ty::Invariant {
648 if let DefKind::OpaqueTy = tcx.def_kind(tcx.parent(param.def_id))
649 && let Some(def_id) = tcx
650 .map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local())
651 .opt_param_def_id(tcx, tcx.parent(opaque_def_id.to_def_id()))
652 {
653 tcx.dcx().emit_err(errors::LifetimeNotCaptured {
654 opaque_span,
655 use_span,
656 param_span: tcx.def_span(def_id),
657 });
658 } else {
659 if tcx.def_kind(tcx.parent(param.def_id)) == DefKind::Trait {
660 tcx.dcx().emit_err(errors::LifetimeImplicitlyCaptured {
661 opaque_span,
662 param_span: tcx.def_span(param.def_id),
663 });
664 } else {
665 tcx.dcx().emit_err(errors::LifetimeNotCaptured {
670 opaque_span,
671 use_span: opaque_span,
672 param_span: use_span,
673 });
674 }
675 }
676 continue;
677 }
678 }
679 ty::GenericParamDefKind::Type { .. } => {
680 if #[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(param.def_id) {
DefKind::Trait | DefKind::TraitAlias => true,
_ => false,
}matches!(tcx.def_kind(param.def_id), DefKind::Trait | DefKind::TraitAlias) {
681 tcx.dcx().emit_err(errors::SelfTyNotCaptured {
683 trait_span: tcx.def_span(param.def_id),
684 opaque_span: tcx.def_span(opaque_def_id),
685 });
686 } else {
687 tcx.dcx().emit_err(errors::ParamNotCaptured {
689 param_span: tcx.def_span(param.def_id),
690 opaque_span: tcx.def_span(opaque_def_id),
691 kind: "type",
692 });
693 }
694 }
695 ty::GenericParamDefKind::Const { .. } => {
696 tcx.dcx().emit_err(errors::ParamNotCaptured {
698 param_span: tcx.def_span(param.def_id),
699 opaque_span: tcx.def_span(opaque_def_id),
700 kind: "const",
701 });
702 }
703 }
704 }
705 }
706}
707
708fn is_enum_of_nonnullable_ptr<'tcx>(
709 tcx: TyCtxt<'tcx>,
710 adt_def: AdtDef<'tcx>,
711 args: GenericArgsRef<'tcx>,
712) -> bool {
713 if adt_def.repr().inhibit_enum_layout_opt() {
714 return false;
715 }
716
717 let [var_one, var_two] = &adt_def.variants().raw[..] else {
718 return false;
719 };
720 let (([], [field]) | ([field], [])) = (&var_one.fields.raw[..], &var_two.fields.raw[..]) else {
721 return false;
722 };
723 #[allow(non_exhaustive_omitted_patterns)] match field.ty(tcx, args).kind() {
ty::FnPtr(..) | ty::Ref(..) => true,
_ => false,
}matches!(field.ty(tcx, args).kind(), ty::FnPtr(..) | ty::Ref(..))
724}
725
726fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
727 if tcx.codegen_fn_attrs(def_id).import_linkage.is_some() {
728 if match tcx.type_of(def_id).instantiate_identity().kind() {
729 ty::RawPtr(_, _) => false,
730 ty::Adt(adt_def, args) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *args),
731 _ => true,
732 } {
733 tcx.dcx().emit_err(errors::LinkageType { span: tcx.def_span(def_id) });
734 }
735 }
736}
737
738pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
739 let mut res = Ok(());
740 let generics = tcx.generics_of(def_id);
741
742 for param in &generics.own_params {
743 match param.kind {
744 ty::GenericParamDefKind::Lifetime { .. } => {}
745 ty::GenericParamDefKind::Type { has_default, .. } => {
746 if has_default {
747 tcx.ensure_ok().type_of(param.def_id);
748 }
749 }
750 ty::GenericParamDefKind::Const { has_default, .. } => {
751 tcx.ensure_ok().type_of(param.def_id);
752 if has_default {
753 let ct = tcx.const_param_default(param.def_id).skip_binder();
755 if let ty::ConstKind::Unevaluated(uv) = ct.kind() {
756 tcx.ensure_ok().type_of(uv.def);
757 }
758 }
759 }
760 }
761 }
762
763 match tcx.def_kind(def_id) {
764 DefKind::Static { .. } => {
765 tcx.ensure_ok().generics_of(def_id);
766 tcx.ensure_ok().type_of(def_id);
767 tcx.ensure_ok().predicates_of(def_id);
768
769 check_static_inhabited(tcx, def_id);
770 check_static_linkage(tcx, def_id);
771 let ty = tcx.type_of(def_id).instantiate_identity();
772 res = res.and(wfcheck::check_static_item(
773 tcx, def_id, ty, true,
774 ));
775
776 return res;
780 }
781 DefKind::Enum => {
782 tcx.ensure_ok().generics_of(def_id);
783 tcx.ensure_ok().type_of(def_id);
784 tcx.ensure_ok().predicates_of(def_id);
785 crate::collect::lower_enum_variant_types(tcx, def_id);
786 check_enum(tcx, def_id);
787 check_variances_for_type_defn(tcx, def_id);
788 }
789 DefKind::Fn => {
790 tcx.ensure_ok().generics_of(def_id);
791 tcx.ensure_ok().type_of(def_id);
792 tcx.ensure_ok().predicates_of(def_id);
793 tcx.ensure_ok().fn_sig(def_id);
794 tcx.ensure_ok().codegen_fn_attrs(def_id);
795 if let Some(i) = tcx.intrinsic(def_id) {
796 intrinsic::check_intrinsic_type(
797 tcx,
798 def_id,
799 tcx.def_ident_span(def_id).unwrap(),
800 i.name,
801 )
802 }
803 }
804 DefKind::Impl { of_trait } => {
805 tcx.ensure_ok().generics_of(def_id);
806 tcx.ensure_ok().type_of(def_id);
807 tcx.ensure_ok().predicates_of(def_id);
808 tcx.ensure_ok().associated_items(def_id);
809 check_diagnostic_attrs(tcx, def_id);
810 if of_trait {
811 let impl_trait_header = tcx.impl_trait_header(def_id);
812 res = res.and(
813 tcx.ensure_ok()
814 .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id),
815 );
816
817 if res.is_ok() {
818 check_impl_items_against_trait(tcx, def_id, impl_trait_header);
822 }
823 }
824 }
825 DefKind::Trait => {
826 tcx.ensure_ok().generics_of(def_id);
827 tcx.ensure_ok().trait_def(def_id);
828 tcx.ensure_ok().explicit_super_predicates_of(def_id);
829 tcx.ensure_ok().predicates_of(def_id);
830 tcx.ensure_ok().associated_items(def_id);
831 let assoc_items = tcx.associated_items(def_id);
832 check_diagnostic_attrs(tcx, def_id);
833
834 for &assoc_item in assoc_items.in_definition_order() {
835 match assoc_item.kind {
836 ty::AssocKind::Type { .. } if assoc_item.defaultness(tcx).has_value() => {
837 let trait_args = GenericArgs::identity_for_item(tcx, def_id);
838 let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
839 tcx,
840 assoc_item,
841 assoc_item,
842 ty::TraitRef::new_from_args(tcx, def_id.to_def_id(), trait_args),
843 );
844 }
845 _ => {}
846 }
847 }
848 }
849 DefKind::TraitAlias => {
850 tcx.ensure_ok().generics_of(def_id);
851 tcx.ensure_ok().explicit_implied_predicates_of(def_id);
852 tcx.ensure_ok().explicit_super_predicates_of(def_id);
853 tcx.ensure_ok().predicates_of(def_id);
854 }
855 def_kind @ (DefKind::Struct | DefKind::Union) => {
856 tcx.ensure_ok().generics_of(def_id);
857 tcx.ensure_ok().type_of(def_id);
858 tcx.ensure_ok().predicates_of(def_id);
859
860 let adt = tcx.adt_def(def_id).non_enum_variant();
861 for f in adt.fields.iter() {
862 tcx.ensure_ok().generics_of(f.did);
863 tcx.ensure_ok().type_of(f.did);
864 tcx.ensure_ok().predicates_of(f.did);
865 }
866
867 if let Some((_, ctor_def_id)) = adt.ctor {
868 crate::collect::lower_variant_ctor(tcx, ctor_def_id.expect_local());
869 }
870 match def_kind {
871 DefKind::Struct => check_struct(tcx, def_id),
872 DefKind::Union => check_union(tcx, def_id),
873 _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
874 }
875 check_variances_for_type_defn(tcx, def_id);
876 }
877 DefKind::OpaqueTy => {
878 check_opaque_precise_captures(tcx, def_id);
879
880 let origin = tcx.local_opaque_ty_origin(def_id);
881 if let hir::OpaqueTyOrigin::FnReturn { parent: fn_def_id, .. }
882 | hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, .. } = origin
883 && let hir::Node::TraitItem(trait_item) = tcx.hir_node_by_def_id(fn_def_id)
884 && let (_, hir::TraitFn::Required(..)) = trait_item.expect_fn()
885 {
886 } else {
888 check_opaque(tcx, def_id);
889 }
890
891 tcx.ensure_ok().predicates_of(def_id);
892 tcx.ensure_ok().explicit_item_bounds(def_id);
893 tcx.ensure_ok().explicit_item_self_bounds(def_id);
894 if tcx.is_conditionally_const(def_id) {
895 tcx.ensure_ok().explicit_implied_const_bounds(def_id);
896 tcx.ensure_ok().const_conditions(def_id);
897 }
898
899 return res;
903 }
904 DefKind::Const => {
905 tcx.ensure_ok().generics_of(def_id);
906 tcx.ensure_ok().type_of(def_id);
907 tcx.ensure_ok().predicates_of(def_id);
908
909 res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
910 let ty = tcx.type_of(def_id).instantiate_identity();
911 let ty_span = tcx.ty_span(def_id);
912 let ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(def_id)), ty);
913 wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(def_id)), ty.into());
914 wfcx.register_bound(
915 traits::ObligationCause::new(
916 ty_span,
917 def_id,
918 ObligationCauseCode::SizedConstOrStatic,
919 ),
920 tcx.param_env(def_id),
921 ty,
922 tcx.require_lang_item(LangItem::Sized, ty_span),
923 );
924 check_where_clauses(wfcx, def_id);
925
926 if {
{
'done:
{
for i in tcx.get_all_attrs(def_id) {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::TypeConst(_)) =>
{
break 'done Some(());
}
_ => {}
}
}
None
}
}.is_some()
}find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) {
927 wfcheck::check_type_const(wfcx, def_id, ty, true)?;
928 }
929 Ok(())
930 }));
931
932 return res;
936 }
937 DefKind::TyAlias => {
938 tcx.ensure_ok().generics_of(def_id);
939 tcx.ensure_ok().type_of(def_id);
940 tcx.ensure_ok().predicates_of(def_id);
941 check_type_alias_type_params_are_used(tcx, def_id);
942 if tcx.type_alias_is_lazy(def_id) {
943 res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
944 let ty = tcx.type_of(def_id).instantiate_identity();
945 let span = tcx.def_span(def_id);
946 let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty);
947 wfcx.register_wf_obligation(
948 span,
949 Some(WellFormedLoc::Ty(def_id)),
950 item_ty.into(),
951 );
952 check_where_clauses(wfcx, def_id);
953 Ok(())
954 }));
955 check_variances_for_type_defn(tcx, def_id);
956 }
957
958 return res;
962 }
963 DefKind::ForeignMod => {
964 let it = tcx.hir_expect_item(def_id);
965 let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
966 return Ok(());
967 };
968
969 check_abi(tcx, it.hir_id(), it.span, abi);
970
971 for &item in items {
972 let def_id = item.owner_id.def_id;
973
974 let generics = tcx.generics_of(def_id);
975 let own_counts = generics.own_counts();
976 if generics.own_params.len() - own_counts.lifetimes != 0 {
977 let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
978 (_, 0) => ("type", "types", Some("u32")),
979 (0, _) => ("const", "consts", None),
982 _ => ("type or const", "types or consts", None),
983 };
984 let name =
985 if {
{
'done:
{
for i in tcx.get_all_attrs(def_id) {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::EiiForeignItem)
=> {
break 'done Some(());
}
_ => {}
}
}
None
}
}.is_some()
}find_attr!(tcx.get_all_attrs(def_id), AttributeKind::EiiForeignItem) {
986 "externally implementable items"
987 } else {
988 "foreign items"
989 };
990
991 let span = tcx.def_span(def_id);
992 {
tcx.dcx().struct_span_err(span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} may not have {1} parameters",
name, kinds))
})).with_code(E0044)
}struct_span_code_err!(
993 tcx.dcx(),
994 span,
995 E0044,
996 "{name} may not have {kinds} parameters",
997 )
998 .with_span_label(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("can\'t have {0} parameters",
kinds))
})format!("can't have {kinds} parameters"))
999 .with_help(
1000 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("replace the {0} parameters with concrete {1}{2}",
kinds, kinds_pl,
egs.map(|egs|
::alloc::__export::must_use({
::alloc::fmt::format(format_args!(" like `{0}`", egs))
})).unwrap_or_default()))
})format!(
1003 "replace the {} parameters with concrete {}{}",
1004 kinds,
1005 kinds_pl,
1006 egs.map(|egs| format!(" like `{egs}`")).unwrap_or_default(),
1007 ),
1008 )
1009 .emit();
1010 }
1011
1012 tcx.ensure_ok().generics_of(def_id);
1013 tcx.ensure_ok().type_of(def_id);
1014 tcx.ensure_ok().predicates_of(def_id);
1015 if tcx.is_conditionally_const(def_id) {
1016 tcx.ensure_ok().explicit_implied_const_bounds(def_id);
1017 tcx.ensure_ok().const_conditions(def_id);
1018 }
1019 match tcx.def_kind(def_id) {
1020 DefKind::Fn => {
1021 tcx.ensure_ok().codegen_fn_attrs(def_id);
1022 tcx.ensure_ok().fn_sig(def_id);
1023 let item = tcx.hir_foreign_item(item);
1024 let hir::ForeignItemKind::Fn(sig, ..) = item.kind else { ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
1025 check_c_variadic_abi(tcx, sig.decl, abi, item.span);
1026 }
1027 DefKind::Static { .. } => {
1028 tcx.ensure_ok().codegen_fn_attrs(def_id);
1029 }
1030 _ => (),
1031 }
1032 }
1033 }
1034 DefKind::Closure => {
1035 tcx.ensure_ok().codegen_fn_attrs(def_id);
1039 return res;
1047 }
1048 DefKind::AssocFn => {
1049 tcx.ensure_ok().codegen_fn_attrs(def_id);
1050 tcx.ensure_ok().type_of(def_id);
1051 tcx.ensure_ok().fn_sig(def_id);
1052 tcx.ensure_ok().predicates_of(def_id);
1053 res = res.and(check_associated_item(tcx, def_id));
1054 let assoc_item = tcx.associated_item(def_id);
1055 match assoc_item.container {
1056 ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {}
1057 ty::AssocContainer::Trait => {
1058 res = res.and(check_trait_item(tcx, def_id));
1059 }
1060 }
1061
1062 return res;
1066 }
1067 DefKind::AssocConst => {
1068 tcx.ensure_ok().type_of(def_id);
1069 tcx.ensure_ok().predicates_of(def_id);
1070 res = res.and(check_associated_item(tcx, def_id));
1071 let assoc_item = tcx.associated_item(def_id);
1072 match assoc_item.container {
1073 ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => {}
1074 ty::AssocContainer::Trait => {
1075 res = res.and(check_trait_item(tcx, def_id));
1076 }
1077 }
1078
1079 return res;
1083 }
1084 DefKind::AssocTy => {
1085 tcx.ensure_ok().predicates_of(def_id);
1086 res = res.and(check_associated_item(tcx, def_id));
1087
1088 let assoc_item = tcx.associated_item(def_id);
1089 let has_type = match assoc_item.container {
1090 ty::AssocContainer::InherentImpl | ty::AssocContainer::TraitImpl(_) => true,
1091 ty::AssocContainer::Trait => {
1092 tcx.ensure_ok().explicit_item_bounds(def_id);
1093 tcx.ensure_ok().explicit_item_self_bounds(def_id);
1094 if tcx.is_conditionally_const(def_id) {
1095 tcx.ensure_ok().explicit_implied_const_bounds(def_id);
1096 tcx.ensure_ok().const_conditions(def_id);
1097 }
1098 res = res.and(check_trait_item(tcx, def_id));
1099 assoc_item.defaultness(tcx).has_value()
1100 }
1101 };
1102 if has_type {
1103 tcx.ensure_ok().type_of(def_id);
1104 }
1105
1106 return res;
1110 }
1111
1112 DefKind::AnonConst | DefKind::InlineConst => return res,
1116 _ => {}
1117 }
1118 let node = tcx.hir_node_by_def_id(def_id);
1119 res.and(match node {
1120 hir::Node::Crate(_) => ::rustc_middle::util::bug::bug_fmt(format_args!("check_well_formed cannot be applied to the crate root"))bug!("check_well_formed cannot be applied to the crate root"),
1121 hir::Node::Item(item) => wfcheck::check_item(tcx, item),
1122 hir::Node::ForeignItem(item) => wfcheck::check_foreign_item(tcx, item),
1123 _ => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("{0:?}", node)));
}unreachable!("{node:?}"),
1124 })
1125}
1126
1127pub(super) fn check_diagnostic_attrs(tcx: TyCtxt<'_>, def_id: LocalDefId) {
1128 let _ = OnUnimplementedDirective::of_item(tcx, def_id.to_def_id());
1130}
1131
1132pub(super) fn check_specialization_validity<'tcx>(
1133 tcx: TyCtxt<'tcx>,
1134 trait_def: &ty::TraitDef,
1135 trait_item: ty::AssocItem,
1136 impl_id: DefId,
1137 impl_item: DefId,
1138) {
1139 let Ok(ancestors) = trait_def.ancestors(tcx, impl_id) else { return };
1140 let mut ancestor_impls = ancestors.skip(1).filter_map(|parent| {
1141 if parent.is_from_trait() {
1142 None
1143 } else {
1144 Some((parent, parent.item(tcx, trait_item.def_id)))
1145 }
1146 });
1147
1148 let opt_result = ancestor_impls.find_map(|(parent_impl, parent_item)| {
1149 match parent_item {
1150 Some(parent_item) if traits::impl_item_is_final(tcx, &parent_item) => {
1153 Some(Err(parent_impl.def_id()))
1154 }
1155
1156 Some(_) => Some(Ok(())),
1158
1159 None => {
1163 if tcx.defaultness(parent_impl.def_id()).is_default() {
1164 None
1165 } else {
1166 Some(Err(parent_impl.def_id()))
1167 }
1168 }
1169 }
1170 });
1171
1172 let result = opt_result.unwrap_or(Ok(()));
1175
1176 if let Err(parent_impl) = result {
1177 if !tcx.is_impl_trait_in_trait(impl_item) {
1178 report_forbidden_specialization(tcx, impl_item, parent_impl);
1179 } else {
1180 tcx.dcx().delayed_bug(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("parent item: {0:?} not marked as default",
parent_impl))
})format!("parent item: {parent_impl:?} not marked as default"));
1181 }
1182 }
1183}
1184
1185fn check_impl_items_against_trait<'tcx>(
1186 tcx: TyCtxt<'tcx>,
1187 impl_id: LocalDefId,
1188 impl_trait_header: ty::ImplTraitHeader<'tcx>,
1189) {
1190 let trait_ref = impl_trait_header.trait_ref.instantiate_identity();
1191 if trait_ref.references_error() {
1195 return;
1196 }
1197
1198 let impl_item_refs = tcx.associated_item_def_ids(impl_id);
1199
1200 match impl_trait_header.polarity {
1202 ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
1203 ty::ImplPolarity::Negative => {
1204 if let [first_item_ref, ..] = impl_item_refs {
1205 let first_item_span = tcx.def_span(first_item_ref);
1206 {
tcx.dcx().struct_span_err(first_item_span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("negative impls cannot have any items"))
})).with_code(E0749)
}struct_span_code_err!(
1207 tcx.dcx(),
1208 first_item_span,
1209 E0749,
1210 "negative impls cannot have any items"
1211 )
1212 .emit();
1213 }
1214 return;
1215 }
1216 }
1217
1218 let trait_def = tcx.trait_def(trait_ref.def_id);
1219
1220 let self_is_guaranteed_unsize_self = tcx.impl_self_is_guaranteed_unsized(impl_id);
1221
1222 for &impl_item in impl_item_refs {
1223 let ty_impl_item = tcx.associated_item(impl_item);
1224 let ty_trait_item = match ty_impl_item.expect_trait_impl() {
1225 Ok(trait_item_id) => tcx.associated_item(trait_item_id),
1226 Err(ErrorGuaranteed { .. }) => continue,
1227 };
1228
1229 let res = tcx.ensure_ok().compare_impl_item(impl_item.expect_local());
1230
1231 if res.is_ok() {
1232 match ty_impl_item.kind {
1233 ty::AssocKind::Fn { .. } => {
1234 compare_impl_item::refine::check_refining_return_position_impl_trait_in_trait(
1235 tcx,
1236 ty_impl_item,
1237 ty_trait_item,
1238 tcx.impl_trait_ref(ty_impl_item.container_id(tcx)).instantiate_identity(),
1239 );
1240 }
1241 ty::AssocKind::Const { .. } => {}
1242 ty::AssocKind::Type { .. } => {}
1243 }
1244 }
1245
1246 if self_is_guaranteed_unsize_self && tcx.generics_require_sized_self(ty_trait_item.def_id) {
1247 tcx.emit_node_span_lint(
1248 rustc_lint_defs::builtin::DEAD_CODE,
1249 tcx.local_def_id_to_hir_id(ty_impl_item.def_id.expect_local()),
1250 tcx.def_span(ty_impl_item.def_id),
1251 errors::UselessImplItem,
1252 )
1253 }
1254
1255 check_specialization_validity(
1256 tcx,
1257 trait_def,
1258 ty_trait_item,
1259 impl_id.to_def_id(),
1260 impl_item,
1261 );
1262 }
1263
1264 if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
1265 let mut missing_items = Vec::new();
1267
1268 let mut must_implement_one_of: Option<&[Ident]> =
1269 trait_def.must_implement_one_of.as_deref();
1270
1271 for &trait_item_id in tcx.associated_item_def_ids(trait_ref.def_id) {
1272 let leaf_def = ancestors.leaf_def(tcx, trait_item_id);
1273
1274 let is_implemented = leaf_def
1275 .as_ref()
1276 .is_some_and(|node_item| node_item.item.defaultness(tcx).has_value());
1277
1278 if !is_implemented
1279 && tcx.defaultness(impl_id).is_final()
1280 && !(self_is_guaranteed_unsize_self && tcx.generics_require_sized_self(trait_item_id))
1282 {
1283 missing_items.push(tcx.associated_item(trait_item_id));
1284 }
1285
1286 let is_implemented_here =
1288 leaf_def.as_ref().is_some_and(|node_item| !node_item.defining_node.is_from_trait());
1289
1290 if !is_implemented_here {
1291 let full_impl_span = tcx.hir_span_with_body(tcx.local_def_id_to_hir_id(impl_id));
1292 match tcx.eval_default_body_stability(trait_item_id, full_impl_span) {
1293 EvalResult::Deny { feature, reason, issue, .. } => default_body_is_unstable(
1294 tcx,
1295 full_impl_span,
1296 trait_item_id,
1297 feature,
1298 reason,
1299 issue,
1300 ),
1301
1302 EvalResult::Allow | EvalResult::Unmarked => {}
1304 }
1305 }
1306
1307 if let Some(required_items) = &must_implement_one_of {
1308 if is_implemented_here {
1309 let trait_item = tcx.associated_item(trait_item_id);
1310 if required_items.contains(&trait_item.ident(tcx)) {
1311 must_implement_one_of = None;
1312 }
1313 }
1314 }
1315
1316 if let Some(leaf_def) = &leaf_def
1317 && !leaf_def.is_final()
1318 && let def_id = leaf_def.item.def_id
1319 && tcx.impl_method_has_trait_impl_trait_tys(def_id)
1320 {
1321 let def_kind = tcx.def_kind(def_id);
1322 let descr = tcx.def_kind_descr(def_kind, def_id);
1323 let (msg, feature) = if tcx.asyncness(def_id).is_async() {
1324 (
1325 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("async {0} in trait cannot be specialized",
descr))
})format!("async {descr} in trait cannot be specialized"),
1326 "async functions in traits",
1327 )
1328 } else {
1329 (
1330 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} with return-position `impl Trait` in trait cannot be specialized",
descr))
})format!(
1331 "{descr} with return-position `impl Trait` in trait cannot be specialized"
1332 ),
1333 "return position `impl Trait` in traits",
1334 )
1335 };
1336 tcx.dcx()
1337 .struct_span_err(tcx.def_span(def_id), msg)
1338 .with_note(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("specialization behaves in inconsistent and surprising ways with {0}, and for now is disallowed",
feature))
})format!(
1339 "specialization behaves in inconsistent and surprising ways with \
1340 {feature}, and for now is disallowed"
1341 ))
1342 .emit();
1343 }
1344 }
1345
1346 if !missing_items.is_empty() {
1347 let full_impl_span = tcx.hir_span_with_body(tcx.local_def_id_to_hir_id(impl_id));
1348 missing_items_err(tcx, impl_id, &missing_items, full_impl_span);
1349 }
1350
1351 if let Some(missing_items) = must_implement_one_of {
1352 let attr_span = {
'done:
{
for i in tcx.get_all_attrs(trait_ref.def_id) {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::RustcMustImplementOneOf {
attr_span, .. }) => {
break 'done Some(*attr_span);
}
_ => {}
}
}
None
}
}find_attr!(tcx.get_all_attrs(trait_ref.def_id), AttributeKind::RustcMustImplementOneOf {attr_span, ..} => *attr_span);
1353
1354 missing_items_must_implement_one_of_err(
1355 tcx,
1356 tcx.def_span(impl_id),
1357 missing_items,
1358 attr_span,
1359 );
1360 }
1361 }
1362}
1363
1364fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
1365 let t = tcx.type_of(def_id).instantiate_identity();
1366 if let ty::Adt(def, args) = t.kind()
1367 && def.is_struct()
1368 {
1369 let fields = &def.non_enum_variant().fields;
1370 if fields.is_empty() {
1371 {
tcx.dcx().struct_span_err(sp,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("SIMD vector cannot be empty"))
})).with_code(E0075)
}struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit();
1372 return;
1373 }
1374
1375 let array_field = &fields[FieldIdx::ZERO];
1376 let array_ty = array_field.ty(tcx, args);
1377 let ty::Array(element_ty, len_const) = array_ty.kind() else {
1378 {
tcx.dcx().struct_span_err(sp,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("SIMD vector\'s only field must be an array"))
})).with_code(E0076)
}struct_span_code_err!(
1379 tcx.dcx(),
1380 sp,
1381 E0076,
1382 "SIMD vector's only field must be an array"
1383 )
1384 .with_span_label(tcx.def_span(array_field.did), "not an array")
1385 .emit();
1386 return;
1387 };
1388
1389 if let Some(second_field) = fields.get(FieldIdx::ONE) {
1390 {
tcx.dcx().struct_span_err(sp,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("SIMD vector cannot have multiple fields"))
})).with_code(E0075)
}struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot have multiple fields")
1391 .with_span_label(tcx.def_span(second_field.did), "excess field")
1392 .emit();
1393 return;
1394 }
1395
1396 if let Some(len) = len_const.try_to_target_usize(tcx) {
1401 if len == 0 {
1402 {
tcx.dcx().struct_span_err(sp,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("SIMD vector cannot be empty"))
})).with_code(E0075)
}struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit();
1403 return;
1404 } else if len > MAX_SIMD_LANES {
1405 {
tcx.dcx().struct_span_err(sp,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("SIMD vector cannot have more than {0} elements",
MAX_SIMD_LANES))
})).with_code(E0075)
}struct_span_code_err!(
1406 tcx.dcx(),
1407 sp,
1408 E0075,
1409 "SIMD vector cannot have more than {MAX_SIMD_LANES} elements",
1410 )
1411 .emit();
1412 return;
1413 }
1414 }
1415
1416 match element_ty.kind() {
1421 ty::Param(_) => (), ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_, _) => (), _ => {
1424 {
tcx.dcx().struct_span_err(sp,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("SIMD vector element type should be a primitive scalar (integer/float/pointer) type"))
})).with_code(E0077)
}struct_span_code_err!(
1425 tcx.dcx(),
1426 sp,
1427 E0077,
1428 "SIMD vector element type should be a \
1429 primitive scalar (integer/float/pointer) type"
1430 )
1431 .emit();
1432 return;
1433 }
1434 }
1435 }
1436}
1437
1438#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("check_scalable_vector",
"rustc_hir_analysis::check::check", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/check/check.rs"),
::tracing_core::__macro_support::Option::Some(1438u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::check::check"),
::tracing_core::field::FieldSet::new(&["span", "def_id",
"scalable"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&span)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&scalable)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: () = loop {};
return __tracing_attr_fake_return;
}
{
let ty = tcx.type_of(def_id).instantiate_identity();
let ty::Adt(def, args) = ty.kind() else { return };
if !def.is_struct() {
tcx.dcx().delayed_bug("`rustc_scalable_vector` applied to non-struct");
return;
}
let fields = &def.non_enum_variant().fields;
match scalable {
ScalableElt::ElementCount(..) if fields.is_empty() => {
let mut err =
tcx.dcx().struct_span_err(span,
"scalable vectors must have a single field");
err.help("scalable vector types' only field must be a primitive scalar type");
err.emit();
return;
}
ScalableElt::ElementCount(..) if fields.len() >= 2 => {
tcx.dcx().struct_span_err(span,
"scalable vectors cannot have multiple fields").emit();
return;
}
ScalableElt::Container if fields.is_empty() => {
let mut err =
tcx.dcx().struct_span_err(span,
"scalable vectors must have a single field");
err.help("tuples of scalable vectors can only contain multiple of the same scalable vector type");
err.emit();
return;
}
_ => {}
}
match scalable {
ScalableElt::ElementCount(..) => {
let element_ty = &fields[FieldIdx::ZERO].ty(tcx, args);
match element_ty.kind() {
ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Bool => (),
_ => {
let mut err =
tcx.dcx().struct_span_err(span,
"element type of a scalable vector must be a primitive scalar");
err.help("only `u*`, `i*`, `f*` and `bool` types are accepted");
err.emit();
}
}
}
ScalableElt::Container => {
let mut prev_field_ty = None;
for field in fields.iter() {
let element_ty = field.ty(tcx, args);
if let ty::Adt(def, _) = element_ty.kind() &&
def.repr().scalable() {
match def.repr().scalable.expect("`repr().scalable.is_some()` != `repr().scalable()`")
{
ScalableElt::ElementCount(_) => {}
ScalableElt::Container => {
tcx.dcx().span_err(tcx.def_span(field.did),
"scalable vector structs cannot contain other scalable vector structs");
break;
}
}
} else {
tcx.dcx().span_err(tcx.def_span(field.did),
"scalable vector structs can only have scalable vector fields");
break;
}
if let Some(prev_ty) = prev_field_ty.replace(element_ty) &&
prev_ty != element_ty {
tcx.dcx().span_err(tcx.def_span(field.did),
"all fields in a scalable vector struct must be the same type");
break;
}
}
}
}
}
}
}#[tracing::instrument(skip(tcx), level = "debug")]
1439fn check_scalable_vector(tcx: TyCtxt<'_>, span: Span, def_id: LocalDefId, scalable: ScalableElt) {
1440 let ty = tcx.type_of(def_id).instantiate_identity();
1441 let ty::Adt(def, args) = ty.kind() else { return };
1442 if !def.is_struct() {
1443 tcx.dcx().delayed_bug("`rustc_scalable_vector` applied to non-struct");
1444 return;
1445 }
1446
1447 let fields = &def.non_enum_variant().fields;
1448 match scalable {
1449 ScalableElt::ElementCount(..) if fields.is_empty() => {
1450 let mut err =
1451 tcx.dcx().struct_span_err(span, "scalable vectors must have a single field");
1452 err.help("scalable vector types' only field must be a primitive scalar type");
1453 err.emit();
1454 return;
1455 }
1456 ScalableElt::ElementCount(..) if fields.len() >= 2 => {
1457 tcx.dcx().struct_span_err(span, "scalable vectors cannot have multiple fields").emit();
1458 return;
1459 }
1460 ScalableElt::Container if fields.is_empty() => {
1461 let mut err =
1462 tcx.dcx().struct_span_err(span, "scalable vectors must have a single field");
1463 err.help("tuples of scalable vectors can only contain multiple of the same scalable vector type");
1464 err.emit();
1465 return;
1466 }
1467 _ => {}
1468 }
1469
1470 match scalable {
1471 ScalableElt::ElementCount(..) => {
1472 let element_ty = &fields[FieldIdx::ZERO].ty(tcx, args);
1473
1474 match element_ty.kind() {
1478 ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Bool => (),
1479 _ => {
1480 let mut err = tcx.dcx().struct_span_err(
1481 span,
1482 "element type of a scalable vector must be a primitive scalar",
1483 );
1484 err.help("only `u*`, `i*`, `f*` and `bool` types are accepted");
1485 err.emit();
1486 }
1487 }
1488 }
1489 ScalableElt::Container => {
1490 let mut prev_field_ty = None;
1491 for field in fields.iter() {
1492 let element_ty = field.ty(tcx, args);
1493 if let ty::Adt(def, _) = element_ty.kind()
1494 && def.repr().scalable()
1495 {
1496 match def
1497 .repr()
1498 .scalable
1499 .expect("`repr().scalable.is_some()` != `repr().scalable()`")
1500 {
1501 ScalableElt::ElementCount(_) => { }
1502 ScalableElt::Container => {
1503 tcx.dcx().span_err(
1504 tcx.def_span(field.did),
1505 "scalable vector structs cannot contain other scalable vector structs",
1506 );
1507 break;
1508 }
1509 }
1510 } else {
1511 tcx.dcx().span_err(
1512 tcx.def_span(field.did),
1513 "scalable vector structs can only have scalable vector fields",
1514 );
1515 break;
1516 }
1517
1518 if let Some(prev_ty) = prev_field_ty.replace(element_ty)
1519 && prev_ty != element_ty
1520 {
1521 tcx.dcx().span_err(
1522 tcx.def_span(field.did),
1523 "all fields in a scalable vector struct must be the same type",
1524 );
1525 break;
1526 }
1527 }
1528 }
1529 }
1530}
1531
1532pub(super) fn check_packed(tcx: TyCtxt<'_>, sp: Span, def: ty::AdtDef<'_>) {
1533 let repr = def.repr();
1534 if repr.packed() {
1535 if let Some(reprs) = {
'done:
{
for i in tcx.get_all_attrs(def.did()) {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(attrs::AttributeKind::Repr {
reprs, .. }) => {
break 'done Some(reprs);
}
_ => {}
}
}
None
}
}find_attr!(tcx.get_all_attrs(def.did()), attrs::AttributeKind::Repr { reprs, .. } => reprs)
1536 {
1537 for (r, _) in reprs {
1538 if let ReprPacked(pack) = r
1539 && let Some(repr_pack) = repr.pack
1540 && pack != &repr_pack
1541 {
1542 {
tcx.dcx().struct_span_err(sp,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("type has conflicting packed representation hints"))
})).with_code(E0634)
}struct_span_code_err!(
1543 tcx.dcx(),
1544 sp,
1545 E0634,
1546 "type has conflicting packed representation hints"
1547 )
1548 .emit();
1549 }
1550 }
1551 }
1552 if repr.align.is_some() {
1553 {
tcx.dcx().struct_span_err(sp,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("type has conflicting packed and align representation hints"))
})).with_code(E0587)
}struct_span_code_err!(
1554 tcx.dcx(),
1555 sp,
1556 E0587,
1557 "type has conflicting packed and align representation hints"
1558 )
1559 .emit();
1560 } else if let Some(def_spans) = check_packed_inner(tcx, def.did(), &mut ::alloc::vec::Vec::new()vec![]) {
1561 let mut err = {
tcx.dcx().struct_span_err(sp,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("packed type cannot transitively contain a `#[repr(align)]` type"))
})).with_code(E0588)
}struct_span_code_err!(
1562 tcx.dcx(),
1563 sp,
1564 E0588,
1565 "packed type cannot transitively contain a `#[repr(align)]` type"
1566 );
1567
1568 err.span_note(
1569 tcx.def_span(def_spans[0].0),
1570 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}` has a `#[repr(align)]` attribute",
tcx.item_name(def_spans[0].0)))
})format!("`{}` has a `#[repr(align)]` attribute", tcx.item_name(def_spans[0].0)),
1571 );
1572
1573 if def_spans.len() > 2 {
1574 let mut first = true;
1575 for (adt_def, span) in def_spans.iter().skip(1).rev() {
1576 let ident = tcx.item_name(*adt_def);
1577 err.span_note(
1578 *span,
1579 if first {
1580 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}` contains a field of type `{1}`",
tcx.type_of(def.did()).instantiate_identity(), ident))
})format!(
1581 "`{}` contains a field of type `{}`",
1582 tcx.type_of(def.did()).instantiate_identity(),
1583 ident
1584 )
1585 } else {
1586 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("...which contains a field of type `{0}`",
ident))
})format!("...which contains a field of type `{ident}`")
1587 },
1588 );
1589 first = false;
1590 }
1591 }
1592
1593 err.emit();
1594 }
1595 }
1596}
1597
1598pub(super) fn check_packed_inner(
1599 tcx: TyCtxt<'_>,
1600 def_id: DefId,
1601 stack: &mut Vec<DefId>,
1602) -> Option<Vec<(DefId, Span)>> {
1603 if let ty::Adt(def, args) = tcx.type_of(def_id).instantiate_identity().kind() {
1604 if def.is_struct() || def.is_union() {
1605 if def.repr().align.is_some() {
1606 return Some(<[_]>::into_vec(::alloc::boxed::box_new([(def.did(), DUMMY_SP)]))vec![(def.did(), DUMMY_SP)]);
1607 }
1608
1609 stack.push(def_id);
1610 for field in &def.non_enum_variant().fields {
1611 if let ty::Adt(def, _) = field.ty(tcx, args).kind()
1612 && !stack.contains(&def.did())
1613 && let Some(mut defs) = check_packed_inner(tcx, def.did(), stack)
1614 {
1615 defs.push((def.did(), field.ident(tcx).span));
1616 return Some(defs);
1617 }
1618 }
1619 stack.pop();
1620 }
1621 }
1622
1623 None
1624}
1625
1626pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) {
1627 if !adt.repr().transparent() {
1628 return;
1629 }
1630
1631 if adt.is_union() && !tcx.features().transparent_unions() {
1632 feature_err(
1633 &tcx.sess,
1634 sym::transparent_unions,
1635 tcx.def_span(adt.did()),
1636 "transparent unions are unstable",
1637 )
1638 .emit();
1639 }
1640
1641 if adt.variants().len() != 1 {
1642 bad_variant_count(tcx, adt, tcx.def_span(adt.did()), adt.did());
1643 return;
1645 }
1646
1647 let typing_env = ty::TypingEnv::non_body_analysis(tcx, adt.did());
1648 struct FieldInfo<'tcx> {
1650 span: Span,
1651 trivial: bool,
1652 ty: Ty<'tcx>,
1653 }
1654
1655 let field_infos = adt.all_fields().map(|field| {
1656 let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did));
1657 let layout = tcx.layout_of(typing_env.as_query_input(ty));
1658 let span = tcx.hir_span_if_local(field.did).unwrap();
1660 let trivial = layout.is_ok_and(|layout| layout.is_1zst());
1661 FieldInfo { span, trivial, ty }
1662 });
1663
1664 let non_trivial_fields = field_infos
1665 .clone()
1666 .filter_map(|field| if !field.trivial { Some(field.span) } else { None });
1667 let non_trivial_count = non_trivial_fields.clone().count();
1668 if non_trivial_count >= 2 {
1669 bad_non_zero_sized_fields(
1670 tcx,
1671 adt,
1672 non_trivial_count,
1673 non_trivial_fields,
1674 tcx.def_span(adt.did()),
1675 );
1676 return;
1677 }
1678
1679 struct UnsuitedInfo<'tcx> {
1682 ty: Ty<'tcx>,
1684 reason: UnsuitedReason,
1685 }
1686 enum UnsuitedReason {
1687 NonExhaustive,
1688 PrivateField,
1689 ReprC,
1690 }
1691
1692 fn check_unsuited<'tcx>(
1693 tcx: TyCtxt<'tcx>,
1694 typing_env: ty::TypingEnv<'tcx>,
1695 ty: Ty<'tcx>,
1696 ) -> ControlFlow<UnsuitedInfo<'tcx>> {
1697 let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);
1699 match ty.kind() {
1700 ty::Tuple(list) => list.iter().try_for_each(|t| check_unsuited(tcx, typing_env, t)),
1701 ty::Array(ty, _) => check_unsuited(tcx, typing_env, *ty),
1702 ty::Adt(def, args) => {
1703 if !def.did().is_local()
1704 && !{
{
'done:
{
for i in tcx.get_all_attrs(def.did()) {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(AttributeKind::RustcPubTransparent(_))
=> {
break 'done Some(());
}
_ => {}
}
}
None
}
}.is_some()
}find_attr!(
1705 tcx.get_all_attrs(def.did()),
1706 AttributeKind::RustcPubTransparent(_)
1707 )
1708 {
1709 let non_exhaustive = def.is_variant_list_non_exhaustive()
1710 || def.variants().iter().any(ty::VariantDef::is_field_list_non_exhaustive);
1711 let has_priv = def.all_fields().any(|f| !f.vis.is_public());
1712 if non_exhaustive || has_priv {
1713 return ControlFlow::Break(UnsuitedInfo {
1714 ty,
1715 reason: if non_exhaustive {
1716 UnsuitedReason::NonExhaustive
1717 } else {
1718 UnsuitedReason::PrivateField
1719 },
1720 });
1721 }
1722 }
1723 if def.repr().c() {
1724 return ControlFlow::Break(UnsuitedInfo { ty, reason: UnsuitedReason::ReprC });
1725 }
1726 def.all_fields()
1727 .map(|field| field.ty(tcx, args))
1728 .try_for_each(|t| check_unsuited(tcx, typing_env, t))
1729 }
1730 _ => ControlFlow::Continue(()),
1731 }
1732 }
1733
1734 let mut prev_unsuited_1zst = false;
1735 for field in field_infos {
1736 if field.trivial
1737 && let Some(unsuited) = check_unsuited(tcx, typing_env, field.ty).break_value()
1738 {
1739 if non_trivial_count > 0 || prev_unsuited_1zst {
1742 tcx.node_span_lint(
1743 REPR_TRANSPARENT_NON_ZST_FIELDS,
1744 tcx.local_def_id_to_hir_id(adt.did().expect_local()),
1745 field.span,
1746 |lint| {
1747 let title = match unsuited.reason {
1748 UnsuitedReason::NonExhaustive => "external non-exhaustive types",
1749 UnsuitedReason::PrivateField => "external types with private fields",
1750 UnsuitedReason::ReprC => "`repr(C)` types",
1751 };
1752 lint.primary_message(
1753 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("zero-sized fields in `repr(transparent)` cannot contain {0}",
title))
})format!("zero-sized fields in `repr(transparent)` cannot contain {title}"),
1754 );
1755 let note = match unsuited.reason {
1756 UnsuitedReason::NonExhaustive => "is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.",
1757 UnsuitedReason::PrivateField => "contains private fields, so it could become non-zero-sized in the future.",
1758 UnsuitedReason::ReprC => "is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.",
1759 };
1760 lint.note(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("this field contains `{0}`, which {1}",
unsuited.ty, note))
})format!(
1761 "this field contains `{field_ty}`, which {note}",
1762 field_ty = unsuited.ty,
1763 ));
1764 },
1765 );
1766 } else {
1767 prev_unsuited_1zst = true;
1768 }
1769 }
1770 }
1771}
1772
1773#[allow(trivial_numeric_casts)]
1774fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
1775 let def = tcx.adt_def(def_id);
1776 def.destructor(tcx); if def.variants().is_empty() {
1779 {
'done:
{
for i in tcx.get_all_attrs(def_id) {
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(attrs::AttributeKind::Repr {
reprs, first_span }) => {
break 'done
Some({
{
tcx.dcx().struct_span_err(reprs.first().map(|repr|
repr.1).unwrap_or(*first_span),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unsupported representation for zero-variant enum"))
})).with_code(E0084)
}.with_span_label(tcx.def_span(def_id),
"zero-variant enum").emit();
});
}
_ => {}
}
}
None
}
};find_attr!(
1780 tcx.get_all_attrs(def_id),
1781 attrs::AttributeKind::Repr { reprs, first_span } => {
1782 struct_span_code_err!(
1783 tcx.dcx(),
1784 reprs.first().map(|repr| repr.1).unwrap_or(*first_span),
1785 E0084,
1786 "unsupported representation for zero-variant enum"
1787 )
1788 .with_span_label(tcx.def_span(def_id), "zero-variant enum")
1789 .emit();
1790 }
1791 );
1792 }
1793
1794 for v in def.variants() {
1795 if let ty::VariantDiscr::Explicit(discr_def_id) = v.discr {
1796 tcx.ensure_ok().typeck(discr_def_id.expect_local());
1797 }
1798 }
1799
1800 if def.repr().int.is_none() {
1801 let is_unit = |var: &ty::VariantDef| #[allow(non_exhaustive_omitted_patterns)] match var.ctor_kind() {
Some(CtorKind::Const) => true,
_ => false,
}matches!(var.ctor_kind(), Some(CtorKind::Const));
1802 let get_disr = |var: &ty::VariantDef| match var.discr {
1803 ty::VariantDiscr::Explicit(disr) => Some(disr),
1804 ty::VariantDiscr::Relative(_) => None,
1805 };
1806
1807 let non_unit = def.variants().iter().find(|var| !is_unit(var));
1808 let disr_unit =
1809 def.variants().iter().filter(|var| is_unit(var)).find_map(|var| get_disr(var));
1810 let disr_non_unit =
1811 def.variants().iter().filter(|var| !is_unit(var)).find_map(|var| get_disr(var));
1812
1813 if disr_non_unit.is_some() || (disr_unit.is_some() && non_unit.is_some()) {
1814 let mut err = {
tcx.dcx().struct_span_err(tcx.def_span(def_id),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`#[repr(inttype)]` must be specified for enums with explicit discriminants and non-unit variants"))
})).with_code(E0732)
}struct_span_code_err!(
1815 tcx.dcx(),
1816 tcx.def_span(def_id),
1817 E0732,
1818 "`#[repr(inttype)]` must be specified for enums with explicit discriminants and non-unit variants"
1819 );
1820 if let Some(disr_non_unit) = disr_non_unit {
1821 err.span_label(
1822 tcx.def_span(disr_non_unit),
1823 "explicit discriminant on non-unit variant specified here",
1824 );
1825 } else {
1826 err.span_label(
1827 tcx.def_span(disr_unit.unwrap()),
1828 "explicit discriminant specified here",
1829 );
1830 err.span_label(
1831 tcx.def_span(non_unit.unwrap().def_id),
1832 "non-unit discriminant declared here",
1833 );
1834 }
1835 err.emit();
1836 }
1837 }
1838
1839 detect_discriminant_duplicate(tcx, def);
1840 check_transparent(tcx, def);
1841}
1842
1843fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) {
1845 let report = |dis: Discr<'tcx>, idx, err: &mut Diag<'_>| {
1848 let var = adt.variant(idx); let (span, display_discr) = match var.discr {
1850 ty::VariantDiscr::Explicit(discr_def_id) => {
1851 if let hir::Node::AnonConst(expr) =
1853 tcx.hir_node_by_def_id(discr_def_id.expect_local())
1854 && let hir::ExprKind::Lit(lit) = &tcx.hir_body(expr.body).value.kind
1855 && let rustc_ast::LitKind::Int(lit_value, _int_kind) = &lit.node
1856 && *lit_value != dis.val
1857 {
1858 (tcx.def_span(discr_def_id), ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}` (overflowed from `{1}`)",
dis, lit_value))
})format!("`{dis}` (overflowed from `{lit_value}`)"))
1859 } else {
1860 (tcx.def_span(discr_def_id), ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", dis))
})format!("`{dis}`"))
1862 }
1863 }
1864 ty::VariantDiscr::Relative(0) => (tcx.def_span(var.def_id), ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", dis))
})format!("`{dis}`")),
1866 ty::VariantDiscr::Relative(distance_to_explicit) => {
1867 if let Some(explicit_idx) =
1872 idx.as_u32().checked_sub(distance_to_explicit).map(VariantIdx::from_u32)
1873 {
1874 let explicit_variant = adt.variant(explicit_idx);
1875 let ve_ident = var.name;
1876 let ex_ident = explicit_variant.name;
1877 let sp = if distance_to_explicit > 1 { "variants" } else { "variant" };
1878
1879 err.span_label(
1880 tcx.def_span(explicit_variant.def_id),
1881 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("discriminant for `{0}` incremented from this startpoint (`{1}` + {2} {3} later => `{0}` = {4})",
ve_ident, ex_ident, distance_to_explicit, sp, dis))
})format!(
1882 "discriminant for `{ve_ident}` incremented from this startpoint \
1883 (`{ex_ident}` + {distance_to_explicit} {sp} later \
1884 => `{ve_ident}` = {dis})"
1885 ),
1886 );
1887 }
1888
1889 (tcx.def_span(var.def_id), ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", dis))
})format!("`{dis}`"))
1890 }
1891 };
1892
1893 err.span_label(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} assigned here", display_discr))
})format!("{display_discr} assigned here"));
1894 };
1895
1896 let mut discrs = adt.discriminants(tcx).collect::<Vec<_>>();
1897
1898 let mut i = 0;
1905 while i < discrs.len() {
1906 let var_i_idx = discrs[i].0;
1907 let mut error: Option<Diag<'_, _>> = None;
1908
1909 let mut o = i + 1;
1910 while o < discrs.len() {
1911 let var_o_idx = discrs[o].0;
1912
1913 if discrs[i].1.val == discrs[o].1.val {
1914 let err = error.get_or_insert_with(|| {
1915 let mut ret = {
tcx.dcx().struct_span_err(tcx.def_span(adt.did()),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("discriminant value `{0}` assigned more than once",
discrs[i].1))
})).with_code(E0081)
}struct_span_code_err!(
1916 tcx.dcx(),
1917 tcx.def_span(adt.did()),
1918 E0081,
1919 "discriminant value `{}` assigned more than once",
1920 discrs[i].1,
1921 );
1922
1923 report(discrs[i].1, var_i_idx, &mut ret);
1924
1925 ret
1926 });
1927
1928 report(discrs[o].1, var_o_idx, err);
1929
1930 discrs[o] = *discrs.last().unwrap();
1932 discrs.pop();
1933 } else {
1934 o += 1;
1935 }
1936 }
1937
1938 if let Some(e) = error {
1939 e.emit();
1940 }
1941
1942 i += 1;
1943 }
1944}
1945
1946fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
1947 if tcx.type_alias_is_lazy(def_id) {
1948 return;
1951 }
1952
1953 let generics = tcx.generics_of(def_id);
1954 if generics.own_counts().types == 0 {
1955 return;
1956 }
1957
1958 let ty = tcx.type_of(def_id).instantiate_identity();
1959 if ty.references_error() {
1960 return;
1962 }
1963
1964 let bounded_params = LazyCell::new(|| {
1966 tcx.explicit_predicates_of(def_id)
1967 .predicates
1968 .iter()
1969 .filter_map(|(predicate, span)| {
1970 let bounded_ty = match predicate.kind().skip_binder() {
1971 ty::ClauseKind::Trait(pred) => pred.trait_ref.self_ty(),
1972 ty::ClauseKind::TypeOutlives(pred) => pred.0,
1973 _ => return None,
1974 };
1975 if let ty::Param(param) = bounded_ty.kind() {
1976 Some((param.index, span))
1977 } else {
1978 None
1979 }
1980 })
1981 .collect::<FxIndexMap<_, _>>()
1987 });
1988
1989 let mut params_used = DenseBitSet::new_empty(generics.own_params.len());
1990 for leaf in ty.walk() {
1991 if let GenericArgKind::Type(leaf_ty) = leaf.kind()
1992 && let ty::Param(param) = leaf_ty.kind()
1993 {
1994 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/check/check.rs:1994",
"rustc_hir_analysis::check::check", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/check/check.rs"),
::tracing_core::__macro_support::Option::Some(1994u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::check::check"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("found use of ty param {0:?}",
param) as &dyn Value))])
});
} else { ; }
};debug!("found use of ty param {:?}", param);
1995 params_used.insert(param.index);
1996 }
1997 }
1998
1999 for param in &generics.own_params {
2000 if !params_used.contains(param.index)
2001 && let ty::GenericParamDefKind::Type { .. } = param.kind
2002 {
2003 let span = tcx.def_span(param.def_id);
2004 let param_name = Ident::new(param.name, span);
2005
2006 let has_explicit_bounds = bounded_params.is_empty()
2010 || (*bounded_params).get(¶m.index).is_some_and(|&&pred_sp| pred_sp != span);
2011 let const_param_help = !has_explicit_bounds;
2012
2013 let mut diag = tcx.dcx().create_err(errors::UnusedGenericParameter {
2014 span,
2015 param_name,
2016 param_def_kind: tcx.def_descr(param.def_id),
2017 help: errors::UnusedGenericParameterHelp::TyAlias { param_name },
2018 usage_spans: ::alloc::vec::Vec::new()vec![],
2019 const_param_help,
2020 });
2021 diag.code(E0091);
2022 diag.emit();
2023 }
2024 }
2025}
2026
2027fn opaque_type_cycle_error(tcx: TyCtxt<'_>, opaque_def_id: LocalDefId) -> ErrorGuaranteed {
2036 let span = tcx.def_span(opaque_def_id);
2037 let mut err = {
tcx.dcx().struct_span_err(span,
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("cannot resolve opaque type"))
})).with_code(E0720)
}struct_span_code_err!(tcx.dcx(), span, E0720, "cannot resolve opaque type");
2038
2039 let mut label = false;
2040 if let Some((def_id, visitor)) = get_owner_return_paths(tcx, opaque_def_id) {
2041 let typeck_results = tcx.typeck(def_id);
2042 if visitor
2043 .returns
2044 .iter()
2045 .filter_map(|expr| typeck_results.node_type_opt(expr.hir_id))
2046 .all(|ty| #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
ty::Never => true,
_ => false,
}matches!(ty.kind(), ty::Never))
2047 {
2048 let spans = visitor
2049 .returns
2050 .iter()
2051 .filter(|expr| typeck_results.node_type_opt(expr.hir_id).is_some())
2052 .map(|expr| expr.span)
2053 .collect::<Vec<Span>>();
2054 let span_len = spans.len();
2055 if span_len == 1 {
2056 err.span_label(spans[0], "this returned value is of `!` type");
2057 } else {
2058 let mut multispan: MultiSpan = spans.clone().into();
2059 for span in spans {
2060 multispan.push_span_label(span, "this returned value is of `!` type");
2061 }
2062 err.span_note(multispan, "these returned values have a concrete \"never\" type");
2063 }
2064 err.help("this error will resolve once the item's body returns a concrete type");
2065 } else {
2066 let mut seen = FxHashSet::default();
2067 seen.insert(span);
2068 err.span_label(span, "recursive opaque type");
2069 label = true;
2070 for (sp, ty) in visitor
2071 .returns
2072 .iter()
2073 .filter_map(|e| typeck_results.node_type_opt(e.hir_id).map(|t| (e.span, t)))
2074 .filter(|(_, ty)| !#[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
ty::Never => true,
_ => false,
}matches!(ty.kind(), ty::Never))
2075 {
2076 #[derive(#[automatically_derived]
impl ::core::default::Default for OpaqueTypeCollector {
#[inline]
fn default() -> OpaqueTypeCollector {
OpaqueTypeCollector {
opaques: ::core::default::Default::default(),
closures: ::core::default::Default::default(),
}
}
}Default)]
2077 struct OpaqueTypeCollector {
2078 opaques: Vec<DefId>,
2079 closures: Vec<DefId>,
2080 }
2081 impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector {
2082 fn visit_ty(&mut self, t: Ty<'tcx>) {
2083 match *t.kind() {
2084 ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
2085 self.opaques.push(def);
2086 }
2087 ty::Closure(def_id, ..) | ty::Coroutine(def_id, ..) => {
2088 self.closures.push(def_id);
2089 t.super_visit_with(self);
2090 }
2091 _ => t.super_visit_with(self),
2092 }
2093 }
2094 }
2095
2096 let mut visitor = OpaqueTypeCollector::default();
2097 ty.visit_with(&mut visitor);
2098 for def_id in visitor.opaques {
2099 let ty_span = tcx.def_span(def_id);
2100 if !seen.contains(&ty_span) {
2101 let descr = if ty.is_impl_trait() { "opaque " } else { "" };
2102 err.span_label(ty_span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("returning this {0}type `{1}`",
descr, ty))
})format!("returning this {descr}type `{ty}`"));
2103 seen.insert(ty_span);
2104 }
2105 err.span_label(sp, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("returning here with type `{0}`",
ty))
})format!("returning here with type `{ty}`"));
2106 }
2107
2108 for closure_def_id in visitor.closures {
2109 let Some(closure_local_did) = closure_def_id.as_local() else {
2110 continue;
2111 };
2112 let typeck_results = tcx.typeck(closure_local_did);
2113
2114 let mut label_match = |ty: Ty<'_>, span| {
2115 for arg in ty.walk() {
2116 if let ty::GenericArgKind::Type(ty) = arg.kind()
2117 && let ty::Alias(
2118 ty::Opaque,
2119 ty::AliasTy { def_id: captured_def_id, .. },
2120 ) = *ty.kind()
2121 && captured_def_id == opaque_def_id.to_def_id()
2122 {
2123 err.span_label(
2124 span,
2125 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} captures itself here",
tcx.def_descr(closure_def_id)))
})format!(
2126 "{} captures itself here",
2127 tcx.def_descr(closure_def_id)
2128 ),
2129 );
2130 }
2131 }
2132 };
2133
2134 for capture in typeck_results.closure_min_captures_flattened(closure_local_did)
2136 {
2137 label_match(capture.place.ty(), capture.get_path_span(tcx));
2138 }
2139 if tcx.is_coroutine(closure_def_id)
2141 && let Some(coroutine_layout) = tcx.mir_coroutine_witnesses(closure_def_id)
2142 {
2143 for interior_ty in &coroutine_layout.field_tys {
2144 label_match(interior_ty.ty, interior_ty.source_info.span);
2145 }
2146 }
2147 }
2148 }
2149 }
2150 }
2151 if !label {
2152 err.span_label(span, "cannot resolve opaque type");
2153 }
2154 err.emit()
2155}
2156
2157pub(super) fn check_coroutine_obligations(
2158 tcx: TyCtxt<'_>,
2159 def_id: LocalDefId,
2160) -> Result<(), ErrorGuaranteed> {
2161 if true {
if !!tcx.is_typeck_child(def_id.to_def_id()) {
::core::panicking::panic("assertion failed: !tcx.is_typeck_child(def_id.to_def_id())")
};
};debug_assert!(!tcx.is_typeck_child(def_id.to_def_id()));
2162
2163 let typeck_results = tcx.typeck(def_id);
2164 let param_env = tcx.param_env(def_id);
2165
2166 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/check/check.rs:2166",
"rustc_hir_analysis::check::check", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/check/check.rs"),
::tracing_core::__macro_support::Option::Some(2166u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::check::check"),
::tracing_core::field::FieldSet::new(&["typeck_results.coroutine_stalled_predicates"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&typeck_results.coroutine_stalled_predicates)
as &dyn Value))])
});
} else { ; }
};debug!(?typeck_results.coroutine_stalled_predicates);
2167
2168 let mode = if tcx.next_trait_solver_globally() {
2169 TypingMode::borrowck(tcx, def_id)
2173 } else {
2174 TypingMode::analysis_in_body(tcx, def_id)
2175 };
2176
2177 let infcx = tcx.infer_ctxt().ignoring_regions().build(mode);
2182
2183 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
2184 for (predicate, cause) in &typeck_results.coroutine_stalled_predicates {
2185 ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, *predicate));
2186 }
2187
2188 let errors = ocx.evaluate_obligations_error_on_ambiguity();
2189 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/check/check.rs:2189",
"rustc_hir_analysis::check::check", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/check/check.rs"),
::tracing_core::__macro_support::Option::Some(2189u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::check::check"),
::tracing_core::field::FieldSet::new(&["errors"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&errors) as
&dyn Value))])
});
} else { ; }
};debug!(?errors);
2190 if !errors.is_empty() {
2191 return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
2192 }
2193
2194 if !tcx.next_trait_solver_globally() {
2195 for (key, ty) in infcx.take_opaque_types() {
2198 let hidden_type = infcx.resolve_vars_if_possible(ty);
2199 let key = infcx.resolve_vars_if_possible(key);
2200 sanity_check_found_hidden_type(tcx, key, hidden_type)?;
2201 }
2202 } else {
2203 let _ = infcx.take_opaque_types();
2206 }
2207
2208 Ok(())
2209}
2210
2211pub(super) fn check_potentially_region_dependent_goals<'tcx>(
2212 tcx: TyCtxt<'tcx>,
2213 def_id: LocalDefId,
2214) -> Result<(), ErrorGuaranteed> {
2215 if !tcx.next_trait_solver_globally() {
2216 return Ok(());
2217 }
2218 let typeck_results = tcx.typeck(def_id);
2219 let param_env = tcx.param_env(def_id);
2220
2221 let typing_mode = TypingMode::borrowck(tcx, def_id);
2223 let infcx = tcx.infer_ctxt().ignoring_regions().build(typing_mode);
2224 let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
2225 for (predicate, cause) in &typeck_results.potentially_region_dependent_goals {
2226 let predicate = fold_regions(tcx, *predicate, |_, _| {
2227 infcx.next_region_var(RegionVariableOrigin::Misc(cause.span))
2228 });
2229 ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, predicate));
2230 }
2231
2232 let errors = ocx.evaluate_obligations_error_on_ambiguity();
2233 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_analysis/src/check/check.rs:2233",
"rustc_hir_analysis::check::check", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_analysis/src/check/check.rs"),
::tracing_core::__macro_support::Option::Some(2233u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_analysis::check::check"),
::tracing_core::field::FieldSet::new(&["errors"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&errors) as
&dyn Value))])
});
} else { ; }
};debug!(?errors);
2234 if errors.is_empty() { Ok(()) } else { Err(infcx.err_ctxt().report_fulfillment_errors(errors)) }
2235}