rustc_hir_analysis/
lib.rs1#![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(never_type)]
71#![feature(rustdoc_internals)]
72#![feature(slice_partition_dedup)]
73#![feature(try_blocks)]
74#![feature(unwrap_infallible)]
75pub mod check;
79
80pub mod autoderef;
81mod check_unused;
82mod coherence;
83mod collect;
84mod constrained_generic_params;
85mod delegation;
86mod errors;
87pub mod hir_ty_lowering;
88pub mod hir_wf_check;
89mod impl_wf_check;
90mod outlives;
91mod variance;
92
93pub use errors::NoVariantNamed;
94use rustc_abi::ExternAbi;
95use rustc_hir as hir;
96use rustc_hir::def::DefKind;
97use rustc_middle::middle;
98use rustc_middle::mir::interpret::GlobalId;
99use rustc_middle::query::Providers;
100use rustc_middle::ty::{self, Const, Ty, TyCtxt};
101use rustc_session::parse::feature_err;
102use rustc_span::symbol::sym;
103use rustc_span::{ErrorGuaranteed, Span};
104use rustc_trait_selection::traits;
105
106pub use crate::collect::suggest_impl_trait;
107use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer};
108
109rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
110
111fn require_c_abi_if_c_variadic(
112 tcx: TyCtxt<'_>,
113 decl: &hir::FnDecl<'_>,
114 abi: ExternAbi,
115 span: Span,
116) {
117 const CONVENTIONS_UNSTABLE: &str =
118 "`C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`";
119 const CONVENTIONS_STABLE: &str = "`C` or `cdecl`";
120 const UNSTABLE_EXPLAIN: &str =
121 "using calling conventions other than `C` or `cdecl` for varargs functions is unstable";
122
123 if !decl.c_variadic || matches!(abi, ExternAbi::C { .. } | ExternAbi::Cdecl { .. }) {
125 return;
126 }
127
128 let extended_abi_support = tcx.features().extended_varargs_abi_support();
130 let extern_system_varargs = tcx.features().extern_system_varargs();
131
132 if extern_system_varargs && let ExternAbi::System { .. } = abi {
134 return;
135 };
136 if extended_abi_support && abi.supports_varargs() {
137 return;
138 };
139
140 match abi {
143 ExternAbi::System { .. } => {
144 feature_err(&tcx.sess, sym::extern_system_varargs, span, UNSTABLE_EXPLAIN)
145 }
146 abi if abi.supports_varargs() => {
147 feature_err(&tcx.sess, sym::extended_varargs_abi_support, span, UNSTABLE_EXPLAIN)
148 }
149 _ => tcx.dcx().create_err(errors::VariadicFunctionCompatibleConvention {
150 span,
151 conventions: if tcx.sess.opts.unstable_features.is_nightly_build() {
152 CONVENTIONS_UNSTABLE
153 } else {
154 CONVENTIONS_STABLE
155 },
156 }),
157 }
158 .emit();
159}
160
161pub fn provide(providers: &mut Providers) {
162 collect::provide(providers);
163 coherence::provide(providers);
164 check::provide(providers);
165 check_unused::provide(providers);
166 variance::provide(providers);
167 outlives::provide(providers);
168 hir_wf_check::provide(providers);
169 *providers = Providers {
170 inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item,
171 enforce_impl_non_lifetime_params_are_constrained:
172 impl_wf_check::enforce_impl_non_lifetime_params_are_constrained,
173 ..*providers
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 tcx.par_hir_for_each_module(|module| {
186 let _: R = tcx.ensure_ok().check_mod_type_wf(module);
187 });
188
189 for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
190 let _: R = tcx.ensure_ok().coherent_trait(trait_def_id);
191 }
192 let _: R = tcx.ensure_ok().crate_inherent_impls_validity_check(());
194 let _: R = tcx.ensure_ok().crate_inherent_impls_overlap_check(());
195 });
196
197 tcx.par_hir_body_owners(|item_def_id| {
200 let def_kind = tcx.def_kind(item_def_id);
201 match def_kind {
202 DefKind::Static { .. } => {
203 tcx.ensure_ok().eval_static_initializer(item_def_id);
204 check::maybe_check_static_with_link_section(tcx, item_def_id);
205 }
206 DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
207 let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty());
208 let cid = GlobalId { instance, promoted: None };
209 let typing_env = ty::TypingEnv::fully_monomorphized();
210 tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid));
211 }
212 _ => (),
213 }
214 if !matches!(def_kind, DefKind::AnonConst) {
216 tcx.ensure_ok().typeck(item_def_id);
217 }
218 });
219
220 if tcx.features().rustc_attrs() {
221 tcx.sess.time("dumping_rustc_attr_data", || {
222 outlives::dump::inferred_outlives(tcx);
223 variance::dump::variances(tcx);
224 collect::dump::opaque_hidden_types(tcx);
225 collect::dump::predicates_and_item_bounds(tcx);
226 collect::dump::def_parents(tcx);
227 collect::dump::vtables(tcx);
228 });
229 }
230
231 tcx.ensure_ok().check_unused_traits(());
232}
233
234pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
245 let env_def_id = tcx.hir_get_parent_item(hir_ty.hir_id);
249 collect::ItemCtxt::new(tcx, env_def_id.def_id)
250 .lowerer()
251 .lower_ty_maybe_return_type_notation(hir_ty)
252}
253
254pub fn lower_const_arg_for_rustdoc<'tcx>(
257 tcx: TyCtxt<'tcx>,
258 hir_ct: &hir::ConstArg<'tcx>,
259 feed: FeedConstTy<'_, 'tcx>,
260) -> Const<'tcx> {
261 let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id);
262 collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed)
263}