use crate::coercion::DynamicCoerceMany;
use crate::gather_locals::GatherLocalsVisitor;
use rustc_data_structures::unord::UnordSet;
-use rustc_errors::{struct_span_err, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{struct_span_err, DiagnosticId, ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
-use rustc_hir::def::Res;
+use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{HirIdMap, Node};
use rustc_hir_analysis::astconv::AstConv;
let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
let param_env = tcx.param_env(def_id);
- let mut fcx = if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
+ let mut fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
+
+ if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
let fn_sig = if rustc_hir_analysis::collect::get_infer_ret_ty(&decl.output).is_some() {
- let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
<dyn AstConv<'_>>::ty_of_fn(&fcx, id, header.unsafety, header.abi, decl, None, None)
} else {
tcx.fn_sig(def_id)
// Compute the function signature from point of view of inside the fn.
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
- let fn_sig = inh.normalize_associated_types_in(
- body.value.span,
- body_id.hir_id,
- param_env,
- fn_sig,
- );
- check_fn(&inh, param_env, fn_sig, decl, def_id, body, None).0
+ let fn_sig = fcx.normalize(body.value.span, fn_sig);
+
+ check_fn(&mut fcx, fn_sig, decl, def_id, body, None);
} else {
- let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
let expected_type = body_ty
.and_then(|ty| match ty.kind {
hir::TyKind::Infer => Some(<dyn AstConv<'_>>::ast_ty_to_ty(&fcx, ty)),
_ => fallback(),
});
- let expected_type = fcx.normalize_associated_types_in(body.value.span, expected_type);
+ let expected_type = fcx.normalize(body.value.span, expected_type);
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
// Gather locals in statics (because of block expressions).
fcx.check_expr_coercable_to_type(&body.value, expected_type, None);
fcx.write_ty(id, expected_type);
-
- fcx
};
fcx.type_inference_fallback();
res: Res,
qpath: &hir::QPath<'_>,
span: Span,
+ err_code: &str,
+ expected: &str,
) -> ErrorGuaranteed {
- struct_span_err!(
- tcx.sess,
+ let res_descr = match res {
+ Res::Def(DefKind::Variant, _) => "struct variant",
+ _ => res.descr(),
+ };
+ let path_str = rustc_hir_pretty::qpath_to_string(qpath);
+ let mut err = tcx.sess.struct_span_err_with_code(
span,
- E0533,
- "expected unit struct, unit variant or constant, found {} `{}`",
- res.descr(),
- rustc_hir_pretty::qpath_to_string(qpath),
- )
+ format!("expected {expected}, found {res_descr} `{path_str}`"),
+ DiagnosticId::Error(err_code.into()),
+ );
+ match res {
+ Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == "E0164" => {
+ let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html";
+ err.span_label(span, "`fn` calls are not allowed in patterns");
+ err.help(format!("for more information, visit {patterns_url}"))
+ }
+ _ => err.span_label(span, format!("not a {expected}")),
+ }
.emit()
}