rustc_hir_analysis/
lib.rs1#![cfg_attr(bootstrap, feature(never_type))]
60#![cfg_attr(bootstrap, feature(unwrap_infallible))]
61#![feature(default_field_values)]
62#![feature(gen_blocks)]
63#![feature(iter_intersperse)]
64#![feature(slice_partition_dedup)]
65#![feature(try_blocks)]
66pub mod check;
70
71pub mod autoderef;
72mod check_unused;
73mod coherence;
74mod collect;
75mod constrained_generic_params;
76pub mod delegation;
77pub mod diagnostics;
78pub mod hir_ty_lowering;
79pub mod hir_wf_check;
80mod impl_wf_check;
81mod outlives;
82mod variance;
83
84use rustc_abi::{CVariadicStatus, ExternAbi};
85use rustc_hir as hir;
86use rustc_hir::def::DefKind;
87use rustc_middle::mir::interpret::GlobalId;
88use rustc_middle::query::Providers;
89use rustc_middle::ty::{Const, Ty, TyCtxt};
90use rustc_middle::{middle, ty};
91use rustc_session::diagnostics::feature_err;
92use rustc_span::{ErrorGuaranteed, Span};
93use rustc_trait_selection::traits;
94
95pub use crate::collect::suggest_impl_trait;
96use crate::hir_ty_lowering::HirTyLowerer;
97
98fn check_c_variadic_abi(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: ExternAbi, span: Span) {
99 if !decl.c_variadic() {
100 return;
102 }
103
104 match abi.supports_c_variadic() {
105 CVariadicStatus::Stable => {}
106 CVariadicStatus::NotSupported => {
107 tcx.dcx().emit_err(diagnostics::VariadicFunctionCompatibleConvention {
108 span,
109 convention: &::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}", abi))
})format!("{abi}"),
110 });
111 }
112 CVariadicStatus::Unstable { feature } => {
113 if !tcx.features().enabled(feature) {
114 feature_err(
115 &tcx.sess,
116 feature,
117 span,
118 ::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"),
119 )
120 .emit();
121 }
122 }
123 }
124}
125
126pub fn provide(providers: &mut Providers) {
128 collect::provide(providers);
129 coherence::provide(providers);
130 check::provide(providers);
131 *providers = Providers {
132 check_unused_traits: check_unused::check_unused_traits,
133 diagnostic_hir_wf_check: hir_wf_check::diagnostic_hir_wf_check,
134 inferred_outlives_crate: outlives::inferred_outlives_crate,
135 inferred_outlives_of: outlives::inferred_outlives_of,
136 inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item,
137 delegation_user_specified_args: delegation::delegation_user_specified_args,
138 enforce_impl_non_lifetime_params_are_constrained:
139 impl_wf_check::enforce_impl_non_lifetime_params_are_constrained,
140 crate_variances: variance::crate_variances,
141 variances_of: variance::variances_of,
142 ..*providers
143 };
144}
145
146pub fn check_crate(tcx: TyCtxt<'_>) {
147 let _prof_timer = tcx.sess.timer("type_check_crate");
148
149 tcx.sess.time("coherence_checking", || {
150 type R = Result<(), ErrorGuaranteed>;
153
154 let _: R = tcx.ensure_result().check_type_wf(());
155
156 for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
157 let _: R = tcx.ensure_result().coherent_trait(trait_def_id);
158 }
159 let _: R = tcx.ensure_result().crate_inherent_impls_validity_check(());
161 let _: R = tcx.ensure_result().crate_inherent_impls_overlap_check(());
162 });
163
164 tcx.par_hir_body_owners(|item_def_id| {
165 let def_kind = tcx.def_kind(item_def_id);
166 match def_kind {
169 DefKind::Static { .. } => {
170 tcx.ensure_ok().eval_static_initializer(item_def_id);
171 check::maybe_check_static_with_link_section(tcx, item_def_id);
172 }
173 DefKind::Const
174 if !tcx.generics_of(item_def_id).own_requires_monomorphization()
175 && tcx.const_of_item(item_def_id).is_none() =>
176 {
177 let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty());
180 let cid = GlobalId { instance, promoted: None };
181 let typing_env = ty::TypingEnv::fully_monomorphized();
182 tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid));
183 }
184 _ => (),
185 }
186 if !(def_kind == DefKind::AnonConst
190 && tcx.anon_const_kind(item_def_id) != ty::AnonConstKind::NonTypeSystemInline
191 || tcx.is_typeck_child(item_def_id.to_def_id()))
192 {
193 tcx.ensure_ok().typeck(item_def_id);
194 }
195 });
196
197 tcx.hir_body_owners().for_each(|item_def_id| {
208 if tcx.needs_coroutine_by_move_body_def_id(item_def_id.to_def_id()) {
211 tcx.ensure_done().coroutine_by_move_body_def_id(item_def_id);
212 }
213 });
214
215 if tcx.features().rustc_attrs() {
216 tcx.sess.time("dumping_rustc_attr_data", || {
217 collect::dump::clauses_and_item_bounds(tcx);
219 collect::dump::def_parents(tcx);
220 collect::dump::generics(tcx);
221 collect::dump::object_lifetime_defaults(tcx);
222 collect::dump::opaque_hidden_types(tcx);
223 collect::dump::vtables(tcx);
224 outlives::dump::inferred_outlives(tcx);
225 variance::dump::variances(tcx);
226 });
228 }
229
230 tcx.ensure_ok().check_unused_traits(());
231}
232
233pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'_>) -> Ty<'tcx> {
244 let env_def_id = tcx.hir_get_parent_item(hir_ty.hir_id);
248 collect::ItemCtxt::new(tcx, env_def_id.def_id)
249 .lowerer()
250 .lower_ty_maybe_return_type_notation(hir_ty)
251}
252
253pub fn lower_const_arg_for_rustdoc<'tcx>(
256 tcx: TyCtxt<'tcx>,
257 hir_ct: &hir::ConstArg<'_>,
258 ty: Ty<'tcx>,
259) -> Const<'tcx> {
260 let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id);
261 collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, ty)
262}