rustc_hir_analysis/
lib.rs1#![cfg_attr(bootstrap, feature(assert_matches))]
60#![feature(default_field_values)]
61#![feature(gen_blocks)]
62#![feature(iter_intersperse)]
63#![feature(never_type)]
64#![feature(slice_partition_dedup)]
65#![feature(try_blocks)]
66#![feature(unwrap_infallible)]
67pub mod check;
71
72pub mod autoderef;
73mod check_unused;
74mod coherence;
75mod collect;
76mod constrained_generic_params;
77mod delegation;
78pub mod errors;
79pub mod hir_ty_lowering;
80pub mod hir_wf_check;
81mod impl_wf_check;
82mod outlives;
83mod variance;
84
85pub use errors::NoVariantNamed;
86use rustc_abi::{CVariadicStatus, ExternAbi};
87use rustc_hir as hir;
88use rustc_hir::def::DefKind;
89use rustc_middle::mir::interpret::GlobalId;
90use rustc_middle::query::Providers;
91use rustc_middle::ty::{Const, Ty, TyCtxt};
92use rustc_middle::{middle, ty};
93use rustc_session::parse::feature_err;
94use rustc_span::{ErrorGuaranteed, Span};
95use rustc_trait_selection::traits;
96
97pub use crate::collect::suggest_impl_trait;
98use crate::hir_ty_lowering::HirTyLowerer;
99
100fn check_c_variadic_abi(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: ExternAbi, span: Span) {
101 if !decl.c_variadic {
102 return;
104 }
105
106 match abi.supports_c_variadic() {
107 CVariadicStatus::Stable => {}
108 CVariadicStatus::NotSupported => {
109 tcx.dcx()
110 .create_err(errors::VariadicFunctionCompatibleConvention {
111 span,
112 convention: &::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}", abi))
})format!("{abi}"),
113 })
114 .emit();
115 }
116 CVariadicStatus::Unstable { feature } => {
117 if !tcx.features().enabled(feature) {
118 feature_err(
119 &tcx.sess,
120 feature,
121 span,
122 ::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"),
123 )
124 .emit();
125 }
126 }
127 }
128}
129
130pub fn provide(providers: &mut Providers) {
132 collect::provide(providers);
133 coherence::provide(providers);
134 check::provide(providers);
135 *providers = Providers {
136 check_unused_traits: check_unused::check_unused_traits,
137 diagnostic_hir_wf_check: hir_wf_check::diagnostic_hir_wf_check,
138 inferred_outlives_crate: outlives::inferred_outlives_crate,
139 inferred_outlives_of: outlives::inferred_outlives_of,
140 inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item,
141 enforce_impl_non_lifetime_params_are_constrained:
142 impl_wf_check::enforce_impl_non_lifetime_params_are_constrained,
143 crate_variances: variance::crate_variances,
144 variances_of: variance::variances_of,
145 ..*providers
146 };
147}
148
149pub fn check_crate(tcx: TyCtxt<'_>) {
150 let _prof_timer = tcx.sess.timer("type_check_crate");
151
152 tcx.sess.time("coherence_checking", || {
153 type R = Result<(), ErrorGuaranteed>;
156
157 let _: R = tcx.ensure_result().check_type_wf(());
158
159 for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
160 let _: R = tcx.ensure_result().coherent_trait(trait_def_id);
161 }
162 let _: R = tcx.ensure_result().crate_inherent_impls_validity_check(());
164 let _: R = tcx.ensure_result().crate_inherent_impls_overlap_check(());
165 });
166
167 tcx.par_hir_body_owners(|item_def_id| {
168 let def_kind = tcx.def_kind(item_def_id);
169 match def_kind {
172 DefKind::Static { .. } => {
173 tcx.ensure_ok().eval_static_initializer(item_def_id);
174 check::maybe_check_static_with_link_section(tcx, item_def_id);
175 }
176 DefKind::Const { .. }
177 if !tcx.generics_of(item_def_id).own_requires_monomorphization()
178 && !tcx.is_type_const(item_def_id) =>
179 {
180 let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty());
183 let cid = GlobalId { instance, promoted: None };
184 let typing_env = ty::TypingEnv::fully_monomorphized();
185 tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid));
186 }
187 _ => (),
188 }
189 if !(#[allow(non_exhaustive_omitted_patterns)] match def_kind {
DefKind::AnonConst => true,
_ => false,
}matches!(def_kind, DefKind::AnonConst) || def_kind.is_typeck_child()) {
192 tcx.ensure_ok().typeck(item_def_id);
193 }
194 if tcx.needs_coroutine_by_move_body_def_id(item_def_id.to_def_id()) {
197 tcx.ensure_done().coroutine_by_move_body_def_id(item_def_id);
198 }
199 });
200
201 if tcx.features().rustc_attrs() {
202 tcx.sess.time("dumping_rustc_attr_data", || {
203 outlives::dump::inferred_outlives(tcx);
204 variance::dump::variances(tcx);
205 collect::dump::opaque_hidden_types(tcx);
206 collect::dump::predicates_and_item_bounds(tcx);
207 collect::dump::def_parents(tcx);
208 collect::dump::vtables(tcx);
209 });
210 }
211
212 tcx.ensure_ok().check_unused_traits(());
213}
214
215pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
226 let env_def_id = tcx.hir_get_parent_item(hir_ty.hir_id);
230 collect::ItemCtxt::new(tcx, env_def_id.def_id)
231 .lowerer()
232 .lower_ty_maybe_return_type_notation(hir_ty)
233}
234
235pub fn lower_const_arg_for_rustdoc<'tcx>(
238 tcx: TyCtxt<'tcx>,
239 hir_ct: &hir::ConstArg<'tcx>,
240 ty: Ty<'tcx>,
241) -> Const<'tcx> {
242 let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id);
243 collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, ty)
244}