diff --git a/README.md b/README.md
index 495ee46a9acb3..9462b10494c93 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ or reading the [rustc guide][rustcguidebuild].
* `curl`
* `git`
* `ssl` which comes in `libssl-dev` or `openssl-devel`
- * `pkg-config` if you are on compiling on Linux and targeting Linux
+ * `pkg-config` if you are compiling on Linux and targeting Linux
2. Clone the [source] with `git`:
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index 2f0a318d5363e..9dcecedd97cae 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -1037,10 +1037,9 @@ impl LoweringContext<'_> {
) -> hir::Expr {
// expand
let mut head = self.lower_expr(head);
- let head_sp = head.span;
let desugared_span = self.mark_span_with_reason(
DesugaringKind::ForLoop,
- head_sp,
+ head.span,
None,
);
head.span = desugared_span;
@@ -1086,21 +1085,21 @@ impl LoweringContext<'_> {
// `match ::std::iter::Iterator::next(&mut iter) { ... }`
let match_expr = {
- let iter = P(self.expr_ident(head_sp, iter, iter_pat_nid));
- let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
+ let iter = P(self.expr_ident(desugared_span, iter, iter_pat_nid));
+ let ref_mut_iter = self.expr_mut_addr_of(desugared_span, iter);
let next_path = &[sym::iter, sym::Iterator, sym::next];
let next_expr = P(self.expr_call_std_path(
- head_sp,
+ desugared_span,
next_path,
hir_vec![ref_mut_iter],
));
let arms = hir_vec![pat_arm, break_arm];
- self.expr_match(head_sp, next_expr, arms, hir::MatchSource::ForLoopDesugar)
+ self.expr_match(desugared_span, next_expr, arms, hir::MatchSource::ForLoopDesugar)
};
- let match_stmt = self.stmt_expr(head_sp, match_expr);
+ let match_stmt = self.stmt_expr(desugared_span, match_expr);
- let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat_hid));
+ let next_expr = P(self.expr_ident(desugared_span, next_ident, next_pat_hid));
// `let mut __next`
let next_let = self.stmt_let_pat(
@@ -1115,7 +1114,7 @@ impl LoweringContext<'_> {
let pat = self.lower_pat(pat);
let pat_let = self.stmt_let_pat(
ThinVec::new(),
- head_sp,
+ desugared_span,
Some(next_expr),
pat,
hir::LocalSource::ForLoopDesugar,
@@ -1152,14 +1151,14 @@ impl LoweringContext<'_> {
let into_iter_path =
&[sym::iter, sym::IntoIterator, sym::into_iter];
P(self.expr_call_std_path(
- head_sp,
+ desugared_span,
into_iter_path,
hir_vec![head],
))
};
let match_expr = P(self.expr_match(
- head_sp,
+ desugared_span,
into_iter_expr,
hir_vec![iter_arm],
hir::MatchSource::ForLoopDesugar,
@@ -1171,7 +1170,7 @@ impl LoweringContext<'_> {
// surrounding scope of the `match` since the `match` is not a terminating scope.
//
// Also, add the attributes to the outer returned expr node.
- self.expr_drop_temps(head_sp, match_expr, e.attrs.clone())
+ self.expr_drop_temps(desugared_span, match_expr, e.attrs.clone())
}
/// Desugar `ExprKind::Try` from: `?` into:
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 42a4a9909f8a9..a1011697ef160 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -818,6 +818,32 @@ impl<'hir> Map<'hir> {
CRATE_HIR_ID
}
+ /// When on a match arm tail expression or on a match arm, give back the enclosing `match`
+ /// expression.
+ ///
+ /// Used by error reporting when there's a type error in a match arm caused by the `match`
+ /// expression needing to be unit.
+ pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&Expr> {
+ for (_, node) in ParentHirIterator::new(hir_id, &self) {
+ match node {
+ Node::Item(_) |
+ Node::ForeignItem(_) |
+ Node::TraitItem(_) |
+ Node::ImplItem(_) => break,
+ Node::Expr(expr) => match expr.kind {
+ ExprKind::Match(_, _, _) => return Some(expr),
+ _ => {}
+ },
+ Node::Stmt(stmt) => match stmt.kind {
+ StmtKind::Local(_) => break,
+ _ => {}
+ }
+ _ => {}
+ }
+ }
+ None
+ }
+
/// Returns the nearest enclosing scope. A scope is roughly an item or block.
pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option {
for (hir_id, node) in ParentHirIterator::new(hir_id, &self) {
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index cd58396d95c62..e925d7429fff4 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -101,7 +101,7 @@ pub use self::error::{
InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviorInfo,
};
-pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue};
+pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue, get_slice_bytes};
pub use self::allocation::{Allocation, AllocationExtra, Relocations, UndefMask};
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index b8bc741419738..32f45cd9d4720 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -611,3 +611,18 @@ impl_stable_hash_for!(enum crate::mir::interpret::ScalarMaybeUndef {
Scalar(v),
Undef
});
+
+/// Gets the bytes of a constant slice value.
+pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] {
+ if let ConstValue::Slice { data, start, end } = val {
+ let len = end - start;
+ data.get_bytes(
+ cx,
+ // invent a pointer, only the offset is relevant anyway
+ Pointer::new(AllocId(0), Size::from_bytes(start as u64)),
+ Size::from_bytes(len as u64),
+ ).unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err))
+ } else {
+ bug!("expected const slice, but found another const value");
+ }
+}
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 2af6963f7122a..3bd61e3455436 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use crate::ty::error::{ExpectedFound, TypeError};
-use crate::mir::interpret::{ConstValue, Scalar};
+use crate::mir::interpret::{ConstValue, get_slice_bytes, Scalar};
use std::rc::Rc;
use std::iter;
use rustc_target::spec::abi;
@@ -584,7 +584,20 @@ pub fn super_relate_consts>(
// FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment
// saying that we're not handling it intentionally.
- // FIXME(const_generics): handle `ConstValue::ByRef` and `ConstValue::Slice`.
+ (a_val @ ConstValue::Slice { .. }, b_val @ ConstValue::Slice { .. }) => {
+ let a_bytes = get_slice_bytes(&tcx, a_val);
+ let b_bytes = get_slice_bytes(&tcx, b_val);
+ if a_bytes == b_bytes {
+ Ok(tcx.mk_const(ty::Const {
+ val: a_val,
+ ty: a.ty,
+ }))
+ } else {
+ Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
+ }
+ }
+
+ // FIXME(const_generics): handle `ConstValue::ByRef`.
// FIXME(const_generics): this is wrong, as it is a projection
(ConstValue::Unevaluated(a_def_id, a_substs),
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 4d2fee3d160ed..fcdf2719ab627 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -13,12 +13,12 @@ use crate::hair::constant::*;
use rustc::lint;
use rustc::mir::{Field, BorrowKind, Mutability};
use rustc::mir::{UserTypeProjection};
-use rustc::mir::interpret::{GlobalId, ConstValue, sign_extend, AllocId, Pointer};
+use rustc::mir::interpret::{GlobalId, ConstValue, get_slice_bytes, sign_extend};
use rustc::traits::{ObligationCause, PredicateObligation};
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree};
use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
use rustc::ty::subst::{SubstsRef, GenericArg};
-use rustc::ty::layout::{VariantIdx, Size};
+use rustc::ty::layout::VariantIdx;
use rustc::hir::{self, RangeEnd};
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@@ -1526,27 +1526,10 @@ pub fn compare_const_vals<'tcx>(
if let ty::Str = ty.kind {
match (a.val, b.val) {
- (
- ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
- ConstValue::Slice { data: alloc_b, start: offset_b, end: end_b },
- ) => {
- let len_a = end_a - offset_a;
- let len_b = end_b - offset_b;
- let a = alloc_a.get_bytes(
- &tcx,
- // invent a pointer, only the offset is relevant anyway
- Pointer::new(AllocId(0), Size::from_bytes(offset_a as u64)),
- Size::from_bytes(len_a as u64),
- );
- let b = alloc_b.get_bytes(
- &tcx,
- // invent a pointer, only the offset is relevant anyway
- Pointer::new(AllocId(0), Size::from_bytes(offset_b as u64)),
- Size::from_bytes(len_b as u64),
- );
- if let (Ok(a), Ok(b)) = (a, b) {
- return from_bool(a == b);
- }
+ (ConstValue::Slice { .. }, ConstValue::Slice { .. }) => {
+ let a_bytes = get_slice_bytes(&tcx, a.val);
+ let b_bytes = get_slice_bytes(&tcx, b.val);
+ return from_bool(a_bytes == b_bytes);
}
_ => (),
}
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 0d35cc53ac6f3..d3bf82b66ad1c 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -348,7 +348,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
_ => false,
};
- let mut bad_struct_syntax_suggestion = || {
+ let mut bad_struct_syntax_suggestion = |def_id: DefId| {
let (followed_by_brace, closing_brace) = self.followed_by_brace(span);
let mut suggested = false;
match source {
@@ -374,6 +374,9 @@ impl<'a> LateResolutionVisitor<'a, '_> {
_ => {}
}
if !suggested {
+ if let Some(span) = self.r.definitions.opt_span(def_id) {
+ err.span_label(span, &format!("`{}` defined here", path_str));
+ }
err.span_label(
span,
format!("did you mean `{} {{ /* fields */ }}`?", path_str),
@@ -437,18 +440,21 @@ impl<'a> LateResolutionVisitor<'a, '_> {
);
}
} else {
- bad_struct_syntax_suggestion();
+ bad_struct_syntax_suggestion(def_id);
}
}
- (Res::Def(DefKind::Union, _), _) |
- (Res::Def(DefKind::Variant, _), _) |
- (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => {
- bad_struct_syntax_suggestion();
+ (Res::Def(DefKind::Union, def_id), _) |
+ (Res::Def(DefKind::Variant, def_id), _) |
+ (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), def_id), _) if ns == ValueNS => {
+ bad_struct_syntax_suggestion(def_id);
}
- (Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), _) if ns == ValueNS => {
+ (Res::Def(DefKind::Ctor(_, CtorKind::Fn), def_id), _) if ns == ValueNS => {
+ if let Some(span) = self.r.definitions.opt_span(def_id) {
+ err.span_label(span, &format!("`{}` defined here", path_str));
+ }
err.span_label(
span,
- format!("did you mean `{} ( /* fields */ )`?", path_str),
+ format!("did you mean `{}( /* fields */ )`?", path_str),
);
}
(Res::SelfTy(..), _) if ns == ValueNS => {
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 13b6b1b8aa08d..a1daed005f302 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -36,7 +36,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`.
//
// FIXME(60707): Consider removing hack with principled solution.
- self.check_expr_has_type_or_error(discrim, self.tcx.types.bool)
+ self.check_expr_has_type_or_error(discrim, self.tcx.types.bool, |_| {})
} else {
self.demand_discriminant_type(arms, discrim)
};
@@ -106,7 +106,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(g) = &arm.guard {
self.diverges.set(pats_diverge);
match g {
- hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool),
+ hir::Guard::If(e) => {
+ self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {})
+ }
};
}
@@ -442,7 +444,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: TypeVariableOriginKind::TypeInference,
span: discrim.span,
});
- self.check_expr_has_type_or_error(discrim, discrim_ty);
+ self.check_expr_has_type_or_error(discrim, discrim_ty, |_| {});
discrim_ty
}
}
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 564a0eac75539..56962d53a6450 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -1163,18 +1163,20 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
fcx.try_coerce(expression, expression_ty, self.expected_ty, AllowTwoPhase::No)
} else {
match self.expressions {
- Expressions::Dynamic(ref exprs) =>
- fcx.try_find_coercion_lub(cause,
- exprs,
- self.merged_ty(),
- expression,
- expression_ty),
- Expressions::UpFront(ref coercion_sites) =>
- fcx.try_find_coercion_lub(cause,
- &coercion_sites[0..self.pushed],
- self.merged_ty(),
- expression,
- expression_ty),
+ Expressions::Dynamic(ref exprs) => fcx.try_find_coercion_lub(
+ cause,
+ exprs,
+ self.merged_ty(),
+ expression,
+ expression_ty,
+ ),
+ Expressions::UpFront(ref coercion_sites) => fcx.try_find_coercion_lub(
+ cause,
+ &coercion_sites[0..self.pushed],
+ self.merged_ty(),
+ expression,
+ expression_ty,
+ ),
}
}
} else {
@@ -1216,7 +1218,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
self.pushed += 1;
}
}
- Err(err) => {
+ Err(coercion_error) => {
let (expected, found) = if label_expression_as_expected {
// In the case where this is a "forced unit", like
// `break`, we want to call the `()` "expected"
@@ -1232,41 +1234,42 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
(self.final_ty.unwrap_or(self.expected_ty), expression_ty)
};
- let mut db;
+ let mut err;
match cause.code {
ObligationCauseCode::ReturnNoExpression => {
- db = struct_span_err!(
+ err = struct_span_err!(
fcx.tcx.sess, cause.span, E0069,
"`return;` in a function whose return type is not `()`");
- db.span_label(cause.span, "return type is not `()`");
+ err.span_label(cause.span, "return type is not `()`");
}
ObligationCauseCode::BlockTailExpression(blk_id) => {
let parent_id = fcx.tcx.hir().get_parent_node(blk_id);
- db = self.report_return_mismatched_types(
+ err = self.report_return_mismatched_types(
cause,
expected,
found,
- err,
+ coercion_error,
fcx,
parent_id,
expression.map(|expr| (expr, blk_id)),
);
}
ObligationCauseCode::ReturnValue(id) => {
- db = self.report_return_mismatched_types(
- cause, expected, found, err, fcx, id, None);
+ err = self.report_return_mismatched_types(
+ cause, expected, found, coercion_error, fcx, id, None);
}
_ => {
- db = fcx.report_mismatched_types(cause, expected, found, err);
+ err = fcx.report_mismatched_types(cause, expected, found, coercion_error);
}
}
if let Some(augment_error) = augment_error {
- augment_error(&mut db);
+ augment_error(&mut err);
}
// Error possibly reported in `check_assign` so avoid emitting error again.
- db.emit_unless(expression.filter(|e| fcx.is_assign_to_bool(e, expected)).is_some());
+ err.emit_unless(expression.filter(|e| fcx.is_assign_to_bool(e, expected))
+ .is_some());
self.final_ty = Some(fcx.tcx.types.err);
}
@@ -1278,12 +1281,12 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
- err: TypeError<'tcx>,
+ ty_err: TypeError<'tcx>,
fcx: &FnCtxt<'a, 'tcx>,
id: hir::HirId,
expression: Option<(&'tcx hir::Expr, hir::HirId)>,
) -> DiagnosticBuilder<'a> {
- let mut db = fcx.report_mismatched_types(cause, expected, found, err);
+ let mut err = fcx.report_mismatched_types(cause, expected, found, ty_err);
let mut pointing_at_return_type = false;
let mut return_sp = None;
@@ -1294,7 +1297,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
let parent_id = fcx.tcx.hir().get_parent_node(id);
let fn_decl = if let Some((expr, blk_id)) = expression {
pointing_at_return_type = fcx.suggest_mismatched_types_on_tail(
- &mut db,
+ &mut err,
expr,
expected,
found,
@@ -1302,6 +1305,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
blk_id,
);
let parent = fcx.tcx.hir().get(parent_id);
+ if let (Some(match_expr), true, false) = (
+ fcx.tcx.hir().get_match_if_cause(expr.hir_id),
+ expected.is_unit(),
+ pointing_at_return_type,
+ ) {
+ if match_expr.span.desugaring_kind().is_none() {
+ err.span_label(match_expr.span, "expected this to be `()`");
+ fcx.suggest_semicolon_at_end(match_expr.span, &mut err);
+ }
+ }
fcx.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
} else {
fcx.get_fn_decl(parent_id)
@@ -1310,20 +1323,20 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
if let (Some((fn_decl, can_suggest)), _) = (fn_decl, pointing_at_return_type) {
if expression.is_none() {
pointing_at_return_type |= fcx.suggest_missing_return_type(
- &mut db, &fn_decl, expected, found, can_suggest);
+ &mut err, &fn_decl, expected, found, can_suggest);
}
if !pointing_at_return_type {
return_sp = Some(fn_decl.output.span()); // `impl Trait` return type
}
}
if let (Some(sp), Some(return_sp)) = (fcx.ret_coercion_span.borrow().as_ref(), return_sp) {
- db.span_label(return_sp, "expected because this return type...");
- db.span_label( *sp, format!(
+ err.span_label(return_sp, "expected because this return type...");
+ err.span_label( *sp, format!(
"...is found to be `{}` here",
fcx.resolve_type_vars_with_obligations(expected),
));
}
- db
+ err
}
pub fn complete<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Ty<'tcx> {
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 6bed321d27f82..04c8536de8dfe 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -53,14 +53,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
expr: &'tcx hir::Expr,
expected: Ty<'tcx>,
+ extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
) -> Ty<'tcx> {
- self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
+ self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected), extend_err)
}
fn check_expr_meets_expectation_or_error(
&self,
expr: &'tcx hir::Expr,
expected: Expectation<'tcx>,
+ extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
) -> Ty<'tcx> {
let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
let mut ty = self.check_expr_with_expectation(expr, expected);
@@ -88,6 +90,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ExprKind::DropTemps(expr) => expr,
_ => expr,
};
+ extend_err(&mut err);
// Error possibly reported in `check_assign` so avoid emitting error again.
err.emit_unless(self.is_assign_to_bool(expr, expected_ty));
}
@@ -971,7 +974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: TypeVariableOriginKind::MiscVariable,
span: element.span,
});
- let element_ty = self.check_expr_has_type_or_error(&element, ty);
+ let element_ty = self.check_expr_has_type_or_error(&element, ty, |_| {});
(element_ty, ty)
}
};
@@ -1058,7 +1061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// the fields with the base_expr. This could cause us to hit errors later
// when certain fields are assumed to exist that in fact do not.
if !error_happened {
- self.check_expr_has_type_or_error(base_expr, adt_ty);
+ self.check_expr_has_type_or_error(base_expr, adt_ty, |_| {});
match adt_ty.kind {
ty::Adt(adt, substs) if adt.is_struct() => {
let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a7832b8c2cf17..092ab0936c0f4 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3879,6 +3879,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
+ fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
+ err.span_suggestion_short(
+ span.shrink_to_hi(),
+ "consider using a semicolon here",
+ ";".to_string(),
+ Applicability::MachineApplicable,
+ );
+ }
+
pub fn check_stmt(&self, stmt: &'tcx hir::Stmt) {
// Don't do all the complex logic below for `DeclItem`.
match stmt.kind {
@@ -3902,7 +3911,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::StmtKind::Item(_) => {}
hir::StmtKind::Expr(ref expr) => {
// Check with expected type of `()`.
- self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
+
+ self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
+ self.suggest_semicolon_at_end(expr.span, err);
+ });
}
hir::StmtKind::Semi(ref expr) => {
self.check_expr(&expr);
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index e11dcfafb8f8b..3a07171b12fb8 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -3610,6 +3610,43 @@ match r {
```
"##,
+E0533: r##"
+An item which isn't a unit struct, a variant, nor a constant has been used as a
+match pattern.
+
+Erroneous code example:
+
+```compile_fail,E0533
+struct Tortoise;
+
+impl Tortoise {
+ fn turtle(&self) -> u32 { 0 }
+}
+
+match 0u32 {
+ Tortoise::turtle => {} // Error!
+ _ => {}
+}
+if let Tortoise::turtle = 0u32 {} // Same error!
+```
+
+If you want to match against a value returned by a method, you need to bind the
+value first:
+
+```
+struct Tortoise;
+
+impl Tortoise {
+ fn turtle(&self) -> u32 { 0 }
+}
+
+match 0u32 {
+ x if x == Tortoise.turtle() => {} // Bound into `x` then we compare it!
+ _ => {}
+}
+```
+"##,
+
E0534: r##"
The `inline` attribute was malformed.
@@ -4935,7 +4972,6 @@ and the pin is required to keep it in the same place in memory.
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with the same definition
// E0558, // replaced with a generic attribute input check
- E0533, // `{}` does not name a unit variant, unit struct or a constant
// E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
E0564, // only named lifetimes are allowed in `impl Trait`,
// but `{}` was found in the type `{}`
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f22fd5ad703d9..2fb6f197dad7c 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -974,15 +974,22 @@ impl<'a> Parser<'a> {
/// This version of parse param doesn't necessarily require identifier names.
fn parse_param_general(
&mut self,
+ is_self_allowed: bool,
is_trait_item: bool,
allow_c_variadic: bool,
is_name_required: impl Fn(&token::Token) -> bool,
) -> PResult<'a, Param> {
let lo = self.token.span;
let attrs = self.parse_outer_attributes()?;
+
+ // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
if let Some(mut param) = self.parse_self_param()? {
param.attrs = attrs.into();
- return self.recover_bad_self_param(param, is_trait_item);
+ return if is_self_allowed {
+ Ok(param)
+ } else {
+ self.recover_bad_self_param(param, is_trait_item)
+ };
}
let is_name_required = is_name_required(&self.token);
@@ -1207,6 +1214,7 @@ impl<'a> Parser<'a> {
}
};
match p.parse_param_general(
+ false,
false,
allow_c_variadic,
do_not_enforce_named_arguments_for_c_variadic
@@ -1361,60 +1369,25 @@ impl<'a> Parser<'a> {
Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident)))
}
- /// Returns the parsed optional self parameter with attributes and whether a self
- /// shortcut was used.
- fn parse_self_parameter_with_attrs(&mut self) -> PResult<'a, Option> {
- let attrs = self.parse_outer_attributes()?;
- let param_opt = self.parse_self_param()?;
- Ok(param_opt.map(|mut param| {
- param.attrs = attrs.into();
- param
- }))
- }
-
/// Parses the parameter list and result type of a function that may have a `self` parameter.
- fn parse_fn_decl_with_self(&mut self, parse_param_fn: F) -> PResult<'a, P>
- where F: FnMut(&mut Parser<'a>) -> PResult<'a, Param>,
- {
- self.expect(&token::OpenDelim(token::Paren))?;
-
- // Parse optional self argument.
- let self_param = self.parse_self_parameter_with_attrs()?;
-
- // Parse the rest of the function parameter list.
- let sep = SeqSep::trailing_allowed(token::Comma);
- let (mut fn_inputs, recovered) = if let Some(self_param) = self_param {
- if self.check(&token::CloseDelim(token::Paren)) {
- (vec![self_param], false)
- } else if self.eat(&token::Comma) {
- let mut fn_inputs = vec![self_param];
- let (mut input, _, recovered) = self.parse_seq_to_before_end(
- &token::CloseDelim(token::Paren), sep, parse_param_fn)?;
- fn_inputs.append(&mut input);
- (fn_inputs, recovered)
- } else {
- match self.expect_one_of(&[], &[]) {
- Err(err) => return Err(err),
- Ok(recovered) => (vec![self_param], recovered),
- }
- }
- } else {
- let (input, _, recovered) =
- self.parse_seq_to_before_end(&token::CloseDelim(token::Paren),
- sep,
- parse_param_fn)?;
- (input, recovered)
- };
+ fn parse_fn_decl_with_self(
+ &mut self,
+ is_name_required: impl Copy + Fn(&token::Token) -> bool,
+ ) -> PResult<'a, P> {
+ // Parse the arguments, starting out with `self` being allowed...
+ let mut is_self_allowed = true;
+ let (mut inputs, _): (Vec<_>, _) = self.parse_paren_comma_seq(|p| {
+ let res = p.parse_param_general(is_self_allowed, true, false, is_name_required);
+ // ...but now that we've parsed the first argument, `self` is no longer allowed.
+ is_self_allowed = false;
+ res
+ })?;
- if !recovered {
- // Parse closing paren and return type.
- self.expect(&token::CloseDelim(token::Paren))?;
- }
// Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
- self.deduplicate_recovered_params_names(&mut fn_inputs);
+ self.deduplicate_recovered_params_names(&mut inputs);
Ok(P(FnDecl {
- inputs: fn_inputs,
+ inputs,
output: self.parse_ret_ty(true)?,
}))
}
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index 92b19b73e5719..64c494416ff34 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -424,13 +424,7 @@ impl<'a> Parser<'a> {
} else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
let ident = self.parse_ident().unwrap();
self.bump(); // `(`
- let kw_name = if let Ok(Some(_)) = self.parse_self_parameter_with_attrs()
- .map_err(|mut e| e.cancel())
- {
- "method"
- } else {
- "function"
- };
+ let kw_name = self.recover_first_param();
self.consume_block(token::Paren);
let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
@@ -477,13 +471,7 @@ impl<'a> Parser<'a> {
self.eat_to_tokens(&[&token::Gt]);
self.bump(); // `>`
let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
- if let Ok(Some(_)) = self.parse_self_parameter_with_attrs()
- .map_err(|mut e| e.cancel())
- {
- ("fn", "method", false)
- } else {
- ("fn", "function", false)
- }
+ ("fn", self.recover_first_param(), false)
} else if self.check(&token::OpenDelim(token::Brace)) {
("struct", "struct", false)
} else {
@@ -505,6 +493,16 @@ impl<'a> Parser<'a> {
self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
}
+ fn recover_first_param(&mut self) -> &'static str {
+ match self.parse_outer_attributes()
+ .and_then(|_| self.parse_self_param())
+ .map_err(|mut e| e.cancel())
+ {
+ Ok(Some(_)) => "method",
+ _ => "function",
+ }
+ }
+
/// This is the fall-through for parsing items.
fn parse_macro_use_or_failure(
&mut self,
@@ -861,9 +859,7 @@ impl<'a> Parser<'a> {
let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;
- let decl = self.parse_fn_decl_with_self(|p| {
- p.parse_param_general(true, false, |_| true)
- })?;
+ let decl = self.parse_fn_decl_with_self(|_| true)?;
generics.where_clause = self.parse_where_clause()?;
*at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
@@ -1034,15 +1030,11 @@ impl<'a> Parser<'a> {
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;
- let decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| {
- // This is somewhat dubious; We don't want to allow
- // argument names to be left off if there is a
- // definition...
-
- // We don't allow argument names to be left off in edition 2018.
- let is_name_required = p.token.span.rust_2018();
- p.parse_param_general(true, false, |_| is_name_required)
- })?;
+ // This is somewhat dubious; We don't want to allow
+ // argument names to be left off if there is a definition...
+ //
+ // We don't allow argument names to be left off in edition 2018.
+ let decl = self.parse_fn_decl_with_self(|t| t.span.rust_2018())?;
generics.where_clause = self.parse_where_clause()?;
let sig = ast::MethodSig {
diff --git a/src/test/ui/const-generics/slice-const-param-mismatch.rs b/src/test/ui/const-generics/slice-const-param-mismatch.rs
new file mode 100644
index 0000000000000..73c75ae666805
--- /dev/null
+++ b/src/test/ui/const-generics/slice-const-param-mismatch.rs
@@ -0,0 +1,14 @@
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+struct ConstString;
+struct ConstBytes;
+
+pub fn main() {
+ let _: ConstString<"Hello"> = ConstString::<"Hello">;
+ let _: ConstString<"Hello"> = ConstString::<"World">; //~ ERROR mismatched types
+ let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↦">;
+ let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">; //~ ERROR mismatched types
+ let _: ConstBytes = ConstBytes::<{&[0x41, 0x41, 0x41]}>;
+ let _: ConstBytes = ConstBytes::; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/const-generics/slice-const-param-mismatch.stderr b/src/test/ui/const-generics/slice-const-param-mismatch.stderr
new file mode 100644
index 0000000000000..72369ab24ebfc
--- /dev/null
+++ b/src/test/ui/const-generics/slice-const-param-mismatch.stderr
@@ -0,0 +1,38 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+ --> $DIR/slice-const-param-mismatch.rs:1:12
+ |
+LL | #![feature(const_generics)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+ --> $DIR/slice-const-param-mismatch.rs:9:35
+ |
+LL | let _: ConstString<"Hello"> = ConstString::<"World">;
+ | ^^^^^^^^^^^^^^^^^^^^^^ expected `"Hello"`, found `"World"`
+ |
+ = note: expected type `ConstString<>`
+ found type `ConstString<>`
+
+error[E0308]: mismatched types
+ --> $DIR/slice-const-param-mismatch.rs:11:33
+ |
+LL | let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">;
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `"ℇ㇈↦"`, found `"ℇ㇈↥"`
+ |
+ = note: expected type `ConstString<>`
+ found type `ConstString<>`
+
+error[E0308]: mismatched types
+ --> $DIR/slice-const-param-mismatch.rs:13:33
+ |
+LL | let _: ConstBytes = ConstBytes::;
+ | ^^^^^^^^^^^^^^^^^^^^ expected `b"AAA"`, found `b"BBB"`
+ |
+ = note: expected type `ConstBytes<>`
+ found type `ConstBytes<>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/slice-const-param.rs b/src/test/ui/const-generics/slice-const-param.rs
new file mode 100644
index 0000000000000..2629caa392106
--- /dev/null
+++ b/src/test/ui/const-generics/slice-const-param.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+pub fn function_with_str() -> &'static str {
+ STRING
+}
+
+pub fn function_with_bytes() -> &'static [u8] {
+ BYTES
+}
+
+pub fn main() {
+ assert_eq!(function_with_str::<"Rust">(), "Rust");
+ assert_eq!(function_with_str::<"ℇ㇈↦">(), "ℇ㇈↦");
+ assert_eq!(function_with_bytes::(), &[0x41, 0x41, 0x41, 0x41]);
+ assert_eq!(function_with_bytes::<{&[0x41, 0x41, 0x41, 0x41]}>(), b"AAAA");
+}
diff --git a/src/test/ui/const-generics/slice-const-param.stderr b/src/test/ui/const-generics/slice-const-param.stderr
new file mode 100644
index 0000000000000..79214a34fdba0
--- /dev/null
+++ b/src/test/ui/const-generics/slice-const-param.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+ --> $DIR/slice-const-param.rs:3:12
+ |
+LL | #![feature(const_generics)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr
index b9681db87b67e..9712157552716 100644
--- a/src/test/ui/empty/empty-struct-braces-expr.stderr
+++ b/src/test/ui/empty/empty-struct-braces-expr.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected value, found struct `Empty1`
--> $DIR/empty-struct-braces-expr.rs:15:14
|
+LL | struct Empty1 {}
+ | ---------------- `Empty1` defined here
+...
LL | let e1 = Empty1;
| ^^^^^^
| |
@@ -10,6 +13,9 @@ LL | let e1 = Empty1;
error[E0423]: expected function, found struct `Empty1`
--> $DIR/empty-struct-braces-expr.rs:16:14
|
+LL | struct Empty1 {}
+ | ---------------- `Empty1` defined here
+...
LL | let e1 = Empty1();
| ^^^^^^
| |
@@ -19,12 +25,18 @@ LL | let e1 = Empty1();
error[E0423]: expected value, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:17:14
|
+LL | Empty3 {}
+ | --------- `E::Empty3` defined here
+...
LL | let e3 = E::Empty3;
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
error[E0423]: expected function, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:18:14
|
+LL | Empty3 {}
+ | --------- `E::Empty3` defined here
+...
LL | let e3 = E::Empty3();
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
diff --git a/src/test/ui/empty/empty-struct-braces-pat-1.stderr b/src/test/ui/empty/empty-struct-braces-pat-1.stderr
index 6c361c703440c..271e811a2fd65 100644
--- a/src/test/ui/empty/empty-struct-braces-pat-1.stderr
+++ b/src/test/ui/empty/empty-struct-braces-pat-1.stderr
@@ -1,6 +1,9 @@
error[E0532]: expected unit struct/variant or constant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-1.rs:24:9
|
+LL | Empty3 {}
+ | --------- `E::Empty3` defined here
+...
LL | E::Empty3 => ()
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
diff --git a/src/test/ui/empty/empty-struct-braces-pat-2.stderr b/src/test/ui/empty/empty-struct-braces-pat-2.stderr
index 12047b5880c3e..3352473788894 100644
--- a/src/test/ui/empty/empty-struct-braces-pat-2.stderr
+++ b/src/test/ui/empty/empty-struct-braces-pat-2.stderr
@@ -1,6 +1,9 @@
error[E0532]: expected tuple struct/variant, found struct `Empty1`
--> $DIR/empty-struct-braces-pat-2.rs:15:9
|
+LL | struct Empty1 {}
+ | ---------------- `Empty1` defined here
+...
LL | Empty1() => ()
| ^^^^^^
| |
@@ -19,6 +22,9 @@ LL | XEmpty1() => ()
error[E0532]: expected tuple struct/variant, found struct `Empty1`
--> $DIR/empty-struct-braces-pat-2.rs:21:9
|
+LL | struct Empty1 {}
+ | ---------------- `Empty1` defined here
+...
LL | Empty1(..) => ()
| ^^^^^^
| |
diff --git a/src/test/ui/empty/empty-struct-braces-pat-3.stderr b/src/test/ui/empty/empty-struct-braces-pat-3.stderr
index af8731b5f0596..aefdd772b1bfd 100644
--- a/src/test/ui/empty/empty-struct-braces-pat-3.stderr
+++ b/src/test/ui/empty/empty-struct-braces-pat-3.stderr
@@ -1,6 +1,9 @@
error[E0532]: expected tuple struct/variant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-3.rs:17:9
|
+LL | Empty3 {}
+ | --------- `E::Empty3` defined here
+...
LL | E::Empty3() => ()
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
@@ -16,6 +19,9 @@ LL | XE::XEmpty3() => ()
error[E0532]: expected tuple struct/variant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-3.rs:25:9
|
+LL | Empty3 {}
+ | --------- `E::Empty3` defined here
+...
LL | E::Empty3(..) => ()
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr
index 6c15e7bf282ce..4b828c0d942e3 100644
--- a/src/test/ui/empty/empty-struct-tuple-pat.stderr
+++ b/src/test/ui/empty/empty-struct-tuple-pat.stderr
@@ -19,8 +19,11 @@ LL | XEmpty6 => ()
error[E0532]: expected unit struct/variant or constant, found tuple variant `E::Empty4`
--> $DIR/empty-struct-tuple-pat.rs:29:9
|
+LL | Empty4()
+ | -------- `E::Empty4` defined here
+...
LL | E::Empty4 => ()
- | ^^^^^^^^^ did you mean `E::Empty4 ( /* fields */ )`?
+ | ^^^^^^^^^ did you mean `E::Empty4( /* fields */ )`?
error[E0532]: expected unit struct/variant or constant, found tuple variant `XE::XEmpty5`
--> $DIR/empty-struct-tuple-pat.rs:33:9
@@ -29,7 +32,7 @@ LL | XE::XEmpty5 => (),
| ^^^^-------
| | |
| | help: a unit variant with a similar name exists: `XEmpty4`
- | did you mean `XE::XEmpty5 ( /* fields */ )`?
+ | did you mean `XE::XEmpty5( /* fields */ )`?
error: aborting due to 4 previous errors
diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr
index ec240003f9182..ce631ca4bf786 100644
--- a/src/test/ui/error-codes/E0423.stderr
+++ b/src/test/ui/error-codes/E0423.stderr
@@ -27,6 +27,9 @@ LL | for _ in (std::ops::Range { start: 0, end: 10 }) {}
error[E0423]: expected function, found struct `Foo`
--> $DIR/E0423.rs:4:13
|
+LL | struct Foo { a: bool };
+ | ---------------------- `Foo` defined here
+LL |
LL | let f = Foo();
| ^^^
| |
diff --git a/src/test/ui/issues/issue-19086.stderr b/src/test/ui/issues/issue-19086.stderr
index d2b9b90890e3c..e2229cbc20922 100644
--- a/src/test/ui/issues/issue-19086.stderr
+++ b/src/test/ui/issues/issue-19086.stderr
@@ -1,6 +1,9 @@
error[E0532]: expected tuple struct/variant, found struct variant `FooB`
--> $DIR/issue-19086.rs:10:9
|
+LL | FooB { x: i32, y: i32 }
+ | ----------------------- `FooB` defined here
+...
LL | FooB(a, b) => println!("{} {}", a, b),
| ^^^^ did you mean `FooB { /* fields */ }`?
diff --git a/src/test/ui/issues/issue-32004.stderr b/src/test/ui/issues/issue-32004.stderr
index b56fa949acb7e..e9a5e217392a6 100644
--- a/src/test/ui/issues/issue-32004.stderr
+++ b/src/test/ui/issues/issue-32004.stderr
@@ -1,11 +1,14 @@
error[E0532]: expected unit struct/variant or constant, found tuple variant `Foo::Bar`
--> $DIR/issue-32004.rs:10:9
|
+LL | Bar(i32),
+ | -------- `Foo::Bar` defined here
+...
LL | Foo::Bar => {}
| ^^^^^---
| | |
| | help: a unit variant with a similar name exists: `Baz`
- | did you mean `Foo::Bar ( /* fields */ )`?
+ | did you mean `Foo::Bar( /* fields */ )`?
error[E0532]: expected tuple struct/variant, found unit struct `S`
--> $DIR/issue-32004.rs:16:9
diff --git a/src/test/ui/issues/issue-63983.stderr b/src/test/ui/issues/issue-63983.stderr
index 67acd1d57c27a..8949c475b6f72 100644
--- a/src/test/ui/issues/issue-63983.stderr
+++ b/src/test/ui/issues/issue-63983.stderr
@@ -1,12 +1,18 @@
error[E0532]: expected unit struct/variant or constant, found tuple variant `MyEnum::Tuple`
--> $DIR/issue-63983.rs:8:9
|
+LL | Tuple(i32),
+ | ---------- `MyEnum::Tuple` defined here
+...
LL | MyEnum::Tuple => "",
- | ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple ( /* fields */ )`?
+ | ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple( /* fields */ )`?
error[E0532]: expected unit struct/variant or constant, found struct variant `MyEnum::Struct`
--> $DIR/issue-63983.rs:10:9
|
+LL | Struct{ s: i32 },
+ | ---------------- `MyEnum::Struct` defined here
+...
LL | MyEnum::Struct => "",
| ^^^^^^^^^^^^^^ did you mean `MyEnum::Struct { /* fields */ }`?
diff --git a/src/test/ui/lint/lint-unused-variables.rs b/src/test/ui/lint/lint-unused-variables.rs
index 1a6b5183f0fae..6850e999242ea 100644
--- a/src/test/ui/lint/lint-unused-variables.rs
+++ b/src/test/ui/lint/lint-unused-variables.rs
@@ -29,6 +29,11 @@ impl RefStruct {
b: i32,
//~^ ERROR unused variable: `b`
) {}
+ fn issue_64682_associated_fn(
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
}
trait RefTrait {
fn bar(
@@ -37,6 +42,11 @@ trait RefTrait {
b: i32,
//~^ ERROR unused variable: `b`
) {}
+ fn issue_64682_associated_fn(
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
}
impl RefTrait for RefStruct {
fn bar(
@@ -45,6 +55,11 @@ impl RefTrait for RefStruct {
b: i32,
//~^ ERROR unused variable: `b`
) {}
+ fn issue_64682_associated_fn(
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
}
fn main() {
diff --git a/src/test/ui/lint/lint-unused-variables.stderr b/src/test/ui/lint/lint-unused-variables.stderr
index 7ed5669e33c24..f8419bf506660 100644
--- a/src/test/ui/lint/lint-unused-variables.stderr
+++ b/src/test/ui/lint/lint-unused-variables.stderr
@@ -17,19 +17,25 @@ LL | b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `a`
- --> $DIR/lint-unused-variables.rs:53:9
+ --> $DIR/lint-unused-variables.rs:68:9
|
LL | a: i32,
| ^ help: consider prefixing with an underscore: `_a`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:59:9
+ --> $DIR/lint-unused-variables.rs:74:9
|
LL | b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:37:9
+ --> $DIR/lint-unused-variables.rs:42:9
+ |
+LL | b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:47:9
|
LL | b: i32,
| ^ help: consider prefixing with an underscore: `_b`
@@ -47,10 +53,22 @@ LL | b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:45:9
+ --> $DIR/lint-unused-variables.rs:34:9
+ |
+LL | b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:55:9
+ |
+LL | b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:60:9
|
LL | b: i32,
| ^ help: consider prefixing with an underscore: `_b`
-error: aborting due to 8 previous errors
+error: aborting due to 11 previous errors
diff --git a/src/test/ui/methods/method-path-in-pattern.rs b/src/test/ui/methods/method-path-in-pattern.rs
index fb1cf7f71e70a..21a91f3f32b24 100644
--- a/src/test/ui/methods/method-path-in-pattern.rs
+++ b/src/test/ui/methods/method-path-in-pattern.rs
@@ -23,4 +23,10 @@ fn main() {
::trait_bar => {}
//~^ ERROR expected unit struct/variant or constant, found method `::trait_bar`
}
+ if let Foo::bar = 0u32 {}
+ //~^ ERROR expected unit struct/variant or constant, found method `::bar`
+ if let ::bar = 0u32 {}
+ //~^ ERROR expected unit struct/variant or constant, found method `::bar`
+ if let Foo::trait_bar = 0u32 {}
+ //~^ ERROR expected unit struct/variant or constant, found method `::trait_bar`
}
diff --git a/src/test/ui/methods/method-path-in-pattern.stderr b/src/test/ui/methods/method-path-in-pattern.stderr
index 3f53ad768825b..257fff4c37dc0 100644
--- a/src/test/ui/methods/method-path-in-pattern.stderr
+++ b/src/test/ui/methods/method-path-in-pattern.stderr
@@ -16,5 +16,24 @@ error[E0533]: expected unit struct/variant or constant, found method `::tra
LL | ::trait_bar => {}
| ^^^^^^^^^^^^^^^^
-error: aborting due to 3 previous errors
+error[E0533]: expected unit struct/variant or constant, found method `::bar`
+ --> $DIR/method-path-in-pattern.rs:26:12
+ |
+LL | if let Foo::bar = 0u32 {}
+ | ^^^^^^^^
+
+error[E0533]: expected unit struct/variant or constant, found method `::bar`
+ --> $DIR/method-path-in-pattern.rs:28:12
+ |
+LL | if let ::bar = 0u32 {}
+ | ^^^^^^^^^^
+
+error[E0533]: expected unit struct/variant or constant, found method `::trait_bar`
+ --> $DIR/method-path-in-pattern.rs:30:12
+ |
+LL | if let Foo::trait_bar = 0u32 {}
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+For more information about this error, try `rustc --explain E0533`.
diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr
index aa21928aaeff2..77da07f40d536 100644
--- a/src/test/ui/namespace/namespace-mix.stderr
+++ b/src/test/ui/namespace/namespace-mix.stderr
@@ -37,6 +37,9 @@ LL | use namespace_mix::xm2::S;
error[E0423]: expected value, found struct variant `m7::V`
--> $DIR/namespace-mix.rs:100:11
|
+LL | V {},
+ | ---- `m7::V` defined here
+...
LL | check(m7::V);
| ^^^^^ did you mean `m7::V { /* fields */ }`?
help: a tuple variant with a similar name exists
diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr
index b46d3ca9c233c..32bb88d31c4c7 100644
--- a/src/test/ui/parser/recover-from-bad-variant.stderr
+++ b/src/test/ui/parser/recover-from-bad-variant.stderr
@@ -12,6 +12,9 @@ LL | let x = Enum::Foo(a: 3, b: 4);
error[E0532]: expected tuple struct/variant, found struct variant `Enum::Foo`
--> $DIR/recover-from-bad-variant.rs:10:9
|
+LL | Foo { a: usize, b: usize },
+ | -------------------------- `Enum::Foo` defined here
+...
LL | Enum::Foo(a, b) => {}
| ^^^^^^^^^ did you mean `Enum::Foo { /* fields */ }`?
diff --git a/src/test/ui/qualified/qualified-path-params.stderr b/src/test/ui/qualified/qualified-path-params.stderr
index b8d3b744e837c..3e8fcdc7ca3e2 100644
--- a/src/test/ui/qualified/qualified-path-params.stderr
+++ b/src/test/ui/qualified/qualified-path-params.stderr
@@ -15,4 +15,5 @@ LL | 0 ..= ::A::f:: => {}
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0029`.
+Some errors have detailed explanations: E0029, E0533.
+For more information about an error, try `rustc --explain E0029`.
diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr
index 293f290f82fd9..c76e5ef8b3617 100644
--- a/src/test/ui/resolve/issue-18252.stderr
+++ b/src/test/ui/resolve/issue-18252.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected function, found struct variant `Foo::Variant`
--> $DIR/issue-18252.rs:6:13
|
+LL | Variant { x: usize }
+ | -------------------- `Foo::Variant` defined here
+...
LL | let f = Foo::Variant(42);
| ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`?
diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr
index 56a0e397b854c..4d20f1580264c 100644
--- a/src/test/ui/resolve/issue-19452.stderr
+++ b/src/test/ui/resolve/issue-19452.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected value, found struct variant `Homura::Madoka`
--> $DIR/issue-19452.rs:10:18
|
+LL | Madoka { age: u32 }
+ | ------------------- `Homura::Madoka` defined here
+...
LL | let homura = Homura::Madoka;
| ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`?
diff --git a/src/test/ui/resolve/issue-39226.stderr b/src/test/ui/resolve/issue-39226.stderr
index c97fb4db6be6b..d9a28e63dce8b 100644
--- a/src/test/ui/resolve/issue-39226.stderr
+++ b/src/test/ui/resolve/issue-39226.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected value, found struct `Handle`
--> $DIR/issue-39226.rs:11:17
|
+LL | struct Handle {}
+ | ---------------- `Handle` defined here
+...
LL | handle: Handle
| ^^^^^^
| |
diff --git a/src/test/ui/resolve/issue-6702.stderr b/src/test/ui/resolve/issue-6702.stderr
index 9a46f0d774262..3fdc7acb274e5 100644
--- a/src/test/ui/resolve/issue-6702.stderr
+++ b/src/test/ui/resolve/issue-6702.stderr
@@ -1,8 +1,13 @@
error[E0423]: expected function, found struct `Monster`
--> $DIR/issue-6702.rs:7:14
|
-LL | let _m = Monster();
- | ^^^^^^^ did you mean `Monster { /* fields */ }`?
+LL | / struct Monster {
+LL | | damage: isize
+LL | | }
+ | |_- `Monster` defined here
+...
+LL | let _m = Monster();
+ | ^^^^^^^ did you mean `Monster { /* fields */ }`?
error: aborting due to previous error
diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr
index 2538bbbf8067f..7d8d1d0abfc21 100644
--- a/src/test/ui/resolve/privacy-enum-ctor.stderr
+++ b/src/test/ui/resolve/privacy-enum-ctor.stderr
@@ -33,8 +33,13 @@ LL | m::Z::Unit;
error[E0423]: expected value, found struct variant `Z::Struct`
--> $DIR/privacy-enum-ctor.rs:29:20
|
-LL | let _: Z = Z::Struct;
- | ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`?
+LL | / Struct {
+LL | | s: u8,
+LL | | },
+ | |_____________- `Z::Struct` defined here
+...
+LL | let _: Z = Z::Struct;
+ | ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`?
error[E0423]: expected value, found enum `m::E`
--> $DIR/privacy-enum-ctor.rs:41:16
@@ -63,8 +68,13 @@ LL | use std::f64::consts::E;
error[E0423]: expected value, found struct variant `m::E::Struct`
--> $DIR/privacy-enum-ctor.rs:45:16
|
-LL | let _: E = m::E::Struct;
- | ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`?
+LL | / Struct {
+LL | | s: u8,
+LL | | },
+ | |_________- `m::E::Struct` defined here
+...
+LL | let _: E = m::E::Struct;
+ | ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`?
error[E0423]: expected value, found enum `E`
--> $DIR/privacy-enum-ctor.rs:49:16
@@ -89,8 +99,13 @@ LL | use std::f64::consts::E;
error[E0423]: expected value, found struct variant `E::Struct`
--> $DIR/privacy-enum-ctor.rs:53:16
|
-LL | let _: E = E::Struct;
- | ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`?
+LL | / Struct {
+LL | | s: u8,
+LL | | },
+ | |_________- `E::Struct` defined here
+...
+LL | let _: E = E::Struct;
+ | ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`?
error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:57:12
@@ -151,8 +166,13 @@ LL | use m::n::Z;
error[E0423]: expected value, found struct variant `m::n::Z::Struct`
--> $DIR/privacy-enum-ctor.rs:64:16
|
-LL | let _: Z = m::n::Z::Struct;
- | ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`?
+LL | / Struct {
+LL | | s: u8,
+LL | | },
+ | |_____________- `m::n::Z::Struct` defined here
+...
+LL | let _: Z = m::n::Z::Struct;
+ | ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`?
error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:68:12
diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr
index 72d62fe45ce74..979367bc623fd 100644
--- a/src/test/ui/resolve/privacy-struct-ctor.stderr
+++ b/src/test/ui/resolve/privacy-struct-ctor.stderr
@@ -16,8 +16,13 @@ LL | S;
error[E0423]: expected value, found struct `S2`
--> $DIR/privacy-struct-ctor.rs:38:5
|
-LL | S2;
- | ^^ did you mean `S2 { /* fields */ }`?
+LL | / pub struct S2 {
+LL | | s: u8
+LL | | }
+ | |_____- `S2` defined here
+...
+LL | S2;
+ | ^^ did you mean `S2 { /* fields */ }`?
error[E0423]: expected value, found struct `xcrate::S`
--> $DIR/privacy-struct-ctor.rs:43:5
diff --git a/src/test/ui/rfc-2565-param-attrs/attr-without-param.rs b/src/test/ui/rfc-2565-param-attrs/attr-without-param.rs
new file mode 100644
index 0000000000000..eeb2191bab462
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/attr-without-param.rs
@@ -0,0 +1,16 @@
+#[cfg(FALSE)]
+impl S {
+ fn f(#[attr]) {} //~ ERROR expected parameter name, found `)`
+}
+
+#[cfg(FALSE)]
+impl T for S {
+ fn f(#[attr]) {} //~ ERROR expected parameter name, found `)`
+}
+
+#[cfg(FALSE)]
+trait T {
+ fn f(#[attr]); //~ ERROR expected argument name, found `)`
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/attr-without-param.stderr b/src/test/ui/rfc-2565-param-attrs/attr-without-param.stderr
new file mode 100644
index 0000000000000..26dff4d4b30bf
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/attr-without-param.stderr
@@ -0,0 +1,20 @@
+error: expected parameter name, found `)`
+ --> $DIR/attr-without-param.rs:3:17
+ |
+LL | fn f(#[attr]) {}
+ | ^ expected parameter name
+
+error: expected parameter name, found `)`
+ --> $DIR/attr-without-param.rs:8:17
+ |
+LL | fn f(#[attr]) {}
+ | ^ expected parameter name
+
+error: expected argument name, found `)`
+ --> $DIR/attr-without-param.rs:13:17
+ |
+LL | fn f(#[attr]);
+ | ^ expected argument name
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs b/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs
index 71815e3c08974..c537c1034b5a6 100644
--- a/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs
+++ b/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs
@@ -11,7 +11,6 @@ macro_rules! checker {
($attr_name:ident, $expected:literal) => {
#[proc_macro_attribute]
pub fn $attr_name(attr: TokenStream, input: TokenStream) -> TokenStream {
- assert!(attr.to_string().is_empty());
assert_eq!(input.to_string(), $expected);
TokenStream::new()
}
@@ -28,7 +27,18 @@ checker!(attr_inherent_1, "fn inherent1(#[a1] self, #[a2] arg1: u8) { }");
checker!(attr_inherent_2, "fn inherent2(#[a1] &self, #[a2] arg1: u8) { }");
checker!(attr_inherent_3, "fn inherent3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) { }");
checker!(attr_inherent_4, "fn inherent4<'a>(#[a1] self: Box, #[a2] arg1: u8) { }");
+checker!(attr_inherent_issue_64682, "fn inherent5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8) { }");
checker!(attr_trait_1, "fn trait1(#[a1] self, #[a2] arg1: u8);");
checker!(attr_trait_2, "fn trait2(#[a1] &self, #[a2] arg1: u8);");
checker!(attr_trait_3, "fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8);");
checker!(attr_trait_4, "fn trait4<'a>(#[a1] self: Box, #[a2] arg1: u8, #[a3] Vec);");
+checker!(attr_trait_issue_64682, "fn trait5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8);");
+checker!(rename_params, r#"impl Foo {
+ fn hello(#[angery(true)] a: i32, #[a2] b: i32, #[what = "how"] c: u32) { }
+ fn hello2(#[a1] #[a2] a: i32, #[what = "how"] b: i32,
+ #[angery(true)] c: u32) {
+ }
+ fn hello_self(#[a1] #[a2] &self, #[a1] #[a2] a: i32,
+ #[what = "how"] b: i32, #[angery(true)] c: u32) {
+ }
+}"#);
diff --git a/src/test/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs b/src/test/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs
new file mode 100644
index 0000000000000..670303906d24c
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs
@@ -0,0 +1,21 @@
+// aux-build:param-attrs.rs
+
+// check-pass
+
+extern crate param_attrs;
+
+use param_attrs::rename_params;
+
+#[rename_params(send_help)]
+impl Foo {
+ fn hello(#[angery(true)] a: i32, #[a2] b: i32, #[what = "how"] c: u32) {}
+ fn hello2(#[a1] #[a2] a: i32, #[what = "how"] b: i32, #[angery(true)] c: u32) {}
+ fn hello_self(
+ #[a1] #[a2] &self,
+ #[a1] #[a2] a: i32,
+ #[what = "how"] b: i32,
+ #[angery(true)] c: u32
+ ) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
index c4684a3fa82b0..bf09171c9a12a 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
@@ -64,6 +64,21 @@ impl SelfStruct {
#[no_mangle] b: i32,
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
) {}
+
+ fn issue_64682_associated_fn(
+ /// Foo
+ //~^ ERROR documentation comments cannot be applied to function
+ #[test] a: i32,
+ //~^ ERROR expected an inert attribute, found an attribute macro
+ /// Baz
+ //~^ ERROR documentation comments cannot be applied to function
+ #[must_use]
+ //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
+ /// Qux
+ //~^ ERROR documentation comments cannot be applied to function
+ #[no_mangle] b: i32,
+ //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
+ ) {}
}
struct RefStruct {}
@@ -104,7 +119,23 @@ trait RefTrait {
#[no_mangle] b: i32,
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
) {}
+
+ fn issue_64682_associated_fn(
+ /// Foo
+ //~^ ERROR documentation comments cannot be applied to function
+ #[test] a: i32,
+ //~^ ERROR expected an inert attribute, found an attribute macro
+ /// Baz
+ //~^ ERROR documentation comments cannot be applied to function
+ #[must_use]
+ //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
+ /// Qux
+ //~^ ERROR documentation comments cannot be applied to function
+ #[no_mangle] b: i32,
+ //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
+ ) {}
}
+
impl RefTrait for RefStruct {
fn foo(
/// Foo
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
index 0fc6ca2f7f37a..4d0349e8765f0 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
@@ -23,25 +23,37 @@ LL | #[test] a: i32,
| ^^^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/param-attrs-builtin-attrs.rs:77:9
+ --> $DIR/param-attrs-builtin-attrs.rs:71:9
|
LL | #[test] a: i32,
| ^^^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/param-attrs-builtin-attrs.rs:96:9
+ --> $DIR/param-attrs-builtin-attrs.rs:92:9
|
LL | #[test] a: i32,
| ^^^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/param-attrs-builtin-attrs.rs:115:9
+ --> $DIR/param-attrs-builtin-attrs.rs:111:9
|
LL | #[test] a: i32,
| ^^^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/param-attrs-builtin-attrs.rs:132:9
+ --> $DIR/param-attrs-builtin-attrs.rs:126:9
+ |
+LL | #[test] a: i32,
+ | ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/param-attrs-builtin-attrs.rs:146:9
+ |
+LL | #[test] a: i32,
+ | ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/param-attrs-builtin-attrs.rs:163:9
|
LL | #[test] a: u32,
| ^^^^^^^
@@ -173,142 +185,202 @@ LL | #[no_mangle] b: i32,
| ^^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:72:9
+ --> $DIR/param-attrs-builtin-attrs.rs:69:9
|
LL | /// Foo
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:73:9
+ |
+LL | /// Baz
+ | ^^^^^^^ doc comments are not allowed here
+
+error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
--> $DIR/param-attrs-builtin-attrs.rs:75:9
|
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:77:9
+ |
+LL | /// Qux
+ | ^^^^^^^ doc comments are not allowed here
+
+error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:79:9
+ |
+LL | #[no_mangle] b: i32,
+ | ^^^^^^^^^^^^
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:87:9
+ |
+LL | /// Foo
+ | ^^^^^^^ doc comments are not allowed here
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:90:9
+ |
LL | /// Bar
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:79:9
+ --> $DIR/param-attrs-builtin-attrs.rs:94:9
|
LL | /// Baz
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:81:9
+ --> $DIR/param-attrs-builtin-attrs.rs:96:9
|
LL | #[must_use]
| ^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:83:9
+ --> $DIR/param-attrs-builtin-attrs.rs:98:9
|
LL | /// Qux
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:85:9
+ --> $DIR/param-attrs-builtin-attrs.rs:100:9
|
LL | #[no_mangle] b: i32,
| ^^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:91:9
+ --> $DIR/param-attrs-builtin-attrs.rs:106:9
|
LL | /// Foo
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:94:9
+ --> $DIR/param-attrs-builtin-attrs.rs:109:9
|
LL | /// Bar
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:98:9
+ --> $DIR/param-attrs-builtin-attrs.rs:113:9
|
LL | /// Baz
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:100:9
+ --> $DIR/param-attrs-builtin-attrs.rs:115:9
|
LL | #[must_use]
| ^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:102:9
+ --> $DIR/param-attrs-builtin-attrs.rs:117:9
|
LL | /// Qux
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:104:9
+ --> $DIR/param-attrs-builtin-attrs.rs:119:9
|
LL | #[no_mangle] b: i32,
| ^^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:110:9
+ --> $DIR/param-attrs-builtin-attrs.rs:124:9
|
LL | /// Foo
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:113:9
+ --> $DIR/param-attrs-builtin-attrs.rs:128:9
+ |
+LL | /// Baz
+ | ^^^^^^^ doc comments are not allowed here
+
+error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:130:9
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:132:9
+ |
+LL | /// Qux
+ | ^^^^^^^ doc comments are not allowed here
+
+error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:134:9
+ |
+LL | #[no_mangle] b: i32,
+ | ^^^^^^^^^^^^
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:141:9
+ |
+LL | /// Foo
+ | ^^^^^^^ doc comments are not allowed here
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:144:9
|
LL | /// Bar
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:117:9
+ --> $DIR/param-attrs-builtin-attrs.rs:148:9
|
LL | /// Baz
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:119:9
+ --> $DIR/param-attrs-builtin-attrs.rs:150:9
|
LL | #[must_use]
| ^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:121:9
+ --> $DIR/param-attrs-builtin-attrs.rs:152:9
|
LL | /// Qux
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:123:9
+ --> $DIR/param-attrs-builtin-attrs.rs:154:9
|
LL | #[no_mangle] b: i32,
| ^^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:130:9
+ --> $DIR/param-attrs-builtin-attrs.rs:161:9
|
LL | /// Foo
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:134:9
+ --> $DIR/param-attrs-builtin-attrs.rs:165:9
|
LL | /// Bar
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:136:9
+ --> $DIR/param-attrs-builtin-attrs.rs:167:9
|
LL | #[must_use]
| ^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:138:9
+ --> $DIR/param-attrs-builtin-attrs.rs:169:9
|
LL | /// Baz
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:140:9
+ --> $DIR/param-attrs-builtin-attrs.rs:171:9
|
LL | #[no_mangle] b: i32
| ^^^^^^^^^^^^
-error: aborting due to 52 previous errors
+error: aborting due to 64 previous errors
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
index d44ff14e99247..a4d9d32b514ac 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
@@ -51,6 +51,14 @@ impl RefStruct {
//~^ ERROR unused variable: `c`
#[cfg_attr(something, cfg(nothing))] d: i32,
) {}
+ fn issue_64682_associated_fn(
+ #[cfg(nothing)] a: i32,
+ #[cfg(something)] b: i32,
+ //~^ ERROR unused variable: `b`
+ #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ //~^ ERROR unused variable: `c`
+ #[cfg_attr(something, cfg(nothing))] d: i32,
+ ) {}
}
trait RefTrait {
fn bar(
@@ -62,6 +70,14 @@ trait RefTrait {
//~^ ERROR unused variable: `c`
#[cfg_attr(something, cfg(nothing))] d: i32,
) {}
+ fn issue_64682_associated_fn(
+ #[cfg(nothing)] a: i32,
+ #[cfg(something)] b: i32,
+ //~^ ERROR unused variable: `b`
+ #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ //~^ ERROR unused variable: `c`
+ #[cfg_attr(something, cfg(nothing))] d: i32,
+ ) {}
}
impl RefTrait for RefStruct {
fn bar(
@@ -73,6 +89,14 @@ impl RefTrait for RefStruct {
//~^ ERROR unused variable: `c`
#[cfg_attr(something, cfg(nothing))] d: i32,
) {}
+ fn issue_64682_associated_fn(
+ #[cfg(nothing)] a: i32,
+ #[cfg(something)] b: i32,
+ //~^ ERROR unused variable: `b`
+ #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ //~^ ERROR unused variable: `c`
+ #[cfg_attr(something, cfg(nothing))] d: i32,
+ ) {}
}
fn main() {
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
index 3232e2a0411a2..8d9571d09a856 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
@@ -23,31 +23,43 @@ LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: consider prefixing with an underscore: `_c`
error: unused variable: `a`
- --> $DIR/param-attrs-cfg.rs:83:27
+ --> $DIR/param-attrs-cfg.rs:107:27
|
LL | #[cfg(something)] a: i32,
| ^ help: consider prefixing with an underscore: `_a`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:89:27
+ --> $DIR/param-attrs-cfg.rs:113:27
|
LL | #[cfg(something)] b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:91:44
+ --> $DIR/param-attrs-cfg.rs:115:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: consider prefixing with an underscore: `_c`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:59:27
+ --> $DIR/param-attrs-cfg.rs:67:27
|
LL | #[cfg(something)] b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:61:44
+ --> $DIR/param-attrs-cfg.rs:69:44
+ |
+LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ | ^ help: consider prefixing with an underscore: `_c`
+
+error: unused variable: `b`
+ --> $DIR/param-attrs-cfg.rs:75:27
+ |
+LL | #[cfg(something)] b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `c`
+ --> $DIR/param-attrs-cfg.rs:77:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: consider prefixing with an underscore: `_c`
@@ -71,16 +83,40 @@ LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: consider prefixing with an underscore: `_c`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:70:27
+ --> $DIR/param-attrs-cfg.rs:56:27
+ |
+LL | #[cfg(something)] b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `c`
+ --> $DIR/param-attrs-cfg.rs:58:44
+ |
+LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ | ^ help: consider prefixing with an underscore: `_c`
+
+error: unused variable: `b`
+ --> $DIR/param-attrs-cfg.rs:86:27
+ |
+LL | #[cfg(something)] b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `c`
+ --> $DIR/param-attrs-cfg.rs:88:44
+ |
+LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ | ^ help: consider prefixing with an underscore: `_c`
+
+error: unused variable: `b`
+ --> $DIR/param-attrs-cfg.rs:94:27
|
LL | #[cfg(something)] b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:72:44
+ --> $DIR/param-attrs-cfg.rs:96:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: consider prefixing with an underscore: `_c`
-error: aborting due to 13 previous errors
+error: aborting due to 19 previous errors
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
index fb86020d992e9..1183ac65b9a7f 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
@@ -36,6 +36,9 @@ impl W {
#[attr_inherent_4]
fn inherent4<'a>(#[a1] self: Box, #[a2] arg1: u8) {}
+
+ #[attr_inherent_issue_64682]
+ fn inherent5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8) {}
}
trait A {
@@ -50,6 +53,9 @@ trait A {
#[attr_trait_4]
fn trait4<'a>(#[a1] self: Box, #[a2] arg1: u8, #[a3] Vec);
+
+ #[attr_trait_issue_64682]
+ fn trait5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8);
}
fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
index e2680446f851a..be9085d5878cb 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
@@ -38,6 +38,9 @@ impl W {
fn inherent4<'a>(#[id] self: Box, #[id] arg1: u8) {}
//~^ ERROR expected an inert attribute, found an attribute macro
//~| ERROR expected an inert attribute, found an attribute macro
+ fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
+ //~^ ERROR expected an inert attribute, found an attribute macro
+ //~| ERROR expected an inert attribute, found an attribute macro
}
trait A {
@@ -54,6 +57,9 @@ trait A {
//~^ ERROR expected an inert attribute, found an attribute macro
//~| ERROR expected an inert attribute, found an attribute macro
//~| ERROR expected an inert attribute, found an attribute macro
+ fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
+ //~^ ERROR expected an inert attribute, found an attribute macro
+ //~| ERROR expected an inert attribute, found an attribute macro
}
fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
index 4654dc1b496f2..1cc3c3d82281b 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
@@ -95,58 +95,82 @@ LL | fn inherent4<'a>(#[id] self: Box, #[id] arg1: u8) {}
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:44:15
+ --> $DIR/proc-macro-cannot-be-used.rs:41:38
+ |
+LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
+ | ^^^^^
+
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/proc-macro-cannot-be-used.rs:41:54
+ |
+LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
+ | ^^^^^
+
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/proc-macro-cannot-be-used.rs:47:15
|
LL | fn trait1(#[id] self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:44:27
+ --> $DIR/proc-macro-cannot-be-used.rs:47:27
|
LL | fn trait1(#[id] self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:47:15
+ --> $DIR/proc-macro-cannot-be-used.rs:50:15
|
LL | fn trait2(#[id] &self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:47:28
+ --> $DIR/proc-macro-cannot-be-used.rs:50:28
|
LL | fn trait2(#[id] &self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:50:19
+ --> $DIR/proc-macro-cannot-be-used.rs:53:19
|
LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:50:39
+ --> $DIR/proc-macro-cannot-be-used.rs:53:39
|
LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:53:19
+ --> $DIR/proc-macro-cannot-be-used.rs:56:19
|
LL | fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:53:42
+ --> $DIR/proc-macro-cannot-be-used.rs:56:42
|
LL | fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:53:58
+ --> $DIR/proc-macro-cannot-be-used.rs:56:58
|
LL | fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec);
| ^^^^^
-error: aborting due to 25 previous errors
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/proc-macro-cannot-be-used.rs:60:38
+ |
+LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
+ | ^^^^^
+
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/proc-macro-cannot-be-used.rs:60:54
+ |
+LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
+ | ^^^^^
+
+error: aborting due to 29 previous errors
diff --git a/src/test/ui/struct-literal-variant-in-if.stderr b/src/test/ui/struct-literal-variant-in-if.stderr
index 85cbc787bc2db..a52ec6dc53938 100644
--- a/src/test/ui/struct-literal-variant-in-if.stderr
+++ b/src/test/ui/struct-literal-variant-in-if.stderr
@@ -50,7 +50,10 @@ error[E0308]: mismatched types
--> $DIR/struct-literal-variant-in-if.rs:10:20
|
LL | if x == E::V { field } {}
- | ^^^^^ expected (), found bool
+ | ---------------^^^^^--- help: consider using a semicolon here
+ | | |
+ | | expected (), found bool
+ | expected this to be `()`
|
= note: expected type `()`
found type `bool`
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
index 28b331bdbdcbc..1af0f7a191e80 100644
--- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
+++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected value, found struct variant `E::B`
--> $DIR/fn-or-tuple-struct-without-args.rs:36:16
|
+LL | B { a: usize },
+ | -------------- `E::B` defined here
+...
LL | let _: E = E::B;
| ^^^-
| | |
diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr
index 6d7d98ac6a16b..fbcfba6653f27 100644
--- a/src/test/ui/suggestions/issue-61226.stderr
+++ b/src/test/ui/suggestions/issue-61226.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected value, found struct `X`
--> $DIR/issue-61226.rs:3:10
|
+LL | struct X {}
+ | ----------- `X` defined here
+LL | fn main() {
LL | vec![X]; //…
| ^ did you mean `X { /* fields */ }`?
diff --git a/src/test/ui/suggestions/match-needing-semi.fixed b/src/test/ui/suggestions/match-needing-semi.fixed
new file mode 100644
index 0000000000000..03cbed1376ea3
--- /dev/null
+++ b/src/test/ui/suggestions/match-needing-semi.fixed
@@ -0,0 +1,18 @@
+// check-only
+// run-rustfix
+
+fn main() {
+ match 3 {
+ 4 => 1,
+ 3 => {
+ 2 //~ ERROR mismatched types
+ }
+ _ => 2
+ };
+ match 3 { //~ ERROR mismatched types
+ 4 => 1,
+ 3 => 2,
+ _ => 2
+ };
+ let _ = ();
+}
diff --git a/src/test/ui/suggestions/match-needing-semi.rs b/src/test/ui/suggestions/match-needing-semi.rs
new file mode 100644
index 0000000000000..f34071ac75886
--- /dev/null
+++ b/src/test/ui/suggestions/match-needing-semi.rs
@@ -0,0 +1,18 @@
+// check-only
+// run-rustfix
+
+fn main() {
+ match 3 {
+ 4 => 1,
+ 3 => {
+ 2 //~ ERROR mismatched types
+ }
+ _ => 2
+ }
+ match 3 { //~ ERROR mismatched types
+ 4 => 1,
+ 3 => 2,
+ _ => 2
+ }
+ let _ = ();
+}
diff --git a/src/test/ui/suggestions/match-needing-semi.stderr b/src/test/ui/suggestions/match-needing-semi.stderr
new file mode 100644
index 0000000000000..988945817c2ee
--- /dev/null
+++ b/src/test/ui/suggestions/match-needing-semi.stderr
@@ -0,0 +1,36 @@
+error[E0308]: mismatched types
+ --> $DIR/match-needing-semi.rs:8:13
+ |
+LL | / match 3 {
+LL | | 4 => 1,
+LL | | 3 => {
+LL | | 2
+ | | ^ expected (), found integer
+LL | | }
+LL | | _ => 2
+LL | | }
+ | | -- help: consider using a semicolon here
+ | |_____|
+ | expected this to be `()`
+ |
+ = note: expected type `()`
+ found type `{integer}`
+
+error[E0308]: mismatched types
+ --> $DIR/match-needing-semi.rs:12:5
+ |
+LL | / match 3 {
+LL | | 4 => 1,
+LL | | 3 => 2,
+LL | | _ => 2
+LL | | }
+ | | ^- help: consider using a semicolon here
+ | |_____|
+ | expected (), found integer
+ |
+ = note: expected type `()`
+ found type `{integer}`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
index 128a85e15634c..357b33de51b84 100644
--- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
@@ -6,3 +6,4 @@ LL | Self::A => (),
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0533`.
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
index c1ea816b7facf..c6528e417d8ae 100644
--- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
@@ -39,5 +39,5 @@ LL | let Alias::Unit() = panic!();
error: aborting due to 5 previous errors
-Some errors have detailed explanations: E0164, E0618.
+Some errors have detailed explanations: E0164, E0533, E0618.
For more information about an error, try `rustc --explain E0164`.