rustc_hir_analysis/
lib.rs
1#![allow(internal_features)]
60#![allow(rustc::diagnostic_outside_of_impl)]
61#![allow(rustc::untranslatable_diagnostic)]
62#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
63#![doc(rust_logo)]
64#![feature(assert_matches)]
65#![feature(coroutines)]
66#![feature(debug_closure_helpers)]
67#![feature(if_let_guard)]
68#![feature(iter_from_coroutine)]
69#![feature(iter_intersperse)]
70#![feature(let_chains)]
71#![feature(never_type)]
72#![feature(rustdoc_internals)]
73#![feature(slice_partition_dedup)]
74#![feature(try_blocks)]
75#![feature(unwrap_infallible)]
76#![warn(unreachable_pub)]
77pub mod check;
81
82pub mod autoderef;
83mod bounds;
84mod check_unused;
85mod coherence;
86mod collect;
87mod constrained_generic_params;
88mod delegation;
89mod errors;
90pub mod hir_ty_lowering;
91pub mod hir_wf_check;
92mod impl_wf_check;
93mod outlives;
94mod variance;
95
96use rustc_abi::ExternAbi;
97use rustc_hir as hir;
98use rustc_hir::def::DefKind;
99use rustc_middle::middle;
100use rustc_middle::mir::interpret::GlobalId;
101use rustc_middle::query::Providers;
102use rustc_middle::ty::{self, Const, Ty, TyCtxt};
103use rustc_session::parse::feature_err;
104use rustc_span::symbol::sym;
105use rustc_span::{ErrorGuaranteed, Span};
106use rustc_trait_selection::traits;
107
108pub use crate::collect::suggest_impl_trait;
109use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
110
111rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
112
113fn require_c_abi_if_c_variadic(
114 tcx: TyCtxt<'_>,
115 decl: &hir::FnDecl<'_>,
116 abi: ExternAbi,
117 span: Span,
118) {
119 const CONVENTIONS_UNSTABLE: &str =
120 "`C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`";
121 const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
122 const UNSTABLE_EXPLAIN: &str =
123 "using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
124
125 if !decl.c_variadic || matches!(abi, ExternAbi::C { .. } | ExternAbi::Cdecl { .. }) {
127 return;
128 }
129
130 let extended_abi_support = tcx.features().extended_varargs_abi_support();
132 let extern_system_varargs = tcx.features().extern_system_varargs();
133
134 if extern_system_varargs && let ExternAbi::System { .. } = abi {
136 return;
137 };
138 if extended_abi_support && abi.supports_varargs() {
139 return;
140 };
141
142 match abi {
145 ExternAbi::System { .. } => {
146 feature_err(&tcx.sess, sym::extern_system_varargs, span, UNSTABLE_EXPLAIN)
147 }
148 abi if abi.supports_varargs() => {
149 feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
150 }
151 _ => tcx.dcx().create_err(errors::VariadicFunctionCompatibleConvention {
152 span,
153 conventions: if tcx.sess.opts.unstable_features.is_nightly_build() {
154 CONVENTIONS_UNSTABLE
155 } else {
156 CONVENTIONS_STABLE
157 },
158 }),
159 }
160 .emit();
161}
162
163pub fn provide(providers: &mut Providers) {
164 collect::provide(providers);
165 coherence::provide(providers);
166 check::provide(providers);
167 check_unused::provide(providers);
168 variance::provide(providers);
169 outlives::provide(providers);
170 hir_wf_check::provide(providers);
171 *providers = Providers {
172 inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item,
173 enforce_impl_non_lifetime_params_are_constrained:
174 impl_wf_check::enforce_impl_non_lifetime_params_are_constrained,
175 ..*providers
176 };
177}
178
179pub fn check_crate(tcx: TyCtxt<'_>) {
180 let _prof_timer = tcx.sess.timer("type_check_crate");
181
182 tcx.sess.time("coherence_checking", || {
183 type R = Result<(), ErrorGuaranteed>;
186
187 tcx.hir().par_for_each_module(|module| {
188 let _: R = tcx.ensure_ok().check_mod_type_wf(module);
189 });
190
191 for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
192 let _: R = tcx.ensure_ok().coherent_trait(trait_def_id);
193 }
194 let _: R = tcx.ensure_ok().crate_inherent_impls_validity_check(());
196 let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(());
197 });
198
199 if tcx.features().rustc_attrs() {
200 tcx.sess.time("dumping_rustc_attr_data", || {
201 outlives::dump::inferred_outlives(tcx);
202 variance::dump::variances(tcx);
203 collect::dump::opaque_hidden_types(tcx);
204 collect::dump::predicates_and_item_bounds(tcx);
205 collect::dump::def_parents(tcx);
206 collect::dump::vtables(tcx);
207 });
208 }
209
210 tcx.hir().par_body_owners(|item_def_id| {
213 let def_kind = tcx.def_kind(item_def_id);
214 match def_kind {
215 DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id),
216 DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
217 let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty());
218 let cid = GlobalId { instance, promoted: None };
219 let typing_env = ty::TypingEnv::fully_monomorphized();
220 tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid));
221 }
222 _ => (),
223 }
224 });
225
226 tcx.hir().par_body_owners(|item_def_id| {
231 let def_kind = tcx.def_kind(item_def_id);
232 if !matches!(def_kind, DefKind::AnonConst) {
233 tcx.ensure_ok().typeck(item_def_id);
234 }
235 });
236
237 tcx.ensure_ok().check_unused_traits(());
238}
239
240pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
251 let env_def_id = tcx.hir().get_parent_item(hir_ty.hir_id);
255 collect::ItemCtxt::new(tcx, env_def_id.def_id).lower_ty(hir_ty)
256}
257
258pub fn lower_const_arg_for_rustdoc<'tcx>(
261 tcx: TyCtxt<'tcx>,
262 hir_ct: &hir::ConstArg<'tcx>,
263 feed: FeedConstTy,
264) -> Const<'tcx> {
265 let env_def_id = tcx.hir().get_parent_item(hir_ct.hir_id);
266 collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed)
267}