From cb9852b8e60b956421cbb6363a75d970d64372cc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 28 Feb 2023 17:29:40 +0000 Subject: [PATCH 1/6] Erase **all** regions when probing for associated types in astconv --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 6 ++++-- tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.rs | 8 ++++++++ .../ui/suggestions/suggest-trait-in-ufcs-in-hrtb.stderr | 9 +++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.rs create mode 100644 tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.stderr diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index a15cf454df72f..7d6213dfc286c 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2403,8 +2403,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { infcx .can_eq( ty::ParamEnv::empty(), - tcx.erase_regions(impl_.self_ty()), - tcx.erase_regions(qself_ty), + impl_.self_ty(), + // Must fold past escaping bound vars too, + // since we have those at this point in astconv. + tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased), ) }) && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative diff --git a/tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.rs b/tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.rs new file mode 100644 index 0000000000000..fbaf41245e9b6 --- /dev/null +++ b/tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.rs @@ -0,0 +1,8 @@ +pub struct Bar(S); + +pub trait Foo {} + +impl Foo for Bar where for<'a> <&'a S>::Item: Foo {} +//~^ ERROR ambiguous associated type + +fn main() {} diff --git a/tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.stderr b/tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.stderr new file mode 100644 index 0000000000000..0ca5b9b920790 --- /dev/null +++ b/tests/ui/suggestions/suggest-trait-in-ufcs-in-hrtb.stderr @@ -0,0 +1,9 @@ +error[E0223]: ambiguous associated type + --> $DIR/suggest-trait-in-ufcs-in-hrtb.rs:5:38 + | +LL | impl Foo for Bar where for<'a> <&'a S>::Item: Foo {} + | ^^^^^^^^^^^^^ help: use the fully-qualified path: `<&'a S as IntoIterator>::Item` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0223`. From 94a200b6a987511082b1a1502137a1956b69f0ce Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 28 Feb 2023 08:12:09 +0000 Subject: [PATCH 2/6] Fix #104367, add test case for mismatched open/close delims --- tests/ui/parser/issues/issue-104367.rs | 6 +++++ tests/ui/parser/issues/issue-104367.stderr | 26 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/ui/parser/issues/issue-104367.rs create mode 100644 tests/ui/parser/issues/issue-104367.stderr diff --git a/tests/ui/parser/issues/issue-104367.rs b/tests/ui/parser/issues/issue-104367.rs new file mode 100644 index 0000000000000..861761b64f4f4 --- /dev/null +++ b/tests/ui/parser/issues/issue-104367.rs @@ -0,0 +1,6 @@ +#[derive(A)] +struct S { + d: [u32; { + #![cfg] { + #![w,) //~ ERROR mismatched closing delimiter + //~ ERROR this file contains an unclosed delimiter diff --git a/tests/ui/parser/issues/issue-104367.stderr b/tests/ui/parser/issues/issue-104367.stderr new file mode 100644 index 0000000000000..e6e76535761fb --- /dev/null +++ b/tests/ui/parser/issues/issue-104367.stderr @@ -0,0 +1,26 @@ +error: mismatched closing delimiter: `)` + --> $DIR/issue-104367.rs:5:15 + | +LL | #![w,) + | ^ ^ mismatched closing delimiter + | | + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-104367.rs:6:71 + | +LL | struct S { + | - unclosed delimiter +LL | d: [u32; { + | - - unclosed delimiter + | | + | unclosed delimiter +LL | #![cfg] { + | - unclosed delimiter +LL | #![w,) + | - missing open `(` for this delimiter +LL | + | ^ + +error: aborting due to 2 previous errors + From a641229916d32e36670e36e8abdf4426baea83e8 Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 1 Mar 2023 13:28:12 +0000 Subject: [PATCH 3/6] Add testcase for issue 105209 --- tests/ui/parser/issues/issue-105209.rs | 3 +++ tests/ui/parser/issues/issue-105209.stderr | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 tests/ui/parser/issues/issue-105209.rs create mode 100644 tests/ui/parser/issues/issue-105209.stderr diff --git a/tests/ui/parser/issues/issue-105209.rs b/tests/ui/parser/issues/issue-105209.rs new file mode 100644 index 0000000000000..6146b795de19a --- /dev/null +++ b/tests/ui/parser/issues/issue-105209.rs @@ -0,0 +1,3 @@ +// compile-flags: -Zunpretty=ast-tree +#![c={#![c[)x //~ ERROR mismatched closing delimiter + //~ ERROR this file contains an unclosed delimiter diff --git a/tests/ui/parser/issues/issue-105209.stderr b/tests/ui/parser/issues/issue-105209.stderr new file mode 100644 index 0000000000000..c75eafa18335e --- /dev/null +++ b/tests/ui/parser/issues/issue-105209.stderr @@ -0,0 +1,22 @@ +error: mismatched closing delimiter: `)` + --> $DIR/issue-105209.rs:2:11 + | +LL | #![c={#![c[)x + | ^^ mismatched closing delimiter + | | + | unclosed delimiter + +error: this file contains an unclosed delimiter + --> $DIR/issue-105209.rs:3:68 + | +LL | #![c={#![c[)x + | - - - - missing open `(` for this delimiter + | | | | + | | | unclosed delimiter + | | unclosed delimiter + | unclosed delimiter +LL | + | ^ + +error: aborting due to 2 previous errors + From 6c2a952b5637f4795ad1d3ed08dfa4f43eaece51 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Wed, 1 Mar 2023 14:32:46 +0000 Subject: [PATCH 4/6] Highlight whole expression for E0599 --- compiler/rustc_hir_typeck/src/method/suggest.rs | 3 +++ src/tools/compiletest/src/runtest.rs | 13 +++++++------ tests/ui/methods/method-call-err-msg.stderr | 17 ++++++++++------- tests/ui/typeck/issue-31173.stderr | 13 +++++++++++-- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 47a4d4e72dffd..60d56263d2e38 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -333,6 +333,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_ty.prefix_string(self.tcx), ty_str_reported, ); + if tcx.sess.source_map().is_multiline(sugg_span) { + err.span_label(sugg_span.with_hi(span.lo()), ""); + } let ty_str = if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 { short_ty_str } else { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 7824ef81d7a93..41c23ff86b25e 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1432,12 +1432,13 @@ impl<'test> TestCx<'test> { expect_help: bool, expect_note: bool, ) -> bool { - match actual_error.kind { - Some(ErrorKind::Help) => expect_help, - Some(ErrorKind::Note) => expect_note, - Some(ErrorKind::Error) | Some(ErrorKind::Warning) => true, - Some(ErrorKind::Suggestion) | None => false, - } + !actual_error.msg.is_empty() + && match actual_error.kind { + Some(ErrorKind::Help) => expect_help, + Some(ErrorKind::Note) => expect_note, + Some(ErrorKind::Error) | Some(ErrorKind::Warning) => true, + Some(ErrorKind::Suggestion) | None => false, + } } fn should_emit_metadata(&self, pm: Option) -> Emit { diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr index c340c2d32b319..bd51378cf1a50 100644 --- a/tests/ui/methods/method-call-err-msg.stderr +++ b/tests/ui/methods/method-call-err-msg.stderr @@ -48,14 +48,17 @@ LL | .two(0, /* isize */); error[E0599]: `Foo` is not an iterator --> $DIR/method-call-err-msg.rs:19:7 | -LL | pub struct Foo; - | -------------- - | | - | method `take` not found for this struct - | doesn't satisfy `Foo: Iterator` +LL | pub struct Foo; + | -------------- + | | + | method `take` not found for this struct + | doesn't satisfy `Foo: Iterator` ... -LL | .take() - | ^^^^ `Foo` is not an iterator +LL | / y.zero() +LL | | .take() + | | -^^^^ `Foo` is not an iterator + | |______| + | | = note: the following trait bounds were not satisfied: `Foo: Iterator` diff --git a/tests/ui/typeck/issue-31173.stderr b/tests/ui/typeck/issue-31173.stderr index 8346c9a0aaecc..b622122f33ea7 100644 --- a/tests/ui/typeck/issue-31173.stderr +++ b/tests/ui/typeck/issue-31173.stderr @@ -24,8 +24,17 @@ note: required by a bound in `cloned` error[E0599]: the method `collect` exists for struct `Cloned, [closure@issue-31173.rs:7:21]>>`, but its trait bounds were not satisfied --> $DIR/issue-31173.rs:12:10 | -LL | .collect(); - | ^^^^^^^ method cannot be called due to unsatisfied trait bounds +LL | let temp: Vec = it + | _________________________- +LL | | .take_while(|&x| { +LL | | found_e = true; +LL | | false +LL | | }) +LL | | .cloned() +LL | | .collect(); + | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds + | |_________| + | --> $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL | = note: doesn't satisfy `<_ as Iterator>::Item = &_` From c9f1a541b36772800482c0b9de198caa1d6d6b2e Mon Sep 17 00:00:00 2001 From: David Koloski Date: Tue, 28 Feb 2023 18:04:27 -0500 Subject: [PATCH 5/6] Run compiler test suite in parallel on Fuchsia --- src/ci/docker/scripts/fuchsia-test-runner.py | 39 ++++++++++++------- src/doc/rustc/src/platform-support/fuchsia.md | 7 +--- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py index c3d532c4b27a3..e7d1d9781d5c4 100755 --- a/src/ci/docker/scripts/fuchsia-test-runner.py +++ b/src/ci/docker/scripts/fuchsia-test-runner.py @@ -9,6 +9,7 @@ import argparse from dataclasses import dataclass +import fcntl import glob import hashlib import json @@ -146,6 +147,9 @@ def host_arch_triple(self): def zxdb_script_path(self): return os.path.join(self.tmp_dir(), "zxdb_script") + def pm_lockfile_path(self): + return os.path.join(self.tmp_dir(), "pm.lock") + def log_info(self, msg): print(msg) @@ -460,6 +464,9 @@ def start(self): stderr=self.subprocess_output(), ) + # Create lockfiles + open(self.pm_lockfile_path(), 'a').close() + # Write to file self.write_to_file() @@ -676,19 +683,25 @@ def log(msg): log("Publishing package to repo...") # Publish package to repo - subprocess.check_call( - [ - self.tool_path("pm"), - "publish", - "-a", - "-repo", - self.repo_dir(), - "-f", - far_path, - ], - stdout=log_file, - stderr=log_file, - ) + with open(self.pm_lockfile_path(), 'w') as pm_lockfile: + fcntl.lockf(pm_lockfile.fileno(), fcntl.LOCK_EX) + subprocess.check_call( + [ + self.tool_path("pm"), + "publish", + "-a", + "-repo", + self.repo_dir(), + "-f", + far_path, + ], + stdout=log_file, + stderr=log_file, + ) + # This lock should be released automatically when the pm + # lockfile is closed, but we'll be polite and unlock it now + # since the spec leaves some wiggle room. + fcntl.lockf(pm_lockfile.fileno(), fcntl.LOCK_UN) log("Running ffx test...") diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index 63dde2aaedd64..2b244375f4015 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -717,7 +717,7 @@ run the full `tests/ui` test suite: --stage=2 \ test tests/ui \ --target x86_64-unknown-fuchsia \ - --run=always --jobs 1 \ + --run=always \ --test-args --target-rustcflags \ --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \ --test-args --target-rustcflags \ @@ -729,9 +729,6 @@ run the full `tests/ui` test suite: ) ``` -*Note: The test suite cannot be run in parallel at the moment, so `x.py` -must be run with `--jobs 1` to ensure only one test runs at a time.* - By default, `x.py` compiles test binaries with `panic=unwind`. If you built your Rust toolchain with `-Cpanic=abort`, you need to tell `x.py` to compile test binaries with `panic=abort` as well: @@ -908,7 +905,7 @@ through our `x.py` invocation. The full invocation is: --stage=2 \ test tests/${TEST} \ --target x86_64-unknown-fuchsia \ - --run=always --jobs 1 \ + --run=always \ --test-args --target-rustcflags \ --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \ --test-args --target-rustcflags \ From d84576955713d223c0c4752dab9111085033c78b Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 27 Feb 2023 01:32:07 +0000 Subject: [PATCH 6/6] Restrict `#[rustc_box]` to `Box::new` calls --- compiler/rustc_ast_lowering/locales/en-US.ftl | 3 -- compiler/rustc_ast_lowering/src/errors.rs | 7 ---- compiler/rustc_ast_lowering/src/expr.rs | 12 ++----- compiler/rustc_mir_build/locales/en-US.ftl | 6 ++++ compiler/rustc_mir_build/src/errors.rs | 19 +++++++++++ compiler/rustc_mir_build/src/thir/cx/expr.rs | 32 ++++++++++++++++- src/tools/clippy/clippy_utils/src/higher.rs | 13 +++---- tests/ui/attributes/rustc-box.rs | 18 ++++++++++ tests/ui/attributes/rustc-box.stderr | 34 +++++++++++++++++++ 9 files changed, 115 insertions(+), 29 deletions(-) create mode 100644 tests/ui/attributes/rustc-box.rs create mode 100644 tests/ui/attributes/rustc-box.stderr diff --git a/compiler/rustc_ast_lowering/locales/en-US.ftl b/compiler/rustc_ast_lowering/locales/en-US.ftl index a2837deafdec4..3ccd84398ec27 100644 --- a/compiler/rustc_ast_lowering/locales/en-US.ftl +++ b/compiler/rustc_ast_lowering/locales/en-US.ftl @@ -22,9 +22,6 @@ ast_lowering_misplaced_impl_trait = ast_lowering_misplaced_assoc_ty_binding = associated type bounds are only allowed in where clauses and function signatures, not in {$position} -ast_lowering_rustc_box_attribute_error = - #[rustc_box] requires precisely one argument and no other attributes are allowed - ast_lowering_underscore_expr_lhs_assign = in expressions, `_` can only be used on the left-hand side of an assignment .label = `_` not allowed here diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index def74c2adeee9..5e6b6050bc0ea 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -87,13 +87,6 @@ pub struct MisplacedAssocTyBinding<'a> { pub position: DiagnosticArgFromDisplay<'a>, } -#[derive(Diagnostic, Clone, Copy)] -#[diag(ast_lowering_rustc_box_attribute_error)] -pub struct RustcBoxAttributeError { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic, Clone, Copy)] #[diag(ast_lowering_underscore_expr_lhs_assign)] pub struct UnderscoreExprLhsAssign { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index d4fafe38638a4..ffb30b1b39127 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -2,7 +2,7 @@ use super::errors::{ AsyncGeneratorsNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks, BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignemnt, GeneratorTooManyParameters, InclusiveRangeWithNoEnd, NotSupportedForLifetimeBinderAsyncClosure, - RustcBoxAttributeError, UnderscoreExprLhsAssign, + UnderscoreExprLhsAssign, }; use super::ResolverAstLoweringExt; use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs}; @@ -83,15 +83,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)), ExprKind::Call(f, args) => { - if e.attrs.get(0).map_or(false, |a| a.has_name(sym::rustc_box)) { - if let [inner] = &args[..] && e.attrs.len() == 1 { - let kind = hir::ExprKind::Box(self.lower_expr(&inner)); - return hir::Expr { hir_id, kind, span: self.lower_span(e.span) }; - } else { - let guar = self.tcx.sess.emit_err(RustcBoxAttributeError { span: e.span }); - hir::ExprKind::Err(guar) - } - } else if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) { + if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) { self.lower_legacy_const_generics((**f).clone(), args.clone(), &legacy_args) } else { let f = self.lower_expr(f); diff --git a/compiler/rustc_mir_build/locales/en-US.ftl b/compiler/rustc_mir_build/locales/en-US.ftl index f9bda721df34d..93e7fb330e093 100644 --- a/compiler/rustc_mir_build/locales/en-US.ftl +++ b/compiler/rustc_mir_build/locales/en-US.ftl @@ -374,3 +374,9 @@ mir_build_suggest_let_else = you might want to use `let else` to handle the {$co } matched mir_build_suggest_attempted_int_lit = alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits + + +mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly + .attributes = no other attributes may be applied + .not_box = `#[rustc_box]` may only be applied to a `Box::new()` call + .missing_box = `#[rustc_box]` requires the `owned_box` lang item diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index c1f6b8b59ce59..dc4d2276e4aab 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -888,3 +888,22 @@ pub enum MiscPatternSuggestion { start_span: Span, }, } + +#[derive(Diagnostic)] +#[diag(mir_build_rustc_box_attribute_error)] +pub struct RustcBoxAttributeError { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub reason: RustcBoxAttrReason, +} + +#[derive(Subdiagnostic)] +pub enum RustcBoxAttrReason { + #[note(mir_build_attributes)] + Attributes, + #[note(mir_build_not_box)] + NotBoxNew, + #[note(mir_build_missing_box)] + MissingBox, +} diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index ae203233bd568..f3fa0c37be985 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -1,3 +1,4 @@ +use crate::errors; use crate::thir::cx::region::Scope; use crate::thir::cx::Cx; use crate::thir::util::UserAnnotatedTyHelpers; @@ -18,7 +19,7 @@ use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{ self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType, }; -use rustc_span::Span; +use rustc_span::{sym, Span}; use rustc_target::abi::VariantIdx; impl<'tcx> Cx<'tcx> { @@ -262,6 +263,7 @@ impl<'tcx> Cx<'tcx> { } } + #[instrument(level = "debug", skip(self), ret)] fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> { let tcx = self.tcx; let expr_ty = self.typeck_results().expr_ty(expr); @@ -322,6 +324,34 @@ impl<'tcx> Cx<'tcx> { fn_span: expr.span, } } else { + let attrs = tcx.hir().attrs(expr.hir_id); + if attrs.iter().any(|a| a.name_or_empty() == sym::rustc_box) { + if attrs.len() != 1 { + tcx.sess.emit_err(errors::RustcBoxAttributeError { + span: attrs[0].span, + reason: errors::RustcBoxAttrReason::Attributes, + }); + } else if let Some(box_item) = tcx.lang_items().owned_box() { + if let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, fn_path)) = fun.kind + && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind + && path.res.opt_def_id().map_or(false, |did| did == box_item) + && fn_path.ident.name == sym::new + && let [value] = args + { + return Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind: ExprKind::Box { value: self.mirror_expr(value) } } + } else { + tcx.sess.emit_err(errors::RustcBoxAttributeError { + span: expr.span, + reason: errors::RustcBoxAttrReason::NotBoxNew + }); + } + } else { + tcx.sess.emit_err(errors::RustcBoxAttributeError { + span: attrs[0].span, + reason: errors::RustcBoxAttrReason::MissingBox, + }); + } + } let adt_data = if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = fun.kind { // Tuple-like ADTs are represented as ExprKind::Call. We convert them here. diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs index 4604ae5c2c7f0..50bef3709309d 100644 --- a/src/tools/clippy/clippy_utils/src/higher.rs +++ b/src/tools/clippy/clippy_utils/src/higher.rs @@ -287,15 +287,12 @@ impl<'a> VecArgs<'a> { Some(VecArgs::Repeat(&args[0], &args[1])) } else if match_def_path(cx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 { // `vec![a, b, c]` case - if_chain! { - if let hir::ExprKind::Box(boxed) = args[0].kind; - if let hir::ExprKind::Array(args) = boxed.kind; - then { - return Some(VecArgs::Vec(args)); - } + if let hir::ExprKind::Call(_, [arg]) = &args[0].kind + && let hir::ExprKind::Array(args) = arg.kind { + Some(VecArgs::Vec(args)) + } else { + None } - - None } else if match_def_path(cx, fun_def_id, &paths::VEC_NEW) && args.is_empty() { Some(VecArgs::Vec(&[])) } else { diff --git a/tests/ui/attributes/rustc-box.rs b/tests/ui/attributes/rustc-box.rs new file mode 100644 index 0000000000000..b3726fb38671b --- /dev/null +++ b/tests/ui/attributes/rustc-box.rs @@ -0,0 +1,18 @@ +#![feature(rustc_attrs, stmt_expr_attributes)] + +fn foo(_: u32, _: u32) {} +fn bar(_: u32) {} + +fn main() { + #[rustc_box] + Box::new(1); // OK + #[rustc_box] + Box::pin(1); //~ ERROR `#[rustc_box]` attribute used incorrectly + #[rustc_box] + foo(1, 1); //~ ERROR `#[rustc_box]` attribute used incorrectly + #[rustc_box] + bar(1); //~ ERROR `#[rustc_box]` attribute used incorrectly + #[rustc_box] //~ ERROR `#[rustc_box]` attribute used incorrectly + #[rustfmt::skip] + Box::new(1); +} diff --git a/tests/ui/attributes/rustc-box.stderr b/tests/ui/attributes/rustc-box.stderr new file mode 100644 index 0000000000000..073a18c7d58ec --- /dev/null +++ b/tests/ui/attributes/rustc-box.stderr @@ -0,0 +1,34 @@ +error: `#[rustc_box]` attribute used incorrectly + --> $DIR/rustc-box.rs:10:5 + | +LL | Box::pin(1); + | ^^^^^^^^^^^ + | + = note: `#[rustc_box]` may only be applied to a `Box::new()` call + +error: `#[rustc_box]` attribute used incorrectly + --> $DIR/rustc-box.rs:12:5 + | +LL | foo(1, 1); + | ^^^^^^^^^ + | + = note: `#[rustc_box]` may only be applied to a `Box::new()` call + +error: `#[rustc_box]` attribute used incorrectly + --> $DIR/rustc-box.rs:14:5 + | +LL | bar(1); + | ^^^^^^ + | + = note: `#[rustc_box]` may only be applied to a `Box::new()` call + +error: `#[rustc_box]` attribute used incorrectly + --> $DIR/rustc-box.rs:15:5 + | +LL | #[rustc_box] + | ^^^^^^^^^^^^ + | + = note: no other attributes may be applied + +error: aborting due to 4 previous errors +