Skip to content

Commit 0940040

Browse files
committed
Auto merge of #103310 - lcnr:rustc_hir_typeck, r=compiler-errors
move hir typeck into separate crate second part rust-lang/compiler-team#529 I avoided pretty much anything that wasn't just a simple move + path adjustment. Left fixmes for methods which are at an odd place r? `@compiler-errors`
2 parents b1ab3b7 + adc700b commit 0940040

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1252
-1154
lines changed

Cargo.lock

+27
Original file line numberDiff line numberDiff line change
@@ -3568,6 +3568,32 @@ dependencies = [
35683568
"rustc_target",
35693569
]
35703570

3571+
[[package]]
3572+
name = "rustc_hir_typeck"
3573+
version = "0.1.0"
3574+
dependencies = [
3575+
"rustc_ast",
3576+
"rustc_data_structures",
3577+
"rustc_errors",
3578+
"rustc_graphviz",
3579+
"rustc_hir",
3580+
"rustc_hir_analysis",
3581+
"rustc_hir_pretty",
3582+
"rustc_index",
3583+
"rustc_infer",
3584+
"rustc_lint",
3585+
"rustc_macros",
3586+
"rustc_middle",
3587+
"rustc_serialize",
3588+
"rustc_session",
3589+
"rustc_span",
3590+
"rustc_target",
3591+
"rustc_trait_selection",
3592+
"rustc_type_ir",
3593+
"smallvec",
3594+
"tracing",
3595+
]
3596+
35713597
[[package]]
35723598
name = "rustc_incremental"
35733599
version = "0.0.0"
@@ -3637,6 +3663,7 @@ dependencies = [
36373663
"rustc_expand",
36383664
"rustc_hir",
36393665
"rustc_hir_analysis",
3666+
"rustc_hir_typeck",
36403667
"rustc_incremental",
36413668
"rustc_lint",
36423669
"rustc_macros",

compiler/rustc_hir_analysis/src/astconv/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
582582
assoc_bindings
583583
}
584584

585-
pub(crate) fn create_substs_for_associated_item(
585+
pub fn create_substs_for_associated_item(
586586
&self,
587587
span: Span,
588588
item_def_id: DefId,

compiler/rustc_hir_analysis/src/check/check.rs

+1-311
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::check::intrinsicck::InlineAsmCtxt;
22

3-
use super::coercion::CoerceMany;
43
use super::compare_method::check_type_bounds;
54
use super::compare_method::{compare_impl_method, compare_ty_impl};
65
use super::*;
@@ -10,10 +9,8 @@ use rustc_hir as hir;
109
use rustc_hir::def::{DefKind, Res};
1110
use rustc_hir::def_id::{DefId, LocalDefId};
1211
use rustc_hir::intravisit::Visitor;
13-
use rustc_hir::lang_items::LangItem;
1412
use rustc_hir::{ItemKind, Node, PathSegment};
1513
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
16-
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1714
use rustc_infer::infer::{DefiningAnchor, RegionVariableOrigin, TyCtxtInferExt};
1815
use rustc_infer::traits::Obligation;
1916
use rustc_lint::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
@@ -34,7 +31,7 @@ use rustc_trait_selection::traits::{self, ObligationCtxt};
3431

3532
use std::ops::ControlFlow;
3633

37-
pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
34+
pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
3835
match tcx.sess.target.is_abi_supported(abi) {
3936
Some(true) => (),
4037
Some(false) => {
@@ -69,313 +66,6 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab
6966
}
7067
}
7168

72-
/// Helper used for fns and closures. Does the grungy work of checking a function
73-
/// body and returns the function context used for that purpose, since in the case of a fn item
74-
/// there is still a bit more to do.
75-
///
76-
/// * ...
77-
/// * inherited: other fields inherited from the enclosing fn (if any)
78-
#[instrument(skip(inherited, body), level = "debug")]
79-
pub(super) fn check_fn<'a, 'tcx>(
80-
inherited: &'a Inherited<'tcx>,
81-
param_env: ty::ParamEnv<'tcx>,
82-
fn_sig: ty::FnSig<'tcx>,
83-
decl: &'tcx hir::FnDecl<'tcx>,
84-
fn_id: hir::HirId,
85-
body: &'tcx hir::Body<'tcx>,
86-
can_be_generator: Option<hir::Movability>,
87-
return_type_pre_known: bool,
88-
) -> (FnCtxt<'a, 'tcx>, Option<GeneratorTypes<'tcx>>) {
89-
// Create the function context. This is either derived from scratch or,
90-
// in the case of closures, based on the outer context.
91-
let mut fcx = FnCtxt::new(inherited, param_env, body.value.hir_id);
92-
fcx.ps.set(UnsafetyState::function(fn_sig.unsafety, fn_id));
93-
fcx.return_type_pre_known = return_type_pre_known;
94-
95-
let tcx = fcx.tcx;
96-
let hir = tcx.hir();
97-
98-
let declared_ret_ty = fn_sig.output();
99-
100-
let ret_ty =
101-
fcx.register_infer_ok_obligations(fcx.infcx.replace_opaque_types_with_inference_vars(
102-
declared_ret_ty,
103-
body.value.hir_id,
104-
decl.output.span(),
105-
param_env,
106-
));
107-
// If we replaced declared_ret_ty with infer vars, then we must be inferring
108-
// an opaque type, so set a flag so we can improve diagnostics.
109-
fcx.return_type_has_opaque = ret_ty != declared_ret_ty;
110-
111-
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
112-
113-
let span = body.value.span;
114-
115-
fn_maybe_err(tcx, span, fn_sig.abi);
116-
117-
if fn_sig.abi == Abi::RustCall {
118-
let expected_args = if let ImplicitSelfKind::None = decl.implicit_self { 1 } else { 2 };
119-
120-
let err = || {
121-
let item = match tcx.hir().get(fn_id) {
122-
Node::Item(hir::Item { kind: ItemKind::Fn(header, ..), .. }) => Some(header),
123-
Node::ImplItem(hir::ImplItem {
124-
kind: hir::ImplItemKind::Fn(header, ..), ..
125-
}) => Some(header),
126-
Node::TraitItem(hir::TraitItem {
127-
kind: hir::TraitItemKind::Fn(header, ..),
128-
..
129-
}) => Some(header),
130-
// Closures are RustCall, but they tuple their arguments, so shouldn't be checked
131-
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => None,
132-
node => bug!("Item being checked wasn't a function/closure: {:?}", node),
133-
};
134-
135-
if let Some(header) = item {
136-
tcx.sess.span_err(header.span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple");
137-
}
138-
};
139-
140-
if fn_sig.inputs().len() != expected_args {
141-
err()
142-
} else {
143-
// FIXME(CraftSpider) Add a check on parameter expansion, so we don't just make the ICE happen later on
144-
// This will probably require wide-scale changes to support a TupleKind obligation
145-
// We can't resolve this without knowing the type of the param
146-
if !matches!(fn_sig.inputs()[expected_args - 1].kind(), ty::Tuple(_) | ty::Param(_)) {
147-
err()
148-
}
149-
}
150-
}
151-
152-
if body.generator_kind.is_some() && can_be_generator.is_some() {
153-
let yield_ty = fcx
154-
.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span });
155-
fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
156-
157-
// Resume type defaults to `()` if the generator has no argument.
158-
let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| tcx.mk_unit());
159-
160-
fcx.resume_yield_tys = Some((resume_ty, yield_ty));
161-
}
162-
163-
GatherLocalsVisitor::new(&fcx).visit_body(body);
164-
165-
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
166-
// (as it's created inside the body itself, not passed in from outside).
167-
let maybe_va_list = if fn_sig.c_variadic {
168-
let span = body.params.last().unwrap().span;
169-
let va_list_did = tcx.require_lang_item(LangItem::VaList, Some(span));
170-
let region = fcx.next_region_var(RegionVariableOrigin::MiscVariable(span));
171-
172-
Some(tcx.bound_type_of(va_list_did).subst(tcx, &[region.into()]))
173-
} else {
174-
None
175-
};
176-
177-
// Add formal parameters.
178-
let inputs_hir = hir.fn_decl_by_hir_id(fn_id).map(|decl| &decl.inputs);
179-
let inputs_fn = fn_sig.inputs().iter().copied();
180-
for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
181-
// Check the pattern.
182-
let ty_span = try { inputs_hir?.get(idx)?.span };
183-
fcx.check_pat_top(&param.pat, param_ty, ty_span, false);
184-
185-
// Check that argument is Sized.
186-
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
187-
// for simple cases like `fn foo(x: Trait)`,
188-
// where we would error once on the parameter as a whole, and once on the binding `x`.
189-
if param.pat.simple_ident().is_none() && !tcx.features().unsized_fn_params {
190-
fcx.require_type_is_sized(param_ty, param.pat.span, traits::SizedArgumentType(ty_span));
191-
}
192-
193-
fcx.write_ty(param.hir_id, param_ty);
194-
}
195-
196-
inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
197-
198-
fcx.in_tail_expr = true;
199-
if let ty::Dynamic(..) = declared_ret_ty.kind() {
200-
// FIXME: We need to verify that the return type is `Sized` after the return expression has
201-
// been evaluated so that we have types available for all the nodes being returned, but that
202-
// requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
203-
// causes unsized errors caused by the `declared_ret_ty` to point at the return expression,
204-
// while keeping the current ordering we will ignore the tail expression's type because we
205-
// don't know it yet. We can't do `check_expr_kind` while keeping `check_return_expr`
206-
// because we will trigger "unreachable expression" lints unconditionally.
207-
// Because of all of this, we perform a crude check to know whether the simplest `!Sized`
208-
// case that a newcomer might make, returning a bare trait, and in that case we populate
209-
// the tail expression's type so that the suggestion will be correct, but ignore all other
210-
// possible cases.
211-
fcx.check_expr(&body.value);
212-
fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
213-
} else {
214-
fcx.require_type_is_sized(declared_ret_ty, decl.output.span(), traits::SizedReturnType);
215-
fcx.check_return_expr(&body.value, false);
216-
}
217-
fcx.in_tail_expr = false;
218-
219-
// We insert the deferred_generator_interiors entry after visiting the body.
220-
// This ensures that all nested generators appear before the entry of this generator.
221-
// resolve_generator_interiors relies on this property.
222-
let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) {
223-
let interior = fcx
224-
.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
225-
fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior, gen_kind));
226-
227-
let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
228-
Some(GeneratorTypes {
229-
resume_ty,
230-
yield_ty,
231-
interior,
232-
movability: can_be_generator.unwrap(),
233-
})
234-
} else {
235-
None
236-
};
237-
238-
// Finalize the return check by taking the LUB of the return types
239-
// we saw and assigning it to the expected return type. This isn't
240-
// really expected to fail, since the coercions would have failed
241-
// earlier when trying to find a LUB.
242-
let coercion = fcx.ret_coercion.take().unwrap().into_inner();
243-
let mut actual_return_ty = coercion.complete(&fcx);
244-
debug!("actual_return_ty = {:?}", actual_return_ty);
245-
if let ty::Dynamic(..) = declared_ret_ty.kind() {
246-
// We have special-cased the case where the function is declared
247-
// `-> dyn Foo` and we don't actually relate it to the
248-
// `fcx.ret_coercion`, so just substitute a type variable.
249-
actual_return_ty =
250-
fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span });
251-
debug!("actual_return_ty replaced with {:?}", actual_return_ty);
252-
}
253-
254-
// HACK(oli-obk, compiler-errors): We should be comparing this against
255-
// `declared_ret_ty`, but then anything uninferred would be inferred to
256-
// the opaque type itself. That again would cause writeback to assume
257-
// we have a recursive call site and do the sadly stabilized fallback to `()`.
258-
fcx.demand_suptype(span, ret_ty, actual_return_ty);
259-
260-
// Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !`
261-
if let Some(panic_impl_did) = tcx.lang_items().panic_impl()
262-
&& panic_impl_did == hir.local_def_id(fn_id).to_def_id()
263-
{
264-
check_panic_info_fn(tcx, panic_impl_did.expect_local(), fn_sig, decl, declared_ret_ty);
265-
}
266-
267-
// Check that a function marked as `#[alloc_error_handler]` has signature `fn(Layout) -> !`
268-
if let Some(alloc_error_handler_did) = tcx.lang_items().oom()
269-
&& alloc_error_handler_did == hir.local_def_id(fn_id).to_def_id()
270-
{
271-
check_alloc_error_fn(tcx, alloc_error_handler_did.expect_local(), fn_sig, decl, declared_ret_ty);
272-
}
273-
274-
(fcx, gen_ty)
275-
}
276-
277-
fn check_panic_info_fn(
278-
tcx: TyCtxt<'_>,
279-
fn_id: LocalDefId,
280-
fn_sig: ty::FnSig<'_>,
281-
decl: &hir::FnDecl<'_>,
282-
declared_ret_ty: Ty<'_>,
283-
) {
284-
let Some(panic_info_did) = tcx.lang_items().panic_info() else {
285-
tcx.sess.err("language item required, but not found: `panic_info`");
286-
return;
287-
};
288-
289-
if *declared_ret_ty.kind() != ty::Never {
290-
tcx.sess.span_err(decl.output.span(), "return type should be `!`");
291-
}
292-
293-
let inputs = fn_sig.inputs();
294-
if inputs.len() != 1 {
295-
tcx.sess.span_err(tcx.def_span(fn_id), "function should have one argument");
296-
return;
297-
}
298-
299-
let arg_is_panic_info = match *inputs[0].kind() {
300-
ty::Ref(region, ty, mutbl) => match *ty.kind() {
301-
ty::Adt(ref adt, _) => {
302-
adt.did() == panic_info_did && mutbl == hir::Mutability::Not && !region.is_static()
303-
}
304-
_ => false,
305-
},
306-
_ => false,
307-
};
308-
309-
if !arg_is_panic_info {
310-
tcx.sess.span_err(decl.inputs[0].span, "argument should be `&PanicInfo`");
311-
}
312-
313-
let DefKind::Fn = tcx.def_kind(fn_id) else {
314-
let span = tcx.def_span(fn_id);
315-
tcx.sess.span_err(span, "should be a function");
316-
return;
317-
};
318-
319-
let generic_counts = tcx.generics_of(fn_id).own_counts();
320-
if generic_counts.types != 0 {
321-
let span = tcx.def_span(fn_id);
322-
tcx.sess.span_err(span, "should have no type parameters");
323-
}
324-
if generic_counts.consts != 0 {
325-
let span = tcx.def_span(fn_id);
326-
tcx.sess.span_err(span, "should have no const parameters");
327-
}
328-
}
329-
330-
fn check_alloc_error_fn(
331-
tcx: TyCtxt<'_>,
332-
fn_id: LocalDefId,
333-
fn_sig: ty::FnSig<'_>,
334-
decl: &hir::FnDecl<'_>,
335-
declared_ret_ty: Ty<'_>,
336-
) {
337-
let Some(alloc_layout_did) = tcx.lang_items().alloc_layout() else {
338-
tcx.sess.err("language item required, but not found: `alloc_layout`");
339-
return;
340-
};
341-
342-
if *declared_ret_ty.kind() != ty::Never {
343-
tcx.sess.span_err(decl.output.span(), "return type should be `!`");
344-
}
345-
346-
let inputs = fn_sig.inputs();
347-
if inputs.len() != 1 {
348-
tcx.sess.span_err(tcx.def_span(fn_id), "function should have one argument");
349-
return;
350-
}
351-
352-
let arg_is_alloc_layout = match inputs[0].kind() {
353-
ty::Adt(ref adt, _) => adt.did() == alloc_layout_did,
354-
_ => false,
355-
};
356-
357-
if !arg_is_alloc_layout {
358-
tcx.sess.span_err(decl.inputs[0].span, "argument should be `Layout`");
359-
}
360-
361-
let DefKind::Fn = tcx.def_kind(fn_id) else {
362-
let span = tcx.def_span(fn_id);
363-
tcx.sess.span_err(span, "`#[alloc_error_handler]` should be a function");
364-
return;
365-
};
366-
367-
let generic_counts = tcx.generics_of(fn_id).own_counts();
368-
if generic_counts.types != 0 {
369-
let span = tcx.def_span(fn_id);
370-
tcx.sess.span_err(span, "`#[alloc_error_handler]` function should have no type parameters");
371-
}
372-
if generic_counts.consts != 0 {
373-
let span = tcx.def_span(fn_id);
374-
tcx.sess
375-
.span_err(span, "`#[alloc_error_handler]` function should have no const parameters");
376-
}
377-
}
378-
37969
fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
38070
let def = tcx.adt_def(def_id);
38171
let span = tcx.def_span(def_id);

0 commit comments

Comments
 (0)