Skip to content

Commit d0eb9c8

Browse files
committed
move type inference for missing types on constants into its own method
1 parent 804c047 commit d0eb9c8

File tree

1 file changed

+58
-46
lines changed
  • compiler/rustc_hir_typeck/src

1 file changed

+58
-46
lines changed

compiler/rustc_hir_typeck/src/lib.rs

+58-46
Original file line numberDiff line numberDiff line change
@@ -191,52 +191,7 @@ fn typeck_with_fallback<'tcx>(
191191

192192
check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params);
193193
} else {
194-
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
195-
if let Some(item) = tcx.opt_associated_item(def_id.into())
196-
&& let ty::AssocKind::Const = item.kind
197-
&& let ty::ImplContainer = item.container
198-
&& let Some(trait_item) = item.trait_item_def_id
199-
{
200-
let args =
201-
tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args;
202-
Some(tcx.type_of(trait_item).instantiate(tcx, args))
203-
} else {
204-
Some(fcx.next_ty_var(TypeVariableOrigin {
205-
kind: TypeVariableOriginKind::TypeInference,
206-
span,
207-
}))
208-
}
209-
} else if let Node::AnonConst(_) = node {
210-
match tcx.parent_hir_node(id) {
211-
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. })
212-
if anon_const.hir_id == id =>
213-
{
214-
Some(fcx.next_ty_var(TypeVariableOrigin {
215-
kind: TypeVariableOriginKind::TypeInference,
216-
span,
217-
}))
218-
}
219-
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), .. })
220-
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), .. }) => {
221-
asm.operands.iter().find_map(|(op, _op_sp)| match op {
222-
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => {
223-
// Inline assembly constants must be integers.
224-
Some(fcx.next_int_var())
225-
}
226-
hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => {
227-
Some(fcx.next_ty_var(TypeVariableOrigin {
228-
kind: TypeVariableOriginKind::MiscVariable,
229-
span,
230-
}))
231-
}
232-
_ => None,
233-
})
234-
}
235-
_ => None,
236-
}
237-
} else {
238-
None
239-
};
194+
let expected_type = infer_type_if_missing(body_ty, &fcx, node);
240195
let expected_type = expected_type.unwrap_or_else(fallback);
241196

242197
let expected_type = fcx.normalize(body.value.span, expected_type);
@@ -306,6 +261,63 @@ fn typeck_with_fallback<'tcx>(
306261
typeck_results
307262
}
308263

264+
fn infer_type_if_missing<'tcx>(
265+
body_ty: Option<&hir::Ty<'tcx>>,
266+
fcx: &FnCtxt<'_, 'tcx>,
267+
node: Node<'tcx>,
268+
) -> Option<Ty<'tcx>> {
269+
let tcx = fcx.tcx;
270+
let def_id = fcx.body_id;
271+
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer, span, .. }) = body_ty {
272+
if let Some(item) = tcx.opt_associated_item(def_id.into())
273+
&& let ty::AssocKind::Const = item.kind
274+
&& let ty::ImplContainer = item.container
275+
&& let Some(trait_item) = item.trait_item_def_id
276+
{
277+
let args =
278+
tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args;
279+
Some(tcx.type_of(trait_item).instantiate(tcx, args))
280+
} else {
281+
Some(fcx.next_ty_var(TypeVariableOrigin {
282+
kind: TypeVariableOriginKind::TypeInference,
283+
span,
284+
}))
285+
}
286+
} else if let Node::AnonConst(_) = node {
287+
let id = tcx.local_def_id_to_hir_id(def_id);
288+
match tcx.parent_hir_node(id) {
289+
Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), span, .. })
290+
if anon_const.hir_id == id =>
291+
{
292+
Some(fcx.next_ty_var(TypeVariableOrigin {
293+
kind: TypeVariableOriginKind::TypeInference,
294+
span,
295+
}))
296+
}
297+
Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), span, .. })
298+
| Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), span, .. }) => {
299+
asm.operands.iter().find_map(|(op, _op_sp)| match op {
300+
hir::InlineAsmOperand::Const { anon_const } if anon_const.hir_id == id => {
301+
// Inline assembly constants must be integers.
302+
Some(fcx.next_int_var())
303+
}
304+
hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => {
305+
Some(fcx.next_ty_var(TypeVariableOrigin {
306+
kind: TypeVariableOriginKind::MiscVariable,
307+
span,
308+
}))
309+
}
310+
_ => None,
311+
})
312+
}
313+
_ => None,
314+
}
315+
} else {
316+
None
317+
};
318+
expected_type
319+
}
320+
309321
/// When `check_fn` is invoked on a coroutine (i.e., a body that
310322
/// includes yield), it returns back some information about the yield
311323
/// points.

0 commit comments

Comments
 (0)