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