summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_typeck/src/pat.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
commit4547b622d8d29df964fa2914213088b148c498fc (patch)
tree9fc6b25f3c3add6b745be9a2400a6e96140046e9 /compiler/rustc_hir_typeck/src/pat.rs
parentReleasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz
rustc-4547b622d8d29df964fa2914213088b148c498fc.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_hir_typeck/src/pat.rs')
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs106
1 files changed, 49 insertions, 57 deletions
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index ea90da4a6..decd317d9 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -19,7 +19,6 @@ use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::source_map::{Span, Spanned};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{BytePos, DUMMY_SP};
-use rustc_trait_selection::autoderef::Autoderef;
use rustc_trait_selection::traits::{ObligationCause, Pattern};
use ty::VariantDef;
@@ -402,6 +401,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
+ 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
@@ -693,7 +702,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let mut_var_suggestion = 'block: {
- if !matches!(mutbl, ast::Mutability::Mut) {
+ if mutbl.is_not() {
break 'block None;
}
@@ -740,7 +749,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
format!("to take parameter `{binding}` by reference, move `&{mutability}` to the type"),
vec![
(pat.span.until(inner.span), "".to_owned()),
- (ty_span.shrink_to_lo(), format!("&{}", mutbl.prefix_str())),
+ (ty_span.shrink_to_lo(), mutbl.ref_prefix_str().to_owned()),
],
Applicability::MachineApplicable
);
@@ -840,12 +849,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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();
+ Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Variant, _) => {
+ let expected = "unit struct, unit variant or constant";
+ let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0533", expected);
+ return tcx.ty_error_with_guaranteed(e);
}
Res::SelfCtor(..)
| Res::Def(
@@ -986,65 +997,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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| {
- let sm = tcx.sess.source_map();
- let path_str = sm
- .span_to_snippet(sm.span_until_char(pat.span, '('))
- .map_or_else(|_| String::new(), |s| format!(" `{}`", s.trim_end()));
- let msg = format!(
- "expected tuple struct or tuple variant, found {}{}",
- res.descr(),
- path_str
- );
-
- let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{msg}");
- match res {
- Res::Def(DefKind::Fn | DefKind::AssocFn, _) => {
- err.span_label(pat.span, "`fn` calls are not allowed in patterns");
- err.help(
- "for more information, visit \
- https://doc.rust-lang.org/book/ch18-00-patterns.html",
- );
- }
- _ => {
- err.span_label(pat.span, "not a tuple variant or struct");
- }
- }
- err.emit();
- on_error();
+ let expected = "tuple struct or tuple variant";
+ let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0164", expected);
+ 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),
@@ -1083,9 +1075,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
} 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
}
@@ -1099,7 +1091,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fields: &'tcx [ty::FieldDef],
expected: Ty<'tcx>,
had_err: bool,
- ) {
+ ) -> ErrorGuaranteed {
let subpats_ending = pluralize!(subpats.len());
let fields_ending = pluralize!(fields.len());
@@ -1246,7 +1238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
- err.emit();
+ err.emit()
}
fn check_pat_tuple(
@@ -1278,12 +1270,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let element_tys = tcx.mk_type_list(element_tys_iter);
let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
if let Some(mut err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, ti) {
- err.emit();
+ let reported = err.emit();
// Walk subpatterns with an expected type of `err` in this case to silence
// further errors being emitted when using the bindings. #50333
- let element_tys_iter = (0..max_len).map(|_| tcx.ty_error());
+ let element_tys_iter = (0..max_len).map(|_| tcx.ty_error_with_guaranteed(reported));
for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
- self.check_pat(elem, tcx.ty_error(), def_bm, ti);
+ self.check_pat(elem, tcx.ty_error_with_guaranteed(reported), def_bm, ti);
}
tcx.mk_tup(element_tys_iter)
} else {
@@ -1468,8 +1460,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// if this is a tuple struct, then all field names will be numbers
// so if any fields in a struct pattern use shorthand syntax, they will
// be invalid identifiers (for example, Foo { 0, 1 }).
- if let (CtorKind::Fn, PatKind::Struct(qpath, field_patterns, ..)) =
- (variant.ctor_kind, &pat.kind)
+ if let (Some(CtorKind::Fn), PatKind::Struct(qpath, field_patterns, ..)) =
+ (variant.ctor_kind(), &pat.kind)
{
let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand);
if has_shorthand_field_name {
@@ -1646,7 +1638,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fields: &'tcx [hir::PatField<'tcx>],
variant: &ty::VariantDef,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
- if let (CtorKind::Fn, PatKind::Struct(qpath, ..)) = (variant.ctor_kind, &pat.kind) {
+ if let (Some(CtorKind::Fn), PatKind::Struct(qpath, ..)) = (variant.ctor_kind(), &pat.kind) {
let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| {
s.print_qpath(qpath, false)
});
@@ -2132,7 +2124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let ty::Array(..) | ty::Slice(..) = ty.kind()
{
err.help("the semantics of slice patterns changed recently; see issue #62254");
- } else if Autoderef::new(&self.infcx, self.param_env, self.body_id, span, expected_ty, span)
+ } else if self.autoderef(span, expected_ty)
.any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
&& let (Some(span), true) = (ti.span, ti.origin_expr)
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)