1
Fork 0

Auto merge of #81761 - m-ou-se:rollup-xp7v07n, r=m-ou-se

Rollup of 9 pull requests

Successful merges:

 - #74304 (Stabilize the Wake trait)
 - #79805 (Rename Iterator::fold_first to reduce and stabilize it)
 - #81556 (introduce future-compatibility warning for forbidden lint groups)
 - #81645 (Add lint for `panic!(123)` which is not accepted in Rust 2021.)
 - #81710 (OsStr eq_ignore_ascii_case takes arg by value)
 - #81711 (add #[inline] to all the public IpAddr functions)
 - #81725 (Move test to be with the others)
 - #81727 (Revert stabilizing integer::BITS.)
 - #81745 (Stabilize poison API of Once, rename poisoned())

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-02-04 23:16:08 +00:00
commit dab3a80f23
72 changed files with 1122 additions and 355 deletions

View file

@ -14,7 +14,6 @@
#![feature(const_fn_transmute)] #![feature(const_fn_transmute)]
#![feature(const_panic)] #![feature(const_panic)]
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(iterator_fold_self)]
#![feature(label_break_value)] #![feature(label_break_value)]
#![feature(nll)] #![feature(nll)]
#![feature(or_patterns)] #![feature(or_patterns)]

View file

@ -28,7 +28,7 @@ pub trait ExpectOne<A: Array> {
impl<A: Array> ExpectOne<A> for SmallVec<A> { impl<A: Array> ExpectOne<A> for SmallVec<A> {
fn expect_one(self, err: &'static str) -> A::Item { fn expect_one(self, err: &'static str) -> A::Item {
assert!(self.len() == 1, err); assert!(self.len() == 1, "{}", err);
self.into_iter().next().unwrap() self.into_iter().next().unwrap()
} }
} }

View file

@ -13,6 +13,7 @@
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(generator_trait)] #![feature(generator_trait)]
#![feature(fn_traits)] #![feature(fn_traits)]
#![feature(int_bits_const)]
#![feature(min_specialization)] #![feature(min_specialization)]
#![feature(auto_traits)] #![feature(auto_traits)]
#![feature(nll)] #![feature(nll)]

View file

@ -901,7 +901,7 @@ impl HandlerInner {
fn span_bug(&mut self, sp: impl Into<MultiSpan>, msg: &str) -> ! { fn span_bug(&mut self, sp: impl Into<MultiSpan>, msg: &str) -> ! {
self.emit_diag_at_span(Diagnostic::new(Bug, msg), sp); 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<MultiSpan>) { fn emit_diag_at_span(&mut self, mut diag: Diagnostic, sp: impl Into<MultiSpan>) {
@ -955,7 +955,7 @@ impl HandlerInner {
fn bug(&mut self, msg: &str) -> ! { fn bug(&mut self, msg: &str) -> ! {
self.emit_diagnostic(&Diagnostic::new(Bug, msg)); self.emit_diagnostic(&Diagnostic::new(Bug, msg));
panic!(ExplicitBug); panic::panic_any(ExplicitBug);
} }
fn delay_as_bug(&mut self, diagnostic: Diagnostic) { fn delay_as_bug(&mut self, diagnostic: Diagnostic) {

View file

@ -358,7 +358,7 @@ impl GenericArgs<'_> {
.iter() .iter()
.filter(|arg| !arg.is_synthetic()) .filter(|arg| !arg.is_synthetic())
.map(|arg| arg.span()) .map(|arg| arg.span())
.fold_first(|span1, span2| span1.to(span2)) .reduce(|span1, span2| span1.to(span2))
} }
/// Returns span encompassing arguments and their surrounding `<>` or `()` /// Returns span encompassing arguments and their surrounding `<>` or `()`

View file

@ -6,7 +6,6 @@
#![feature(const_fn)] // For the unsizing cast on `&[]` #![feature(const_fn)] // For the unsizing cast on `&[]`
#![feature(const_panic)] #![feature(const_panic)]
#![feature(in_band_lifetimes)] #![feature(in_band_lifetimes)]
#![feature(iterator_fold_self)]
#![feature(once_cell)] #![feature(once_cell)]
#![feature(or_patterns)] #![feature(or_patterns)]
#![recursion_limit = "256"] #![recursion_limit = "256"]

View file

@ -39,6 +39,7 @@ use rustc_session::SessionLintStore;
use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP}; use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
use rustc_target::abi::LayoutOf; use rustc_target::abi::LayoutOf;
use tracing::debug;
use std::cell::Cell; use std::cell::Cell;
use std::slice; 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::<Vec<_>>()
);
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 /// Checks the name of a lint for its existence, and whether it was
/// renamed or removed. Generates a DiagnosticBuilder containing a /// renamed or removed. Generates a DiagnosticBuilder containing a
/// warning for renamed and removed lints. This is over both lint /// warning for renamed and removed lints. This is over both lint

View file

@ -5,7 +5,7 @@ use rustc_ast::attr;
use rustc_ast::unwrap_or; use rustc_ast::unwrap_or;
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap; 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 as hir;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_hir::{intravisit, HirId}; use rustc_hir::{intravisit, HirId};
@ -17,11 +17,15 @@ use rustc_middle::lint::{
}; };
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt; 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::parse::feature_err;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
use rustc_span::{source_map::MultiSpan, Span, DUMMY_SP}; use rustc_span::{source_map::MultiSpan, Span, DUMMY_SP};
use tracing::debug;
use std::cmp; use std::cmp;
@ -51,6 +55,7 @@ pub struct LintLevelsBuilder<'s> {
id_to_set: FxHashMap<HirId, u32>, id_to_set: FxHashMap<HirId, u32>,
cur: u32, cur: u32,
warn_about_weird_lints: bool, warn_about_weird_lints: bool,
store: &'s LintStore,
} }
pub struct BuilderPush { pub struct BuilderPush {
@ -59,13 +64,14 @@ pub struct BuilderPush {
} }
impl<'s> LintLevelsBuilder<'s> { 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 { let mut builder = LintLevelsBuilder {
sess, sess,
sets: LintLevelSets::new(), sets: LintLevelSets::new(),
cur: 0, cur: 0,
id_to_set: Default::default(), id_to_set: Default::default(),
warn_about_weird_lints, warn_about_weird_lints,
store,
}; };
builder.process_command_line(sess, store); builder.process_command_line(sess, store);
assert_eq!(builder.sets.list.len(), 1); assert_eq!(builder.sets.list.len(), 1);
@ -120,36 +126,75 @@ impl<'s> LintLevelsBuilder<'s> {
if let (Level::Forbid, old_src) = if let (Level::Forbid, old_src) =
self.sets.get_lint_level(id.lint, self.cur, Some(&specs), &self.sess) self.sets.get_lint_level(id.lint, self.cur, Some(&specs), &self.sess)
{ {
let mut diag_builder = struct_span_err!( // Backwards compatibility check:
self.sess, //
src.span(), // We used to not consider `forbid(lint_group)`
E0453, // as preventing `allow(lint)` for some lint `lint` in
"{}({}) incompatible with previous forbid", // `lint_group`. For now, issue a future-compatibility
level.as_str(), // warning for this case.
src.name(), 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 { let decorate_diag_builder = |mut diag_builder: DiagnosticBuilder<'_>| {
LintLevelSource::Default => { diag_builder.span_label(src.span(), "overruled by previous forbid");
diag_builder.note(&format!( match old_src {
"`forbid` lint level is the default for {}", LintLevelSource::Default => {
id.to_string() 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 { LintLevelSource::Node(_, forbid_source_span, reason) => {
diag_builder.note(&rationale.as_str()); 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.emit();
diag_builder.note("`forbid` lint level was set on command line"); };
} 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 // Retain the forbid lint level, unless we are
return; // issuing a FCW. In the FCW case, we want to
// respect the new setting.
if !fcw_warning {
return;
}
} }
} }
specs.insert(id, (level, src)); specs.insert(id, (level, src));

View file

@ -55,8 +55,8 @@ mod late;
mod levels; mod levels;
mod methods; mod methods;
mod non_ascii_idents; mod non_ascii_idents;
mod non_fmt_panic;
mod nonstandard_style; mod nonstandard_style;
mod panic_fmt;
mod passes; mod passes;
mod redundant_semicolon; mod redundant_semicolon;
mod traits; mod traits;
@ -81,8 +81,8 @@ use builtin::*;
use internal::*; use internal::*;
use methods::*; use methods::*;
use non_ascii_idents::*; use non_ascii_idents::*;
use non_fmt_panic::NonPanicFmt;
use nonstandard_style::*; use nonstandard_style::*;
use panic_fmt::PanicFmt;
use redundant_semicolon::*; use redundant_semicolon::*;
use traits::*; use traits::*;
use types::*; use types::*;
@ -169,7 +169,7 @@ macro_rules! late_lint_passes {
ClashingExternDeclarations: ClashingExternDeclarations::new(), ClashingExternDeclarations: ClashingExternDeclarations::new(),
DropTraitConstraints: DropTraitConstraints, DropTraitConstraints: DropTraitConstraints,
TemporaryCStringAsPtr: TemporaryCStringAsPtr, TemporaryCStringAsPtr: TemporaryCStringAsPtr,
PanicFmt: PanicFmt, NonPanicFmt: NonPanicFmt,
] ]
); );
}; };

View file

@ -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<Vec<_>> =
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)
}

View file

@ -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<Vec<_>> = 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();
});
}
}
}
}
}
}

View file

@ -5,10 +5,48 @@
//! compiler code, rather than using their own custom pass. Those //! compiler code, rather than using their own custom pass. Those
//! lints are all available in `rustc_lint::builtin`. //! lints are all available in `rustc_lint::builtin`.
// ignore-tidy-filelength
use crate::{declare_lint, declare_lint_pass}; use crate::{declare_lint, declare_lint_pass};
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::symbol::sym; 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 <https://github.com/rust-lang/rust/issues/81670>",
edition: None,
};
}
declare_lint! { declare_lint! {
/// The `ill_formed_attribute_input` lint detects ill-formed attribute /// The `ill_formed_attribute_input` lint detects ill-formed attribute
/// inputs that were previously accepted and used in practice. /// 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 /// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler. /// that are used by other parts of the compiler.
HardwiredLints => [ HardwiredLints => [
FORBIDDEN_LINT_GROUPS,
ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
ARITHMETIC_OVERFLOW, ARITHMETIC_OVERFLOW,
UNCONDITIONAL_PANIC, UNCONDITIONAL_PANIC,

View file

@ -5,7 +5,10 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_errors::{DiagnosticBuilder, DiagnosticId}; use rustc_errors::{DiagnosticBuilder, DiagnosticId};
use rustc_hir::HirId; 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_session::{DiagnosticMessageId, Session};
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::{DesugaringKind, ExpnKind, MultiSpan}; 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 // 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 // directives against the warnings "lint". If, for example, there's an
// `allow(warnings)` in scope then we want to respect that instead. // `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) = let (warnings_level, warnings_src) =
self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux); self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux);
if let Some(configured_warning_level) = warnings_level { if let Some(configured_warning_level) = warnings_level {

View file

@ -3,7 +3,7 @@
use crate::ty::{tls, TyCtxt}; use crate::ty::{tls, TyCtxt};
use rustc_span::{MultiSpan, Span}; use rustc_span::{MultiSpan, Span};
use std::fmt; use std::fmt;
use std::panic::Location; use std::panic::{panic_any, Location};
#[cold] #[cold]
#[inline(never)] #[inline(never)]
@ -32,7 +32,7 @@ fn opt_span_bug_fmt<S: Into<MultiSpan>>(
match (tcx, span) { match (tcx, span) {
(Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, &msg), (Some(tcx), Some(span)) => tcx.sess.diagnostic().span_bug(span, &msg),
(Some(tcx), None) => tcx.sess.diagnostic().bug(&msg), (Some(tcx), None) => tcx.sess.diagnostic().bug(&msg),
(None, _) => panic!(msg), (None, _) => panic_any(msg),
} }
}); });
unreachable!(); unreachable!();

View file

@ -17,6 +17,7 @@ Core encoding and decoding interfaces.
#![feature(min_specialization)] #![feature(min_specialization)]
#![feature(vec_spare_capacity)] #![feature(vec_spare_capacity)]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(int_bits_const)]
#![feature(maybe_uninit_slice)] #![feature(maybe_uninit_slice)]
#![feature(new_uninit)] #![feature(new_uninit)]
#![cfg_attr(test, feature(test))] #![cfg_attr(test, feature(test))]

View file

@ -1,3 +1,4 @@
#![feature(int_bits_const)]
#![feature(maybe_uninit_slice)] #![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_uninit_array)]

View file

@ -102,6 +102,7 @@
#![feature(fn_traits)] #![feature(fn_traits)]
#![feature(fundamental)] #![feature(fundamental)]
#![feature(inplace_iteration)] #![feature(inplace_iteration)]
#![feature(int_bits_const)]
#![feature(lang_items)] #![feature(lang_items)]
#![feature(layout_for_ptr)] #![feature(layout_for_ptr)]
#![feature(maybe_uninit_ref)] #![feature(maybe_uninit_ref)]

View file

@ -1,4 +1,4 @@
#![unstable(feature = "wake_trait", issue = "69912")] #![stable(feature = "wake_trait", since = "1.51.0")]
//! Types and Traits for working with asynchronous tasks. //! Types and Traits for working with asynchronous tasks.
use core::mem::ManuallyDrop; use core::mem::ManuallyDrop;
use core::task::{RawWaker, RawWakerVTable, Waker}; use core::task::{RawWaker, RawWakerVTable, Waker};
@ -16,18 +16,70 @@ use crate::sync::Arc;
/// to wake up a task is stored in an [`Arc`]. Some executors (especially /// to wake up a task is stored in an [`Arc`]. Some executors (especially
/// those for embedded systems) cannot use this API, which is why [`RawWaker`] /// those for embedded systems) cannot use this API, which is why [`RawWaker`]
/// exists as an alternative for those systems. /// exists as an alternative for those systems.
#[unstable(feature = "wake_trait", issue = "69912")] ///
/// [arc]: ../../std/sync/struct.Arc.html
///
/// # Examples
///
/// A basic `block_on` function that takes a future and runs it to completion on
/// the current thread.
///
/// **Note:** This example trades correctness for simplicity. In order to prevent
/// deadlocks, production-grade implementations will also need to handle
/// intermediate calls to `thread::unpark` as well as nested invocations.
///
/// ```rust
/// use std::future::Future;
/// use std::sync::Arc;
/// use std::task::{Context, Poll, Wake};
/// use std::thread::{self, Thread};
///
/// /// A waker that wakes up the current thread when called.
/// struct ThreadWaker(Thread);
///
/// impl Wake for ThreadWaker {
/// fn wake(self: Arc<Self>) {
/// self.0.unpark();
/// }
/// }
///
/// /// Run a future to completion on the current thread.
/// fn block_on<T>(fut: impl Future<Output = T>) -> T {
/// // Pin the future so it can be polled.
/// let mut fut = Box::pin(fut);
///
/// // Create a new context to be passed to the future.
/// let t = thread::current();
/// let waker = Arc::new(ThreadWaker(t)).into();
/// let mut cx = Context::from_waker(&waker);
///
/// // Run the future to completion.
/// loop {
/// match fut.as_mut().poll(&mut cx) {
/// Poll::Ready(res) => return res,
/// Poll::Pending => thread::park(),
/// }
/// }
/// }
///
/// block_on(async {
/// println!("Hi from inside a future!");
/// });
/// ```
#[stable(feature = "wake_trait", since = "1.51.0")]
pub trait Wake { pub trait Wake {
/// Wake this task. /// Wake this task.
#[unstable(feature = "wake_trait", issue = "69912")] #[stable(feature = "wake_trait", since = "1.51.0")]
fn wake(self: Arc<Self>); fn wake(self: Arc<Self>);
/// Wake this task without consuming the waker. /// Wake this task without consuming the waker.
/// ///
/// If an executor supports a cheaper way to wake without consuming the /// If an executor supports a cheaper way to wake without consuming the
/// waker, it should override this method. By default, it clones the /// waker, it should override this method. By default, it clones the
/// [`Arc`] and calls `wake` on the clone. /// [`Arc`] and calls [`wake`] on the clone.
#[unstable(feature = "wake_trait", issue = "69912")] ///
/// [`wake`]: Wake::wake
#[stable(feature = "wake_trait", since = "1.51.0")]
fn wake_by_ref(self: &Arc<Self>) { fn wake_by_ref(self: &Arc<Self>) {
self.clone().wake(); self.clone().wake();
} }
@ -35,7 +87,7 @@ pub trait Wake {
#[cfg_attr(bootstrap, allow(rustc::ineffective_unstable_trait_impl))] #[cfg_attr(bootstrap, allow(rustc::ineffective_unstable_trait_impl))]
#[cfg_attr(not(bootstrap), allow(ineffective_unstable_trait_impl))] #[cfg_attr(not(bootstrap), allow(ineffective_unstable_trait_impl))]
#[unstable(feature = "wake_trait", issue = "69912")] #[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker { impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
fn from(waker: Arc<W>) -> Waker { fn from(waker: Arc<W>) -> Waker {
// SAFETY: This is safe because raw_waker safely constructs // SAFETY: This is safe because raw_waker safely constructs
@ -46,7 +98,7 @@ impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
#[cfg_attr(bootstrap, allow(rustc::ineffective_unstable_trait_impl))] #[cfg_attr(bootstrap, allow(rustc::ineffective_unstable_trait_impl))]
#[cfg_attr(not(bootstrap), allow(ineffective_unstable_trait_impl))] #[cfg_attr(not(bootstrap), allow(ineffective_unstable_trait_impl))]
#[unstable(feature = "wake_trait", issue = "69912")] #[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker { impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
fn from(waker: Arc<W>) -> RawWaker { fn from(waker: Arc<W>) -> RawWaker {
raw_waker(waker) raw_waker(waker)

View file

@ -17,6 +17,7 @@
#![feature(binary_heap_retain)] #![feature(binary_heap_retain)]
#![feature(inplace_iteration)] #![feature(inplace_iteration)]
#![feature(iter_map_while)] #![feature(iter_map_while)]
#![feature(int_bits_const)]
#![feature(vecdeque_binary_search)] #![feature(vecdeque_binary_search)]
#![feature(slice_group_by)] #![feature(slice_group_by)]
#![feature(vec_extend_from_within)] #![feature(vec_extend_from_within)]

View file

@ -2028,7 +2028,8 @@ pub trait Iterator {
self.try_fold((), call(f)) self.try_fold((), call(f))
} }
/// An iterator method that applies a function, producing a single, final value. /// Folds every element into an accumulator by applying an operation,
/// returning the final result.
/// ///
/// `fold()` takes two arguments: an initial value, and a closure with two /// `fold()` takes two arguments: an initial value, and a closure with two
/// arguments: an 'accumulator', and an element. The closure returns the value that /// arguments: an 'accumulator', and an element. The closure returns the value that
@ -2049,6 +2050,9 @@ pub trait Iterator {
/// may not terminate for infinite iterators, even on traits for which a /// may not terminate for infinite iterators, even on traits for which a
/// result is determinable in finite time. /// result is determinable in finite time.
/// ///
/// Note: [`reduce()`] can be used to use the first element as the initial
/// value, if the accumulator type and item type is the same.
///
/// # Note to Implementors /// # Note to Implementors
/// ///
/// Several of the other (forward) methods have default implementations in /// Several of the other (forward) methods have default implementations in
@ -2104,6 +2108,8 @@ pub trait Iterator {
/// // they're the same /// // they're the same
/// assert_eq!(result, result2); /// assert_eq!(result, result2);
/// ``` /// ```
///
/// [`reduce()`]: Iterator::reduce
#[doc(alias = "reduce")] #[doc(alias = "reduce")]
#[doc(alias = "inject")] #[doc(alias = "inject")]
#[inline] #[inline]
@ -2120,10 +2126,15 @@ pub trait Iterator {
accum accum
} }
/// The same as [`fold()`], but uses the first element in the /// Reduces the elements to a single one, by repeatedly applying a reducing
/// iterator as the initial value, folding every subsequent element into it. /// operation.
/// If the iterator is empty, return [`None`]; otherwise, return the result ///
/// of the fold. /// If the iterator is empty, returns [`None`]; otherwise, returns the
/// result of the reduction.
///
/// For iterators with at least one element, this is the same as [`fold()`]
/// with the first element of the iterator as the initial value, folding
/// every subsequent element into it.
/// ///
/// [`fold()`]: Iterator::fold /// [`fold()`]: Iterator::fold
/// ///
@ -2132,13 +2143,11 @@ pub trait Iterator {
/// Find the maximum value: /// Find the maximum value:
/// ///
/// ``` /// ```
/// #![feature(iterator_fold_self)]
///
/// fn find_max<I>(iter: I) -> Option<I::Item> /// fn find_max<I>(iter: I) -> Option<I::Item>
/// where I: Iterator, /// where I: Iterator,
/// I::Item: Ord, /// I::Item: Ord,
/// { /// {
/// iter.fold_first(|a, b| { /// iter.reduce(|a, b| {
/// if a >= b { a } else { b } /// if a >= b { a } else { b }
/// }) /// })
/// } /// }
@ -2149,8 +2158,8 @@ pub trait Iterator {
/// assert_eq!(find_max(b.iter()), None); /// assert_eq!(find_max(b.iter()), None);
/// ``` /// ```
#[inline] #[inline]
#[unstable(feature = "iterator_fold_self", issue = "68125")] #[stable(feature = "iterator_fold_self", since = "1.51.0")]
fn fold_first<F>(mut self, f: F) -> Option<Self::Item> fn reduce<F>(mut self, f: F) -> Option<Self::Item>
where where
Self: Sized, Self: Sized,
F: FnMut(Self::Item, Self::Item) -> Self::Item, F: FnMut(Self::Item, Self::Item) -> Self::Item,
@ -2647,7 +2656,7 @@ pub trait Iterator {
move |x, y| cmp::max_by(x, y, &mut compare) move |x, y| cmp::max_by(x, y, &mut compare)
} }
self.fold_first(fold(compare)) self.reduce(fold(compare))
} }
/// Returns the element that gives the minimum value from the /// Returns the element that gives the minimum value from the
@ -2707,7 +2716,7 @@ pub trait Iterator {
move |x, y| cmp::min_by(x, y, &mut compare) move |x, y| cmp::min_by(x, y, &mut compare)
} }
self.fold_first(fold(compare)) self.reduce(fold(compare))
} }
/// Reverses an iterator's direction. /// Reverses an iterator's direction.

View file

@ -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. `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 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, panic entirely. This macro panics with a string and uses the [`format!`] syntax
and the single-argument form of the `panic!` macro will be the value which for building the message.
is transmitted.
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 [`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 using the `panic!` macro. This macro should be used to avoid proceeding using
incorrect values, such as from external sources. Detailed information about incorrect values, such as from external sources. Detailed information about
error handling is found in the [book]. 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. See also the macro [`compile_error!`], for raising errors during compilation.
[ounwrap]: Option::unwrap [ounwrap]: Option::unwrap
[runwrap]: Result::unwrap [runwrap]: Result::unwrap
[`panic_any`]: ../std/panic/fn.panic_any.html
[`Box`]: ../std/boxed/struct.Box.html [`Box`]: ../std/boxed/struct.Box.html
[`Any`]: crate::any::Any [`Any`]: crate::any::Any
[`format!`]: ../std/macro.format.html [`format!`]: ../std/macro.format.html
@ -42,6 +43,6 @@ program with code `101`.
# #![allow(unreachable_code)] # #![allow(unreachable_code)]
panic!(); panic!();
panic!("this is a terrible mistake!"); 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"); panic!("this is a {} {message}", "fancy", message = "message");
std::panic::panic_any(4); // panic with the value of 4 to be collected elsewhere
``` ```

View file

@ -32,9 +32,10 @@ macro_rules! int_impl {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(int_bits_const)]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")] #[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; pub const BITS: u32 = $BITS;
/// Converts a string slice in a given base to an integer. /// Converts a string slice in a given base to an integer.

View file

@ -32,9 +32,10 @@ macro_rules! uint_impl {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(int_bits_const)]
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::BITS, ", stringify!($BITS), ");")] #[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; pub const BITS: u32 = $BITS;
/// Converts a string slice in a given base to an integer. /// Converts a string slice in a given base to an integer.

View file

@ -70,6 +70,7 @@
#![feature(partition_point)] #![feature(partition_point)]
#![feature(once_cell)] #![feature(once_cell)]
#![feature(unsafe_block_in_unsafe_fn)] #![feature(unsafe_block_in_unsafe_fn)]
#![feature(int_bits_const)]
#![feature(nonzero_leading_trailing_zeros)] #![feature(nonzero_leading_trailing_zeros)]
#![feature(const_option)] #![feature(const_option)]
#![feature(integer_atomics)] #![feature(integer_atomics)]

View file

@ -18,6 +18,7 @@
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/" issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/"
)] )]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(int_bits_const)]
#![feature(lang_items)] #![feature(lang_items)]
#![feature(nll)] #![feature(nll)]
#![feature(panic_unwind)] #![feature(panic_unwind)]

View file

@ -826,7 +826,7 @@ impl OsStr {
/// assert!(!OsString::from("Ferrös").eq_ignore_ascii_case("FERRÖS")); /// assert!(!OsString::from("Ferrös").eq_ignore_ascii_case("FERRÖS"));
/// ``` /// ```
#[unstable(feature = "osstring_ascii", issue = "70516")] #[unstable(feature = "osstring_ascii", issue = "70516")]
pub fn eq_ignore_ascii_case<S: ?Sized + AsRef<OsStr>>(&self, other: &S) -> bool { pub fn eq_ignore_ascii_case<S: AsRef<OsStr>>(&self, other: S) -> bool {
self.inner.eq_ignore_ascii_case(&other.as_ref().inner) self.inner.eq_ignore_ascii_case(&other.as_ref().inner)
} }
} }

View file

@ -329,7 +329,6 @@
#![feature(unwind_attributes)] #![feature(unwind_attributes)]
#![feature(vec_into_raw_parts)] #![feature(vec_into_raw_parts)]
#![feature(vec_spare_capacity)] #![feature(vec_spare_capacity)]
#![feature(wake_trait)]
// NB: the above list is sorted to minimize merge conflicts. // NB: the above list is sorted to minimize merge conflicts.
#![default_lib_allocator] #![default_lib_allocator]
@ -508,7 +507,7 @@ pub mod task {
pub use core::task::*; pub use core::task::*;
#[doc(inline)] #[doc(inline)]
#[unstable(feature = "wake_trait", issue = "69912")] #[stable(feature = "wake_trait", since = "1.51.0")]
pub use alloc::task::*; pub use alloc::task::*;
} }

View file

@ -150,6 +150,7 @@ impl IpAddr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ip", since = "1.50.0")] #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
#[stable(feature = "ip_shared", since = "1.12.0")] #[stable(feature = "ip_shared", since = "1.12.0")]
#[inline]
pub const fn is_unspecified(&self) -> bool { pub const fn is_unspecified(&self) -> bool {
match self { match self {
IpAddr::V4(ip) => ip.is_unspecified(), IpAddr::V4(ip) => ip.is_unspecified(),
@ -172,6 +173,7 @@ impl IpAddr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ip", since = "1.50.0")] #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
#[stable(feature = "ip_shared", since = "1.12.0")] #[stable(feature = "ip_shared", since = "1.12.0")]
#[inline]
pub const fn is_loopback(&self) -> bool { pub const fn is_loopback(&self) -> bool {
match self { match self {
IpAddr::V4(ip) => ip.is_loopback(), IpAddr::V4(ip) => ip.is_loopback(),
@ -195,6 +197,7 @@ impl IpAddr {
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1)).is_global(), true); /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1)).is_global(), true);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ip", issue = "76205")] #[rustc_const_unstable(feature = "const_ip", issue = "76205")]
#[inline]
pub const fn is_global(&self) -> bool { pub const fn is_global(&self) -> bool {
match self { match self {
IpAddr::V4(ip) => ip.is_global(), IpAddr::V4(ip) => ip.is_global(),
@ -217,6 +220,7 @@ impl IpAddr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ip", since = "1.50.0")] #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
#[stable(feature = "ip_shared", since = "1.12.0")] #[stable(feature = "ip_shared", since = "1.12.0")]
#[inline]
pub const fn is_multicast(&self) -> bool { pub const fn is_multicast(&self) -> bool {
match self { match self {
IpAddr::V4(ip) => ip.is_multicast(), IpAddr::V4(ip) => ip.is_multicast(),
@ -243,6 +247,7 @@ impl IpAddr {
/// ); /// );
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ip", issue = "76205")] #[rustc_const_unstable(feature = "const_ip", issue = "76205")]
#[inline]
pub const fn is_documentation(&self) -> bool { pub const fn is_documentation(&self) -> bool {
match self { match self {
IpAddr::V4(ip) => ip.is_documentation(), IpAddr::V4(ip) => ip.is_documentation(),
@ -265,6 +270,7 @@ impl IpAddr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ip", since = "1.50.0")] #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
#[stable(feature = "ipaddr_checker", since = "1.16.0")] #[stable(feature = "ipaddr_checker", since = "1.16.0")]
#[inline]
pub const fn is_ipv4(&self) -> bool { pub const fn is_ipv4(&self) -> bool {
matches!(self, IpAddr::V4(_)) matches!(self, IpAddr::V4(_))
} }
@ -284,6 +290,7 @@ impl IpAddr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ip", since = "1.50.0")] #[rustc_const_stable(feature = "const_ip", since = "1.50.0")]
#[stable(feature = "ipaddr_checker", since = "1.16.0")] #[stable(feature = "ipaddr_checker", since = "1.16.0")]
#[inline]
pub const fn is_ipv6(&self) -> bool { pub const fn is_ipv6(&self) -> bool {
matches!(self, IpAddr::V6(_)) matches!(self, IpAddr::V6(_))
} }
@ -303,6 +310,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
// `s_addr` is stored as BE on all machine and the array is in BE order. // `s_addr` is stored as BE on all machine and the array is in BE order.
// So the native endian conversion method is used so that it's never swapped. // So the native endian conversion method is used so that it's never swapped.
@ -360,6 +368,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub const fn octets(&self) -> [u8; 4] { pub const fn octets(&self) -> [u8; 4] {
// This returns the order we want because s_addr is stored in big-endian. // This returns the order we want because s_addr is stored in big-endian.
self.inner.s_addr.to_ne_bytes() self.inner.s_addr.to_ne_bytes()
@ -382,6 +391,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.32.0")]
#[stable(feature = "ip_shared", since = "1.12.0")] #[stable(feature = "ip_shared", since = "1.12.0")]
#[inline]
pub const fn is_unspecified(&self) -> bool { pub const fn is_unspecified(&self) -> bool {
self.inner.s_addr == 0 self.inner.s_addr == 0
} }
@ -402,6 +412,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")] #[stable(since = "1.7.0", feature = "ip_17")]
#[inline]
pub const fn is_loopback(&self) -> bool { pub const fn is_loopback(&self) -> bool {
self.octets()[0] == 127 self.octets()[0] == 127
} }
@ -431,6 +442,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")] #[stable(since = "1.7.0", feature = "ip_17")]
#[inline]
pub const fn is_private(&self) -> bool { pub const fn is_private(&self) -> bool {
match self.octets() { match self.octets() {
[10, ..] => true, [10, ..] => true,
@ -457,6 +469,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")] #[stable(since = "1.7.0", feature = "ip_17")]
#[inline]
pub const fn is_link_local(&self) -> bool { pub const fn is_link_local(&self) -> bool {
matches!(self.octets(), [169, 254, ..]) matches!(self.octets(), [169, 254, ..])
} }
@ -531,6 +544,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true); /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
#[inline]
pub const fn is_global(&self) -> bool { pub const fn is_global(&self) -> bool {
// check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
// globally routable addresses in the 192.0.0.0/24 range. // globally routable addresses in the 192.0.0.0/24 range.
@ -568,6 +582,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(100, 128, 0, 0).is_shared(), false); /// assert_eq!(Ipv4Addr::new(100, 128, 0, 0).is_shared(), false);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
#[inline]
pub const fn is_shared(&self) -> bool { pub const fn is_shared(&self) -> bool {
self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000) self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
} }
@ -600,6 +615,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false); /// assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
#[inline]
pub const fn is_ietf_protocol_assignment(&self) -> bool { pub const fn is_ietf_protocol_assignment(&self) -> bool {
self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0 self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0
} }
@ -623,6 +639,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(198, 20, 0, 0).is_benchmarking(), false); /// assert_eq!(Ipv4Addr::new(198, 20, 0, 0).is_benchmarking(), false);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
#[inline]
pub const fn is_benchmarking(&self) -> bool { pub const fn is_benchmarking(&self) -> bool {
self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18 self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18
} }
@ -655,6 +672,7 @@ impl Ipv4Addr {
/// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false); /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")]
#[inline]
pub const fn is_reserved(&self) -> bool { pub const fn is_reserved(&self) -> bool {
self.octets()[0] & 240 == 240 && !self.is_broadcast() self.octets()[0] & 240 == 240 && !self.is_broadcast()
} }
@ -677,6 +695,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")] #[stable(since = "1.7.0", feature = "ip_17")]
#[inline]
pub const fn is_multicast(&self) -> bool { pub const fn is_multicast(&self) -> bool {
self.octets()[0] >= 224 && self.octets()[0] <= 239 self.octets()[0] >= 224 && self.octets()[0] <= 239
} }
@ -697,6 +716,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")] #[stable(since = "1.7.0", feature = "ip_17")]
#[inline]
pub const fn is_broadcast(&self) -> bool { pub const fn is_broadcast(&self) -> bool {
u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets()) u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets())
} }
@ -723,6 +743,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")] #[stable(since = "1.7.0", feature = "ip_17")]
#[inline]
pub const fn is_documentation(&self) -> bool { pub const fn is_documentation(&self) -> bool {
match self.octets() { match self.octets() {
[192, 0, 2, _] => true, [192, 0, 2, _] => true,
@ -753,6 +774,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub const fn to_ipv6_compatible(&self) -> Ipv6Addr { pub const fn to_ipv6_compatible(&self) -> Ipv6Addr {
let [a, b, c, d] = self.octets(); let [a, b, c, d] = self.octets();
Ipv6Addr { Ipv6Addr {
@ -776,6 +798,7 @@ impl Ipv4Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv4", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub const fn to_ipv6_mapped(&self) -> Ipv6Addr { pub const fn to_ipv6_mapped(&self) -> Ipv6Addr {
let [a, b, c, d] = self.octets(); let [a, b, c, d] = self.octets();
Ipv6Addr { Ipv6Addr {
@ -817,6 +840,7 @@ impl From<Ipv4Addr> for IpAddr {
/// IpAddr::from(addr) /// IpAddr::from(addr)
/// ) /// )
/// ``` /// ```
#[inline]
fn from(ipv4: Ipv4Addr) -> IpAddr { fn from(ipv4: Ipv4Addr) -> IpAddr {
IpAddr::V4(ipv4) IpAddr::V4(ipv4)
} }
@ -838,6 +862,7 @@ impl From<Ipv6Addr> for IpAddr {
/// IpAddr::from(addr) /// IpAddr::from(addr)
/// ); /// );
/// ``` /// ```
#[inline]
fn from(ipv6: Ipv6Addr) -> IpAddr { fn from(ipv6: Ipv6Addr) -> IpAddr {
IpAddr::V6(ipv6) IpAddr::V6(ipv6)
} }
@ -875,6 +900,7 @@ impl fmt::Debug for Ipv4Addr {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl Clone for Ipv4Addr { impl Clone for Ipv4Addr {
#[inline]
fn clone(&self) -> Ipv4Addr { fn clone(&self) -> Ipv4Addr {
*self *self
} }
@ -882,6 +908,7 @@ impl Clone for Ipv4Addr {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for Ipv4Addr { impl PartialEq for Ipv4Addr {
#[inline]
fn eq(&self, other: &Ipv4Addr) -> bool { fn eq(&self, other: &Ipv4Addr) -> bool {
self.inner.s_addr == other.inner.s_addr self.inner.s_addr == other.inner.s_addr
} }
@ -889,6 +916,7 @@ impl PartialEq for Ipv4Addr {
#[stable(feature = "ip_cmp", since = "1.16.0")] #[stable(feature = "ip_cmp", since = "1.16.0")]
impl PartialEq<Ipv4Addr> for IpAddr { impl PartialEq<Ipv4Addr> for IpAddr {
#[inline]
fn eq(&self, other: &Ipv4Addr) -> bool { fn eq(&self, other: &Ipv4Addr) -> bool {
match self { match self {
IpAddr::V4(v4) => v4 == other, IpAddr::V4(v4) => v4 == other,
@ -899,6 +927,7 @@ impl PartialEq<Ipv4Addr> for IpAddr {
#[stable(feature = "ip_cmp", since = "1.16.0")] #[stable(feature = "ip_cmp", since = "1.16.0")]
impl PartialEq<IpAddr> for Ipv4Addr { impl PartialEq<IpAddr> for Ipv4Addr {
#[inline]
fn eq(&self, other: &IpAddr) -> bool { fn eq(&self, other: &IpAddr) -> bool {
match other { match other {
IpAddr::V4(v4) => self == v4, IpAddr::V4(v4) => self == v4,
@ -912,6 +941,7 @@ impl Eq for Ipv4Addr {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl hash::Hash for Ipv4Addr { impl hash::Hash for Ipv4Addr {
#[inline]
fn hash<H: hash::Hasher>(&self, s: &mut H) { fn hash<H: hash::Hasher>(&self, s: &mut H) {
// NOTE: // NOTE:
// * hash in big endian order // * hash in big endian order
@ -923,6 +953,7 @@ impl hash::Hash for Ipv4Addr {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for Ipv4Addr { impl PartialOrd for Ipv4Addr {
#[inline]
fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> { fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
Some(self.cmp(other)) Some(self.cmp(other))
} }
@ -930,6 +961,7 @@ impl PartialOrd for Ipv4Addr {
#[stable(feature = "ip_cmp", since = "1.16.0")] #[stable(feature = "ip_cmp", since = "1.16.0")]
impl PartialOrd<Ipv4Addr> for IpAddr { impl PartialOrd<Ipv4Addr> for IpAddr {
#[inline]
fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> { fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
match self { match self {
IpAddr::V4(v4) => v4.partial_cmp(other), IpAddr::V4(v4) => v4.partial_cmp(other),
@ -940,6 +972,7 @@ impl PartialOrd<Ipv4Addr> for IpAddr {
#[stable(feature = "ip_cmp", since = "1.16.0")] #[stable(feature = "ip_cmp", since = "1.16.0")]
impl PartialOrd<IpAddr> for Ipv4Addr { impl PartialOrd<IpAddr> for Ipv4Addr {
#[inline]
fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> { fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
match other { match other {
IpAddr::V4(v4) => self.partial_cmp(v4), IpAddr::V4(v4) => self.partial_cmp(v4),
@ -950,6 +983,7 @@ impl PartialOrd<IpAddr> for Ipv4Addr {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl Ord for Ipv4Addr { impl Ord for Ipv4Addr {
#[inline]
fn cmp(&self, other: &Ipv4Addr) -> Ordering { fn cmp(&self, other: &Ipv4Addr) -> Ordering {
// Compare as native endian // Compare as native endian
u32::from_be(self.inner.s_addr).cmp(&u32::from_be(other.inner.s_addr)) u32::from_be(self.inner.s_addr).cmp(&u32::from_be(other.inner.s_addr))
@ -974,6 +1008,7 @@ impl From<Ipv4Addr> for u32 {
/// let addr = Ipv4Addr::new(0xca, 0xfe, 0xba, 0xbe); /// let addr = Ipv4Addr::new(0xca, 0xfe, 0xba, 0xbe);
/// assert_eq!(0xcafebabe, u32::from(addr)); /// assert_eq!(0xcafebabe, u32::from(addr));
/// ``` /// ```
#[inline]
fn from(ip: Ipv4Addr) -> u32 { fn from(ip: Ipv4Addr) -> u32 {
let ip = ip.octets(); let ip = ip.octets();
u32::from_be_bytes(ip) u32::from_be_bytes(ip)
@ -992,6 +1027,7 @@ impl From<u32> for Ipv4Addr {
/// let addr = Ipv4Addr::from(0xcafebabe); /// let addr = Ipv4Addr::from(0xcafebabe);
/// assert_eq!(Ipv4Addr::new(0xca, 0xfe, 0xba, 0xbe), addr); /// assert_eq!(Ipv4Addr::new(0xca, 0xfe, 0xba, 0xbe), addr);
/// ``` /// ```
#[inline]
fn from(ip: u32) -> Ipv4Addr { fn from(ip: u32) -> Ipv4Addr {
Ipv4Addr::from(ip.to_be_bytes()) Ipv4Addr::from(ip.to_be_bytes())
} }
@ -1009,6 +1045,7 @@ impl From<[u8; 4]> for Ipv4Addr {
/// let addr = Ipv4Addr::from([13u8, 12u8, 11u8, 10u8]); /// let addr = Ipv4Addr::from([13u8, 12u8, 11u8, 10u8]);
/// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr); /// assert_eq!(Ipv4Addr::new(13, 12, 11, 10), addr);
/// ``` /// ```
#[inline]
fn from(octets: [u8; 4]) -> Ipv4Addr { fn from(octets: [u8; 4]) -> Ipv4Addr {
Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]) Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3])
} }
@ -1026,6 +1063,7 @@ impl From<[u8; 4]> for IpAddr {
/// let addr = IpAddr::from([13u8, 12u8, 11u8, 10u8]); /// let addr = IpAddr::from([13u8, 12u8, 11u8, 10u8]);
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(13, 12, 11, 10)), addr); /// assert_eq!(IpAddr::V4(Ipv4Addr::new(13, 12, 11, 10)), addr);
/// ``` /// ```
#[inline]
fn from(octets: [u8; 4]) -> IpAddr { fn from(octets: [u8; 4]) -> IpAddr {
IpAddr::V4(Ipv4Addr::from(octets)) IpAddr::V4(Ipv4Addr::from(octets))
} }
@ -1046,6 +1084,7 @@ impl Ipv6Addr {
#[rustc_allow_const_fn_unstable(const_fn_transmute)] #[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")] #[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr { pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
let addr16 = [ let addr16 = [
a.to_be(), a.to_be(),
@ -1107,6 +1146,7 @@ impl Ipv6Addr {
#[rustc_allow_const_fn_unstable(const_fn_transmute)] #[rustc_allow_const_fn_unstable(const_fn_transmute)]
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub const fn segments(&self) -> [u16; 8] { pub const fn segments(&self) -> [u16; 8] {
// All elements in `s6_addr` must be big endian. // All elements in `s6_addr` must be big endian.
// SAFETY: `[u8; 16]` is always safe to transmute to `[u16; 8]`. // SAFETY: `[u8; 16]` is always safe to transmute to `[u16; 8]`.
@ -1142,6 +1182,7 @@ impl Ipv6Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")] #[stable(since = "1.7.0", feature = "ip_17")]
#[inline]
pub const fn is_unspecified(&self) -> bool { pub const fn is_unspecified(&self) -> bool {
u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets()) u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets())
} }
@ -1162,6 +1203,7 @@ impl Ipv6Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")] #[stable(since = "1.7.0", feature = "ip_17")]
#[inline]
pub const fn is_loopback(&self) -> bool { pub const fn is_loopback(&self) -> bool {
u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets()) u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets())
} }
@ -1186,6 +1228,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true); /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[inline]
pub const fn is_global(&self) -> bool { pub const fn is_global(&self) -> bool {
match self.multicast_scope() { match self.multicast_scope() {
Some(Ipv6MulticastScope::Global) => true, Some(Ipv6MulticastScope::Global) => true,
@ -1211,6 +1254,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true); /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[inline]
pub const fn is_unique_local(&self) -> bool { pub const fn is_unique_local(&self) -> bool {
(self.segments()[0] & 0xfe00) == 0xfc00 (self.segments()[0] & 0xfe00) == 0xfc00
} }
@ -1265,6 +1309,7 @@ impl Ipv6Addr {
/// [IETF RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6 /// [IETF RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6
/// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406 /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[inline]
pub const fn is_unicast_link_local_strict(&self) -> bool { pub const fn is_unicast_link_local_strict(&self) -> bool {
matches!(self.segments(), [0xfe80, 0, 0, 0, ..]) matches!(self.segments(), [0xfe80, 0, 0, 0, ..])
} }
@ -1318,6 +1363,7 @@ impl Ipv6Addr {
/// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4 /// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4
/// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406 /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[inline]
pub const fn is_unicast_link_local(&self) -> bool { pub const fn is_unicast_link_local(&self) -> bool {
(self.segments()[0] & 0xffc0) == 0xfe80 (self.segments()[0] & 0xffc0) == 0xfe80
} }
@ -1357,6 +1403,7 @@ impl Ipv6Addr {
/// ///
/// [RFC 3879]: https://tools.ietf.org/html/rfc3879 /// [RFC 3879]: https://tools.ietf.org/html/rfc3879
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[inline]
pub const fn is_unicast_site_local(&self) -> bool { pub const fn is_unicast_site_local(&self) -> bool {
(self.segments()[0] & 0xffc0) == 0xfec0 (self.segments()[0] & 0xffc0) == 0xfec0
} }
@ -1379,6 +1426,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true); /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[inline]
pub const fn is_documentation(&self) -> bool { pub const fn is_documentation(&self) -> bool {
(self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8) (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
} }
@ -1414,6 +1462,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(), true); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(), true);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[inline]
pub const fn is_unicast_global(&self) -> bool { pub const fn is_unicast_global(&self) -> bool {
!self.is_multicast() !self.is_multicast()
&& !self.is_loopback() && !self.is_loopback()
@ -1439,6 +1488,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[inline]
pub const fn multicast_scope(&self) -> Option<Ipv6MulticastScope> { pub const fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
if self.is_multicast() { if self.is_multicast() {
match self.segments()[0] & 0x000f { match self.segments()[0] & 0x000f {
@ -1472,6 +1522,7 @@ impl Ipv6Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[stable(since = "1.7.0", feature = "ip_17")] #[stable(since = "1.7.0", feature = "ip_17")]
#[inline]
pub const fn is_multicast(&self) -> bool { pub const fn is_multicast(&self) -> bool {
(self.segments()[0] & 0xff00) == 0xff00 (self.segments()[0] & 0xff00) == 0xff00
} }
@ -1498,6 +1549,7 @@ impl Ipv6Addr {
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4_mapped(), None); /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4_mapped(), None);
/// ``` /// ```
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
#[inline]
pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> { pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
match self.octets() { match self.octets() {
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => { [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => {
@ -1527,6 +1579,7 @@ impl Ipv6Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")] #[rustc_const_stable(feature = "const_ipv6", since = "1.50.0")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub const fn to_ipv4(&self) -> Option<Ipv4Addr> { pub const fn to_ipv4(&self) -> Option<Ipv4Addr> {
if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() { if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() {
let [a, b] = ab.to_be_bytes(); let [a, b] = ab.to_be_bytes();
@ -1547,6 +1600,7 @@ impl Ipv6Addr {
/// ``` /// ```
#[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")] #[rustc_const_stable(feature = "const_ipv6", since = "1.32.0")]
#[stable(feature = "ipv6_to_octets", since = "1.12.0")] #[stable(feature = "ipv6_to_octets", since = "1.12.0")]
#[inline]
pub const fn octets(&self) -> [u8; 16] { pub const fn octets(&self) -> [u8; 16] {
self.inner.s6_addr self.inner.s6_addr
} }
@ -1658,6 +1712,7 @@ impl fmt::Debug for Ipv6Addr {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl Clone for Ipv6Addr { impl Clone for Ipv6Addr {
#[inline]
fn clone(&self) -> Ipv6Addr { fn clone(&self) -> Ipv6Addr {
*self *self
} }
@ -1665,6 +1720,7 @@ impl Clone for Ipv6Addr {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for Ipv6Addr { impl PartialEq for Ipv6Addr {
#[inline]
fn eq(&self, other: &Ipv6Addr) -> bool { fn eq(&self, other: &Ipv6Addr) -> bool {
self.inner.s6_addr == other.inner.s6_addr self.inner.s6_addr == other.inner.s6_addr
} }
@ -1672,6 +1728,7 @@ impl PartialEq for Ipv6Addr {
#[stable(feature = "ip_cmp", since = "1.16.0")] #[stable(feature = "ip_cmp", since = "1.16.0")]
impl PartialEq<IpAddr> for Ipv6Addr { impl PartialEq<IpAddr> for Ipv6Addr {
#[inline]
fn eq(&self, other: &IpAddr) -> bool { fn eq(&self, other: &IpAddr) -> bool {
match other { match other {
IpAddr::V4(_) => false, IpAddr::V4(_) => false,
@ -1682,6 +1739,7 @@ impl PartialEq<IpAddr> for Ipv6Addr {
#[stable(feature = "ip_cmp", since = "1.16.0")] #[stable(feature = "ip_cmp", since = "1.16.0")]
impl PartialEq<Ipv6Addr> for IpAddr { impl PartialEq<Ipv6Addr> for IpAddr {
#[inline]
fn eq(&self, other: &Ipv6Addr) -> bool { fn eq(&self, other: &Ipv6Addr) -> bool {
match self { match self {
IpAddr::V4(_) => false, IpAddr::V4(_) => false,
@ -1695,6 +1753,7 @@ impl Eq for Ipv6Addr {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl hash::Hash for Ipv6Addr { impl hash::Hash for Ipv6Addr {
#[inline]
fn hash<H: hash::Hasher>(&self, s: &mut H) { fn hash<H: hash::Hasher>(&self, s: &mut H) {
self.inner.s6_addr.hash(s) self.inner.s6_addr.hash(s)
} }
@ -1702,6 +1761,7 @@ impl hash::Hash for Ipv6Addr {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd for Ipv6Addr { impl PartialOrd for Ipv6Addr {
#[inline]
fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> { fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
Some(self.cmp(other)) Some(self.cmp(other))
} }
@ -1709,6 +1769,7 @@ impl PartialOrd for Ipv6Addr {
#[stable(feature = "ip_cmp", since = "1.16.0")] #[stable(feature = "ip_cmp", since = "1.16.0")]
impl PartialOrd<Ipv6Addr> for IpAddr { impl PartialOrd<Ipv6Addr> for IpAddr {
#[inline]
fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> { fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
match self { match self {
IpAddr::V4(_) => Some(Ordering::Less), IpAddr::V4(_) => Some(Ordering::Less),
@ -1719,6 +1780,7 @@ impl PartialOrd<Ipv6Addr> for IpAddr {
#[stable(feature = "ip_cmp", since = "1.16.0")] #[stable(feature = "ip_cmp", since = "1.16.0")]
impl PartialOrd<IpAddr> for Ipv6Addr { impl PartialOrd<IpAddr> for Ipv6Addr {
#[inline]
fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> { fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
match other { match other {
IpAddr::V4(_) => Some(Ordering::Greater), IpAddr::V4(_) => Some(Ordering::Greater),
@ -1729,6 +1791,7 @@ impl PartialOrd<IpAddr> for Ipv6Addr {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl Ord for Ipv6Addr { impl Ord for Ipv6Addr {
#[inline]
fn cmp(&self, other: &Ipv6Addr) -> Ordering { fn cmp(&self, other: &Ipv6Addr) -> Ordering {
self.segments().cmp(&other.segments()) self.segments().cmp(&other.segments())
} }
@ -1760,6 +1823,7 @@ impl From<Ipv6Addr> for u128 {
/// ); /// );
/// assert_eq!(0x102030405060708090A0B0C0D0E0F00D_u128, u128::from(addr)); /// assert_eq!(0x102030405060708090A0B0C0D0E0F00D_u128, u128::from(addr));
/// ``` /// ```
#[inline]
fn from(ip: Ipv6Addr) -> u128 { fn from(ip: Ipv6Addr) -> u128 {
let ip = ip.octets(); let ip = ip.octets();
u128::from_be_bytes(ip) u128::from_be_bytes(ip)
@ -1782,6 +1846,7 @@ impl From<u128> for Ipv6Addr {
/// ), /// ),
/// addr); /// addr);
/// ``` /// ```
#[inline]
fn from(ip: u128) -> Ipv6Addr { fn from(ip: u128) -> Ipv6Addr {
Ipv6Addr::from(ip.to_be_bytes()) Ipv6Addr::from(ip.to_be_bytes())
} }
@ -1810,6 +1875,7 @@ impl From<[u8; 16]> for Ipv6Addr {
/// addr /// addr
/// ); /// );
/// ``` /// ```
#[inline]
fn from(octets: [u8; 16]) -> Ipv6Addr { fn from(octets: [u8; 16]) -> Ipv6Addr {
let inner = c::in6_addr { s6_addr: octets }; let inner = c::in6_addr { s6_addr: octets };
Ipv6Addr::from_inner(inner) Ipv6Addr::from_inner(inner)
@ -1839,6 +1905,7 @@ impl From<[u16; 8]> for Ipv6Addr {
/// addr /// addr
/// ); /// );
/// ``` /// ```
#[inline]
fn from(segments: [u16; 8]) -> Ipv6Addr { fn from(segments: [u16; 8]) -> Ipv6Addr {
let [a, b, c, d, e, f, g, h] = segments; let [a, b, c, d, e, f, g, h] = segments;
Ipv6Addr::new(a, b, c, d, e, f, g, h) Ipv6Addr::new(a, b, c, d, e, f, g, h)
@ -1868,6 +1935,7 @@ impl From<[u8; 16]> for IpAddr {
/// addr /// addr
/// ); /// );
/// ``` /// ```
#[inline]
fn from(octets: [u8; 16]) -> IpAddr { fn from(octets: [u8; 16]) -> IpAddr {
IpAddr::V6(Ipv6Addr::from(octets)) IpAddr::V6(Ipv6Addr::from(octets))
} }
@ -1896,6 +1964,7 @@ impl From<[u16; 8]> for IpAddr {
/// addr /// addr
/// ); /// );
/// ``` /// ```
#[inline]
fn from(segments: [u16; 8]) -> IpAddr { fn from(segments: [u16; 8]) -> IpAddr {
IpAddr::V6(Ipv6Addr::from(segments)) IpAddr::V6(Ipv6Addr::from(segments))
} }

View file

@ -125,7 +125,7 @@ unsafe impl Send for Once {}
/// State yielded to [`Once::call_once_force()`]s closure parameter. The state /// State yielded to [`Once::call_once_force()`]s closure parameter. The state
/// can be used to query the poison status of the [`Once`]. /// can be used to query the poison status of the [`Once`].
#[unstable(feature = "once_poison", issue = "33577")] #[stable(feature = "once_poison", since = "1.51.0")]
#[derive(Debug)] #[derive(Debug)]
pub struct OnceState { pub struct OnceState {
poisoned: bool, poisoned: bool,
@ -280,8 +280,6 @@ impl Once {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(once_poison)]
///
/// use std::sync::Once; /// use std::sync::Once;
/// use std::thread; /// use std::thread;
/// ///
@ -301,13 +299,13 @@ impl Once {
/// ///
/// // call_once_force will still run and reset the poisoned state /// // call_once_force will still run and reset the poisoned state
/// INIT.call_once_force(|state| { /// INIT.call_once_force(|state| {
/// assert!(state.poisoned()); /// assert!(state.is_poisoned());
/// }); /// });
/// ///
/// // once any success happens, we stop propagating the poison /// // once any success happens, we stop propagating the poison
/// INIT.call_once(|| {}); /// INIT.call_once(|| {});
/// ``` /// ```
#[unstable(feature = "once_poison", issue = "33577")] #[stable(feature = "once_poison", since = "1.51.0")]
pub fn call_once_force<F>(&self, f: F) pub fn call_once_force<F>(&self, f: F)
where where
F: FnOnce(&OnceState), F: FnOnce(&OnceState),
@ -526,8 +524,6 @@ impl OnceState {
/// A poisoned [`Once`]: /// A poisoned [`Once`]:
/// ///
/// ``` /// ```
/// #![feature(once_poison)]
///
/// use std::sync::Once; /// use std::sync::Once;
/// use std::thread; /// use std::thread;
/// ///
@ -540,24 +536,22 @@ impl OnceState {
/// assert!(handle.join().is_err()); /// assert!(handle.join().is_err());
/// ///
/// INIT.call_once_force(|state| { /// INIT.call_once_force(|state| {
/// assert!(state.poisoned()); /// assert!(state.is_poisoned());
/// }); /// });
/// ``` /// ```
/// ///
/// An unpoisoned [`Once`]: /// An unpoisoned [`Once`]:
/// ///
/// ``` /// ```
/// #![feature(once_poison)]
///
/// use std::sync::Once; /// use std::sync::Once;
/// ///
/// static INIT: Once = Once::new(); /// static INIT: Once = Once::new();
/// ///
/// INIT.call_once_force(|state| { /// INIT.call_once_force(|state| {
/// assert!(!state.poisoned()); /// assert!(!state.is_poisoned());
/// }); /// });
#[unstable(feature = "once_poison", issue = "33577")] #[stable(feature = "once_poison", since = "1.51.0")]
pub fn poisoned(&self) -> bool { pub fn is_poisoned(&self) -> bool {
self.poisoned self.poisoned
} }

View file

@ -69,7 +69,7 @@ fn poison_bad() {
let mut called = false; let mut called = false;
O.call_once_force(|p| { O.call_once_force(|p| {
called = true; called = true;
assert!(p.poisoned()) assert!(p.is_poisoned())
}); });
assert!(called); assert!(called);
@ -92,7 +92,7 @@ fn wait_for_force_to_finish() {
let (tx2, rx2) = channel(); let (tx2, rx2) = channel();
let t1 = thread::spawn(move || { let t1 = thread::spawn(move || {
O.call_once_force(|p| { O.call_once_force(|p| {
assert!(p.poisoned()); assert!(p.is_poisoned());
tx1.send(()).unwrap(); tx1.send(()).unwrap();
rx2.recv().unwrap(); rx2.recv().unwrap();
}); });

View file

@ -77,15 +77,15 @@ fn test_comparison_ops() {
for &(op, bs) in v.iter() { for &(op, bs) in v.iter() {
let s = format!("%{{1}}%{{2}}%{}%d", op); let s = format!("%{{1}}%{{2}}%{}%d", op);
let res = expand(s.as_bytes(), &[], &mut Variables::new()); 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]]); assert_eq!(res.unwrap(), vec![b'0' + bs[0]]);
let s = format!("%{{1}}%{{1}}%{}%d", op); let s = format!("%{{1}}%{{1}}%{}%d", op);
let res = expand(s.as_bytes(), &[], &mut Variables::new()); 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]]); assert_eq!(res.unwrap(), vec![b'0' + bs[1]]);
let s = format!("%{{2}}%{{1}}%{}%d", op); let s = format!("%{{2}}%{{1}}%{}%d", op);
let res = expand(s.as_bytes(), &[], &mut Variables::new()); 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]]); assert_eq!(res.unwrap(), vec![b'0' + bs[2]]);
} }
} }
@ -95,13 +95,13 @@ fn test_conditionals() {
let mut vars = Variables::new(); 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 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); 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::<Vec<_>>()); assert_eq!(res.unwrap(), "\\E[31m".bytes().collect::<Vec<_>>());
let res = expand(s, &[Number(8)], &mut vars); 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::<Vec<_>>()); assert_eq!(res.unwrap(), "\\E[90m".bytes().collect::<Vec<_>>());
let res = expand(s, &[Number(42)], &mut vars); 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::<Vec<_>>()); assert_eq!(res.unwrap(), "\\E[38;5;42m".bytes().collect::<Vec<_>>());
} }

View file

@ -199,7 +199,7 @@ fn test_should_panic_bad_message() {
fn test_should_panic_non_string_message_type() { fn test_should_panic_non_string_message_type() {
use crate::tests::TrFailedMsg; use crate::tests::TrFailedMsg;
fn f() { fn f() {
panic!(1i32); std::panic::panic_any(1i32);
} }
let expected = "foobar"; let expected = "foobar";
let failed_msg = format!( let failed_msg = format!(

View file

@ -50,7 +50,7 @@ fn test() {
.output().unwrap(); .output().unwrap();
assert!(child_output.status.success(), assert!(child_output.status.success(),
format!("child assertion failed\n child stdout:\n {}\n child stderr:\n {}", "child assertion failed\n child stdout:\n {}\n child stderr:\n {}",
str::from_utf8(&child_output.stdout).unwrap(), str::from_utf8(&child_output.stdout).unwrap(),
str::from_utf8(&child_output.stderr).unwrap())); str::from_utf8(&child_output.stderr).unwrap());
} }

View file

@ -4,7 +4,6 @@
// edition:2018 // edition:2018
#![allow(dead_code)] #![allow(dead_code)]
#![feature(wake_trait)]
use std::future::Future; use std::future::Future;
use std::task::{Waker, Wake, Context}; use std::task::{Waker, Wake, Context};
use std::sync::Arc; use std::sync::Arc;

View file

@ -1,4 +1,5 @@
#![feature(const_panic)] #![feature(const_panic)]
#![allow(non_fmt_panic)]
#![crate_type = "lib"] #![crate_type = "lib"]
const MSG: &str = "hello"; const MSG: &str = "hello";

View file

@ -1,10 +1,10 @@
error: any use of this value will cause an error 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"); 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 = 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! = 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) = 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 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!(); 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! = 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 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = 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 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!(); 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! = 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 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = 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 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!(); 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! = 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 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = 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 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); 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! = 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 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = 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 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"); 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! = 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 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = 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 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!(); 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! = 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 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = 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 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!(); 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! = 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 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = 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 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!(); 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! = 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 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = 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 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); 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! = 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 <https://github.com/rust-lang/rust/issues/71800> = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>

View file

@ -82,7 +82,7 @@ impl Allocator {
self.cur_ops.set(self.cur_ops.get() + 1); self.cur_ops.set(self.cur_ops.get() + 1);
if self.cur_ops.get() == self.failing_op { if self.cur_ops.get() == self.failing_op {
panic!(InjectedFailure); panic::panic_any(InjectedFailure);
} }
} }
} }

View file

@ -46,7 +46,7 @@ impl Allocator {
self.cur_ops.set(self.cur_ops.get() + 1); self.cur_ops.set(self.cur_ops.get() + 1);
if self.cur_ops.get() == self.failing_op { if self.cur_ops.get() == self.failing_op {
panic!(InjectedFailure); panic::panic_any(InjectedFailure);
} }
let mut data = self.data.borrow_mut(); 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); self.1.cur_ops.set(self.1.cur_ops.get() + 1);
if self.1.cur_ops.get() == self.1.failing_op { if self.1.cur_ops.get() == self.1.failing_op {
panic!(InjectedFailure); panic::panic_any(InjectedFailure);
} }
} }
} }

View file

@ -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. // 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. // 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(|| { let msg = std::panic::catch_unwind(|| {
panic!("{foo}"); panic!("{foo}");
}).unwrap_err(); }).unwrap_err();

View file

@ -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
}

View file

@ -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

View file

@ -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() {}

View file

@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/81670>
error: aborting due to 9 previous errors

View file

@ -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: ();
}

View file

@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/81670>
warning: 4 warnings emitted

View file

@ -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: ();
}

View file

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

View file

@ -14,14 +14,17 @@
// compile-flags: -Z deduplicate-diagnostics=yes // compile-flags: -Z deduplicate-diagnostics=yes
#![forbid(forbidden_lint_groups)]
fn forbid_first(num: i32) -> i32 { fn forbid_first(num: i32) -> i32 {
#![forbid(unused)] #![forbid(unused)]
#![deny(unused)] #![deny(unused)]
//~^ ERROR: deny(unused) incompatible with previous forbid //~^ ERROR: deny(unused) incompatible with previous forbid
//~| WARNING being phased out
//~| ERROR: deny(unused) incompatible with previous forbid
//~| WARNING being phased out
#![warn(unused)] #![warn(unused)]
//~^ ERROR: warn(unused) incompatible with previous forbid
#![allow(unused)] #![allow(unused)]
//~^ ERROR: allow(unused) incompatible with previous forbid
num * num num * num
} }

View file

@ -1,29 +1,29 @@
error[E0453]: deny(unused) incompatible with previous forbid error: deny(unused) incompatible with previous forbid
--> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:19:13 --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:21:13
| |
LL | #![forbid(unused)] LL | #![forbid(unused)]
| ------ `forbid` level set here | ------ `forbid` level set here
LL | #![deny(unused)] LL | #![deny(unused)]
| ^^^^^^ overruled by previous forbid | ^^^^^^ 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 <https://github.com/rust-lang/rust/issues/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 --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:21:13
| |
LL | #![forbid(unused)] LL | #![forbid(unused)]
| ------ `forbid` level set here | ------ `forbid` level set here
... LL | #![deny(unused)]
LL | #![warn(unused)]
| ^^^^^^ overruled by previous forbid | ^^^^^^ 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)] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
| ------ `forbid` level set here = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670>
...
LL | #![allow(unused)]
| ^^^^^^ overruled by previous forbid
error: aborting due to 3 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0453`.

View file

@ -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() {}

View file

@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/81670>
warning: 4 warnings emitted

View file

@ -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: ();
}

View file

@ -15,11 +15,16 @@
// compile-flags: -Z deduplicate-diagnostics=yes // compile-flags: -Z deduplicate-diagnostics=yes
#![forbid(unused, non_snake_case)] #![forbid(unused, non_snake_case)]
#![forbid(forbidden_lint_groups)]
#[allow(unused_variables)] //~ ERROR incompatible with previous #[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() {} fn foo() {}
#[allow(unused)] //~ ERROR incompatible with previous #[allow(unused)] //~ ERROR incompatible with previous
//~^ WARNING this was previously accepted by the compiler
fn bar() {} fn bar() {}
#[allow(nonstandard_style)] //~ ERROR incompatible with previous #[allow(nonstandard_style)] //~ ERROR incompatible with previous

View file

@ -1,23 +1,34 @@
error[E0453]: allow(unused_variables) incompatible with previous forbid error: allow(unused_variables) incompatible with previous forbid
--> $DIR/outer-forbid.rs:19:9 --> $DIR/outer-forbid.rs:20:9
| |
LL | #![forbid(unused, non_snake_case)] LL | #![forbid(unused, non_snake_case)]
| ------ `forbid` level set here | ------ `forbid` level set here
LL | ...
LL | #[allow(unused_variables)] LL | #[allow(unused_variables)]
| ^^^^^^^^^^^^^^^^ overruled by previous forbid | ^^^^^^^^^^^^^^^^ 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 <https://github.com/rust-lang/rust/issues/81670>
error[E0453]: allow(unused) incompatible with previous forbid error: allow(unused) incompatible with previous forbid
--> $DIR/outer-forbid.rs:22:9 --> $DIR/outer-forbid.rs:26:9
| |
LL | #![forbid(unused, non_snake_case)] LL | #![forbid(unused, non_snake_case)]
| ------ `forbid` level set here | ------ `forbid` level set here
... ...
LL | #[allow(unused)] LL | #[allow(unused)]
| ^^^^^^ overruled by previous forbid | ^^^^^^ 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 <https://github.com/rust-lang/rust/issues/81670>
error[E0453]: allow(nonstandard_style) incompatible with previous forbid 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)] LL | #![forbid(unused, non_snake_case)]
| -------------- `forbid` level set here | -------------- `forbid` level set here
@ -25,6 +36,18 @@ LL | #![forbid(unused, non_snake_case)]
LL | #[allow(nonstandard_style)] LL | #[allow(nonstandard_style)]
| ^^^^^^^^^^^^^^^^^ overruled by previous forbid | ^^^^^^^^^^^^^^^^^ 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 <https://github.com/rust-lang/rust/issues/81670>
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0453`. For more information about this error, try `rustc --explain E0453`.

View file

@ -2,6 +2,8 @@
// error-pattern:panicked at 'test-assert-owned' // error-pattern:panicked at 'test-assert-owned'
// ignore-emscripten no processes // ignore-emscripten no processes
#![allow(non_fmt_panic)]
fn main() { fn main() {
assert!(false, "test-assert-owned".to_string()); assert!(false, "test-assert-owned".to_string());
} }

View file

@ -57,7 +57,7 @@ fn writeln_1arg() {
// //
// (Example: Issue #48042) // (Example: Issue #48042)
#[test] #[test]
#[allow(panic_fmt)] #[allow(non_fmt_panic)]
fn to_format_or_not_to_format() { fn to_format_or_not_to_format() {
// ("{}" is the easiest string to test because if this gets // ("{}" is the easiest string to test because if this gets
// sent to format_args!, it'll simply fail to compile. // sent to format_args!, it'll simply fail to compile.

View file

@ -38,7 +38,7 @@ fn main() {
assert_eq!(get(), vec![0, 2, 3, 1]); assert_eq!(get(), vec![0, 2, 3, 1]);
let _ = std::panic::catch_unwind(|| { 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 // here, the temporaries (5/7) live until the end of the

View file

@ -13,19 +13,27 @@ fn main() {
core::panic!("Hello {}"); //~ WARN panic message contains an unused formatting placeholder core::panic!("Hello {}"); //~ WARN panic message contains an unused formatting placeholder
assert!(false, "{:03x} {test} bla"); assert!(false, "{:03x} {test} bla");
//~^ WARN panic message contains unused formatting placeholders //~^ 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 debug_assert!(false, "{{}} bla"); //~ WARN panic message contains braces
panic!(C); // No warning (yet) panic!(C); //~ WARN panic message is not a string literal
panic!(S); // No warning (yet) 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 an unused formatting placeholder
panic!(concat!("{", "{")); //~ WARN panic message contains braces panic!(concat!("{", "{")); //~ WARN panic message contains braces
fancy_panic::fancy_panic!("test {} 123"); fancy_panic::fancy_panic!("test {} 123");
//~^ WARN panic message contains an unused formatting placeholder //~^ 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, // Check that the lint only triggers for std::panic and core::panic,
// not any panic macro: // not any panic macro:
macro_rules! panic { macro_rules! panic {
($e:expr) => (); ($e:expr) => ();
} }
panic!("{}"); // OK panic!("{}"); // OK
panic!(S); // OK
} }

View file

@ -1,35 +1,35 @@
warning: panic message contains a brace 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: {"); LL | panic!("here's a brace: {");
| ^ | ^
| |
= note: `#[warn(panic_fmt)]` on by default = note: `#[warn(non_fmt_panic)]` on by default
= 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 help: add a "{}" format string to use the message literally
| |
LL | panic!("{}", "here's a brace: {"); LL | panic!("{}", "here's a brace: {");
| ^^^^^ | ^^^^^
warning: panic message contains 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: }"); 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 help: add a "{}" format string to use the message literally
| |
LL | std::panic!("{}", "another one: }"); LL | std::panic!("{}", "another one: }");
| ^^^^^ | ^^^^^
warning: panic message contains an unused formatting placeholder 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 {}"); 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 help: add the missing argument
| |
LL | core::panic!("Hello {}", ...); LL | core::panic!("Hello {}", ...);
@ -40,12 +40,12 @@ LL | core::panic!("{}", "Hello {}");
| ^^^^^ | ^^^^^
warning: panic message contains unused formatting placeholders 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"); 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 help: add the missing arguments
| |
LL | assert!(false, "{:03x} {test} bla", ...); 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"); 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 warning: panic message contains braces
--> $DIR/panic-brace.rs:16:27 --> $DIR/non-fmt-panic.rs:18:27
| |
LL | debug_assert!(false, "{{}} bla"); 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 help: add a "{}" format string to use the message literally
| |
LL | debug_assert!(false, "{}", "{{}} bla"); 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 warning: panic message contains an unused formatting placeholder
--> $DIR/panic-brace.rs:19:12 --> $DIR/non-fmt-panic.rs:23:12
| |
LL | panic!(concat!("{", "}")); 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 help: add the missing argument
| |
LL | panic!(concat!("{", "}"), ...); LL | panic!(concat!("{", "}"), ...);
@ -84,24 +156,32 @@ LL | panic!("{}", concat!("{", "}"));
| ^^^^^ | ^^^^^
warning: panic message contains braces warning: panic message contains braces
--> $DIR/panic-brace.rs:20:5 --> $DIR/non-fmt-panic.rs:24:5
| |
LL | panic!(concat!("{", "{")); 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 help: add a "{}" format string to use the message literally
| |
LL | panic!("{}", concat!("{", "{")); LL | panic!("{}", concat!("{", "{"));
| ^^^^^ | ^^^^^
warning: panic message contains an unused formatting placeholder 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"); 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: 8 warnings emitted 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: 14 warnings emitted

View file

@ -1,5 +1,6 @@
#![allow(unused_assignments)] #![allow(unused_assignments)]
#![allow(unused_variables)] #![allow(unused_variables)]
#![allow(non_fmt_panic)]
// run-fail // run-fail
// error-pattern:wooooo // error-pattern:wooooo

View file

@ -2,6 +2,8 @@
// error-pattern:panicked at 'Box<Any>' // error-pattern:panicked at 'Box<Any>'
// ignore-emscripten no processes // ignore-emscripten no processes
#![allow(non_fmt_panic)]
fn main() { fn main() {
panic!(Box::new(612_i64)); panic!(Box::new(612_i64));
} }

View file

@ -3,6 +3,7 @@
// ignore-emscripten no processes // ignore-emscripten no processes
#![feature(box_syntax)] #![feature(box_syntax)]
#![allow(non_fmt_panic)]
fn main() { fn main() {
panic!(box 413 as Box<dyn std::any::Any + Send>); panic!(box 413 as Box<dyn std::any::Any + Send>);

View file

@ -5,7 +5,7 @@
// ignore-emscripten no processes // ignore-emscripten no processes
fn main() { fn main() {
panic!({ panic!("{}", {
while true { while true {
panic!("giraffe") panic!("giraffe")
} }

View file

@ -2183,7 +2183,7 @@ fn lint_expect_fun_call(
span_replace_word, span_replace_word,
&format!("use of `{}` followed by a function call", name), &format!("use of `{}` followed by a function call", name),
"try this", "try this",
format!("unwrap_or_else({} {{ panic!({}) }})", closure_args, arg_root_snippet), format!("unwrap_or_else({} {{ panic!(\"{{}}\", {}) }})", closure_args, arg_root_snippet),
applicability, applicability,
); );
} }

View file

@ -9,14 +9,12 @@ fn test_missing_tests() {
if !missing_files.is_empty() { if !missing_files.is_empty() {
assert!( assert!(
false, false,
format!( "Didn't see a test file for the following files:\n\n{}\n",
"Didn't see a test file for the following files:\n\n{}\n", missing_files
missing_files .iter()
.iter() .map(|s| format!("\t{}", s))
.map(|s| format!("\t{}", s)) .collect::<Vec<_>>()
.collect::<Vec<_>>() .join("\n")
.join("\n")
)
); );
} }
} }

View file

@ -1,3 +1,5 @@
#![allow(non_fmt_panic)]
macro_rules! assert_const { macro_rules! assert_const {
($len:expr) => { ($len:expr) => {
assert!($len > 0); assert!($len > 0);

View file

@ -1,5 +1,5 @@
error: `assert!(true)` will be optimized out by the compiler 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); 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) = 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 error: `assert!(false)` should probably be replaced
--> $DIR/assertions_on_constants.rs:10:5 --> $DIR/assertions_on_constants.rs:12:5
| |
LL | assert!(false); 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) = 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 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"); 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) = 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 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"); 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) = 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 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()); 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) = 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 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); 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) = 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 error: `assert!(false)` should probably be replaced
--> $DIR/assertions_on_constants.rs:21:5 --> $DIR/assertions_on_constants.rs:23:5
| |
LL | assert!(C); 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) = 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 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"); 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) = 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 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); LL | debug_assert!(true);
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^

View file

@ -74,12 +74,12 @@ fn main() {
"foo" "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_static_str()) });
Some("foo").unwrap_or_else(|| { panic!(get_non_static_str(&0).to_string()) }); Some("foo").unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) });
} }
//Issue #3839 //Issue #3839

View file

@ -34,31 +34,31 @@ error: use of `expect` followed by a function call
--> $DIR/expect_fun_call.rs:77:21 --> $DIR/expect_fun_call.rs:77:21
| |
LL | Some("foo").expect(&get_string()); 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 error: use of `expect` followed by a function call
--> $DIR/expect_fun_call.rs:78:21 --> $DIR/expect_fun_call.rs:78:21
| |
LL | Some("foo").expect(get_string().as_ref()); 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 error: use of `expect` followed by a function call
--> $DIR/expect_fun_call.rs:79:21 --> $DIR/expect_fun_call.rs:79:21
| |
LL | Some("foo").expect(get_string().as_str()); 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 error: use of `expect` followed by a function call
--> $DIR/expect_fun_call.rs:81:21 --> $DIR/expect_fun_call.rs:81:21
| |
LL | Some("foo").expect(get_static_str()); 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 error: use of `expect` followed by a function call
--> $DIR/expect_fun_call.rs:82:21 --> $DIR/expect_fun_call.rs:82:21
| |
LL | Some("foo").expect(get_non_static_str(&0)); 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 error: use of `expect` followed by a function call
--> $DIR/expect_fun_call.rs:86:16 --> $DIR/expect_fun_call.rs:86:16

View file

@ -36,7 +36,7 @@ impl From<Option<String>> for Invalid {
fn from(s: Option<String>) -> Invalid { fn from(s: Option<String>) -> Invalid {
let s = s.unwrap(); let s = s.unwrap();
if !s.is_empty() { if !s.is_empty() {
panic!(42); panic!("42");
} else if s.parse::<u32>().unwrap() != 42 { } else if s.parse::<u32>().unwrap() != 42 {
panic!("{:?}", s); panic!("{:?}", s);
} }

View file

@ -59,8 +59,8 @@ note: potential failure(s)
LL | let s = s.unwrap(); LL | let s = s.unwrap();
| ^^^^^^^^^^ | ^^^^^^^^^^
LL | if !s.is_empty() { LL | if !s.is_empty() {
LL | panic!(42); LL | panic!("42");
| ^^^^^^^^^^^ | ^^^^^^^^^^^^^
LL | } else if s.parse::<u32>().unwrap() != 42 { LL | } else if s.parse::<u32>().unwrap() != 42 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | panic!("{:?}", s); LL | panic!("{:?}", s);