}
}
+ if self.tcx.features().string_deref_patterns && let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind {
+ let tcx = self.tcx;
+ let expected = self.resolve_vars_if_possible(expected);
+ pat_ty = match expected.kind() {
+ ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => expected,
+ ty::Str => tcx.mk_static_str(),
+ _ => pat_ty,
+ };
+ }
+
// Somewhat surprising: in this case, the subtyping relation goes the
// opposite way as the other cases. Actually what we really want is not
// a subtyping relation at all but rather that there exists a LUB
let (res, opt_ty, segments) = path_resolution;
match res {
Res::Err => {
- self.set_tainted_by_errors();
- return tcx.ty_error();
+ let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
+ self.set_tainted_by_errors(e);
+ return tcx.ty_error_with_guaranteed(e);
}
Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => {
- report_unexpected_variant_res(tcx, res, qpath, pat.span);
- return tcx.ty_error();
+ let e = report_unexpected_variant_res(tcx, res, qpath, pat.span);
+ return tcx.ty_error_with_guaranteed(e);
}
Res::SelfCtor(..)
| Res::Def(
ti: TopInfo<'tcx>,
) -> Ty<'tcx> {
let tcx = self.tcx;
- let on_error = || {
+ let on_error = |e| {
for pat in subpats {
- self.check_pat(pat, tcx.ty_error(), def_bm, ti);
+ self.check_pat(pat, tcx.ty_error_with_guaranteed(e), def_bm, ti);
}
};
let report_unexpected_res = |res: Res| {
err.span_label(pat.span, "not a tuple variant or struct");
}
}
- err.emit();
- on_error();
+ let e = err.emit();
+ on_error(e);
+ e
};
// Resolve the path and check the definition for errors.
let (res, opt_ty, segments) =
self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
if res == Res::Err {
- self.set_tainted_by_errors();
- on_error();
- return self.tcx.ty_error();
+ let e = tcx.sess.delay_span_bug(pat.span, "`Res:Err` but no error emitted");
+ self.set_tainted_by_errors(e);
+ on_error(e);
+ return tcx.ty_error_with_guaranteed(e);
}
// Type-check the path.
let (pat_ty, res) =
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
if !pat_ty.is_fn() {
- report_unexpected_res(res);
- return tcx.ty_error();
+ let e = report_unexpected_res(res);
+ return tcx.ty_error_with_guaranteed(e);
}
let variant = match res {
Res::Err => {
- self.set_tainted_by_errors();
- on_error();
- return tcx.ty_error();
+ let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted");
+ self.set_tainted_by_errors(e);
+ on_error(e);
+ return tcx.ty_error_with_guaranteed(e);
}
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
- report_unexpected_res(res);
- return tcx.ty_error();
+ let e = report_unexpected_res(res);
+ return tcx.ty_error_with_guaranteed(e);
}
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res),
_ => bug!("unexpected pattern resolution: {:?}", res),
}
} else {
// Pattern has wrong number of fields.
- self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
- on_error();
- return tcx.ty_error();
+ let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
+ on_error(e);
+ return tcx.ty_error_with_guaranteed(e);
}
pat_ty
}
fields: &'tcx [ty::FieldDef],
expected: Ty<'tcx>,
had_err: bool,
- ) {
+ ) -> ErrorGuaranteed {
let subpats_ending = pluralize!(subpats.len());
let fields_ending = pluralize!(fields.len());
}
}
- err.emit();
+ err.emit()
}
fn check_pat_tuple(