diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 90d31d4801f92..024d9687f3119 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -28,7 +28,7 @@ pub trait ExpectOne { impl ExpectOne for SmallVec { fn expect_one(self, err: &'static str) -> A::Item { - assert!(self.len() == 1, err); + assert!(self.len() == 1, "{}", err); self.into_iter().next().unwrap() } } diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 36d261fb737ce..5880bbd3de44e 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -13,6 +13,7 @@ #![feature(unboxed_closures)] #![feature(generator_trait)] #![feature(fn_traits)] +#![feature(int_bits_const)] #![feature(min_specialization)] #![feature(auto_traits)] #![feature(nll)] diff --git a/compiler/rustc_error_codes/src/error_codes/E0463.md b/compiler/rustc_error_codes/src/error_codes/E0463.md index e46938c607d34..d0cd1b1dcb75b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0463.md +++ b/compiler/rustc_error_codes/src/error_codes/E0463.md @@ -11,3 +11,24 @@ extern crate cake_is_a_lie; // error: can't find crate for `cake_is_a_lie` You need to link your code to the relevant crate in order to be able to use it (through Cargo or the `-L` option of rustc example). Plugins are crates as well, and you link to them the same way. + +## Common causes + +- The crate is not present at all. If using Cargo, add it to `[dependencies]` + in Cargo.toml. +- The crate is present, but under a different name. If using Cargo, look for + `package = ` under `[dependencies]` in Cargo.toml. + +## Common causes for missing `std` or `core` + +- You are cross-compiling for a target which doesn't have `std` prepackaged. + Consider one of the following: + + Adding a pre-compiled version of std with `rustup target add` + + Building std from source with `cargo build -Z build-std` + + Using `#![no_std]` at the crate root, so you won't need `std` in the first + place. +- You are developing the compiler itself and haven't built libstd from source. + You can usually build it with `x.py build library/std`. More information + about x.py is available in the [rustc-dev-guide]. + +[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#building-the-compiler diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index e184e929b0745..aa88233209940 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -901,7 +901,7 @@ impl HandlerInner { fn span_bug(&mut self, sp: impl Into, msg: &str) -> ! { self.emit_diag_at_span(Diagnostic::new(Bug, msg), sp); - panic!(ExplicitBug); + panic::panic_any(ExplicitBug); } fn emit_diag_at_span(&mut self, mut diag: Diagnostic, sp: impl Into) { @@ -955,7 +955,7 @@ impl HandlerInner { fn bug(&mut self, msg: &str) -> ! { self.emit_diagnostic(&Diagnostic::new(Bug, msg)); - panic!(ExplicitBug); + panic::panic_any(ExplicitBug); } fn delay_as_bug(&mut self, diagnostic: Diagnostic) { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 1c16dc026670b..58bcd37478a73 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2057,6 +2057,28 @@ pub enum PrimTy { } impl PrimTy { + /// All of the primitive types + pub const ALL: [Self; 17] = [ + // any changes here should also be reflected in `PrimTy::from_name` + Self::Int(IntTy::I8), + Self::Int(IntTy::I16), + Self::Int(IntTy::I32), + Self::Int(IntTy::I64), + Self::Int(IntTy::I128), + Self::Int(IntTy::Isize), + Self::Uint(UintTy::U8), + Self::Uint(UintTy::U16), + Self::Uint(UintTy::U32), + Self::Uint(UintTy::U64), + Self::Uint(UintTy::U128), + Self::Uint(UintTy::Usize), + Self::Float(FloatTy::F32), + Self::Float(FloatTy::F64), + Self::Bool, + Self::Char, + Self::Str, + ]; + pub fn name_str(self) -> &'static str { match self { PrimTy::Int(i) => i.name_str(), @@ -2078,6 +2100,33 @@ impl PrimTy { PrimTy::Char => sym::char, } } + + /// Returns the matching `PrimTy` for a `Symbol` such as "str" or "i32". + /// Returns `None` if no matching type is found. + pub fn from_name(name: Symbol) -> Option { + let ty = match name { + // any changes here should also be reflected in `PrimTy::ALL` + sym::i8 => Self::Int(IntTy::I8), + sym::i16 => Self::Int(IntTy::I16), + sym::i32 => Self::Int(IntTy::I32), + sym::i64 => Self::Int(IntTy::I64), + sym::i128 => Self::Int(IntTy::I128), + sym::isize => Self::Int(IntTy::Isize), + sym::u8 => Self::Uint(UintTy::U8), + sym::u16 => Self::Uint(UintTy::U16), + sym::u32 => Self::Uint(UintTy::U32), + sym::u64 => Self::Uint(UintTy::U64), + sym::u128 => Self::Uint(UintTy::U128), + sym::usize => Self::Uint(UintTy::Usize), + sym::f32 => Self::Float(FloatTy::F32), + sym::f64 => Self::Float(FloatTy::F64), + sym::bool => Self::Bool, + sym::char => Self::Char, + sym::str => Self::Str, + _ => return None, + }; + Some(ty) + } } #[derive(Debug, HashStable_Generic)] diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs index 6cc3e9427d1a7..c11b98e77aa58 100644 --- a/compiler/rustc_index/src/bit_set/tests.rs +++ b/compiler/rustc_index/src/bit_set/tests.rs @@ -1,6 +1,7 @@ use super::*; extern crate test; +use std::hint::black_box; use test::Bencher; #[test] @@ -364,3 +365,36 @@ fn union_hybrid_sparse_full_small_domain(b: &mut Bencher) { sparse.union(&dense); }) } + +#[bench] +fn bench_insert(b: &mut Bencher) { + let mut bs = BitSet::new_filled(99999usize); + b.iter(|| { + black_box(bs.insert(black_box(100u32))); + }); +} + +#[bench] +fn bench_remove(b: &mut Bencher) { + let mut bs = BitSet::new_filled(99999usize); + b.iter(|| { + black_box(bs.remove(black_box(100u32))); + }); +} + +#[bench] +fn bench_iter(b: &mut Bencher) { + let bs = BitSet::new_filled(99999usize); + b.iter(|| { + bs.iter().map(|b: usize| black_box(b)).for_each(drop); + }); +} + +#[bench] +fn bench_intersect(b: &mut Bencher) { + let mut ba: BitSet = BitSet::new_filled(99999usize); + let bb = BitSet::new_filled(99999usize); + b.iter(|| { + ba.intersect(black_box(&bb)); + }); +} diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 8bd9dad785c4b..58a9064b9195b 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -39,6 +39,7 @@ use rustc_session::SessionLintStore; use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP}; use rustc_target::abi::LayoutOf; +use tracing::debug; use std::cell::Cell; use std::slice; @@ -336,6 +337,20 @@ impl LintStore { } } + /// True if this symbol represents a lint group name. + pub fn is_lint_group(&self, lint_name: Symbol) -> bool { + debug!( + "is_lint_group(lint_name={:?}, lint_groups={:?})", + lint_name, + self.lint_groups.keys().collect::>() + ); + let lint_name_str = &*lint_name.as_str(); + self.lint_groups.contains_key(&lint_name_str) || { + let warnings_name_str = crate::WARNINGS.name_lower(); + lint_name_str == &*warnings_name_str + } + } + /// Checks the name of a lint for its existence, and whether it was /// renamed or removed. Generates a DiagnosticBuilder containing a /// warning for renamed and removed lints. This is over both lint diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 18cd25e5d2aa3..1fc2bd0916757 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -5,7 +5,7 @@ use rustc_ast::attr; use rustc_ast::unwrap_or; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{struct_span_err, Applicability}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_hir::{intravisit, HirId}; @@ -17,11 +17,15 @@ use rustc_middle::lint::{ }; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; -use rustc_session::lint::{builtin, Level, Lint, LintId}; +use rustc_session::lint::{ + builtin::{self, FORBIDDEN_LINT_GROUPS}, + Level, Lint, LintId, +}; use rustc_session::parse::feature_err; use rustc_session::Session; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{source_map::MultiSpan, Span, DUMMY_SP}; +use tracing::debug; use std::cmp; @@ -51,6 +55,7 @@ pub struct LintLevelsBuilder<'s> { id_to_set: FxHashMap, cur: u32, warn_about_weird_lints: bool, + store: &'s LintStore, } pub struct BuilderPush { @@ -59,13 +64,14 @@ pub struct BuilderPush { } impl<'s> LintLevelsBuilder<'s> { - pub fn new(sess: &'s Session, warn_about_weird_lints: bool, store: &LintStore) -> Self { + pub fn new(sess: &'s Session, warn_about_weird_lints: bool, store: &'s LintStore) -> Self { let mut builder = LintLevelsBuilder { sess, sets: LintLevelSets::new(), cur: 0, id_to_set: Default::default(), warn_about_weird_lints, + store, }; builder.process_command_line(sess, store); assert_eq!(builder.sets.list.len(), 1); @@ -120,36 +126,75 @@ impl<'s> LintLevelsBuilder<'s> { if let (Level::Forbid, old_src) = self.sets.get_lint_level(id.lint, self.cur, Some(&specs), &self.sess) { - let mut diag_builder = struct_span_err!( - self.sess, - src.span(), - E0453, - "{}({}) incompatible with previous forbid", - level.as_str(), - src.name(), + // Backwards compatibility check: + // + // We used to not consider `forbid(lint_group)` + // as preventing `allow(lint)` for some lint `lint` in + // `lint_group`. For now, issue a future-compatibility + // warning for this case. + let id_name = id.lint.name_lower(); + let fcw_warning = match old_src { + LintLevelSource::Default => false, + LintLevelSource::Node(symbol, _, _) => self.store.is_lint_group(symbol), + LintLevelSource::CommandLine(symbol, _) => self.store.is_lint_group(symbol), + }; + debug!( + "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}", + fcw_warning, specs, old_src, id_name ); - diag_builder.span_label(src.span(), "overruled by previous forbid"); - match old_src { - LintLevelSource::Default => { - diag_builder.note(&format!( - "`forbid` lint level is the default for {}", - id.to_string() - )); - } - LintLevelSource::Node(_, forbid_source_span, reason) => { - diag_builder.span_label(forbid_source_span, "`forbid` level set here"); - if let Some(rationale) = reason { - diag_builder.note(&rationale.as_str()); + + let decorate_diag_builder = |mut diag_builder: DiagnosticBuilder<'_>| { + diag_builder.span_label(src.span(), "overruled by previous forbid"); + match old_src { + LintLevelSource::Default => { + diag_builder.note(&format!( + "`forbid` lint level is the default for {}", + id.to_string() + )); + } + LintLevelSource::Node(_, forbid_source_span, reason) => { + diag_builder.span_label(forbid_source_span, "`forbid` level set here"); + if let Some(rationale) = reason { + diag_builder.note(&rationale.as_str()); + } + } + LintLevelSource::CommandLine(_, _) => { + diag_builder.note("`forbid` lint level was set on command line"); } } - LintLevelSource::CommandLine(_, _) => { - diag_builder.note("`forbid` lint level was set on command line"); - } + diag_builder.emit(); + }; + if !fcw_warning { + let diag_builder = struct_span_err!( + self.sess, + src.span(), + E0453, + "{}({}) incompatible with previous forbid", + level.as_str(), + src.name(), + ); + decorate_diag_builder(diag_builder); + } else { + self.struct_lint( + FORBIDDEN_LINT_GROUPS, + Some(src.span().into()), + |diag_builder| { + let diag_builder = diag_builder.build(&format!( + "{}({}) incompatible with previous forbid", + level.as_str(), + src.name(), + )); + decorate_diag_builder(diag_builder); + }, + ); } - diag_builder.emit(); - // Retain the forbid lint level - return; + // Retain the forbid lint level, unless we are + // issuing a FCW. In the FCW case, we want to + // respect the new setting. + if !fcw_warning { + return; + } } } specs.insert(id, (level, src)); diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 6f44436e2a010..638b73c27a8d7 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -55,8 +55,8 @@ mod late; mod levels; mod methods; mod non_ascii_idents; +mod non_fmt_panic; mod nonstandard_style; -mod panic_fmt; mod passes; mod redundant_semicolon; mod traits; @@ -81,8 +81,8 @@ use builtin::*; use internal::*; use methods::*; use non_ascii_idents::*; +use non_fmt_panic::NonPanicFmt; use nonstandard_style::*; -use panic_fmt::PanicFmt; use redundant_semicolon::*; use traits::*; use types::*; @@ -169,7 +169,7 @@ macro_rules! late_lint_passes { ClashingExternDeclarations: ClashingExternDeclarations::new(), DropTraitConstraints: DropTraitConstraints, TemporaryCStringAsPtr: TemporaryCStringAsPtr, - PanicFmt: PanicFmt, + NonPanicFmt: NonPanicFmt, ] ); }; diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs new file mode 100644 index 0000000000000..e98297b692c92 --- /dev/null +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -0,0 +1,197 @@ +use crate::{LateContext, LateLintPass, LintContext}; +use rustc_ast as ast; +use rustc_errors::{pluralize, Applicability}; +use rustc_hir as hir; +use rustc_middle::ty; +use rustc_parse_format::{ParseMode, Parser, Piece}; +use rustc_span::{sym, symbol::kw, InnerSpan, Span, Symbol}; + +declare_lint! { + /// The `non_fmt_panic` lint detects `panic!(..)` invocations where the first + /// argument is not a formatting string. + /// + /// ### Example + /// + /// ```rust,no_run + /// panic!("{}"); + /// panic!(123); + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// In Rust 2018 and earlier, `panic!(x)` directly uses `x` as the message. + /// That means that `panic!("{}")` panics with the message `"{}"` instead + /// of using it as a formatting string, and `panic!(123)` will panic with + /// an `i32` as message. + /// + /// Rust 2021 always interprets the first argument as format string. + NON_FMT_PANIC, + Warn, + "detect single-argument panic!() invocations in which the argument is not a format string", + report_in_external_macro +} + +declare_lint_pass!(NonPanicFmt => [NON_FMT_PANIC]); + +impl<'tcx> LateLintPass<'tcx> for NonPanicFmt { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { + if let hir::ExprKind::Call(f, [arg]) = &expr.kind { + if let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind() { + if Some(def_id) == cx.tcx.lang_items().begin_panic_fn() + || Some(def_id) == cx.tcx.lang_items().panic_fn() + || Some(def_id) == cx.tcx.lang_items().panic_str() + { + if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id { + if cx.tcx.is_diagnostic_item(sym::std_panic_2015_macro, id) + || cx.tcx.is_diagnostic_item(sym::core_panic_2015_macro, id) + { + check_panic(cx, f, arg); + } + } + } + } + } + } +} + +fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tcx hir::Expr<'tcx>) { + if let hir::ExprKind::Lit(lit) = &arg.kind { + if let ast::LitKind::Str(sym, _) = lit.node { + // The argument is a string literal. + check_panic_str(cx, f, arg, &sym.as_str()); + return; + } + } + + // The argument is *not* a string literal. + + let (span, panic) = panic_call(cx, f); + + cx.struct_span_lint(NON_FMT_PANIC, arg.span, |lint| { + let mut l = lint.build("panic message is not a string literal"); + l.note("this is no longer accepted in Rust 2021"); + if span.contains(arg.span) { + l.span_suggestion_verbose( + arg.span.shrink_to_lo(), + "add a \"{}\" format string to Display the message", + "\"{}\", ".into(), + Applicability::MaybeIncorrect, + ); + if panic == sym::std_panic_macro { + l.span_suggestion_verbose( + span.until(arg.span), + "or use std::panic::panic_any instead", + "std::panic::panic_any(".into(), + Applicability::MachineApplicable, + ); + } + } + l.emit(); + }); +} + +fn check_panic_str<'tcx>( + cx: &LateContext<'tcx>, + f: &'tcx hir::Expr<'tcx>, + arg: &'tcx hir::Expr<'tcx>, + fmt: &str, +) { + if !fmt.contains(&['{', '}'][..]) { + // No brace, no problem. + return; + } + + let fmt_span = arg.span.source_callsite(); + + let (snippet, style) = match cx.sess().parse_sess.source_map().span_to_snippet(fmt_span) { + Ok(snippet) => { + // Count the number of `#`s between the `r` and `"`. + let style = snippet.strip_prefix('r').and_then(|s| s.find('"')); + (Some(snippet), style) + } + Err(_) => (None, None), + }; + + let mut fmt_parser = + Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format); + let n_arguments = (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count(); + + let (span, _) = panic_call(cx, f); + + if n_arguments > 0 && fmt_parser.errors.is_empty() { + let arg_spans: Vec<_> = match &fmt_parser.arg_places[..] { + [] => vec![fmt_span], + v => v.iter().map(|span| fmt_span.from_inner(*span)).collect(), + }; + cx.struct_span_lint(NON_FMT_PANIC, arg_spans, |lint| { + let mut l = lint.build(match n_arguments { + 1 => "panic message contains an unused formatting placeholder", + _ => "panic message contains unused formatting placeholders", + }); + l.note("this message is not used as a format string when given without arguments, but will be in Rust 2021"); + if span.contains(arg.span) { + l.span_suggestion( + arg.span.shrink_to_hi(), + &format!("add the missing argument{}", pluralize!(n_arguments)), + ", ...".into(), + Applicability::HasPlaceholders, + ); + l.span_suggestion( + arg.span.shrink_to_lo(), + "or add a \"{}\" format string to use the message literally", + "\"{}\", ".into(), + Applicability::MachineApplicable, + ); + } + l.emit(); + }); + } else { + let brace_spans: Option> = + snippet.filter(|s| s.starts_with('"') || s.starts_with("r#")).map(|s| { + s.char_indices() + .filter(|&(_, c)| c == '{' || c == '}') + .map(|(i, _)| fmt_span.from_inner(InnerSpan { start: i, end: i + 1 })) + .collect() + }); + let msg = match &brace_spans { + Some(v) if v.len() == 1 => "panic message contains a brace", + _ => "panic message contains braces", + }; + cx.struct_span_lint(NON_FMT_PANIC, brace_spans.unwrap_or(vec![span]), |lint| { + let mut l = lint.build(msg); + l.note("this message is not used as a format string, but will be in Rust 2021"); + if span.contains(arg.span) { + l.span_suggestion( + arg.span.shrink_to_lo(), + "add a \"{}\" format string to use the message literally", + "\"{}\", ".into(), + Applicability::MachineApplicable, + ); + } + l.emit(); + }); + } +} + +fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span, Symbol) { + let mut expn = f.span.ctxt().outer_expn_data(); + + let mut panic_macro = kw::Empty; + + // Unwrap more levels of macro expansion, as panic_2015!() + // was likely expanded from panic!() and possibly from + // [debug_]assert!(). + for &i in + &[sym::std_panic_macro, sym::core_panic_macro, sym::assert_macro, sym::debug_assert_macro] + { + let parent = expn.call_site.ctxt().outer_expn_data(); + if parent.macro_def_id.map_or(false, |id| cx.tcx.is_diagnostic_item(i, id)) { + expn = parent; + panic_macro = i; + } + } + + (expn.call_site, panic_macro) +} diff --git a/compiler/rustc_lint/src/panic_fmt.rs b/compiler/rustc_lint/src/panic_fmt.rs deleted file mode 100644 index 4a6aca72acbbe..0000000000000 --- a/compiler/rustc_lint/src/panic_fmt.rs +++ /dev/null @@ -1,155 +0,0 @@ -use crate::{LateContext, LateLintPass, LintContext}; -use rustc_ast as ast; -use rustc_errors::{pluralize, Applicability}; -use rustc_hir as hir; -use rustc_middle::ty; -use rustc_parse_format::{ParseMode, Parser, Piece}; -use rustc_span::{sym, InnerSpan}; - -declare_lint! { - /// The `panic_fmt` lint detects `panic!("..")` with `{` or `}` in the string literal. - /// - /// ### Example - /// - /// ```rust,no_run - /// panic!("{}"); - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// In Rust 2018 and earlier, `panic!("{}")` panics with the message `"{}"`, - /// as a `panic!()` invocation with a single argument does not use `format_args!()`. - /// Rust 2021 interprets this string as format string, which breaks this. - PANIC_FMT, - Warn, - "detect braces in single-argument panic!() invocations", - report_in_external_macro -} - -declare_lint_pass!(PanicFmt => [PANIC_FMT]); - -impl<'tcx> LateLintPass<'tcx> for PanicFmt { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) { - if let hir::ExprKind::Call(f, [arg]) = &expr.kind { - if let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind() { - if Some(def_id) == cx.tcx.lang_items().begin_panic_fn() - || Some(def_id) == cx.tcx.lang_items().panic_fn() - { - check_panic(cx, f, arg); - } - } - } - } -} - -fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tcx hir::Expr<'tcx>) { - if let hir::ExprKind::Lit(lit) = &arg.kind { - if let ast::LitKind::Str(sym, _) = lit.node { - let mut expn = f.span.ctxt().outer_expn_data(); - if let Some(id) = expn.macro_def_id { - if cx.tcx.is_diagnostic_item(sym::std_panic_2015_macro, id) - || cx.tcx.is_diagnostic_item(sym::core_panic_2015_macro, id) - { - let fmt = sym.as_str(); - if !fmt.contains(&['{', '}'][..]) { - return; - } - - let fmt_span = arg.span.source_callsite(); - - let (snippet, style) = - match cx.sess().parse_sess.source_map().span_to_snippet(fmt_span) { - Ok(snippet) => { - // Count the number of `#`s between the `r` and `"`. - let style = snippet.strip_prefix('r').and_then(|s| s.find('"')); - (Some(snippet), style) - } - Err(_) => (None, None), - }; - - let mut fmt_parser = - Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format); - let n_arguments = - (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count(); - - // Unwrap more levels of macro expansion, as panic_2015!() - // was likely expanded from panic!() and possibly from - // [debug_]assert!(). - for &assert in &[ - sym::std_panic_macro, - sym::core_panic_macro, - sym::assert_macro, - sym::debug_assert_macro, - ] { - let parent = expn.call_site.ctxt().outer_expn_data(); - if parent - .macro_def_id - .map_or(false, |id| cx.tcx.is_diagnostic_item(assert, id)) - { - expn = parent; - } - } - - if n_arguments > 0 && fmt_parser.errors.is_empty() { - let arg_spans: Vec<_> = match &fmt_parser.arg_places[..] { - [] => vec![fmt_span], - v => v.iter().map(|span| fmt_span.from_inner(*span)).collect(), - }; - cx.struct_span_lint(PANIC_FMT, arg_spans, |lint| { - let mut l = lint.build(match n_arguments { - 1 => "panic message contains an unused formatting placeholder", - _ => "panic message contains unused formatting placeholders", - }); - l.note("this message is not used as a format string when given without arguments, but will be in a future Rust edition"); - if expn.call_site.contains(arg.span) { - l.span_suggestion( - arg.span.shrink_to_hi(), - &format!("add the missing argument{}", pluralize!(n_arguments)), - ", ...".into(), - Applicability::HasPlaceholders, - ); - l.span_suggestion( - arg.span.shrink_to_lo(), - "or add a \"{}\" format string to use the message literally", - "\"{}\", ".into(), - Applicability::MachineApplicable, - ); - } - l.emit(); - }); - } else { - let brace_spans: Option> = snippet - .filter(|s| s.starts_with('"') || s.starts_with("r#")) - .map(|s| { - s.char_indices() - .filter(|&(_, c)| c == '{' || c == '}') - .map(|(i, _)| { - fmt_span.from_inner(InnerSpan { start: i, end: i + 1 }) - }) - .collect() - }); - let msg = match &brace_spans { - Some(v) if v.len() == 1 => "panic message contains a brace", - _ => "panic message contains braces", - }; - cx.struct_span_lint(PANIC_FMT, brace_spans.unwrap_or(vec![expn.call_site]), |lint| { - let mut l = lint.build(msg); - l.note("this message is not used as a format string, but will be in a future Rust edition"); - if expn.call_site.contains(arg.span) { - l.span_suggestion( - arg.span.shrink_to_lo(), - "add a \"{}\" format string to use the message literally", - "\"{}\", ".into(), - Applicability::MachineApplicable, - ); - } - l.emit(); - }); - } - } - } - } - } -} diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 4337600384008..da62ad3a6b1cd 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -5,10 +5,48 @@ //! compiler code, rather than using their own custom pass. Those //! lints are all available in `rustc_lint::builtin`. +// ignore-tidy-filelength + use crate::{declare_lint, declare_lint_pass}; use rustc_span::edition::Edition; use rustc_span::symbol::sym; +declare_lint! { + /// The `forbidden_lint_groups` lint detects violations of + /// `forbid` applied to a lint group. Due to a bug in the compiler, + /// these used to be overlooked entirely. They now generate a warning. + /// + /// ### Example + /// + /// ```rust + /// #![forbid(warnings)] + /// #![deny(bad_style)] + /// + /// fn main() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Recommended fix + /// + /// If your crate is using `#![forbid(warnings)]`, + /// we recommend that you change to `#![deny(warnings)]`. + /// + /// ### Explanation + /// + /// Due to a compiler bug, applying `forbid` to lint groups + /// previously had no effect. The bug is now fixed but instead of + /// enforcing `forbid` we issue this future-compatibility warning + /// to avoid breaking existing crates. + pub FORBIDDEN_LINT_GROUPS, + Warn, + "applying forbid to lint-groups", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #81670 ", + edition: None, + }; +} + declare_lint! { /// The `ill_formed_attribute_input` lint detects ill-formed attribute /// inputs that were previously accepted and used in practice. @@ -2888,6 +2926,7 @@ declare_lint_pass! { /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. HardwiredLints => [ + FORBIDDEN_LINT_GROUPS, ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, ARITHMETIC_OVERFLOW, UNCONDITIONAL_PANIC, diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 0bdccf7b5f073..ca73481b21699 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -5,7 +5,10 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_hir::HirId; -use rustc_session::lint::{builtin, Level, Lint, LintId}; +use rustc_session::lint::{ + builtin::{self, FORBIDDEN_LINT_GROUPS}, + Level, Lint, LintId, +}; use rustc_session::{DiagnosticMessageId, Session}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; @@ -89,7 +92,12 @@ impl LintLevelSets { // If we're about to issue a warning, check at the last minute for any // directives against the warnings "lint". If, for example, there's an // `allow(warnings)` in scope then we want to respect that instead. - if level == Level::Warn { + // + // We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically + // triggers in cases (like #80988) where you have `forbid(warnings)`, + // and so if we turned that into an error, it'd defeat the purpose of the + // future compatibility warning. + if level == Level::Warn && LintId::of(lint) != LintId::of(FORBIDDEN_LINT_GROUPS) { let (warnings_level, warnings_src) = self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux); if let Some(configured_warning_level) = warnings_level { diff --git a/compiler/rustc_middle/src/util/bug.rs b/compiler/rustc_middle/src/util/bug.rs index e79adcdb54598..791d5060fe5c7 100644 --- a/compiler/rustc_middle/src/util/bug.rs +++ b/compiler/rustc_middle/src/util/bug.rs @@ -3,7 +3,7 @@ use crate::ty::{tls, TyCtxt}; use rustc_span::{MultiSpan, Span}; use std::fmt; -use std::panic::Location; +use std::panic::{panic_any, Location}; #[cold] #[inline(never)] @@ -32,7 +32,7 @@ fn opt_span_bug_fmt>( match (tcx, span) { (Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, &msg), (Some(tcx), None) => tcx.sess.diagnostic().bug(&msg), - (None, _) => panic!(msg), + (None, _) => panic_any(msg), } }); unreachable!(); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9d55bafd2868e..0714d76f7448a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -9,6 +9,7 @@ use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::PrimTy; use rustc_middle::bug; use rustc_middle::ty::{self, DefIdTree}; use rustc_session::Session; @@ -718,10 +719,9 @@ impl<'a> Resolver<'a> { } } Scope::BuiltinTypes => { - let primitive_types = &this.primitive_type_table.primitive_types; - suggestions.extend(primitive_types.iter().flat_map(|(name, prim_ty)| { + suggestions.extend(PrimTy::ALL.iter().filter_map(|prim_ty| { let res = Res::PrimTy(*prim_ty); - filter_fn(res).then_some(TypoSuggestion::from_res(*name, res)) + filter_fn(res).then_some(TypoSuggestion::from_res(prim_ty.name(), res)) })) } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 9b5b793363b5b..cca40a793dd00 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -20,7 +20,7 @@ use rustc_errors::DiagnosticId; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX}; -use rustc_hir::TraitCandidate; +use rustc_hir::{PrimTy, TraitCandidate}; use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -1927,7 +1927,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.r.trait_map.insert(id, traits); } - if self.r.primitive_type_table.primitive_types.contains_key(&path[0].ident.name) { + if PrimTy::from_name(path[0].ident.name).is_some() { let mut std_path = Vec::with_capacity(1 + path.len()); std_path.push(Segment::from_ident(Ident::with_dummy_span(sym::std))); @@ -2121,13 +2121,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // The same fallback is used when `a` resolves to nothing. PathResult::Module(ModuleOrUniformRoot::Module(_)) | PathResult::Failed { .. } if (ns == TypeNS || path.len() > 1) - && self - .r - .primitive_type_table - .primitive_types - .contains_key(&path[0].ident.name) => + && PrimTy::from_name(path[0].ident.name).is_some() => { - let prim = self.r.primitive_type_table.primitive_types[&path[0].ident.name]; + let prim = PrimTy::from_name(path[0].ident.name).unwrap(); PartialRes::with_unresolved_segments(Res::PrimTy(prim), path.len() - 1) } PathResult::Module(ModuleOrUniformRoot::Module(module)) => { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 927535b72bdb5..d2a693a568828 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1212,8 +1212,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { // Add primitive types to the mix if filter_fn(Res::PrimTy(PrimTy::Bool)) { names.extend( - self.r.primitive_type_table.primitive_types.iter().map(|(name, prim_ty)| { - TypoSuggestion::from_res(*name, Res::PrimTy(*prim_ty)) + PrimTy::ALL.iter().map(|prim_ty| { + TypoSuggestion::from_res(prim_ty.name(), Res::PrimTy(*prim_ty)) }), ) } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b19990e49b84f..2be669a1726a1 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -25,7 +25,7 @@ use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::node_id::NodeMap; use rustc_ast::unwrap_or; use rustc_ast::visit::{self, Visitor}; -use rustc_ast::{self as ast, FloatTy, IntTy, NodeId, UintTy}; +use rustc_ast::{self as ast, NodeId}; use rustc_ast::{Crate, CRATE_NODE_ID}; use rustc_ast::{ItemKind, Path}; use rustc_ast_lowering::ResolverAstLowering; @@ -39,8 +39,7 @@ use rustc_hir::def::Namespace::*; use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX}; use rustc_hir::definitions::{DefKey, DefPathData, Definitions}; -use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint}; -use rustc_hir::TraitCandidate; +use rustc_hir::{PrimTy, TraitCandidate}; use rustc_index::vec::IndexVec; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::hir::exports::ExportMap; @@ -834,39 +833,6 @@ impl<'a> NameBinding<'a> { } } -/// Interns the names of the primitive types. -/// -/// All other types are defined somewhere and possibly imported, but the primitive ones need -/// special handling, since they have no place of origin. -struct PrimitiveTypeTable { - primitive_types: FxHashMap, -} - -impl PrimitiveTypeTable { - fn new() -> PrimitiveTypeTable { - let mut table = FxHashMap::default(); - - table.insert(sym::bool, Bool); - table.insert(sym::char, Char); - table.insert(sym::f32, Float(FloatTy::F32)); - table.insert(sym::f64, Float(FloatTy::F64)); - table.insert(sym::isize, Int(IntTy::Isize)); - table.insert(sym::i8, Int(IntTy::I8)); - table.insert(sym::i16, Int(IntTy::I16)); - table.insert(sym::i32, Int(IntTy::I32)); - table.insert(sym::i64, Int(IntTy::I64)); - table.insert(sym::i128, Int(IntTy::I128)); - table.insert(sym::str, Str); - table.insert(sym::usize, Uint(UintTy::Usize)); - table.insert(sym::u8, Uint(UintTy::U8)); - table.insert(sym::u16, Uint(UintTy::U16)); - table.insert(sym::u32, Uint(UintTy::U32)); - table.insert(sym::u64, Uint(UintTy::U64)); - table.insert(sym::u128, Uint(UintTy::U128)); - Self { primitive_types: table } - } -} - #[derive(Debug, Default, Clone)] pub struct ExternPreludeEntry<'a> { extern_crate_item: Option<&'a NameBinding<'a>>, @@ -912,9 +878,6 @@ pub struct Resolver<'a> { /// "self-confirming" import resolutions during import validation. unusable_binding: Option<&'a NameBinding<'a>>, - /// The idents for the primitive types. - primitive_type_table: PrimitiveTypeTable, - /// Resolutions for nodes that have a single resolution. partial_res_map: NodeMap, /// Resolutions for import nodes, which have multiple resolutions in different namespaces. @@ -1284,8 +1247,6 @@ impl<'a> Resolver<'a> { last_import_segment: false, unusable_binding: None, - primitive_type_table: PrimitiveTypeTable::new(), - partial_res_map: Default::default(), import_res_map: Default::default(), label_res_map: Default::default(), @@ -1994,9 +1955,9 @@ impl<'a> Resolver<'a> { } if ns == TypeNS { - if let Some(prim_ty) = self.primitive_type_table.primitive_types.get(&ident.name) { + if let Some(prim_ty) = PrimTy::from_name(ident.name) { let binding = - (Res::PrimTy(*prim_ty), ty::Visibility::Public, DUMMY_SP, ExpnId::root()) + (Res::PrimTy(prim_ty), ty::Visibility::Public, DUMMY_SP, ExpnId::root()) .to_name_binding(self.arenas); return Some(LexicalScopeBinding::Item(binding)); } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index d0adee2429d9a..d76db7c645abc 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -21,6 +21,7 @@ use rustc_expand::expand::{AstFragment, Invocation, InvocationKind}; use rustc_feature::is_builtin_attr_name; use rustc_hir::def::{self, DefKind, NonMacroAttrKind}; use rustc_hir::def_id; +use rustc_hir::PrimTy; use rustc_middle::middle::stability; use rustc_middle::ty; use rustc_session::lint::builtin::{SOFT_UNSTABLE, UNUSED_MACROS}; @@ -796,12 +797,10 @@ impl<'a> Resolver<'a> { } result } - Scope::BuiltinTypes => { - match this.primitive_type_table.primitive_types.get(&ident.name).cloned() { - Some(prim_ty) => ok(Res::PrimTy(prim_ty), DUMMY_SP, this.arenas), - None => Err(Determinacy::Determined), - } - } + Scope::BuiltinTypes => match PrimTy::from_name(ident.name) { + Some(prim_ty) => ok(Res::PrimTy(prim_ty), DUMMY_SP, this.arenas), + None => Err(Determinacy::Determined), + }, }; match result { diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index ea04e7bb44b3b..53c3adcc20c02 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -17,6 +17,7 @@ Core encoding and decoding interfaces. #![feature(min_specialization)] #![feature(vec_spare_capacity)] #![feature(core_intrinsics)] +#![feature(int_bits_const)] #![feature(maybe_uninit_slice)] #![feature(new_uninit)] #![cfg_attr(test, feature(test))] diff --git a/compiler/rustc_serialize/tests/leb128.rs b/compiler/rustc_serialize/tests/leb128.rs index 3e2aab5125ab7..a2bcf2c251d7a 100644 --- a/compiler/rustc_serialize/tests/leb128.rs +++ b/compiler/rustc_serialize/tests/leb128.rs @@ -1,3 +1,4 @@ +#![feature(int_bits_const)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array)] diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 3a757e5f0075d..47f14fa6b7a74 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -113,6 +113,8 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { sysroot.join(&relative_target_lib_path(sysroot, target_triple)) } +// This function checks if sysroot is found using env::args().next(), and if it +// is not found, uses env::current_exe() to imply sysroot. pub fn get_or_default_sysroot() -> PathBuf { // Follow symlinks. If the resolved path is relative, make it absolute. fn canonicalize(path: PathBuf) -> PathBuf { @@ -123,15 +125,51 @@ pub fn get_or_default_sysroot() -> PathBuf { fix_windows_verbatim_for_gcc(&path) } - match env::current_exe() { - Ok(exe) => { - let mut p = canonicalize(exe); - p.pop(); - p.pop(); - p + // Use env::current_exe() to get the path of the executable following + // symlinks/canonicalizing components. + fn from_current_exe() -> PathBuf { + match env::current_exe() { + Ok(exe) => { + let mut p = canonicalize(exe); + p.pop(); + p.pop(); + p + } + Err(e) => panic!("failed to get current_exe: {}", e), + } + } + + // Use env::args().next() to get the path of the executable without + // following symlinks/canonicalizing any component. This makes the rustc + // binary able to locate Rust libraries in systems using content-addressable + // storage (CAS). + fn from_env_args_next() -> Option { + match env::args_os().next() { + Some(first_arg) => { + let mut p = PathBuf::from(first_arg); + + // Check if sysroot is found using env::args().next() only if the rustc in argv[0] + // is a symlink (see #79253). We might want to change/remove it to conform with + // https://www.gnu.org/prep/standards/standards.html#Finding-Program-Files in the + // future. + if fs::read_link(&p).is_err() { + // Path is not a symbolic link or does not exist. + return None; + } + + p.pop(); + p.pop(); + let mut libdir = PathBuf::from(&p); + libdir.push(find_libdir(&p).as_ref()); + if libdir.exists() { Some(p) } else { None } + } + None => None, } - Err(e) => panic!("failed to get current_exe: {}", e), } + + // Check if sysroot is found using env::args().next(), and if is not found, + // use env::current_exe() to imply sysroot. + from_env_args_next().unwrap_or(from_current_exe()) } // The name of the directory rustc expects libraries to be located. diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 0a1ecced49abc..a49979fb7aa18 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -102,6 +102,7 @@ #![feature(fn_traits)] #![feature(fundamental)] #![feature(inplace_iteration)] +#![feature(int_bits_const)] #![feature(lang_items)] #![feature(layout_for_ptr)] #![feature(maybe_uninit_ref)] diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 9c7343e8cbf5a..dd98f806451d8 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -17,6 +17,7 @@ #![feature(binary_heap_retain)] #![feature(inplace_iteration)] #![feature(iter_map_while)] +#![feature(int_bits_const)] #![feature(vecdeque_binary_search)] #![feature(slice_group_by)] #![feature(vec_extend_from_within)] diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index a02e74d5e5a4d..6e502426df906 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -10,22 +10,23 @@ tests. `panic!` is closely tied with the `unwrap` method of both `panic!` when they are set to [`None`] or [`Err`] variants. This macro is used to inject panic into a Rust thread, causing the thread to -panic entirely. Each thread's panic can be reaped as the [`Box`]`<`[`Any`]`>` type, -and the single-argument form of the `panic!` macro will be the value which -is transmitted. +panic entirely. This macro panics with a string and uses the [`format!`] syntax +for building the message. + +Each thread's panic can be reaped as the [`Box`]`<`[`Any`]`>` type, +which contains either a `&str` or `String` for regular `panic!()` invocations. +To panic with a value of another other type, [`panic_any`] can be used. [`Result`] enum is often a better solution for recovering from errors than using the `panic!` macro. This macro should be used to avoid proceeding using incorrect values, such as from external sources. Detailed information about error handling is found in the [book]. -The multi-argument form of this macro panics with a string and has the -[`format!`] syntax for building a string. - See also the macro [`compile_error!`], for raising errors during compilation. [ounwrap]: Option::unwrap [runwrap]: Result::unwrap +[`panic_any`]: ../std/panic/fn.panic_any.html [`Box`]: ../std/boxed/struct.Box.html [`Any`]: crate::any::Any [`format!`]: ../std/macro.format.html @@ -42,6 +43,6 @@ program with code `101`. # #![allow(unreachable_code)] panic!(); panic!("this is a terrible mistake!"); -panic!(4); // panic with the value of 4 to be collected elsewhere panic!("this is a {} {message}", "fancy", message = "message"); +std::panic::panic_any(4); // panic with the value of 4 to be collected elsewhere ``` diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 96affd17cc520..8fdd7c9e5d7fb 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -32,9 +32,10 @@ macro_rules! int_impl { /// # Examples /// /// ``` + /// #![feature(int_bits_const)] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")] /// ``` - #[stable(feature = "int_bits_const", since = "1.51.0")] + #[unstable(feature = "int_bits_const", issue = "76904")] pub const BITS: u32 = $BITS; /// Converts a string slice in a given base to an integer. diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index aee424b9b1392..9fccf3f72ce1a 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -32,9 +32,10 @@ macro_rules! uint_impl { /// # Examples /// /// ``` + /// #![feature(int_bits_const)] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")] /// ``` - #[stable(feature = "int_bits_const", since = "1.51.0")] + #[unstable(feature = "int_bits_const", issue = "76904")] pub const BITS: u32 = $BITS; /// Converts a string slice in a given base to an integer. diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 26dbcb8569b43..bc0e3e059c917 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -70,6 +70,7 @@ #![feature(partition_point)] #![feature(once_cell)] #![feature(unsafe_block_in_unsafe_fn)] +#![feature(int_bits_const)] #![feature(nonzero_leading_trailing_zeros)] #![feature(const_option)] #![feature(integer_atomics)] diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index 99a0c67fc11b9..9ce9c477ec0f0 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -18,6 +18,7 @@ issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/" )] #![feature(core_intrinsics)] +#![feature(int_bits_const)] #![feature(lang_items)] #![feature(nll)] #![feature(panic_unwind)] diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 21060182d60bc..c9c8f68cd9cce 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -826,7 +826,7 @@ impl OsStr { /// assert!(!OsString::from("Ferrös").eq_ignore_ascii_case("FERRÖS")); /// ``` #[unstable(feature = "osstring_ascii", issue = "70516")] - pub fn eq_ignore_ascii_case>(&self, other: &S) -> bool { + pub fn eq_ignore_ascii_case>(&self, other: S) -> bool { self.inner.eq_ignore_ascii_case(&other.as_ref().inner) } } diff --git a/library/std/src/sys/wasi/ext/fs.rs b/library/std/src/sys/wasi/ext/fs.rs index 4f7cf6018d90f..a8da003d550ac 100644 --- a/library/std/src/sys/wasi/ext/fs.rs +++ b/library/std/src/sys/wasi/ext/fs.rs @@ -514,3 +514,11 @@ pub fn symlink, U: AsRef>( .fd() .symlink(osstr2str(old_path.as_ref().as_ref())?, osstr2str(new_path.as_ref().as_ref())?) } + +/// Create a symbolic link. +/// +/// This is a convenience API similar to [`std::os::unix::fs::symlink`] and +/// [`std::os::windows::fs::symlink_file`] and [`symlink_dir`](std::os::windows::fs::symlink_dir). +pub fn symlink_path, U: AsRef>(old_path: P, new_path: U) -> io::Result<()> { + crate::sys::fs::symlink(old_path.as_ref(), new_path.as_ref()) +} diff --git a/library/term/src/terminfo/parm/tests.rs b/library/term/src/terminfo/parm/tests.rs index b975bd2d19882..1cc0967c8f42e 100644 --- a/library/term/src/terminfo/parm/tests.rs +++ b/library/term/src/terminfo/parm/tests.rs @@ -77,15 +77,15 @@ fn test_comparison_ops() { for &(op, bs) in v.iter() { let s = format!("%{{1}}%{{2}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), vec![b'0' + bs[0]]); let s = format!("%{{1}}%{{1}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), vec![b'0' + bs[1]]); let s = format!("%{{2}}%{{1}}%{}%d", op); let res = expand(s.as_bytes(), &[], &mut Variables::new()); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), vec![b'0' + bs[2]]); } } @@ -95,13 +95,13 @@ fn test_conditionals() { let mut vars = Variables::new(); let s = b"\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m"; let res = expand(s, &[Number(1)], &mut vars); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), "\\E[31m".bytes().collect::>()); let res = expand(s, &[Number(8)], &mut vars); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), "\\E[90m".bytes().collect::>()); let res = expand(s, &[Number(42)], &mut vars); - assert!(res.is_ok(), res.unwrap_err()); + assert!(res.is_ok(), "{}", res.unwrap_err()); assert_eq!(res.unwrap(), "\\E[38;5;42m".bytes().collect::>()); } diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs index 99e12c973c4a2..f0586d510dbdb 100644 --- a/library/test/src/tests.rs +++ b/library/test/src/tests.rs @@ -199,7 +199,7 @@ fn test_should_panic_bad_message() { fn test_should_panic_non_string_message_type() { use crate::tests::TrFailedMsg; fn f() { - panic!(1i32); + std::panic::panic_any(1i32); } let expected = "foobar"; let failed_msg = format!( diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index f0e33be757d16..d9132f20d85b3 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1880,8 +1880,7 @@ impl Step for RemoteCopyLibs { builder.info(&format!("REMOTE copy libs to emulator ({})", target)); t!(fs::create_dir_all(builder.out.join("tmp"))); - let server = - builder.ensure(tool::RemoteTestServer { compiler: compiler.with_stage(0), target }); + let server = builder.ensure(tool::RemoteTestServer { compiler, target }); // Spawn the emulator and wait for it to come online let tool = builder.tool_exe(Tool::RemoteTestClient); diff --git a/src/test/ui-fulldeps/issue-15149.rs b/src/test/ui-fulldeps/issue-15149.rs index c80628aabc83f..c7ef5ad70a114 100644 --- a/src/test/ui-fulldeps/issue-15149.rs +++ b/src/test/ui-fulldeps/issue-15149.rs @@ -50,7 +50,7 @@ fn test() { .output().unwrap(); assert!(child_output.status.success(), - format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}", - str::from_utf8(&child_output.stdout).unwrap(), - str::from_utf8(&child_output.stderr).unwrap())); + "child assertion failed\n child stdout:\n {}\n child stderr:\n {}", + str::from_utf8(&child_output.stdout).unwrap(), + str::from_utf8(&child_output.stderr).unwrap()); } diff --git a/src/test/ui/consts/const-eval/const_panic.rs b/src/test/ui/consts/const-eval/const_panic.rs index e9d66477d60a5..8ae8376ae4a6f 100644 --- a/src/test/ui/consts/const-eval/const_panic.rs +++ b/src/test/ui/consts/const-eval/const_panic.rs @@ -1,4 +1,5 @@ #![feature(const_panic)] +#![allow(non_fmt_panic)] #![crate_type = "lib"] const MSG: &str = "hello"; diff --git a/src/test/ui/consts/const-eval/const_panic.stderr b/src/test/ui/consts/const-eval/const_panic.stderr index 713be5b662d54..74907a0b49518 100644 --- a/src/test/ui/consts/const-eval/const_panic.stderr +++ b/src/test/ui/consts/const-eval/const_panic.stderr @@ -1,10 +1,10 @@ error: any use of this value will cause an error - --> $DIR/const_panic.rs:6:15 + --> $DIR/const_panic.rs:7:15 | LL | const Z: () = std::panic!("cheese"); | --------------^^^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:6:15 + | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:7:15 | = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! @@ -12,108 +12,108 @@ LL | const Z: () = std::panic!("cheese"); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:10:16 + --> $DIR/const_panic.rs:11:16 | LL | const Z2: () = std::panic!(); | ---------------^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:10:16 + | the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:11:16 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:14:15 + --> $DIR/const_panic.rs:15:15 | LL | const Y: () = std::unreachable!(); | --------------^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:14:15 + | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:15:15 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:18:15 + --> $DIR/const_panic.rs:19:15 | LL | const X: () = std::unimplemented!(); | --------------^^^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:18:15 + | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:19:15 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:22:15 + --> $DIR/const_panic.rs:23:15 | LL | const W: () = std::panic!(MSG); | --------------^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'hello', $DIR/const_panic.rs:22:15 + | the evaluated program panicked at 'hello', $DIR/const_panic.rs:23:15 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:26:20 + --> $DIR/const_panic.rs:27:20 | LL | const Z_CORE: () = core::panic!("cheese"); | -------------------^^^^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:26:20 + | the evaluated program panicked at 'cheese', $DIR/const_panic.rs:27:20 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:30:21 + --> $DIR/const_panic.rs:31:21 | LL | const Z2_CORE: () = core::panic!(); | --------------------^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:30:21 + | the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:31:21 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:34:20 + --> $DIR/const_panic.rs:35:20 | LL | const Y_CORE: () = core::unreachable!(); | -------------------^^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:34:20 + | the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:35:20 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:38:20 + --> $DIR/const_panic.rs:39:20 | LL | const X_CORE: () = core::unimplemented!(); | -------------------^^^^^^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:38:20 + | the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:39:20 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: any use of this value will cause an error - --> $DIR/const_panic.rs:42:20 + --> $DIR/const_panic.rs:43:20 | LL | const W_CORE: () = core::panic!(MSG); | -------------------^^^^^^^^^^^^^^^^^- | | - | the evaluated program panicked at 'hello', $DIR/const_panic.rs:42:20 + | the evaluated program panicked at 'hello', $DIR/const_panic.rs:43:20 | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs index a952fe8e76e81..cb6d58a23d936 100644 --- a/src/test/ui/drop/dynamic-drop-async.rs +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -82,7 +82,7 @@ impl Allocator { self.cur_ops.set(self.cur_ops.get() + 1); if self.cur_ops.get() == self.failing_op { - panic!(InjectedFailure); + panic::panic_any(InjectedFailure); } } } diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index ddccee20e12a6..e28bedb982dd9 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -46,7 +46,7 @@ impl Allocator { self.cur_ops.set(self.cur_ops.get() + 1); if self.cur_ops.get() == self.failing_op { - panic!(InjectedFailure); + panic::panic_any(InjectedFailure); } let mut data = self.data.borrow_mut(); @@ -67,7 +67,7 @@ impl<'a> Drop for Ptr<'a> { self.1.cur_ops.set(self.1.cur_ops.get() + 1); if self.1.cur_ops.get() == self.1.failing_op { - panic!(InjectedFailure); + panic::panic_any(InjectedFailure); } } } diff --git a/src/test/ui/fmt/format-args-capture.rs b/src/test/ui/fmt/format-args-capture.rs index 4e3fa9a3c589a..d5886a13558c6 100644 --- a/src/test/ui/fmt/format-args-capture.rs +++ b/src/test/ui/fmt/format-args-capture.rs @@ -31,7 +31,7 @@ fn panic_with_single_argument_does_not_get_formatted() { // RFC #2795 suggests that this may need to change so that captured arguments are formatted. // For stability reasons this will need to part of an edition change. - #[allow(panic_fmt)] + #[allow(non_fmt_panic)] let msg = std::panic::catch_unwind(|| { panic!("{foo}"); }).unwrap_err(); diff --git a/src/test/ui/lint/forbid-group-group-1.rs b/src/test/ui/lint/forbid-group-group-1.rs new file mode 100644 index 0000000000000..80f7db4e56036 --- /dev/null +++ b/src/test/ui/lint/forbid-group-group-1.rs @@ -0,0 +1,13 @@ +// Check what happens when we forbid a smaller group but +// then allow a superset of that group. + +#![forbid(nonstandard_style)] + +// FIXME: Arguably this should be an error, but the WARNINGS group is +// treated in a very special (and rather ad-hoc) way and +// it fails to trigger. +#[allow(warnings)] +fn main() { + let A: (); + //~^ ERROR should have a snake case name +} diff --git a/src/test/ui/lint/forbid-group-group-1.stderr b/src/test/ui/lint/forbid-group-group-1.stderr new file mode 100644 index 0000000000000..fd425e5f74e6f --- /dev/null +++ b/src/test/ui/lint/forbid-group-group-1.stderr @@ -0,0 +1,15 @@ +error: variable `A` should have a snake case name + --> $DIR/forbid-group-group-1.rs:11:9 + | +LL | let A: (); + | ^ help: convert the identifier to snake case: `a` + | +note: the lint level is defined here + --> $DIR/forbid-group-group-1.rs:4:11 + | +LL | #![forbid(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ + = note: `#[forbid(non_snake_case)]` implied by `#[forbid(nonstandard_style)]` + +error: aborting due to previous error + diff --git a/src/test/ui/lint/forbid-group-group-2.rs b/src/test/ui/lint/forbid-group-group-2.rs new file mode 100644 index 0000000000000..b12fd72da7494 --- /dev/null +++ b/src/test/ui/lint/forbid-group-group-2.rs @@ -0,0 +1,26 @@ +// Check what happens when we forbid a bigger group but +// then deny a subset of that group. + +#![forbid(warnings)] +#![deny(forbidden_lint_groups)] + +#[allow(nonstandard_style)] +//~^ ERROR incompatible with previous +//~| WARNING previously accepted by the compiler +//~| ERROR incompatible with previous +//~| WARNING previously accepted by the compiler +//~| ERROR incompatible with previous +//~| WARNING previously accepted by the compiler +//~| ERROR incompatible with previous +//~| WARNING previously accepted by the compiler +//~| ERROR incompatible with previous +//~| WARNING previously accepted by the compiler +//~| ERROR incompatible with previous +//~| WARNING previously accepted by the compiler +//~| ERROR incompatible with previous +//~| WARNING previously accepted by the compiler +//~| ERROR incompatible with previous +//~| WARNING previously accepted by the compiler +//~| ERROR incompatible with previous +//~| WARNING previously accepted by the compiler +fn main() {} diff --git a/src/test/ui/lint/forbid-group-group-2.stderr b/src/test/ui/lint/forbid-group-group-2.stderr new file mode 100644 index 0000000000000..214e949c11a74 --- /dev/null +++ b/src/test/ui/lint/forbid-group-group-2.stderr @@ -0,0 +1,115 @@ +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | +note: the lint level is defined here + --> $DIR/forbid-group-group-2.rs:5:9 + | +LL | #![deny(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +error: allow(nonstandard_style) incompatible with previous forbid + --> $DIR/forbid-group-group-2.rs:7:9 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +... +LL | #[allow(nonstandard_style)] + | ^^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +error: aborting due to 9 previous errors + diff --git a/src/test/ui/lint/forbid-group-member.rs b/src/test/ui/lint/forbid-group-member.rs new file mode 100644 index 0000000000000..6f1b2e9f66812 --- /dev/null +++ b/src/test/ui/lint/forbid-group-member.rs @@ -0,0 +1,19 @@ +// Check what happens when we forbid a group but +// then allow a member of that group. +// +// check-pass + +#![forbid(unused)] + +#[allow(unused_variables)] +//~^ WARNING incompatible with previous forbid +//~| WARNING previously accepted +//~| WARNING incompatible with previous forbid +//~| WARNING previously accepted +//~| WARNING incompatible with previous forbid +//~| WARNING previously accepted +//~| WARNING incompatible with previous forbid +//~| WARNING previously accepted +fn main() { + let a: (); +} diff --git a/src/test/ui/lint/forbid-group-member.stderr b/src/test/ui/lint/forbid-group-member.stderr new file mode 100644 index 0000000000000..c818d7ff60605 --- /dev/null +++ b/src/test/ui/lint/forbid-group-member.stderr @@ -0,0 +1,51 @@ +warning: allow(unused_variables) incompatible with previous forbid + --> $DIR/forbid-group-member.rs:8:9 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | +LL | #[allow(unused_variables)] + | ^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = note: `#[warn(forbidden_lint_groups)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +warning: allow(unused_variables) incompatible with previous forbid + --> $DIR/forbid-group-member.rs:8:9 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | +LL | #[allow(unused_variables)] + | ^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +warning: allow(unused_variables) incompatible with previous forbid + --> $DIR/forbid-group-member.rs:8:9 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | +LL | #[allow(unused_variables)] + | ^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +warning: allow(unused_variables) incompatible with previous forbid + --> $DIR/forbid-group-member.rs:8:9 + | +LL | #![forbid(unused)] + | ------ `forbid` level set here +LL | +LL | #[allow(unused_variables)] + | ^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +warning: 4 warnings emitted + diff --git a/src/test/ui/lint/forbid-member-group.rs b/src/test/ui/lint/forbid-member-group.rs new file mode 100644 index 0000000000000..3279029a9cbc3 --- /dev/null +++ b/src/test/ui/lint/forbid-member-group.rs @@ -0,0 +1,12 @@ +// Check what happens when we forbid a member of +// a group but then allow the group. + +#![forbid(unused_variables)] + +#[allow(unused)] +//~^ ERROR incompatible with previous forbid +//~| ERROR incompatible with previous forbid +//~| ERROR incompatible with previous forbid +fn main() { + let a: (); +} diff --git a/src/test/ui/lint/forbid-member-group.stderr b/src/test/ui/lint/forbid-member-group.stderr new file mode 100644 index 0000000000000..1d8ab4d5edb0c --- /dev/null +++ b/src/test/ui/lint/forbid-member-group.stderr @@ -0,0 +1,30 @@ +error[E0453]: allow(unused) incompatible with previous forbid + --> $DIR/forbid-member-group.rs:6:9 + | +LL | #![forbid(unused_variables)] + | ---------------- `forbid` level set here +LL | +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + +error[E0453]: allow(unused) incompatible with previous forbid + --> $DIR/forbid-member-group.rs:6:9 + | +LL | #![forbid(unused_variables)] + | ---------------- `forbid` level set here +LL | +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + +error[E0453]: allow(unused) incompatible with previous forbid + --> $DIR/forbid-member-group.rs:6:9 + | +LL | #![forbid(unused_variables)] + | ---------------- `forbid` level set here +LL | +LL | #[allow(unused)] + | ^^^^^^ overruled by previous forbid + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs index f725304cf29d4..05d7d924c8fab 100644 --- a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs +++ b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.rs @@ -14,14 +14,17 @@ // compile-flags: -Z deduplicate-diagnostics=yes +#![forbid(forbidden_lint_groups)] + fn forbid_first(num: i32) -> i32 { #![forbid(unused)] #![deny(unused)] //~^ ERROR: deny(unused) incompatible with previous forbid + //~| WARNING being phased out + //~| ERROR: deny(unused) incompatible with previous forbid + //~| WARNING being phased out #![warn(unused)] - //~^ ERROR: warn(unused) incompatible with previous forbid #![allow(unused)] - //~^ ERROR: allow(unused) incompatible with previous forbid num * num } diff --git a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr index 9f107411c102a..475410cecffa3 100644 --- a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr +++ b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr @@ -1,29 +1,29 @@ -error[E0453]: deny(unused) incompatible with previous forbid - --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:19:13 +error: deny(unused) incompatible with previous forbid + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:21:13 | LL | #![forbid(unused)] | ------ `forbid` level set here LL | #![deny(unused)] | ^^^^^^ overruled by previous forbid + | +note: the lint level is defined here + --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 -error[E0453]: warn(unused) incompatible with previous forbid +error: deny(unused) incompatible with previous forbid --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:21:13 | LL | #![forbid(unused)] | ------ `forbid` level set here -... -LL | #![warn(unused)] +LL | #![deny(unused)] | ^^^^^^ overruled by previous forbid - -error[E0453]: allow(unused) incompatible with previous forbid - --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:23:14 | -LL | #![forbid(unused)] - | ------ `forbid` level set here -... -LL | #![allow(unused)] - | ^^^^^^ overruled by previous forbid + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/lint/issue-80988.rs b/src/test/ui/lint/issue-80988.rs new file mode 100644 index 0000000000000..16a041928db73 --- /dev/null +++ b/src/test/ui/lint/issue-80988.rs @@ -0,0 +1,16 @@ +// Regression test for #80988 +// +// check-pass + +#![forbid(warnings)] + +#[deny(warnings)] +//~^ WARNING incompatible with previous forbid +//~| WARNING being phased out +//~| WARNING incompatible with previous forbid +//~| WARNING being phased out +//~| WARNING incompatible with previous forbid +//~| WARNING being phased out +//~| WARNING incompatible with previous forbid +//~| WARNING being phased out +fn main() {} diff --git a/src/test/ui/lint/issue-80988.stderr b/src/test/ui/lint/issue-80988.stderr new file mode 100644 index 0000000000000..4cae11f97c0fb --- /dev/null +++ b/src/test/ui/lint/issue-80988.stderr @@ -0,0 +1,51 @@ +warning: deny(warnings) incompatible with previous forbid + --> $DIR/issue-80988.rs:7:8 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +LL | +LL | #[deny(warnings)] + | ^^^^^^^^ overruled by previous forbid + | + = note: `#[warn(forbidden_lint_groups)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +warning: deny(warnings) incompatible with previous forbid + --> $DIR/issue-80988.rs:7:8 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +LL | +LL | #[deny(warnings)] + | ^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +warning: deny(warnings) incompatible with previous forbid + --> $DIR/issue-80988.rs:7:8 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +LL | +LL | #[deny(warnings)] + | ^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +warning: deny(warnings) incompatible with previous forbid + --> $DIR/issue-80988.rs:7:8 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +LL | +LL | #[deny(warnings)] + | ^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +warning: 4 warnings emitted + diff --git a/src/test/ui/lint/issue-81218.rs b/src/test/ui/lint/issue-81218.rs new file mode 100644 index 0000000000000..f02aa9040ebc5 --- /dev/null +++ b/src/test/ui/lint/issue-81218.rs @@ -0,0 +1,14 @@ +// Regression test for #81218 +// +// check-pass + +#![forbid(warnings)] + +#[allow(unused_variables)] +fn main() { + // We want to ensure that you don't get an error + // here. The idea is that a derive might generate + // code that would otherwise trigger the "unused variables" + // lint, but it is meant to be suppressed. + let x: (); +} diff --git a/src/test/ui/lint/outer-forbid.rs b/src/test/ui/lint/outer-forbid.rs index d45848bf706f3..486ec3c46804f 100644 --- a/src/test/ui/lint/outer-forbid.rs +++ b/src/test/ui/lint/outer-forbid.rs @@ -15,11 +15,16 @@ // compile-flags: -Z deduplicate-diagnostics=yes #![forbid(unused, non_snake_case)] +#![forbid(forbidden_lint_groups)] #[allow(unused_variables)] //~ ERROR incompatible with previous +//~^ ERROR incompatible with previous +//~| WARNING this was previously accepted by the compiler +//~| WARNING this was previously accepted by the compiler fn foo() {} #[allow(unused)] //~ ERROR incompatible with previous +//~^ WARNING this was previously accepted by the compiler fn bar() {} #[allow(nonstandard_style)] //~ ERROR incompatible with previous diff --git a/src/test/ui/lint/outer-forbid.stderr b/src/test/ui/lint/outer-forbid.stderr index c012c20697e16..d69157a8bb3ad 100644 --- a/src/test/ui/lint/outer-forbid.stderr +++ b/src/test/ui/lint/outer-forbid.stderr @@ -1,23 +1,34 @@ -error[E0453]: allow(unused_variables) incompatible with previous forbid - --> $DIR/outer-forbid.rs:19:9 +error: allow(unused_variables) incompatible with previous forbid + --> $DIR/outer-forbid.rs:20:9 | LL | #![forbid(unused, non_snake_case)] | ------ `forbid` level set here -LL | +... LL | #[allow(unused_variables)] | ^^^^^^^^^^^^^^^^ overruled by previous forbid + | +note: the lint level is defined here + --> $DIR/outer-forbid.rs:18:11 + | +LL | #![forbid(forbidden_lint_groups)] + | ^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 -error[E0453]: allow(unused) incompatible with previous forbid - --> $DIR/outer-forbid.rs:22:9 +error: allow(unused) incompatible with previous forbid + --> $DIR/outer-forbid.rs:26:9 | LL | #![forbid(unused, non_snake_case)] | ------ `forbid` level set here ... LL | #[allow(unused)] | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 error[E0453]: allow(nonstandard_style) incompatible with previous forbid - --> $DIR/outer-forbid.rs:25:9 + --> $DIR/outer-forbid.rs:30:9 | LL | #![forbid(unused, non_snake_case)] | -------------- `forbid` level set here @@ -25,6 +36,18 @@ LL | #![forbid(unused, non_snake_case)] LL | #[allow(nonstandard_style)] | ^^^^^^^^^^^^^^^^^ overruled by previous forbid -error: aborting due to 3 previous errors +error: allow(unused_variables) incompatible with previous forbid + --> $DIR/outer-forbid.rs:20:9 + | +LL | #![forbid(unused, non_snake_case)] + | ------ `forbid` level set here +... +LL | #[allow(unused_variables)] + | ^^^^^^^^^^^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0453`. diff --git a/src/test/ui/macros/assert-macro-owned.rs b/src/test/ui/macros/assert-macro-owned.rs index b50fe65c0150f..2846f2a1f8353 100644 --- a/src/test/ui/macros/assert-macro-owned.rs +++ b/src/test/ui/macros/assert-macro-owned.rs @@ -2,6 +2,8 @@ // error-pattern:panicked at 'test-assert-owned' // ignore-emscripten no processes +#![allow(non_fmt_panic)] + fn main() { assert!(false, "test-assert-owned".to_string()); } diff --git a/src/test/ui/macros/macro-comma-behavior-rpass.rs b/src/test/ui/macros/macro-comma-behavior-rpass.rs index c46274d59b658..fd2c590ae5fd6 100644 --- a/src/test/ui/macros/macro-comma-behavior-rpass.rs +++ b/src/test/ui/macros/macro-comma-behavior-rpass.rs @@ -57,7 +57,7 @@ fn writeln_1arg() { // // (Example: Issue #48042) #[test] -#[allow(panic_fmt)] +#[allow(non_fmt_panic)] fn to_format_or_not_to_format() { // ("{}" is the easiest string to test because if this gets // sent to format_args!, it'll simply fail to compile. diff --git a/src/test/ui/mir/mir_drop_order.rs b/src/test/ui/mir/mir_drop_order.rs index 2949437b1e4b6..22c804abf5cc8 100644 --- a/src/test/ui/mir/mir_drop_order.rs +++ b/src/test/ui/mir/mir_drop_order.rs @@ -38,7 +38,7 @@ fn main() { assert_eq!(get(), vec![0, 2, 3, 1]); let _ = std::panic::catch_unwind(|| { - (d(4), &d(5), d(6), &d(7), panic!(InjectedFailure)); + (d(4), &d(5), d(6), &d(7), panic::panic_any(InjectedFailure)); }); // here, the temporaries (5/7) live until the end of the diff --git a/src/test/ui/panic-brace.rs b/src/test/ui/non-fmt-panic.rs similarity index 70% rename from src/test/ui/panic-brace.rs rename to src/test/ui/non-fmt-panic.rs index 754dcc287d0f9..25c53316e1290 100644 --- a/src/test/ui/panic-brace.rs +++ b/src/test/ui/non-fmt-panic.rs @@ -13,19 +13,27 @@ fn main() { core::panic!("Hello {}"); //~ WARN panic message contains an unused formatting placeholder assert!(false, "{:03x} {test} bla"); //~^ WARN panic message contains unused formatting placeholders + assert!(false, S); + //~^ WARN panic message is not a string literal debug_assert!(false, "{{}} bla"); //~ WARN panic message contains braces - panic!(C); // No warning (yet) - panic!(S); // No warning (yet) + panic!(C); //~ WARN panic message is not a string literal + panic!(S); //~ WARN panic message is not a string literal + std::panic!(123); //~ WARN panic message is not a string literal + core::panic!(&*"abc"); //~ WARN panic message is not a string literal panic!(concat!("{", "}")); //~ WARN panic message contains an unused formatting placeholder panic!(concat!("{", "{")); //~ WARN panic message contains braces fancy_panic::fancy_panic!("test {} 123"); //~^ WARN panic message contains an unused formatting placeholder + fancy_panic::fancy_panic!(S); + //~^ WARN panic message is not a string literal + // Check that the lint only triggers for std::panic and core::panic, // not any panic macro: macro_rules! panic { ($e:expr) => (); } panic!("{}"); // OK + panic!(S); // OK } diff --git a/src/test/ui/panic-brace.stderr b/src/test/ui/non-fmt-panic.stderr similarity index 52% rename from src/test/ui/panic-brace.stderr rename to src/test/ui/non-fmt-panic.stderr index 93808891c3c37..45187c518c423 100644 --- a/src/test/ui/panic-brace.stderr +++ b/src/test/ui/non-fmt-panic.stderr @@ -1,35 +1,35 @@ warning: panic message contains a brace - --> $DIR/panic-brace.rs:11:29 + --> $DIR/non-fmt-panic.rs:11:29 | LL | panic!("here's a brace: {"); | ^ | - = note: `#[warn(panic_fmt)]` on by default - = note: this message is not used as a format string, but will be in a future Rust edition + = note: `#[warn(non_fmt_panic)]` on by default + = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | LL | panic!("{}", "here's a brace: {"); | ^^^^^ warning: panic message contains a brace - --> $DIR/panic-brace.rs:12:31 + --> $DIR/non-fmt-panic.rs:12:31 | LL | std::panic!("another one: }"); | ^ | - = note: this message is not used as a format string, but will be in a future Rust edition + = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | LL | std::panic!("{}", "another one: }"); | ^^^^^ warning: panic message contains an unused formatting placeholder - --> $DIR/panic-brace.rs:13:25 + --> $DIR/non-fmt-panic.rs:13:25 | LL | core::panic!("Hello {}"); | ^^ | - = note: this message is not used as a format string when given without arguments, but will be in a future Rust edition + = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing argument | LL | core::panic!("Hello {}", ...); @@ -40,12 +40,12 @@ LL | core::panic!("{}", "Hello {}"); | ^^^^^ warning: panic message contains unused formatting placeholders - --> $DIR/panic-brace.rs:14:21 + --> $DIR/non-fmt-panic.rs:14:21 | LL | assert!(false, "{:03x} {test} bla"); | ^^^^^^ ^^^^^^ | - = note: this message is not used as a format string when given without arguments, but will be in a future Rust edition + = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing arguments | LL | assert!(false, "{:03x} {test} bla", ...); @@ -55,25 +55,97 @@ help: or add a "{}" format string to use the message literally LL | assert!(false, "{}", "{:03x} {test} bla"); | ^^^^^ +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:16:20 + | +LL | assert!(false, S); + | ^ + | + = note: this is no longer accepted in Rust 2021 +help: add a "{}" format string to Display the message + | +LL | assert!(false, "{}", S); + | ^^^^^ + warning: panic message contains braces - --> $DIR/panic-brace.rs:16:27 + --> $DIR/non-fmt-panic.rs:18:27 | LL | debug_assert!(false, "{{}} bla"); | ^^^^ | - = note: this message is not used as a format string, but will be in a future Rust edition + = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | LL | debug_assert!(false, "{}", "{{}} bla"); | ^^^^^ +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:19:12 + | +LL | panic!(C); + | ^ + | + = note: this is no longer accepted in Rust 2021 +help: add a "{}" format string to Display the message + | +LL | panic!("{}", C); + | ^^^^^ +help: or use std::panic::panic_any instead + | +LL | std::panic::panic_any(C); + | ^^^^^^^^^^^^^^^^^^^^^^ + +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:20:12 + | +LL | panic!(S); + | ^ + | + = note: this is no longer accepted in Rust 2021 +help: add a "{}" format string to Display the message + | +LL | panic!("{}", S); + | ^^^^^ +help: or use std::panic::panic_any instead + | +LL | std::panic::panic_any(S); + | ^^^^^^^^^^^^^^^^^^^^^^ + +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:21:17 + | +LL | std::panic!(123); + | ^^^ + | + = note: this is no longer accepted in Rust 2021 +help: add a "{}" format string to Display the message + | +LL | std::panic!("{}", 123); + | ^^^^^ +help: or use std::panic::panic_any instead + | +LL | std::panic::panic_any(123); + | ^^^^^^^^^^^^^^^^^^^^^^ + +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:22:18 + | +LL | core::panic!(&*"abc"); + | ^^^^^^^ + | + = note: this is no longer accepted in Rust 2021 +help: add a "{}" format string to Display the message + | +LL | core::panic!("{}", &*"abc"); + | ^^^^^ + warning: panic message contains an unused formatting placeholder - --> $DIR/panic-brace.rs:19:12 + --> $DIR/non-fmt-panic.rs:23:12 | LL | panic!(concat!("{", "}")); | ^^^^^^^^^^^^^^^^^ | - = note: this message is not used as a format string when given without arguments, but will be in a future Rust edition + = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 help: add the missing argument | LL | panic!(concat!("{", "}"), ...); @@ -84,24 +156,32 @@ LL | panic!("{}", concat!("{", "}")); | ^^^^^ warning: panic message contains braces - --> $DIR/panic-brace.rs:20:5 + --> $DIR/non-fmt-panic.rs:24:5 | LL | panic!(concat!("{", "{")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this message is not used as a format string, but will be in a future Rust edition + = note: this message is not used as a format string, but will be in Rust 2021 help: add a "{}" format string to use the message literally | LL | panic!("{}", concat!("{", "{")); | ^^^^^ warning: panic message contains an unused formatting placeholder - --> $DIR/panic-brace.rs:22:37 + --> $DIR/non-fmt-panic.rs:26:37 | LL | fancy_panic::fancy_panic!("test {} 123"); | ^^ | - = note: this message is not used as a format string when given without arguments, but will be in a future Rust edition + = note: this message is not used as a format string when given without arguments, but will be in Rust 2021 + +warning: panic message is not a string literal + --> $DIR/non-fmt-panic.rs:29:31 + | +LL | fancy_panic::fancy_panic!(S); + | ^ + | + = note: this is no longer accepted in Rust 2021 -warning: 8 warnings emitted +warning: 14 warnings emitted diff --git a/src/test/ui/pattern/or-pattern-macro-pat.rs b/src/test/ui/or-patterns/macro-pat.rs similarity index 100% rename from src/test/ui/pattern/or-pattern-macro-pat.rs rename to src/test/ui/or-patterns/macro-pat.rs diff --git a/src/test/ui/panics/explicit-panic-msg.rs b/src/test/ui/panics/explicit-panic-msg.rs index 1789e2e62c8b2..bfcc12cd186bd 100644 --- a/src/test/ui/panics/explicit-panic-msg.rs +++ b/src/test/ui/panics/explicit-panic-msg.rs @@ -1,5 +1,6 @@ #![allow(unused_assignments)] #![allow(unused_variables)] +#![allow(non_fmt_panic)] // run-fail // error-pattern:wooooo diff --git a/src/test/ui/panics/panic-macro-any-wrapped.rs b/src/test/ui/panics/panic-macro-any-wrapped.rs index 80c87c6f32c4b..95ae6ffe8be02 100644 --- a/src/test/ui/panics/panic-macro-any-wrapped.rs +++ b/src/test/ui/panics/panic-macro-any-wrapped.rs @@ -2,6 +2,8 @@ // error-pattern:panicked at 'Box' // ignore-emscripten no processes +#![allow(non_fmt_panic)] + fn main() { panic!(Box::new(612_i64)); } diff --git a/src/test/ui/panics/panic-macro-any.rs b/src/test/ui/panics/panic-macro-any.rs index ffc7114c1f5f2..d2a7ba3713a51 100644 --- a/src/test/ui/panics/panic-macro-any.rs +++ b/src/test/ui/panics/panic-macro-any.rs @@ -3,6 +3,7 @@ // ignore-emscripten no processes #![feature(box_syntax)] +#![allow(non_fmt_panic)] fn main() { panic!(box 413 as Box); diff --git a/src/test/ui/panics/while-panic.rs b/src/test/ui/panics/while-panic.rs index 857f65a225228..3c6ee8fa3155e 100644 --- a/src/test/ui/panics/while-panic.rs +++ b/src/test/ui/panics/while-panic.rs @@ -5,7 +5,7 @@ // ignore-emscripten no processes fn main() { - panic!({ + panic!("{}", { while true { panic!("giraffe") } diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index a17c5996293e9..4ee423b383b0f 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -2183,7 +2183,7 @@ fn lint_expect_fun_call( span_replace_word, &format!("use of `{}` followed by a function call", name), "try this", - format!("unwrap_or_else({} {{ panic!({}) }})", closure_args, arg_root_snippet), + format!("unwrap_or_else({} {{ panic!(\"{{}}\", {}) }})", closure_args, arg_root_snippet), applicability, ); } diff --git a/src/tools/clippy/clippy_lints/src/misc_early.rs b/src/tools/clippy/clippy_lints/src/misc_early.rs index 5bc45c87874b4..84a0df92f5b43 100644 --- a/src/tools/clippy/clippy_lints/src/misc_early.rs +++ b/src/tools/clippy/clippy_lints/src/misc_early.rs @@ -1,4 +1,4 @@ -use crate::utils::{constants, snippet_opt, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then}; +use crate::utils::{snippet_opt, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then}; use rustc_ast::ast::{ BindingMode, Expr, ExprKind, GenericParamKind, Generics, Lit, LitFloatType, LitIntType, LitKind, Mutability, NodeId, Pat, PatKind, UnOp, @@ -6,6 +6,7 @@ use rustc_ast::ast::{ use rustc_ast::visit::FnKind; use rustc_data_structures::fx::FxHashMap; use rustc_errors::Applicability; +use rustc_hir::PrimTy; use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -264,13 +265,12 @@ impl EarlyLintPass for MiscEarlyLints { fn check_generics(&mut self, cx: &EarlyContext<'_>, gen: &Generics) { for param in &gen.params { if let GenericParamKind::Type { .. } = param.kind { - let name = param.ident.as_str(); - if constants::BUILTIN_TYPES.contains(&&*name) { + if let Some(prim_ty) = PrimTy::from_name(param.ident.name) { span_lint( cx, BUILTIN_TYPE_SHADOW, param.ident.span, - &format!("this generic shadows the built-in type `{}`", name), + &format!("this generic shadows the built-in type `{}`", prim_ty.name()), ); } } diff --git a/src/tools/clippy/clippy_lints/src/utils/constants.rs b/src/tools/clippy/clippy_lints/src/utils/constants.rs deleted file mode 100644 index 522932f054d89..0000000000000 --- a/src/tools/clippy/clippy_lints/src/utils/constants.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! This module contains some useful constants. - -#![deny(clippy::missing_docs_in_private_items)] - -/// List of the built-in types names. -/// -/// See also [the reference][reference-types] for a list of such types. -/// -/// [reference-types]: https://doc.rust-lang.org/reference/types.html -pub const BUILTIN_TYPES: &[&str] = &[ - "i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "i128", "u128", "isize", "usize", "f32", "f64", "bool", - "str", "char", -]; diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs index ef45f9fdcd5d4..de1538233a8c3 100644 --- a/src/tools/clippy/clippy_lints/src/utils/mod.rs +++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs @@ -8,7 +8,6 @@ pub mod author; pub mod camel_case; pub mod comparisons; pub mod conf; -pub mod constants; mod diagnostics; pub mod eager_or_lazy; pub mod higher; diff --git a/src/tools/clippy/tests/missing-test-files.rs b/src/tools/clippy/tests/missing-test-files.rs index d87bb4be3c3f9..9cef7438d225c 100644 --- a/src/tools/clippy/tests/missing-test-files.rs +++ b/src/tools/clippy/tests/missing-test-files.rs @@ -9,14 +9,12 @@ fn test_missing_tests() { if !missing_files.is_empty() { assert!( false, - format!( - "Didn't see a test file for the following files:\n\n{}\n", - missing_files - .iter() - .map(|s| format!("\t{}", s)) - .collect::>() - .join("\n") - ) + "Didn't see a test file for the following files:\n\n{}\n", + missing_files + .iter() + .map(|s| format!("\t{}", s)) + .collect::>() + .join("\n") ); } } diff --git a/src/tools/clippy/tests/ui/assertions_on_constants.rs b/src/tools/clippy/tests/ui/assertions_on_constants.rs index 60d721c2f2049..e989de6540456 100644 --- a/src/tools/clippy/tests/ui/assertions_on_constants.rs +++ b/src/tools/clippy/tests/ui/assertions_on_constants.rs @@ -1,3 +1,5 @@ +#![allow(non_fmt_panic)] + macro_rules! assert_const { ($len:expr) => { assert!($len > 0); diff --git a/src/tools/clippy/tests/ui/assertions_on_constants.stderr b/src/tools/clippy/tests/ui/assertions_on_constants.stderr index 8f09c8ce9d52a..c66fdf093f514 100644 --- a/src/tools/clippy/tests/ui/assertions_on_constants.stderr +++ b/src/tools/clippy/tests/ui/assertions_on_constants.stderr @@ -1,5 +1,5 @@ error: `assert!(true)` will be optimized out by the compiler - --> $DIR/assertions_on_constants.rs:9:5 + --> $DIR/assertions_on_constants.rs:11:5 | LL | assert!(true); | ^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | assert!(true); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `assert!(false)` should probably be replaced - --> $DIR/assertions_on_constants.rs:10:5 + --> $DIR/assertions_on_constants.rs:12:5 | LL | assert!(false); | ^^^^^^^^^^^^^^^ @@ -18,7 +18,7 @@ LL | assert!(false); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `assert!(true)` will be optimized out by the compiler - --> $DIR/assertions_on_constants.rs:11:5 + --> $DIR/assertions_on_constants.rs:13:5 | LL | assert!(true, "true message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | assert!(true, "true message"); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `assert!(false, "false message")` should probably be replaced - --> $DIR/assertions_on_constants.rs:12:5 + --> $DIR/assertions_on_constants.rs:14:5 | LL | assert!(false, "false message"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | assert!(false, "false message"); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `assert!(false, msg.to_uppercase())` should probably be replaced - --> $DIR/assertions_on_constants.rs:15:5 + --> $DIR/assertions_on_constants.rs:17:5 | LL | assert!(false, msg.to_uppercase()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | assert!(false, msg.to_uppercase()); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `assert!(true)` will be optimized out by the compiler - --> $DIR/assertions_on_constants.rs:18:5 + --> $DIR/assertions_on_constants.rs:20:5 | LL | assert!(B); | ^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | assert!(B); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `assert!(false)` should probably be replaced - --> $DIR/assertions_on_constants.rs:21:5 + --> $DIR/assertions_on_constants.rs:23:5 | LL | assert!(C); | ^^^^^^^^^^^ @@ -63,7 +63,7 @@ LL | assert!(C); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `assert!(false, "C message")` should probably be replaced - --> $DIR/assertions_on_constants.rs:22:5 + --> $DIR/assertions_on_constants.rs:24:5 | LL | assert!(C, "C message"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | assert!(C, "C message"); = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) error: `debug_assert!(true)` will be optimized out by the compiler - --> $DIR/assertions_on_constants.rs:24:5 + --> $DIR/assertions_on_constants.rs:26:5 | LL | debug_assert!(true); | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/expect_fun_call.fixed b/src/tools/clippy/tests/ui/expect_fun_call.fixed index f3d8a941a92bc..a756d1cf50659 100644 --- a/src/tools/clippy/tests/ui/expect_fun_call.fixed +++ b/src/tools/clippy/tests/ui/expect_fun_call.fixed @@ -74,12 +74,12 @@ fn main() { "foo" } - Some("foo").unwrap_or_else(|| { panic!(get_string()) }); - Some("foo").unwrap_or_else(|| { panic!(get_string()) }); - Some("foo").unwrap_or_else(|| { panic!(get_string()) }); + Some("foo").unwrap_or_else(|| { panic!("{}", get_string()) }); + Some("foo").unwrap_or_else(|| { panic!("{}", get_string()) }); + Some("foo").unwrap_or_else(|| { panic!("{}", get_string()) }); - Some("foo").unwrap_or_else(|| { panic!(get_static_str()) }); - Some("foo").unwrap_or_else(|| { panic!(get_non_static_str(&0).to_string()) }); + Some("foo").unwrap_or_else(|| { panic!("{}", get_static_str()) }); + Some("foo").unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) }); } //Issue #3839 diff --git a/src/tools/clippy/tests/ui/expect_fun_call.stderr b/src/tools/clippy/tests/ui/expect_fun_call.stderr index a492e2df89d47..6dc796f5cee37 100644 --- a/src/tools/clippy/tests/ui/expect_fun_call.stderr +++ b/src/tools/clippy/tests/ui/expect_fun_call.stderr @@ -34,31 +34,31 @@ error: use of `expect` followed by a function call --> $DIR/expect_fun_call.rs:77:21 | LL | Some("foo").expect(&get_string()); - | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!(get_string()) })` + | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: use of `expect` followed by a function call --> $DIR/expect_fun_call.rs:78:21 | LL | Some("foo").expect(get_string().as_ref()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!(get_string()) })` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: use of `expect` followed by a function call --> $DIR/expect_fun_call.rs:79:21 | LL | Some("foo").expect(get_string().as_str()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!(get_string()) })` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: use of `expect` followed by a function call --> $DIR/expect_fun_call.rs:81:21 | LL | Some("foo").expect(get_static_str()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!(get_static_str()) })` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_static_str()) })` error: use of `expect` followed by a function call --> $DIR/expect_fun_call.rs:82:21 | LL | Some("foo").expect(get_non_static_str(&0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!(get_non_static_str(&0).to_string()) })` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) })` error: use of `expect` followed by a function call --> $DIR/expect_fun_call.rs:86:16 diff --git a/src/tools/clippy/tests/ui/fallible_impl_from.rs b/src/tools/clippy/tests/ui/fallible_impl_from.rs index 679f4a7dc357d..5d5af4e463297 100644 --- a/src/tools/clippy/tests/ui/fallible_impl_from.rs +++ b/src/tools/clippy/tests/ui/fallible_impl_from.rs @@ -36,7 +36,7 @@ impl From> for Invalid { fn from(s: Option) -> Invalid { let s = s.unwrap(); if !s.is_empty() { - panic!(42); + panic!("42"); } else if s.parse::().unwrap() != 42 { panic!("{:?}", s); } diff --git a/src/tools/clippy/tests/ui/fallible_impl_from.stderr b/src/tools/clippy/tests/ui/fallible_impl_from.stderr index ab976b947b356..f787b30bdabc5 100644 --- a/src/tools/clippy/tests/ui/fallible_impl_from.stderr +++ b/src/tools/clippy/tests/ui/fallible_impl_from.stderr @@ -59,8 +59,8 @@ note: potential failure(s) LL | let s = s.unwrap(); | ^^^^^^^^^^ LL | if !s.is_empty() { -LL | panic!(42); - | ^^^^^^^^^^^ +LL | panic!("42"); + | ^^^^^^^^^^^^^ LL | } else if s.parse::().unwrap() != 42 { | ^^^^^^^^^^^^^^^^^^^^^^^^^ LL | panic!("{:?}", s); diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index d92758eb7474c..cd9d530096496 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -218,25 +218,19 @@ fn handle_run(socket: TcpStream, work: &Path, tmp: &Path, lock: &Mutex<()>, conf cmd.args(args); cmd.envs(env); + // On windows, libraries are just searched in the executable directory, + // system directories, PWD, and PATH, in that order. PATH is the only one + // we can change for this. + let library_path = if cfg!(windows) { "PATH" } else { "LD_LIBRARY_PATH" }; + // Support libraries were uploaded to `work` earlier, so make sure that's // in `LD_LIBRARY_PATH`. Also include our own current dir which may have // had some libs uploaded. - if cfg!(windows) { - // On windows, libraries are just searched in the executable directory, - // system directories, PWD, and PATH, in that order. PATH is the only one - // we can change for this. - cmd.env( - "PATH", - env::join_paths( - std::iter::once(work.to_owned()) - .chain(std::iter::once(path.clone())) - .chain(env::split_paths(&env::var_os("PATH").unwrap())), - ) - .unwrap(), - ); - } else { - cmd.env("LD_LIBRARY_PATH", format!("{}:{}", work.display(), path.display())); + let mut paths = vec![work.to_owned(), path.clone()]; + if let Some(library_path) = env::var_os(library_path) { + paths.extend(env::split_paths(&library_path)); } + cmd.env(library_path, env::join_paths(paths).unwrap()); // Some tests assume RUST_TEST_TMPDIR exists cmd.env("RUST_TEST_TMPDIR", tmp.to_owned());