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`.