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