rustc_hir_analysis/
lib.rs1#![allow(rustc::diagnostic_outside_of_impl)]
60#![allow(rustc::untranslatable_diagnostic)]
61#![cfg_attr(bootstrap, feature(debug_closure_helpers))]
62#![feature(assert_matches)]
63#![feature(gen_blocks)]
64#![feature(if_let_guard)]
65#![feature(iter_intersperse)]
66#![feature(never_type)]
67#![feature(slice_partition_dedup)]
68#![feature(try_blocks)]
69#![feature(unwrap_infallible)]
70pub mod check;
74
75pub mod autoderef;
76mod check_unused;
77mod coherence;
78mod collect;
79mod constrained_generic_params;
80mod delegation;
81pub mod errors;
82pub mod hir_ty_lowering;
83pub mod hir_wf_check;
84mod impl_wf_check;
85mod outlives;
86mod variance;
87
88pub use errors::NoVariantNamed;
89use rustc_abi::{CVariadicStatus, ExternAbi};
90use rustc_hir::attrs::AttributeKind;
91use rustc_hir::def::DefKind;
92use rustc_hir::lints::DelayedLint;
93use rustc_hir::{
94 find_attr, {self as hir},
95};
96use rustc_middle::mir::interpret::GlobalId;
97use rustc_middle::query::Providers;
98use rustc_middle::ty::{Const, Ty, TyCtxt};
99use rustc_middle::{middle, ty};
100use rustc_session::parse::feature_err;
101use rustc_span::{ErrorGuaranteed, Span};
102use rustc_trait_selection::traits;
103
104pub use crate::collect::suggest_impl_trait;
105use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
106
107rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
108
109fn check_c_variadic_abi(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: ExternAbi, span: Span) {
110 if !decl.c_variadic {
111 return;
113 }
114
115 match abi.supports_c_variadic() {
116 CVariadicStatus::Stable => {}
117 CVariadicStatus::NotSupported => {
118 tcx.dcx()
119 .create_err(errors::VariadicFunctionCompatibleConvention {
120 span,
121 convention: &format!("{abi}"),
122 })
123 .emit();
124 }
125 CVariadicStatus::Unstable { feature } => {
126 if !tcx.features().enabled(feature) {
127 feature_err(
128 &tcx.sess,
129 feature,
130 span,
131 format!("C-variadic functions with the {abi} calling convention are unstable"),
132 )
133 .emit();
134 }
135 }
136 }
137}
138
139pub fn provide(providers: &mut Providers) {
141 collect::provide(providers);
142 coherence::provide(providers);
143 check::provide(providers);
144 *providers = Providers {
145 check_unused_traits: check_unused::check_unused_traits,
146 diagnostic_hir_wf_check: hir_wf_check::diagnostic_hir_wf_check,
147 inferred_outlives_crate: outlives::inferred_outlives_crate,
148 inferred_outlives_of: outlives::inferred_outlives_of,
149 inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item,
150 enforce_impl_non_lifetime_params_are_constrained:
151 impl_wf_check::enforce_impl_non_lifetime_params_are_constrained,
152 crate_variances: variance::crate_variances,
153 variances_of: variance::variances_of,
154 ..*providers
155 };
156}
157
158fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) {
159 match lint {
160 DelayedLint::AttributeParsing(attribute_lint) => {
161 rustc_attr_parsing::emit_attribute_lint(attribute_lint, tcx)
162 }
163 }
164}
165
166pub fn check_crate(tcx: TyCtxt<'_>) {
167 let _prof_timer = tcx.sess.timer("type_check_crate");
168
169 tcx.sess.time("coherence_checking", || {
170 type R = Result<(), ErrorGuaranteed>;
173
174 let _: R = tcx.ensure_ok().check_type_wf(());
175
176 for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
177 let _: R = tcx.ensure_ok().coherent_trait(trait_def_id);
178 }
179 let _: R = tcx.ensure_ok().crate_inherent_impls_validity_check(());
181 let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(());
182 });
183
184 tcx.sess.time("emit_ast_lowering_delayed_lints", || {
185 #[cfg(debug_assertions)]
196 {
197 for owner_id in tcx.hir_crate_items(()).owners() {
199 if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
201 if !delayed_lints.lints.is_empty() {
202 assert!(
204 tcx.hir_crate_items(()).delayed_lint_items().any(|i| i == owner_id)
205 );
206 }
207 }
208 }
209 }
210
211 for owner_id in tcx.hir_crate_items(()).delayed_lint_items() {
212 if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
213 for lint in &delayed_lints.lints {
214 emit_delayed_lint(lint, tcx);
215 }
216 }
217 }
218 });
219
220 tcx.par_hir_body_owners(|item_def_id| {
221 let def_kind = tcx.def_kind(item_def_id);
222 match def_kind {
225 DefKind::Static { .. } => {
226 tcx.ensure_ok().eval_static_initializer(item_def_id);
227 check::maybe_check_static_with_link_section(tcx, item_def_id);
228 }
229 DefKind::Const
230 if !tcx.generics_of(item_def_id).own_requires_monomorphization()
231 && !find_attr!(tcx.get_all_attrs(item_def_id), AttributeKind::TypeConst(_)) =>
232 {
233 let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty());
236 let cid = GlobalId { instance, promoted: None };
237 let typing_env = ty::TypingEnv::fully_monomorphized();
238 tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid));
239 }
240 _ => (),
241 }
242 if !(matches!(def_kind, DefKind::AnonConst) || def_kind.is_typeck_child()) {
245 tcx.ensure_ok().typeck(item_def_id);
246 }
247 if tcx.needs_coroutine_by_move_body_def_id(item_def_id.to_def_id()) {
250 tcx.ensure_done().coroutine_by_move_body_def_id(item_def_id);
251 }
252 });
253
254 if tcx.features().rustc_attrs() {
255 tcx.sess.time("dumping_rustc_attr_data", || {
256 outlives::dump::inferred_outlives(tcx);
257 variance::dump::variances(tcx);
258 collect::dump::opaque_hidden_types(tcx);
259 collect::dump::predicates_and_item_bounds(tcx);
260 collect::dump::def_parents(tcx);
261 collect::dump::vtables(tcx);
262 });
263 }
264
265 tcx.ensure_ok().check_unused_traits(());
266}
267
268pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
279 let env_def_id = tcx.hir_get_parent_item(hir_ty.hir_id);
283 collect::ItemCtxt::new(tcx, env_def_id.def_id)
284 .lowerer()
285 .lower_ty_maybe_return_type_notation(hir_ty)
286}
287
288pub fn lower_const_arg_for_rustdoc<'tcx>(
291 tcx: TyCtxt<'tcx>,
292 hir_ct: &hir::ConstArg<'tcx>,
293 feed: FeedConstTy<'_, 'tcx>,
294) -> Const<'tcx> {
295 let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id);
296 collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed)
297}