From 96a8048f46a943fe034826df80f54d4b06276117 Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Fri, 18 Sep 2020 13:08:31 +0000 Subject: [PATCH 01/29] rustc_ast_passes: allow c-variadic associated fns - Allow c-variadic associated functions - Add test for c-variadic functions in the Impl context --- .../rustc_ast_passes/src/ast_validation.rs | 3 +- src/test/ui/c-variadic/variadic-ffi-6.rs | 16 ++++++ src/test/ui/c-variadic/variadic-ffi-7.rs | 55 +++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/c-variadic/variadic-ffi-7.rs diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 31c05325d1d25..2aae1e45d8c51 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -537,7 +537,8 @@ impl<'a> AstValidator<'a> { fn check_c_varadic_type(&self, fk: FnKind<'a>) { match (fk.ctxt(), fk.header()) { (Some(FnCtxt::Foreign), _) => return, - (Some(FnCtxt::Free), Some(header)) => match header.ext { + (Some(FnCtxt::Free), Some(header)) + | (Some(FnCtxt::Assoc(AssocCtxt::Impl)), Some(header)) => match header.ext { Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }) | Extern::Implicit if matches!(header.unsafety, Unsafe::Yes(_)) => { diff --git a/src/test/ui/c-variadic/variadic-ffi-6.rs b/src/test/ui/c-variadic/variadic-ffi-6.rs index 4dd8a2d452181..644c4cf3f6d17 100644 --- a/src/test/ui/c-variadic/variadic-ffi-6.rs +++ b/src/test/ui/c-variadic/variadic-ffi-6.rs @@ -11,3 +11,19 @@ pub unsafe extern "C" fn use_vararg_lifetime( pub unsafe extern "C" fn use_normal_arg_lifetime(x: &usize, y: ...) -> &usize { // OK x } + +#[repr(C)] +pub struct Foo(usize); + + +impl Foo { + #[no_mangle] + pub unsafe extern "C" fn assoc_fn(_format: *const i8, ap: ...) -> usize { // OK + ap.arg() + } + + #[no_mangle] + pub unsafe extern "C" fn method(&self, _format: *const i8, ap: ...) -> usize { // OK + ap.arg() + } +} diff --git a/src/test/ui/c-variadic/variadic-ffi-7.rs b/src/test/ui/c-variadic/variadic-ffi-7.rs new file mode 100644 index 0000000000000..8c1d592e7eb26 --- /dev/null +++ b/src/test/ui/c-variadic/variadic-ffi-7.rs @@ -0,0 +1,55 @@ +// run-pass +#![feature(c_variadic)] + +macro_rules! variadic_tests { + (generate) => { + pub unsafe extern "C" fn sum(n: usize, mut ap: ...) -> usize { + (0..n).fold(0usize, |acc, _| { + acc + ap.arg::() + }) + } + + pub unsafe extern "C" fn mixed_types(_: usize, mut ap: ...) { + use std::ffi::{CString, CStr}; + + assert_eq!(ap.arg::().floor(), 12.0f64.floor()); + assert_eq!(ap.arg::(), 0x10000001); + assert_eq!(ap.arg::(), 0x42); + let cstr = CStr::from_ptr(ap.arg::<*const i8>()); + assert!(cstr == &*CString::new("Hello").unwrap()); + } + }; + + (test_sum $p:path) => { + unsafe { + assert_eq!($p(5, 2, 4, 8, 16, 32), 62); + assert_eq!($p(4, 10, 8, 8, 16, 2), 42); + } + }; + + (test_mixed_types $p:path) => { + unsafe { + use std::ffi::CString; + + $p(0, 12.56f64, 0x10000001, 0x42, CString::new("Hello").unwrap().as_ptr()); + } + } +} + +mod foo { + variadic_tests!(generate); +} + +struct Foo; + +impl Foo { + variadic_tests!(generate); +} + +fn main() { + variadic_tests!(test_sum foo::sum); + variadic_tests!(test_sum Foo::sum); + + variadic_tests!(test_mixed_types foo::mixed_types); + variadic_tests!(test_mixed_types Foo::mixed_types); +} From 43c181bac4d88dbe7bdd762688dcf18313f01093 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 4 Aug 2020 13:48:05 +0200 Subject: [PATCH 02/29] Use `tracing` spans to trace the entire MIR interp stack --- Cargo.lock | 15 +--- compiler/rustc_driver/Cargo.toml | 1 + compiler/rustc_driver/src/lib.rs | 20 +++-- compiler/rustc_mir/Cargo.toml | 1 - .../rustc_mir/src/interpret/eval_context.rs | 77 ++++++++++++++----- src/tools/tidy/src/deps.rs | 1 - 6 files changed, 75 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d23b29d39bf86..db072cbb7e709 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1723,15 +1723,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "log_settings" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd" -dependencies = [ - "lazy_static", -] - [[package]] name = "lsp-codec" version = "0.1.2" @@ -3520,6 +3511,7 @@ dependencies = [ "rustc_target", "tracing", "tracing-subscriber", + "tracing-tree", "winapi 0.3.9", ] @@ -3807,7 +3799,6 @@ version = "0.0.0" dependencies = [ "either", "itertools 0.9.0", - "log_settings", "polonius-engine", "regex", "rustc_apfloat", @@ -5102,9 +5093,9 @@ dependencies = [ [[package]] name = "tracing-tree" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1a3dc4774db3a6b2d66a4f8d8de670e874ec3ed55615860c994927419b32c5f" +checksum = "43aac8afb493b08e1e1904956f7407c1e671b9c83b26a17e1bd83d6a3520e350" dependencies = [ "ansi_term 0.12.1", "atty", diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml index adfce1008e1ed..f610e88b7fce5 100644 --- a/compiler/rustc_driver/Cargo.toml +++ b/compiler/rustc_driver/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["dylib"] libc = "0.2" tracing = { version = "0.1.18" } tracing-subscriber = { version = "0.2.10", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } +tracing-tree = "0.1.6" rustc_middle = { path = "../rustc_middle" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 7118437c0c850..7e12d783cb41e 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1241,11 +1241,21 @@ pub fn init_env_logger(env: &str) { Ok(s) if s.is_empty() => return, Ok(_) => {} } - let builder = tracing_subscriber::FmtSubscriber::builder(); - - let builder = builder.with_env_filter(tracing_subscriber::EnvFilter::from_env(env)); - - builder.init() + let filter = tracing_subscriber::EnvFilter::from_env(env); + let layer = tracing_tree::HierarchicalLayer::default() + .with_indent_lines(true) + .with_ansi(true) + .with_targets(true) + .with_thread_ids(true) + .with_thread_names(true) + .with_wraparound(10) + .with_verbose_exit(true) + .with_verbose_entry(true) + .with_indent_amount(2); + + use tracing_subscriber::layer::SubscriberExt; + let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer); + tracing::subscriber::set_global_default(subscriber).unwrap(); } pub fn main() -> ! { diff --git a/compiler/rustc_mir/Cargo.toml b/compiler/rustc_mir/Cargo.toml index a6d22243d6df6..487668cfa1109 100644 --- a/compiler/rustc_mir/Cargo.toml +++ b/compiler/rustc_mir/Cargo.toml @@ -12,7 +12,6 @@ either = "1.5.0" rustc_graphviz = { path = "../rustc_graphviz" } itertools = "0.9" tracing = "0.1" -log_settings = "0.1.1" polonius-engine = "0.12.0" regex = "1" rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index f97096984fa9b..45b5dd62479d9 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -48,8 +48,41 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { FxHashMap<(Ty<'tcx>, Option>), Pointer>, } +// The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread +// boundary and dropped in the other thread, it would exit the span in the other thread. +struct SpanGuard(tracing::Span, std::marker::PhantomData<*const u8>); + +impl SpanGuard { + /// By default a `SpanGuard` does nothing. + fn new() -> Self { + Self(tracing::Span::none(), std::marker::PhantomData) + } + + /// If a span is entered, we exit the previous span (if any, normally none) and enter the + /// new span. This is mainly so we don't have to use `Option` for the `tracing_span` field of + /// `Frame` by creating a dummy span to being with and then entering it once the frame has + /// been pushed. + fn enter(&mut self, span: tracing::Span) { + // This executes the destructor on the previous instance of `SpanGuard`, ensuring that + // we never enter or exit more spans than vice versa. Unless you `mem::leak`, then we + // can't protect the tracing stack, but that'll just lead to weird logging, no actual + // problems. + *self = Self(span, std::marker::PhantomData); + self.0.with_subscriber(|(id, dispatch)| { + dispatch.enter(id); + }); + } +} + +impl Drop for SpanGuard { + fn drop(&mut self) { + self.0.with_subscriber(|(id, dispatch)| { + dispatch.exit(id); + }); + } +} + /// A stack frame. -#[derive(Clone)] pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> { //////////////////////////////////////////////////////////////////////////////// // Function and callsite information @@ -80,6 +113,11 @@ pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> { /// can either directly contain `Scalar` or refer to some part of an `Allocation`. pub locals: IndexVec>, + /// The span of the `tracing` crate is stored here. + /// When the guard is dropped, the span is exited. This gives us + /// a full stack trace on all tracing statements. + tracing_span: SpanGuard, + //////////////////////////////////////////////////////////////////////////////// // Current position within the function //////////////////////////////////////////////////////////////////////////////// @@ -184,6 +222,7 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> { locals: self.locals, loc: self.loc, extra, + tracing_span: self.tracing_span, } } } @@ -637,11 +676,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return_place: Option>, return_to_block: StackPopCleanup, ) -> InterpResult<'tcx> { - if !self.stack().is_empty() { - info!("PAUSING({}) {}", self.frame_idx(), self.frame().instance); - } - ::log_settings::settings().indentation += 1; - // first push a stack frame so we have access to the local substs let pre_frame = Frame { body, @@ -652,6 +686,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // all methods actually know about the frame locals: IndexVec::new(), instance, + tracing_span: SpanGuard::new(), extra: (), }; let frame = M::init_frame_extra(self, pre_frame)?; @@ -696,7 +731,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.frame_mut().locals = locals; M::after_stack_push(self)?; self.frame_mut().loc = Ok(mir::Location::START); - info!("ENTERING({}) {}", self.frame_idx(), self.frame().instance); + + let span = info_span!("frame", "{}", instance); + self.frame_mut().tracing_span.enter(span); Ok(()) } @@ -746,12 +783,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// The cleanup block ends with a special `Resume` terminator, which will /// cause us to continue unwinding. pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx> { - info!( - "LEAVING({}) {} (unwinding = {})", - self.frame_idx(), - self.frame().instance, - unwinding - ); + info!(unwinding); // Sanity check `unwinding`. assert_eq!( @@ -766,7 +798,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_ub_format!("unwinding past the topmost frame of the stack"); } - ::log_settings::settings().indentation -= 1; let frame = self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); @@ -824,12 +855,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } if !self.stack().is_empty() { - info!( - "CONTINUING({}) {} (unwinding = {})", - self.frame_idx(), - self.frame().instance, - unwinding - ); + info!(unwinding); } Ok(()) @@ -995,7 +1021,16 @@ where { fn hash_stable(&self, hcx: &mut StableHashingContext<'ctx>, hasher: &mut StableHasher) { // Exhaustive match on fields to make sure we forget no field. - let Frame { body, instance, return_to_block, return_place, locals, loc, extra } = self; + let Frame { + body, + instance, + return_to_block, + return_place, + locals, + loc, + extra, + tracing_span: _, + } = self; body.hash_stable(hcx, hasher); instance.hash_stable(hcx, hasher); return_to_block.hash_stable(hcx, hasher); diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 356705305d78b..0c52fee68a968 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -116,7 +116,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "libz-sys", "lock_api", "log", - "log_settings", "maybe-uninit", "md-5", "measureme", From 916d23614b462dbaa60cdb5540a139f5db1fe950 Mon Sep 17 00:00:00 2001 From: Jake Vossen Date: Wed, 30 Sep 2020 10:07:15 -0600 Subject: [PATCH 03/29] updated p! macro to accept literals --- compiler/rustc_middle/src/ty/print/pretty.rs | 173 ++++++++++--------- 1 file changed, 92 insertions(+), 81 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 7b5cf681f38fb..adf1fc5e16a09 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -28,6 +28,9 @@ use std::ops::{Deref, DerefMut}; use super::*; macro_rules! p { + (@$lit:literal) => { + write!(scoped_cx!(), $lit)? + }; (@write($($data:expr),+)) => { write!(scoped_cx!(), $($data),+)? }; @@ -37,8 +40,8 @@ macro_rules! p { (@$method:ident($($arg:expr),*)) => { scoped_cx!() = scoped_cx!().$method($($arg),*)? }; - ($($kind:ident $data:tt),+) => {{ - $(p!(@$kind $data);)+ + ($($elem:tt $(($($args:tt)*))?),+) => {{ + $(p!(@ $elem $(($($args)*))?);)+ }}; } macro_rules! define_scoped_cx { @@ -478,7 +481,7 @@ pub trait PrettyPrinter<'tcx>: p!(print(self_ty)); if let Some(trait_ref) = trait_ref { - p!(write(" as "), print(trait_ref.print_only_trait_path())); + p!(" as ", print(trait_ref.print_only_trait_path())); } Ok(cx) }) @@ -495,9 +498,9 @@ pub trait PrettyPrinter<'tcx>: self.generic_delimiters(|mut cx| { define_scoped_cx!(cx); - p!(write("impl ")); + p!("impl "); if let Some(trait_ref) = trait_ref { - p!(print(trait_ref.print_only_trait_path()), write(" for ")); + p!(print(trait_ref.print_only_trait_path()), " for "); } p!(print(self_ty)); @@ -509,8 +512,8 @@ pub trait PrettyPrinter<'tcx>: define_scoped_cx!(self); match *ty.kind() { - ty::Bool => p!(write("bool")), - ty::Char => p!(write("char")), + ty::Bool => p!("bool"), + ty::Char => p!("char"), ty::Int(t) => p!(write("{}", t.name_str())), ty::Uint(t) => p!(write("{}", t.name_str())), ty::Float(t) => p!(write("{}", t.name_str())), @@ -525,23 +528,23 @@ pub trait PrettyPrinter<'tcx>: p!(print(tm.ty)) } ty::Ref(r, ty, mutbl) => { - p!(write("&")); + p!("&"); if self.region_should_not_be_omitted(r) { p!(print(r), write(" ")); } p!(print(ty::TypeAndMut { ty, mutbl })) } - ty::Never => p!(write("!")), + ty::Never => p!("!"), ty::Tuple(ref tys) => { - p!(write("("), comma_sep(tys.iter())); + p!("(", comma_sep(tys.iter())); if tys.len() == 1 { - p!(write(",")); + p!(","); } - p!(write(")")) + p!(")") } ty::FnDef(def_id, substs) => { let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs); - p!(print(sig), write(" {{"), print_value_path(def_id, substs), write("}}")); + p!(print(sig), " {{", print_value_path(def_id, substs), "}}"); } ty::FnPtr(ref bare_fn) => p!(print(bare_fn)), ty::Infer(infer_ty) => { @@ -555,7 +558,7 @@ pub trait PrettyPrinter<'tcx>: p!(write("{}", infer_ty)) } } - ty::Error(_) => p!(write("[type error]")), + ty::Error(_) => p!("[type error]"), ty::Param(ref param_ty) => p!(write("{}", param_ty)), ty::Bound(debruijn, bound_ty) => match bound_ty.kind { ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?, @@ -567,11 +570,11 @@ pub trait PrettyPrinter<'tcx>: ty::Dynamic(data, r) => { let print_r = self.region_should_not_be_omitted(r); if print_r { - p!(write("(")); + p!("("); } - p!(write("dyn "), print(data)); + p!("dyn ", print(data)); if print_r { - p!(write(" + "), print(r), write(")")); + p!(" + ", print(r), ")"); } } ty::Foreign(def_id) => { @@ -597,7 +600,7 @@ pub trait PrettyPrinter<'tcx>: p!(write("{}", name)); // FIXME(eddyb) print this with `print_def_path`. if !substs.is_empty() { - p!(write("::")); + p!("::"); p!(generic_delimiters(|cx| cx.comma_sep(substs.iter()))); } return Ok(self); @@ -608,7 +611,7 @@ pub trait PrettyPrinter<'tcx>: let mut first = true; let mut is_sized = false; - p!(write("impl")); + p!("impl"); for predicate in bounds.predicates { // Note: We can't use `to_opt_poly_trait_ref` here as `predicate` // may contain unbound variables. We therefore do this manually. @@ -634,12 +637,12 @@ pub trait PrettyPrinter<'tcx>: if !is_sized { p!(write("{}?Sized", if first { " " } else { "+" })); } else if first { - p!(write(" Sized")); + p!(" Sized"); } Ok(self) })?); } - ty::Str => p!(write("str")), + ty::Str => p!("str"), ty::Generator(did, substs, movability) => { p!(write("[")); match movability { @@ -674,10 +677,10 @@ pub trait PrettyPrinter<'tcx>: } if substs.as_generator().is_valid() { - p!(write(" "), print(substs.as_generator().witness())); + p!(" ", print(substs.as_generator().witness())); } - p!(write("]")); + p!("]") } ty::GeneratorWitness(types) => { p!(in_binder(&types)); @@ -723,24 +726,24 @@ pub trait PrettyPrinter<'tcx>: p!(write("]")); } ty::Array(ty, sz) => { - p!(write("["), print(ty), write("; ")); + p!("[", print(ty), "; "); if self.tcx().sess.verbose() { p!(write("{:?}", sz)); } else if let ty::ConstKind::Unevaluated(..) = sz.val { // Do not try to evaluate unevaluated constants. If we are const evaluating an // array length anon const, rustc will (with debug assertions) print the // constant's path. Which will end up here again. - p!(write("_")); + p!("_"); } else if let Some(n) = sz.val.try_to_bits(self.tcx().data_layout.pointer_size) { p!(write("{}", n)); } else if let ty::ConstKind::Param(param) = sz.val { p!(write("{}", param)); } else { - p!(write("_")); + p!("_"); } - p!(write("]")) + p!("]") } - ty::Slice(ty) => p!(write("["), print(ty), write("]")), + ty::Slice(ty) => p!("[", print(ty), "]"), } Ok(self) @@ -847,7 +850,7 @@ pub trait PrettyPrinter<'tcx>: for (_, def_id) in auto_traits { if !first { - p!(write(" + ")); + p!(" + "); } first = false; @@ -865,16 +868,16 @@ pub trait PrettyPrinter<'tcx>: ) -> Result { define_scoped_cx!(self); - p!(write("("), comma_sep(inputs.iter().copied())); + p!("(", comma_sep(inputs.iter().copied())); if c_variadic { if !inputs.is_empty() { - p!(write(", ")); + p!(", "); } - p!(write("...")); + p!("..."); } - p!(write(")")); + p!(")"); if !output.is_unit() { - p!(write(" -> "), print(output)); + p!(" -> ", print(output)); } Ok(self) @@ -945,7 +948,7 @@ pub trait PrettyPrinter<'tcx>: self.pretty_print_bound_var(debruijn, bound_var)? } ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)), - ty::ConstKind::Error(_) => p!(write("[const error]")), + ty::ConstKind::Error(_) => p!("[const error]"), }; Ok(self) } @@ -987,17 +990,17 @@ pub trait PrettyPrinter<'tcx>: { p!(pretty_print_byte_str(byte_str)) } else { - p!(write("")) + p!("") } } // FIXME: for statics and functions, we could in principle print more detail. Some(GlobalAlloc::Static(def_id)) => p!(write("", def_id)), - Some(GlobalAlloc::Function(_)) => p!(write("")), - None => p!(write("")), + Some(GlobalAlloc::Function(_)) => p!(""), + None => p!(""), }, // Bool - (Scalar::Raw { data: 0, .. }, ty::Bool) => p!(write("false")), - (Scalar::Raw { data: 1, .. }, ty::Bool) => p!(write("true")), + (Scalar::Raw { data: 0, .. }, ty::Bool) => p!("false"), + (Scalar::Raw { data: 1, .. }, ty::Bool) => p!("true"), // Float (Scalar::Raw { data, .. }, ty::Float(ast::FloatTy::F32)) => { p!(write("{}f32", Single::from_bits(data))) @@ -1009,12 +1012,20 @@ pub trait PrettyPrinter<'tcx>: (Scalar::Raw { data, .. }, ty::Uint(ui)) => { let size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size(); let int = ConstInt::new(data, size, false, ty.is_ptr_sized_integral()); - if print_ty { p!(write("{:#?}", int)) } else { p!(write("{:?}", int)) } + if print_ty { + p!(write("{:#?}", int)) + } else { + p!(write("{:?}", int)) + } } (Scalar::Raw { data, .. }, ty::Int(i)) => { let size = Integer::from_attr(&self.tcx(), SignedInt(*i)).size(); let int = ConstInt::new(data, size, true, ty.is_ptr_sized_integral()); - if print_ty { p!(write("{:#?}", int)) } else { p!(write("{:?}", int)) } + if print_ty { + p!(write("{:#?}", int)) + } else { + p!(write("{:?}", int)) + } } // Char (Scalar::Raw { data, .. }, ty::Char) if char::from_u32(data as u32).is_some() => { @@ -1093,13 +1104,13 @@ pub trait PrettyPrinter<'tcx>: fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result { define_scoped_cx!(self); - p!(write("b\"")); + p!("b\""); for &c in byte_str { for e in std::ascii::escape_default(c) { self.write_char(e as char)?; } } - p!(write("\"")); + p!("\""); Ok(self) } @@ -1112,7 +1123,7 @@ pub trait PrettyPrinter<'tcx>: define_scoped_cx!(self); if self.tcx().sess.verbose() { - p!(write("ConstValue({:?}: ", ct), print(ty), write(")")); + p!(write("ConstValue({:?}: ", ct), print(ty), ")"); return Ok(self); } @@ -1149,7 +1160,7 @@ pub trait PrettyPrinter<'tcx>: let ptr = Pointer::new(AllocId(0), offset); let byte_str = alloc.get_bytes(&self.tcx(), ptr, n).unwrap(); - p!(write("*")); + p!("*"); p!(pretty_print_byte_str(byte_str)); Ok(self) } @@ -1173,14 +1184,14 @@ pub trait PrettyPrinter<'tcx>: match *ty.kind() { ty::Array(..) => { - p!(write("["), comma_sep(fields), write("]")); + p!("[", comma_sep(fields), "]"); } ty::Tuple(..) => { - p!(write("("), comma_sep(fields)); + p!("(", comma_sep(fields)); if contents.fields.len() == 1 { - p!(write(",")); + p!(","); } - p!(write(")")); + p!(")"); } ty::Adt(def, substs) if def.variants.is_empty() => { p!(print_value_path(def.did, substs)); @@ -1194,19 +1205,19 @@ pub trait PrettyPrinter<'tcx>: match variant_def.ctor_kind { CtorKind::Const => {} CtorKind::Fn => { - p!(write("("), comma_sep(fields), write(")")); + p!("(", comma_sep(fields), ")"); } CtorKind::Fictive => { - p!(write(" {{ ")); + p!(" {{ "); let mut first = true; for (field_def, field) in variant_def.fields.iter().zip(fields) { if !first { - p!(write(", ")); + p!(", "); } p!(write("{}: ", field_def.ident), print(field)); first = false; } - p!(write(" }}")); + p!(" }}"); } } } @@ -1224,7 +1235,7 @@ pub trait PrettyPrinter<'tcx>: // fallback p!(write("{:?}", ct)); if print_ty { - p!(write(": "), print(ty)); + p!(": ", print(ty)); } Ok(self) } @@ -1637,7 +1648,7 @@ impl PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> { if this.print_alloc_ids { p!(write("{:?}", p)); } else { - p!(write("&_")); + p!("&_"); } Ok(this) }; @@ -1703,11 +1714,11 @@ impl FmtPrinter<'_, '_, F> { ty::ReVar(_) => {} ty::ReErased => {} ty::ReStatic => { - p!(write("'static")); + p!("'static"); return Ok(self); } ty::ReEmpty(ty::UniverseIndex::ROOT) => { - p!(write("'")); + p!("'"); return Ok(self); } ty::ReEmpty(ui) => { @@ -1716,7 +1727,7 @@ impl FmtPrinter<'_, '_, F> { } } - p!(write("'_")); + p!("'_"); Ok(self) } @@ -1847,7 +1858,7 @@ where type Error = P::Error; fn print(&self, mut cx: P) -> Result { define_scoped_cx!(cx); - p!(print(self.0), write(": "), print(self.1)); + p!(print(self.0), ": ", print(self.1)); Ok(cx) } } @@ -1945,7 +1956,7 @@ define_print_and_forward_display! { (self, cx): &'tcx ty::List> { - p!(write("{{"), comma_sep(self.iter()), write("}}")) + p!("{{", comma_sep(self.iter()), "}}") } ty::TypeAndMut<'tcx> { @@ -1981,7 +1992,7 @@ define_print_and_forward_display! { p!(write("extern {} ", self.abi)); } - p!(write("fn"), pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); + p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output())); } ty::InferTy { @@ -1990,7 +2001,7 @@ define_print_and_forward_display! { return Ok(cx); } match *self { - ty::TyVar(_) => p!(write("_")), + ty::TyVar(_) => p!("_"), ty::IntVar(_) => p!(write("{}", "{integer}")), ty::FloatVar(_) => p!(write("{}", "{float}")), ty::FreshTy(v) => p!(write("FreshTy({})", v)), @@ -2016,16 +2027,16 @@ define_print_and_forward_display! { } ty::SubtypePredicate<'tcx> { - p!(print(self.a), write(" <: "), print(self.b)) + p!(print(self.a), " <: ", print(self.b)) } ty::TraitPredicate<'tcx> { - p!(print(self.trait_ref.self_ty()), write(": "), + p!(print(self.trait_ref.self_ty()), ": ", print(self.trait_ref.print_only_trait_path())) } ty::ProjectionPredicate<'tcx> { - p!(print(self.projection_ty), write(" == "), print(self.ty)) + p!(print(self.projection_ty), " == ", print(self.ty)) } ty::ProjectionTy<'tcx> { @@ -2034,9 +2045,9 @@ define_print_and_forward_display! { ty::ClosureKind { match *self { - ty::ClosureKind::Fn => p!(write("Fn")), - ty::ClosureKind::FnMut => p!(write("FnMut")), - ty::ClosureKind::FnOnce => p!(write("FnOnce")), + ty::ClosureKind::Fn => p!("Fn"), + ty::ClosureKind::FnMut => p!("FnMut"), + ty::ClosureKind::FnOnce => p!("FnOnce"), } } @@ -2051,7 +2062,7 @@ define_print_and_forward_display! { match *self { ty::PredicateAtom::Trait(ref data, constness) => { if let hir::Constness::Const = constness { - p!(write("const ")); + p!("const "); } p!(print(data)) } @@ -2059,33 +2070,33 @@ define_print_and_forward_display! { ty::PredicateAtom::RegionOutlives(predicate) => p!(print(predicate)), ty::PredicateAtom::TypeOutlives(predicate) => p!(print(predicate)), ty::PredicateAtom::Projection(predicate) => p!(print(predicate)), - ty::PredicateAtom::WellFormed(arg) => p!(print(arg), write(" well-formed")), + ty::PredicateAtom::WellFormed(arg) => p!(print(arg), " well-formed"), ty::PredicateAtom::ObjectSafe(trait_def_id) => { - p!(write("the trait `"), + p!("the trait `", print_def_path(trait_def_id, &[]), - write("` is object-safe")) + "` is object-safe") } ty::PredicateAtom::ClosureKind(closure_def_id, _closure_substs, kind) => { - p!(write("the closure `"), + p!("the closure `", print_value_path(closure_def_id, &[]), write("` implements the trait `{}`", kind)) } ty::PredicateAtom::ConstEvaluatable(def, substs) => { - p!(write("the constant `"), + p!("the constant `", print_value_path(def.did, substs), - write("` can be evaluated")) + "` can be evaluated") } ty::PredicateAtom::ConstEquate(c1, c2) => { - p!(write("the constant `"), + p!("the constant `", print(c1), - write("` equals `"), + "` equals `", print(c2), - write("`")) + "`") } ty::PredicateAtom::TypeWellFormedFromEnv(ty) => { - p!(write("the type `"), + p!("the type `", print(ty), - write("` is found in the environment")) + "` is found in the environment") } } } From d103fe15d16dddd3300799375e9e6516e1d072e5 Mon Sep 17 00:00:00 2001 From: Jake Vossen Date: Wed, 30 Sep 2020 10:12:48 -0600 Subject: [PATCH 04/29] Fixed more write literals after master merge --- compiler/rustc_middle/src/ty/print/pretty.rs | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index adf1fc5e16a09..c4246fa1d9581 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -647,11 +647,11 @@ pub trait PrettyPrinter<'tcx>: p!(write("[")); match movability { hir::Movability::Movable => {} - hir::Movability::Static => p!(write("static ")), + hir::Movability::Static => p!("static "), } if !self.tcx().sess.verbose() { - p!(write("generator")); + p!("generator"); // FIXME(eddyb) should use `def_span`. if let Some(did) = did.as_local() { let hir_id = self.tcx().hir().local_def_id_to_hir_id(did); @@ -664,7 +664,7 @@ pub trait PrettyPrinter<'tcx>: p!(print_def_path(did, substs)); if substs.as_generator().is_valid() { // Search for the first inference variable - p!(write(" upvar_tys=(")); + p!(" upvar_tys=("); let mut uninferred_ty = substs.as_generator().upvar_tys().filter(|ty| ty.is_ty_infer()); if uninferred_ty.next().is_some() { @@ -672,7 +672,7 @@ pub trait PrettyPrinter<'tcx>: } else { self = self.comma_sep(substs.as_generator().upvar_tys())?; } - p!(write(")")); + p!(")"); } } @@ -693,7 +693,7 @@ pub trait PrettyPrinter<'tcx>: if let Some(did) = did.as_local() { let hir_id = self.tcx().hir().local_def_id_to_hir_id(did); if self.tcx().sess.opts.debugging_opts.span_free_formats { - p!(write("@"), print_def_path(did.to_def_id(), substs)); + p!("@", print_def_path(did.to_def_id(), substs)); } else { let span = self.tcx().hir().span(hir_id); p!(write("@{}", self.tcx().sess.source_map().span_to_string(span))); @@ -710,20 +710,20 @@ pub trait PrettyPrinter<'tcx>: if uninferred_ty.next().is_some() { // If the upvar substs contain an inference variable we haven't // finished capture analysis. - p!(write(" closure_substs=(unavailable)")); + p!(" closure_substs=(unavailable)"); } else { - p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty())); + p!(" closure_kind_ty=", print(substs.as_closure().kind_ty())); p!( - write(" closure_sig_as_fn_ptr_ty="), + " closure_sig_as_fn_ptr_ty=", print(substs.as_closure().sig_as_fn_ptr_ty()) ); - p!(write(" upvar_tys=(")); + p!(" upvar_tys=("); self = self.comma_sep(substs.as_closure().upvar_tys())?; - p!(write(")")); + p!(")"); } } } - p!(write("]")); + p!("]"); } ty::Array(ty, sz) => { p!("[", print(ty), "; "); From f69a88b7d345e09e076ae65e4c8538c6f034b47c Mon Sep 17 00:00:00 2001 From: Jake Vossen Date: Wed, 30 Sep 2020 10:52:51 -0600 Subject: [PATCH 05/29] updated p! macro to accept literals --- compiler/rustc_middle/src/ty/print/pretty.rs | 43 ++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c4246fa1d9581..8166e1dd6ff5c 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -646,8 +646,13 @@ pub trait PrettyPrinter<'tcx>: ty::Generator(did, substs, movability) => { p!(write("[")); match movability { +<<<<<<< HEAD hir::Movability::Movable => {} hir::Movability::Static => p!("static "), +======= + hir::Movability::Movable => p!("[generator"), + hir::Movability::Static => p!("[static generator"), +>>>>>>> 4bc0ae233aa... updated p! macro to accept literals } if !self.tcx().sess.verbose() { @@ -686,6 +691,7 @@ pub trait PrettyPrinter<'tcx>: p!(in_binder(&types)); } ty::Closure(did, substs) => { +<<<<<<< HEAD p!(write("[")); if !self.tcx().sess.verbose() { p!(write("closure")); @@ -697,6 +703,33 @@ pub trait PrettyPrinter<'tcx>: } else { let span = self.tcx().hir().span(hir_id); p!(write("@{}", self.tcx().sess.source_map().span_to_string(span))); +======= + p!("[closure"); + + // FIXME(eddyb) should use `def_span`. + if let Some(did) = did.as_local() { + let hir_id = self.tcx().hir().local_def_id_to_hir_id(did); + if self.tcx().sess.opts.debugging_opts.span_free_formats { + p!("@", print_def_path(did.to_def_id(), substs)); + } else { + let span = self.tcx().hir().span(hir_id); + p!(write("@{}", self.tcx().sess.source_map().span_to_string(span))); + } + + if substs.as_closure().is_valid() { + let upvar_tys = substs.as_closure().upvar_tys(); + let mut sep = " "; + for (&var_id, upvar_ty) in self + .tcx() + .upvars_mentioned(did) + .as_ref() + .iter() + .flat_map(|v| v.keys()) + .zip(upvar_tys) + { + p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty)); + sep = ", "; +>>>>>>> 4bc0ae233aa... updated p! macro to accept literals } } else { p!(write("@{}", self.tcx().def_path_str(did))); @@ -723,7 +756,17 @@ pub trait PrettyPrinter<'tcx>: } } } +<<<<<<< HEAD p!("]"); +======= + + if self.tcx().sess.verbose() && substs.as_closure().is_valid() { + p!(" closure_kind_ty=", print(substs.as_closure().kind_ty())); + p!(" closure_sig_as_fn_ptr_ty=", print(substs.as_closure().sig_as_fn_ptr_ty())); + } + + p!("]") +>>>>>>> 4bc0ae233aa... updated p! macro to accept literals } ty::Array(ty, sz) => { p!("[", print(ty), "; "); From 50326740651c182e430c8a075e07ae39d3eb180e Mon Sep 17 00:00:00 2001 From: Jake Vossen Date: Wed, 30 Sep 2020 10:54:27 -0600 Subject: [PATCH 06/29] fixed merge conflicts --- compiler/rustc_middle/src/ty/print/pretty.rs | 43 -------------------- 1 file changed, 43 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 8166e1dd6ff5c..c4246fa1d9581 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -646,13 +646,8 @@ pub trait PrettyPrinter<'tcx>: ty::Generator(did, substs, movability) => { p!(write("[")); match movability { -<<<<<<< HEAD hir::Movability::Movable => {} hir::Movability::Static => p!("static "), -======= - hir::Movability::Movable => p!("[generator"), - hir::Movability::Static => p!("[static generator"), ->>>>>>> 4bc0ae233aa... updated p! macro to accept literals } if !self.tcx().sess.verbose() { @@ -691,7 +686,6 @@ pub trait PrettyPrinter<'tcx>: p!(in_binder(&types)); } ty::Closure(did, substs) => { -<<<<<<< HEAD p!(write("[")); if !self.tcx().sess.verbose() { p!(write("closure")); @@ -703,33 +697,6 @@ pub trait PrettyPrinter<'tcx>: } else { let span = self.tcx().hir().span(hir_id); p!(write("@{}", self.tcx().sess.source_map().span_to_string(span))); -======= - p!("[closure"); - - // FIXME(eddyb) should use `def_span`. - if let Some(did) = did.as_local() { - let hir_id = self.tcx().hir().local_def_id_to_hir_id(did); - if self.tcx().sess.opts.debugging_opts.span_free_formats { - p!("@", print_def_path(did.to_def_id(), substs)); - } else { - let span = self.tcx().hir().span(hir_id); - p!(write("@{}", self.tcx().sess.source_map().span_to_string(span))); - } - - if substs.as_closure().is_valid() { - let upvar_tys = substs.as_closure().upvar_tys(); - let mut sep = " "; - for (&var_id, upvar_ty) in self - .tcx() - .upvars_mentioned(did) - .as_ref() - .iter() - .flat_map(|v| v.keys()) - .zip(upvar_tys) - { - p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty)); - sep = ", "; ->>>>>>> 4bc0ae233aa... updated p! macro to accept literals } } else { p!(write("@{}", self.tcx().def_path_str(did))); @@ -756,17 +723,7 @@ pub trait PrettyPrinter<'tcx>: } } } -<<<<<<< HEAD p!("]"); -======= - - if self.tcx().sess.verbose() && substs.as_closure().is_valid() { - p!(" closure_kind_ty=", print(substs.as_closure().kind_ty())); - p!(" closure_sig_as_fn_ptr_ty=", print(substs.as_closure().sig_as_fn_ptr_ty())); - } - - p!("]") ->>>>>>> 4bc0ae233aa... updated p! macro to accept literals } ty::Array(ty, sz) => { p!("[", print(ty), "; "); From dffb9d6a26a29ea4cbad7df2371e004e7ae20269 Mon Sep 17 00:00:00 2001 From: Jake Vossen Date: Wed, 30 Sep 2020 10:55:34 -0600 Subject: [PATCH 07/29] cargo fmt --- compiler/rustc_middle/src/ty/print/pretty.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c4246fa1d9581..610eb2cddbe6f 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1012,20 +1012,12 @@ pub trait PrettyPrinter<'tcx>: (Scalar::Raw { data, .. }, ty::Uint(ui)) => { let size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size(); let int = ConstInt::new(data, size, false, ty.is_ptr_sized_integral()); - if print_ty { - p!(write("{:#?}", int)) - } else { - p!(write("{:?}", int)) - } + if print_ty { p!(write("{:#?}", int)) } else { p!(write("{:?}", int)) } } (Scalar::Raw { data, .. }, ty::Int(i)) => { let size = Integer::from_attr(&self.tcx(), SignedInt(*i)).size(); let int = ConstInt::new(data, size, true, ty.is_ptr_sized_integral()); - if print_ty { - p!(write("{:#?}", int)) - } else { - p!(write("{:?}", int)) - } + if print_ty { p!(write("{:#?}", int)) } else { p!(write("{:?}", int)) } } // Char (Scalar::Raw { data, .. }, ty::Char) if char::from_u32(data as u32).is_some() => { From c1e17f56ea1d3cc64cd7d1be6fc2557d0fd65f06 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 1 Oct 2020 14:09:57 +0900 Subject: [PATCH 08/29] Add a regression test for issue-66501 --- src/test/ui/pattern/issue-66501.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/test/ui/pattern/issue-66501.rs diff --git a/src/test/ui/pattern/issue-66501.rs b/src/test/ui/pattern/issue-66501.rs new file mode 100644 index 0000000000000..ffcfd4ad83e1f --- /dev/null +++ b/src/test/ui/pattern/issue-66501.rs @@ -0,0 +1,12 @@ +// check-pass + +#![allow(unreachable_patterns)] + +fn main() { + const CONST: &[Option<()>; 1] = &[Some(())]; + match &[Some(())] { + &[None] => {} + CONST => {} + &[Some(())] => {} + } +} From 8631e1c57504624824add1b059d12cdc86cdd87c Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 1 Oct 2020 14:10:23 +0900 Subject: [PATCH 09/29] Add a regression test for issue-68951 --- src/test/ui/issues/issue-68951.rs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/test/ui/issues/issue-68951.rs diff --git a/src/test/ui/issues/issue-68951.rs b/src/test/ui/issues/issue-68951.rs new file mode 100644 index 0000000000000..1c1e92c5bbcbb --- /dev/null +++ b/src/test/ui/issues/issue-68951.rs @@ -0,0 +1,9 @@ +// check-pass + +fn main() { + let array = [0x42u8; 10]; + for b in &array { + let lo = b & 0xf; + let hi = (b >> 4) & 0xf; + } +} From 50ffd6b7cbdf6baedbd3a22f4ea79ebdf7c48af9 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 1 Oct 2020 14:10:33 +0900 Subject: [PATCH 10/29] Add a regression test for issue-72565 --- src/test/ui/pattern/issue-72565.rs | 8 ++++++++ src/test/ui/pattern/issue-72565.stderr | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 src/test/ui/pattern/issue-72565.rs create mode 100644 src/test/ui/pattern/issue-72565.stderr diff --git a/src/test/ui/pattern/issue-72565.rs b/src/test/ui/pattern/issue-72565.rs new file mode 100644 index 0000000000000..1e262fd506765 --- /dev/null +++ b/src/test/ui/pattern/issue-72565.rs @@ -0,0 +1,8 @@ +const F: &'static dyn PartialEq = &7u32; + +fn main() { + let a: &dyn PartialEq = &7u32; + match a { + F => panic!(), //~ ERROR: `&dyn PartialEq` cannot be used in patterns + } +} diff --git a/src/test/ui/pattern/issue-72565.stderr b/src/test/ui/pattern/issue-72565.stderr new file mode 100644 index 0000000000000..2f82616b27764 --- /dev/null +++ b/src/test/ui/pattern/issue-72565.stderr @@ -0,0 +1,8 @@ +error: `&dyn PartialEq` cannot be used in patterns + --> $DIR/issue-72565.rs:6:9 + | +LL | F => panic!(), + | ^ + +error: aborting due to previous error + From d4fdf6e7542941ab8d5b0d43f9c5bc0b278f638d Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 1 Oct 2020 14:10:44 +0900 Subject: [PATCH 11/29] Add a regression test for issue-74244 --- .../ui/type-alias-impl-trait/issue-74244.rs | 20 +++++++++++++++++++ .../type-alias-impl-trait/issue-74244.stderr | 9 +++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/test/ui/type-alias-impl-trait/issue-74244.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-74244.stderr diff --git a/src/test/ui/type-alias-impl-trait/issue-74244.rs b/src/test/ui/type-alias-impl-trait/issue-74244.rs new file mode 100644 index 0000000000000..bb4104b3d2519 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74244.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_impl_trait)] + +trait Allocator { + type Buffer; +} + +struct DefaultAllocator; + +impl Allocator for DefaultAllocator { + //~^ ERROR: the type parameter `T` is not constrained + type Buffer = (); +} + +type A = impl Fn(::Buffer); + +fn foo() -> A { + |_| () +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-74244.stderr b/src/test/ui/type-alias-impl-trait/issue-74244.stderr new file mode 100644 index 0000000000000..ff6bacd277e1e --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74244.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74244.rs:9:6 + | +LL | impl Allocator for DefaultAllocator { + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. From 38f460f8669de8ee0d975ec89f06e89a5849ab65 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 1 Oct 2020 14:10:53 +0900 Subject: [PATCH 12/29] Add a regression test for issue-75299 --- src/test/ui/const-generics/issues/issue-75299.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/test/ui/const-generics/issues/issue-75299.rs diff --git a/src/test/ui/const-generics/issues/issue-75299.rs b/src/test/ui/const-generics/issues/issue-75299.rs new file mode 100644 index 0000000000000..23f30a1eea073 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-75299.rs @@ -0,0 +1,11 @@ +// compile-flags: -Zmir-opt-level=3 +// run-pass + +#![feature(const_generics)] +#![allow(incomplete_features)] +fn main() { + fn foo() -> [u8; N] { + [0; N] + } + let _x = foo::<1>(); +} From 8f9472cc9e372351964390bdf531cc65b13768c7 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 1 Oct 2020 08:32:24 +0200 Subject: [PATCH 13/29] Only mention that a stack frame is being popped when starting to do so --- compiler/rustc_mir/src/interpret/eval_context.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 45b5dd62479d9..93da6e3d38a93 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -783,7 +783,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// The cleanup block ends with a special `Resume` terminator, which will /// cause us to continue unwinding. pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx> { - info!(unwinding); + info!( + "popping stack frame ({})", + if unwinding { "during unwinding" } else { "returning from function" } + ); // Sanity check `unwinding`. assert_eq!( @@ -854,10 +857,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - if !self.stack().is_empty() { - info!(unwinding); - } - Ok(()) } From cd159fd7f9f8eec5792e6fd7f1b347ea3e028301 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 19 Aug 2020 03:05:44 -0700 Subject: [PATCH 14/29] Uplift drop-bounds lint from clippy --- compiler/rustc_lint/src/lib.rs | 3 + compiler/rustc_lint/src/traits.rs | 79 +++++++++++++++++++ library/core/src/mem/mod.rs | 1 + .../ui/drop-bounds/drop-bounds-impl-drop.rs | 14 ++++ src/test/ui/drop-bounds/drop-bounds.rs | 19 +++++ src/test/ui/drop-bounds/drop-bounds.stderr | 50 ++++++++++++ 6 files changed, 166 insertions(+) create mode 100644 compiler/rustc_lint/src/traits.rs create mode 100644 src/test/ui/drop-bounds/drop-bounds-impl-drop.rs create mode 100644 src/test/ui/drop-bounds/drop-bounds.rs create mode 100644 src/test/ui/drop-bounds/drop-bounds.stderr diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 33caedfc19826..49e80f9d8a531 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -53,6 +53,7 @@ mod non_ascii_idents; mod nonstandard_style; mod passes; mod redundant_semicolon; +mod traits; mod types; mod unused; @@ -75,6 +76,7 @@ use internal::*; use non_ascii_idents::*; use nonstandard_style::*; use redundant_semicolon::*; +use traits::*; use types::*; use unused::*; @@ -157,6 +159,7 @@ macro_rules! late_lint_passes { MissingDebugImplementations: MissingDebugImplementations::default(), ArrayIntoIter: ArrayIntoIter, ClashingExternDeclarations: ClashingExternDeclarations::new(), + DropTraitConstraints: DropTraitConstraints, ] ); }; diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs new file mode 100644 index 0000000000000..d4f79036e5a18 --- /dev/null +++ b/compiler/rustc_lint/src/traits.rs @@ -0,0 +1,79 @@ +use crate::LateContext; +use crate::LateLintPass; +use crate::LintContext; +use rustc_hir as hir; +use rustc_span::symbol::sym; + +declare_lint! { + /// The `drop_bounds` lint checks for generics with `std::ops::Drop` as + /// bounds. + /// + /// ### Example + /// + /// ```rust + /// fn foo() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// `Drop` bounds do not really accomplish anything. A type may have + /// compiler-generated drop glue without implementing the `Drop` trait + /// itself. The `Drop` trait also only has one method, `Drop::drop`, and + /// that function is by fiat not callable in user code. So there is really + /// no use case for using `Drop` in trait bounds. + /// + /// The most likely use case of a drop bound is to distinguish between + /// types that have destructors and types that don't. Combined with + /// specialization, a naive coder would write an implementation that + /// assumed a type could be trivially dropped, then write a specialization + /// for `T: Drop` that actually calls the destructor. Except that doing so + /// is not correct; String, for example, doesn't actually implement Drop, + /// but because String contains a Vec, assuming it can be trivially dropped + /// will leak memory. + pub DROP_BOUNDS, + Warn, + "bounds of the form `T: Drop` are useless" +} + +declare_lint_pass!( + /// Lint for bounds of the form `T: Drop`, which usually + /// indicate an attempt to emulate `std::mem::needs_drop`. + DropTraitConstraints => [DROP_BOUNDS] +); + +impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { + use rustc_middle::ty::PredicateAtom::*; + + let def_id = cx.tcx.hir().local_def_id(item.hir_id); + let predicates = cx.tcx.explicit_predicates_of(def_id); + for &(predicate, span) in predicates.predicates { + let trait_predicate = match predicate.skip_binders() { + Trait(trait_predicate, _constness) => trait_predicate, + _ => continue, + }; + let def_id = trait_predicate.trait_ref.def_id; + if cx.tcx.lang_items().drop_trait() == Some(def_id) { + // Explicitly allow `impl Drop`, a drop-guards-as-Voldemort-type pattern. + if trait_predicate.trait_ref.self_ty().is_impl_trait() { + continue; + } + cx.struct_span_lint(DROP_BOUNDS, span, |lint| { + let needs_drop = match cx.tcx.get_diagnostic_item(sym::needs_drop) { + Some(needs_drop) => needs_drop, + None => return, + }; + let msg = format!( + "bounds on `{}` are useless, consider instead \ + using `{}` to detect if a type has a destructor", + predicate, + cx.tcx.def_path_str(needs_drop) + ); + lint.build(&msg).emit() + }); + } + } + } +} diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index aa1b5529df222..a2c7da6e6958e 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -568,6 +568,7 @@ pub unsafe fn align_of_val_raw(val: *const T) -> usize { #[inline] #[stable(feature = "needs_drop", since = "1.21.0")] #[rustc_const_stable(feature = "const_needs_drop", since = "1.36.0")] +#[rustc_diagnostic_item = "needs_drop"] pub const fn needs_drop() -> bool { intrinsics::needs_drop::() } diff --git a/src/test/ui/drop-bounds/drop-bounds-impl-drop.rs b/src/test/ui/drop-bounds/drop-bounds-impl-drop.rs new file mode 100644 index 0000000000000..063efc7b31abd --- /dev/null +++ b/src/test/ui/drop-bounds/drop-bounds-impl-drop.rs @@ -0,0 +1,14 @@ +// run-pass +#![deny(drop_bounds)] +// As a special exemption, `impl Drop` in the return position raises no error. +// This allows a convenient way to return an unnamed drop guard. +fn voldemort_type() -> impl Drop { + struct Voldemort; + impl Drop for Voldemort { + fn drop(&mut self) {} + } + Voldemort +} +fn main() { + let _ = voldemort_type(); +} diff --git a/src/test/ui/drop-bounds/drop-bounds.rs b/src/test/ui/drop-bounds/drop-bounds.rs new file mode 100644 index 0000000000000..c73538278d3be --- /dev/null +++ b/src/test/ui/drop-bounds/drop-bounds.rs @@ -0,0 +1,19 @@ +#![deny(drop_bounds)] +fn foo() {} //~ ERROR +fn bar() +where + U: Drop, //~ ERROR +{ +} +fn baz(_x: impl Drop) {} //~ ERROR +struct Foo { //~ ERROR + _x: T +} +struct Bar where U: Drop { //~ ERROR + _x: U +} +trait Baz: Drop { //~ ERROR +} +impl Baz for T { //~ ERROR +} +fn main() {} diff --git a/src/test/ui/drop-bounds/drop-bounds.stderr b/src/test/ui/drop-bounds/drop-bounds.stderr new file mode 100644 index 0000000000000..15ba4c9a64989 --- /dev/null +++ b/src/test/ui/drop-bounds/drop-bounds.stderr @@ -0,0 +1,50 @@ +error: bounds on `T: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:2:11 + | +LL | fn foo() {} + | ^^^^ + | +note: the lint level is defined here + --> $DIR/drop-bounds.rs:1:9 + | +LL | #![deny(drop_bounds)] + | ^^^^^^^^^^^ + +error: bounds on `U: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:5:8 + | +LL | U: Drop, + | ^^^^ + +error: bounds on `impl Drop: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:8:17 + | +LL | fn baz(_x: impl Drop) {} + | ^^^^ + +error: bounds on `T: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:9:15 + | +LL | struct Foo { + | ^^^^ + +error: bounds on `U: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:12:24 + | +LL | struct Bar where U: Drop { + | ^^^^ + +error: bounds on `Self: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:15:12 + | +LL | trait Baz: Drop { + | ^^^^ + +error: bounds on `T: Drop` are useless, consider instead using `std::mem::needs_drop` to detect if a type has a destructor + --> $DIR/drop-bounds.rs:17:9 + | +LL | impl Baz for T { + | ^^^^ + +error: aborting due to 7 previous errors + From e87d391a0f34f29a180ccdff842e19176d16ebbe Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Fri, 2 Oct 2020 11:47:03 +0200 Subject: [PATCH 15/29] BTreeMap: complete the compile-time test_variance test case --- .../alloc/src/collections/btree/map/tests.rs | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 8018514fa1776..8ce9900bd3702 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -1,12 +1,10 @@ +use super::super::{navigate::Position, node, DeterministicRng}; +use super::Entry::{Occupied, Vacant}; +use super::*; use crate::boxed::Box; -use crate::collections::btree::navigate::Position; -use crate::collections::btree::node; -use crate::collections::btree_map::Entry::{Occupied, Vacant}; -use crate::collections::BTreeMap; use crate::fmt::Debug; use crate::rc::Rc; -use crate::string::String; -use crate::string::ToString; +use crate::string::{String, ToString}; use crate::vec::Vec; use std::convert::TryFrom; use std::iter::FromIterator; @@ -16,19 +14,17 @@ use std::ops::RangeBounds; use std::panic::{catch_unwind, AssertUnwindSafe}; use std::sync::atomic::{AtomicUsize, Ordering}; -use super::super::DeterministicRng; - // Capacity of a tree with a single level, -// i.e. a tree who's root is a leaf node at height 0. +// i.e., a tree who's root is a leaf node at height 0. const NODE_CAPACITY: usize = node::CAPACITY; // Minimum number of elements to insert, to guarantee a tree with 2 levels, -// i.e. a tree who's root is an internal node at height 1, with edges to leaf nodes. +// i.e., a tree who's root is an internal node at height 1, with edges to leaf nodes. // It's not the minimum size: removing an element from such a tree does not always reduce height. const MIN_INSERTS_HEIGHT_1: usize = NODE_CAPACITY + 1; // Minimum number of elements to insert in ascending order, to guarantee a tree with 3 levels, -// i.e. a tree who's root is an internal node at height 2, with edges to more internal nodes. +// i.e., a tree who's root is an internal node at height 2, with edges to more internal nodes. // It's not the minimum size: removing an element from such a tree does not always reduce height. const MIN_INSERTS_HEIGHT_2: usize = 89; @@ -1386,44 +1382,65 @@ fn test_clone_from() { } } -#[test] #[allow(dead_code)] fn test_variance() { - use std::collections::btree_map::{IntoIter, Iter, Keys, Range, Values}; - fn map_key<'new>(v: BTreeMap<&'static str, ()>) -> BTreeMap<&'new str, ()> { v } fn map_val<'new>(v: BTreeMap<(), &'static str>) -> BTreeMap<(), &'new str> { v } + fn iter_key<'a, 'new>(v: Iter<'a, &'static str, ()>) -> Iter<'a, &'new str, ()> { v } fn iter_val<'a, 'new>(v: Iter<'a, (), &'static str>) -> Iter<'a, (), &'new str> { v } + fn into_iter_key<'new>(v: IntoIter<&'static str, ()>) -> IntoIter<&'new str, ()> { v } fn into_iter_val<'new>(v: IntoIter<(), &'static str>) -> IntoIter<(), &'new str> { v } + + fn into_keys_key<'new>(v: IntoKeys<&'static str, ()>) -> IntoKeys<&'new str, ()> { + v + } + fn into_keys_val<'new>(v: IntoKeys<(), &'static str>) -> IntoKeys<(), &'new str> { + v + } + + fn into_values_key<'new>(v: IntoValues<&'static str, ()>) -> IntoValues<&'new str, ()> { + v + } + fn into_values_val<'new>(v: IntoValues<(), &'static str>) -> IntoValues<(), &'new str> { + v + } + fn range_key<'a, 'new>(v: Range<'a, &'static str, ()>) -> Range<'a, &'new str, ()> { v } fn range_val<'a, 'new>(v: Range<'a, (), &'static str>) -> Range<'a, (), &'new str> { v } - fn keys<'a, 'new>(v: Keys<'a, &'static str, ()>) -> Keys<'a, &'new str, ()> { + + fn keys_key<'a, 'new>(v: Keys<'a, &'static str, ()>) -> Keys<'a, &'new str, ()> { v } - fn vals<'a, 'new>(v: Values<'a, (), &'static str>) -> Values<'a, (), &'new str> { + fn keys_val<'a, 'new>(v: Keys<'a, (), &'static str>) -> Keys<'a, (), &'new str> { + v + } + + fn values_key<'a, 'new>(v: Values<'a, &'static str, ()>) -> Values<'a, &'new str, ()> { + v + } + fn values_val<'a, 'new>(v: Values<'a, (), &'static str>) -> Values<'a, (), &'new str> { v } } -#[test] #[allow(dead_code)] fn test_sync() { fn map(v: &BTreeMap) -> impl Sync + '_ { From 90c8b43bc3cb867715bd08d93c3bb6e06819c3b1 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Sun, 27 Sep 2020 01:10:30 +0200 Subject: [PATCH 16/29] BTreeMap: document DrainFilterInner better --- library/alloc/src/collections/btree/map.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 3fb03a5412e4f..ee0f525fb15ee 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1666,10 +1666,14 @@ where /// Most of the implementation of DrainFilter, independent of the type /// of the predicate, thus also serving for BTreeSet::DrainFilter. pub(super) struct DrainFilterInner<'a, K: 'a, V: 'a> { + /// Reference to the length field in the borrowed map, updated live. length: &'a mut usize, - // dormant_root is wrapped in an Option to be able to `take` it. + /// Burried reference to the root field in the borrowed map. + /// Wrapped in `Option` to allow drop handler to `take` it. dormant_root: Option>>, - // cur_leaf_edge is wrapped in an Option because maps without root lack a leaf edge. + /// Contains a leaf edge preceding the next element to be returned, or the last leaf edge. + /// Empty if the map has no root, if iteration went beyond the last leaf edge, + /// or if a panic occurred in the predicate. cur_leaf_edge: Option, K, V, marker::Leaf>, marker::Edge>>, } From dceb81af1ea4cbefd5e8bf49f738e03e9e3fac9c Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 2 Oct 2020 11:34:14 -0700 Subject: [PATCH 17/29] Deprecate clippy lint --- .../clippy_lints/src/deprecated_lints.rs | 9 +++ .../clippy/clippy_lints/src/drop_bounds.rs | 73 ------------------- src/tools/clippy/clippy_lints/src/lib.rs | 9 +-- .../clippy/clippy_lints/src/utils/paths.rs | 1 - src/tools/clippy/src/lintlist/mod.rs | 7 -- src/tools/clippy/tests/ui/deprecated.rs | 1 + src/tools/clippy/tests/ui/deprecated.stderr | 8 +- src/tools/clippy/tests/ui/drop_bounds.rs | 8 -- src/tools/clippy/tests/ui/drop_bounds.stderr | 16 ---- 9 files changed, 21 insertions(+), 111 deletions(-) delete mode 100644 src/tools/clippy/clippy_lints/src/drop_bounds.rs delete mode 100644 src/tools/clippy/tests/ui/drop_bounds.rs delete mode 100644 src/tools/clippy/tests/ui/drop_bounds.stderr diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs index c17a0e8333058..c5884361dff9d 100644 --- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs +++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs @@ -163,3 +163,12 @@ declare_deprecated_lint! { pub REGEX_MACRO, "the regex! macro has been removed from the regex crate in 2018" } + +declare_deprecated_lint! { + /// **What it does:** Nothing. This lint has been deprecated. + /// + /// **Deprecation reason:** This lint has been uplifted to rustc and is now called + /// `drop_bounds`. + pub DROP_BOUNDS, + "this lint has been uplifted to rustc and is now called `drop_bounds`" +} diff --git a/src/tools/clippy/clippy_lints/src/drop_bounds.rs b/src/tools/clippy/clippy_lints/src/drop_bounds.rs deleted file mode 100644 index ec3b6afa6300f..0000000000000 --- a/src/tools/clippy/clippy_lints/src/drop_bounds.rs +++ /dev/null @@ -1,73 +0,0 @@ -use crate::utils::{match_def_path, paths, span_lint}; -use if_chain::if_chain; -use rustc_hir::{GenericBound, GenericParam, WhereBoundPredicate, WherePredicate}; -use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; - -declare_clippy_lint! { - /// **What it does:** Checks for generics with `std::ops::Drop` as bounds. - /// - /// **Why is this bad?** `Drop` bounds do not really accomplish anything. - /// A type may have compiler-generated drop glue without implementing the - /// `Drop` trait itself. The `Drop` trait also only has one method, - /// `Drop::drop`, and that function is by fiat not callable in user code. - /// So there is really no use case for using `Drop` in trait bounds. - /// - /// The most likely use case of a drop bound is to distinguish between types - /// that have destructors and types that don't. Combined with specialization, - /// a naive coder would write an implementation that assumed a type could be - /// trivially dropped, then write a specialization for `T: Drop` that actually - /// calls the destructor. Except that doing so is not correct; String, for - /// example, doesn't actually implement Drop, but because String contains a - /// Vec, assuming it can be trivially dropped will leak memory. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// fn foo() {} - /// ``` - /// Could be written as: - /// ```rust - /// fn foo() {} - /// ``` - pub DROP_BOUNDS, - correctness, - "bounds of the form `T: Drop` are useless" -} - -const DROP_BOUNDS_SUMMARY: &str = "bounds of the form `T: Drop` are useless, \ - use `std::mem::needs_drop` to detect if a type has drop glue"; - -declare_lint_pass!(DropBounds => [DROP_BOUNDS]); - -impl<'tcx> LateLintPass<'tcx> for DropBounds { - fn check_generic_param(&mut self, cx: &LateContext<'tcx>, p: &'tcx GenericParam<'_>) { - for bound in p.bounds.iter() { - lint_bound(cx, bound); - } - } - fn check_where_predicate(&mut self, cx: &LateContext<'tcx>, p: &'tcx WherePredicate<'_>) { - if let WherePredicate::BoundPredicate(WhereBoundPredicate { bounds, .. }) = p { - for bound in *bounds { - lint_bound(cx, bound); - } - } - } -} - -fn lint_bound<'tcx>(cx: &LateContext<'tcx>, bound: &'tcx GenericBound<'_>) { - if_chain! { - if let GenericBound::Trait(t, _) = bound; - if let Some(def_id) = t.trait_ref.path.res.opt_def_id(); - if match_def_path(cx, def_id, &paths::DROP_TRAIT); - then { - span_lint( - cx, - DROP_BOUNDS, - t.span, - DROP_BOUNDS_SUMMARY - ); - } - } -} diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index c3ff34e6e1eed..70efdaeb9c669 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -179,7 +179,6 @@ mod derive; mod doc; mod double_comparison; mod double_parens; -mod drop_bounds; mod drop_forget_ref; mod duration_subsec; mod else_if_without_else; @@ -478,6 +477,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: "clippy::regex_macro", "the regex! macro has been removed from the regex crate in 2018", ); + store.register_removed( + "clippy::drop_bounds", + "this lint has been uplifted to rustc and is now called `drop_bounds`", + ); // end deprecated lints, do not remove this comment, it’s used in `update_lints` // begin register lints, do not remove this comment, it’s used in `update_lints` @@ -532,7 +535,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &doc::NEEDLESS_DOCTEST_MAIN, &double_comparison::DOUBLE_COMPARISONS, &double_parens::DOUBLE_PARENS, - &drop_bounds::DROP_BOUNDS, &drop_forget_ref::DROP_COPY, &drop_forget_ref::DROP_REF, &drop_forget_ref::FORGET_COPY, @@ -959,7 +961,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|| box strings::StringLitAsBytes); store.register_late_pass(|| box derive::Derive); store.register_late_pass(|| box types::CharLitAsU8); - store.register_late_pass(|| box drop_bounds::DropBounds); store.register_late_pass(|| box get_last_with_len::GetLastWithLen); store.register_late_pass(|| box drop_forget_ref::DropForgetRef); store.register_late_pass(|| box empty_enum::EmptyEnum); @@ -1282,7 +1283,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&doc::NEEDLESS_DOCTEST_MAIN), LintId::of(&double_comparison::DOUBLE_COMPARISONS), LintId::of(&double_parens::DOUBLE_PARENS), - LintId::of(&drop_bounds::DROP_BOUNDS), LintId::of(&drop_forget_ref::DROP_COPY), LintId::of(&drop_forget_ref::DROP_REF), LintId::of(&drop_forget_ref::FORGET_COPY), @@ -1714,7 +1714,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&copies::IF_SAME_THEN_ELSE), LintId::of(&derive::DERIVE_HASH_XOR_EQ), LintId::of(&derive::DERIVE_ORD_XOR_PARTIAL_ORD), - LintId::of(&drop_bounds::DROP_BOUNDS), LintId::of(&drop_forget_ref::DROP_COPY), LintId::of(&drop_forget_ref::DROP_REF), LintId::of(&drop_forget_ref::FORGET_COPY), diff --git a/src/tools/clippy/clippy_lints/src/utils/paths.rs b/src/tools/clippy/clippy_lints/src/utils/paths.rs index 1583afad208ab..be837a61dc07e 100644 --- a/src/tools/clippy/clippy_lints/src/utils/paths.rs +++ b/src/tools/clippy/clippy_lints/src/utils/paths.rs @@ -31,7 +31,6 @@ pub const DISPLAY_FMT_METHOD: [&str; 4] = ["core", "fmt", "Display", "fmt"]; pub const DISPLAY_TRAIT: [&str; 3] = ["core", "fmt", "Display"]; pub const DOUBLE_ENDED_ITERATOR: [&str; 4] = ["core", "iter", "traits", "DoubleEndedIterator"]; pub const DROP: [&str; 3] = ["core", "mem", "drop"]; -pub const DROP_TRAIT: [&str; 4] = ["core", "ops", "drop", "Drop"]; pub const DURATION: [&str; 3] = ["core", "time", "Duration"]; pub const EARLY_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "EarlyContext"]; pub const EXIT: [&str; 3] = ["std", "process", "exit"]; diff --git a/src/tools/clippy/src/lintlist/mod.rs b/src/tools/clippy/src/lintlist/mod.rs index 9603023ed0671..f6d529de9a3a2 100644 --- a/src/tools/clippy/src/lintlist/mod.rs +++ b/src/tools/clippy/src/lintlist/mod.rs @@ -423,13 +423,6 @@ pub static ref ALL_LINTS: Vec = vec![ deprecation: None, module: "double_parens", }, - Lint { - name: "drop_bounds", - group: "correctness", - desc: "bounds of the form `T: Drop` are useless", - deprecation: None, - module: "drop_bounds", - }, Lint { name: "drop_copy", group: "correctness", diff --git a/src/tools/clippy/tests/ui/deprecated.rs b/src/tools/clippy/tests/ui/deprecated.rs index 3eefb232780f1..9e32fe36ece4d 100644 --- a/src/tools/clippy/tests/ui/deprecated.rs +++ b/src/tools/clippy/tests/ui/deprecated.rs @@ -8,5 +8,6 @@ #[warn(clippy::into_iter_on_array)] #[warn(clippy::unused_label)] #[warn(clippy::regex_macro)] +#[warn(clippy::drop_bounds)] fn main() {} diff --git a/src/tools/clippy/tests/ui/deprecated.stderr b/src/tools/clippy/tests/ui/deprecated.stderr index a80e2bf31feb6..d3400a7be09fd 100644 --- a/src/tools/clippy/tests/ui/deprecated.stderr +++ b/src/tools/clippy/tests/ui/deprecated.stderr @@ -60,11 +60,17 @@ error: lint `clippy::regex_macro` has been removed: `the regex! macro has been r LL | #[warn(clippy::regex_macro)] | ^^^^^^^^^^^^^^^^^^^ +error: lint `clippy::drop_bounds` has been removed: `this lint has been uplifted to rustc and is now called `drop_bounds`` + --> $DIR/deprecated.rs:11:8 + | +LL | #[warn(clippy::drop_bounds)] + | ^^^^^^^^^^^^^^^^^^^ + error: lint `clippy::str_to_string` has been removed: `using `str::to_string` is common even today and specialization will likely happen soon` --> $DIR/deprecated.rs:1:8 | LL | #[warn(clippy::str_to_string)] | ^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 12 previous errors diff --git a/src/tools/clippy/tests/ui/drop_bounds.rs b/src/tools/clippy/tests/ui/drop_bounds.rs deleted file mode 100644 index 6d6a9dc078399..0000000000000 --- a/src/tools/clippy/tests/ui/drop_bounds.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![allow(unused)] -fn foo() {} -fn bar() -where - T: Drop, -{ -} -fn main() {} diff --git a/src/tools/clippy/tests/ui/drop_bounds.stderr b/src/tools/clippy/tests/ui/drop_bounds.stderr deleted file mode 100644 index 8208c0ed7e398..0000000000000 --- a/src/tools/clippy/tests/ui/drop_bounds.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error: bounds of the form `T: Drop` are useless, use `std::mem::needs_drop` to detect if a type has drop glue - --> $DIR/drop_bounds.rs:2:11 - | -LL | fn foo() {} - | ^^^^ - | - = note: `#[deny(clippy::drop_bounds)]` on by default - -error: bounds of the form `T: Drop` are useless, use `std::mem::needs_drop` to detect if a type has drop glue - --> $DIR/drop_bounds.rs:5:8 - | -LL | T: Drop, - | ^^^^ - -error: aborting due to 2 previous errors - From 3ea96b86ab8f2afec172bc7452876540388e4df9 Mon Sep 17 00:00:00 2001 From: Jake Vossen Date: Fri, 2 Oct 2020 15:08:01 -0600 Subject: [PATCH 18/29] made multiline macro calls into single line --- compiler/rustc_middle/src/ty/print/pretty.rs | 24 +++++--------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 610eb2cddbe6f..c95316c96abc4 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -530,7 +530,7 @@ pub trait PrettyPrinter<'tcx>: ty::Ref(r, ty, mutbl) => { p!("&"); if self.region_should_not_be_omitted(r) { - p!(print(r), write(" ")); + p!(print(r), " "); } p!(print(ty::TypeAndMut { ty, mutbl })) } @@ -2064,31 +2064,19 @@ define_print_and_forward_display! { ty::PredicateAtom::Projection(predicate) => p!(print(predicate)), ty::PredicateAtom::WellFormed(arg) => p!(print(arg), " well-formed"), ty::PredicateAtom::ObjectSafe(trait_def_id) => { - p!("the trait `", - print_def_path(trait_def_id, &[]), - "` is object-safe") + p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe") } ty::PredicateAtom::ClosureKind(closure_def_id, _closure_substs, kind) => { - p!("the closure `", - print_value_path(closure_def_id, &[]), - write("` implements the trait `{}`", kind)) + p!("the closure `", print_value_path(closure_def_id, &[]), write("` implements the trait `{}`", kind)) } ty::PredicateAtom::ConstEvaluatable(def, substs) => { - p!("the constant `", - print_value_path(def.did, substs), - "` can be evaluated") + p!("the constant `", print_value_path(def.did, substs), "` can be evaluated") } ty::PredicateAtom::ConstEquate(c1, c2) => { - p!("the constant `", - print(c1), - "` equals `", - print(c2), - "`") + p!("the constant `", print(c1), "` equals `", print(c2), "`") } ty::PredicateAtom::TypeWellFormedFromEnv(ty) => { - p!("the type `", - print(ty), - "` is found in the environment") + p!("the type `", print(ty), "` is found in the environment") } } } From 4c9bcf3b39faa07afb40a79b0d932a4accaeb82b Mon Sep 17 00:00:00 2001 From: Camelid Date: Fri, 2 Oct 2020 14:33:23 -0700 Subject: [PATCH 19/29] Fix test name Remove trailing `-`. --- ...lify-arm-identity-.rs => issue-77359-simplify-arm-identity.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/mir/{issue-77359-simplify-arm-identity-.rs => issue-77359-simplify-arm-identity.rs} (100%) diff --git a/src/test/ui/mir/issue-77359-simplify-arm-identity-.rs b/src/test/ui/mir/issue-77359-simplify-arm-identity.rs similarity index 100% rename from src/test/ui/mir/issue-77359-simplify-arm-identity-.rs rename to src/test/ui/mir/issue-77359-simplify-arm-identity.rs From 87f3f81451f72fc7b5acb4a569bb79a51a8604c3 Mon Sep 17 00:00:00 2001 From: Camelid Date: Fri, 2 Oct 2020 14:32:14 -0700 Subject: [PATCH 20/29] Improve rustdoc error for failed intra-doc link resolution The previous error was confusing since it made it sound like you can't link to items that are defined outside the current module. Also suggested importing the item. --- .../passes/collect_intra_doc_links.rs | 8 +-- .../deny-intra-link-resolution-failure.stderr | 3 +- src/test/rustdoc-ui/intra-link-errors.rs | 15 +++-- src/test/rustdoc-ui/intra-link-errors.stderr | 57 ++++++++++-------- .../intra-link-span-ice-55723.stderr | 3 +- .../intra-links-warning-crlf.stderr | 12 ++-- .../rustdoc-ui/intra-links-warning.stderr | 59 +++++++++++++------ src/test/rustdoc-ui/lint-group.stderr | 3 +- 8 files changed, 102 insertions(+), 58 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index cf94ea384fd60..632e6c9f91c11 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1575,17 +1575,17 @@ fn resolution_failure( _ => None, }; // See if this was a module: `[path]` or `[std::io::nope]` - if let Some(module) = last_found_module { - let module_name = collector.cx.tcx.item_name(module); + if let Some(_module) = last_found_module { let note = format!( - "the module `{}` contains no item named `{}`", - module_name, unresolved + "there is no item named `{}` in scope", + unresolved ); if let Some(span) = sp { diag.span_label(span, ¬e); } else { diag.note(¬e); } + diag.help(&format!("did you mean to import `{}`?", unresolved)); // If the link has `::` in it, assume it was meant to be an intra-doc link. // Otherwise, the `[]` might be unrelated. // FIXME: don't show this for autolinks (`<>`), `()` style links, or reference links diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr index 33260fa0e1e66..96b805dbc82a3 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr @@ -2,13 +2,14 @@ error: unresolved link to `v2` --> $DIR/deny-intra-link-resolution-failure.rs:3:6 | LL | /// [v2] - | ^^ the module `deny_intra_link_resolution_failure` contains no item named `v2` + | ^^ there is no item named `v2` in scope | note: the lint level is defined here --> $DIR/deny-intra-link-resolution-failure.rs:1:9 | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ + = help: did you mean to import `v2`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-link-errors.rs b/src/test/rustdoc-ui/intra-link-errors.rs index 0278caf308776..babcc3c43b4ae 100644 --- a/src/test/rustdoc-ui/intra-link-errors.rs +++ b/src/test/rustdoc-ui/intra-link-errors.rs @@ -6,23 +6,28 @@ /// [path::to::nonexistent::module] //~^ ERROR unresolved link -//~| NOTE `intra_link_errors` contains no item named `path` +//~| NOTE there is no item named `path` in scope +//~| HELP did you mean to import `path`? /// [path::to::nonexistent::macro!] //~^ ERROR unresolved link -//~| NOTE `intra_link_errors` contains no item named `path` +//~| NOTE there is no item named `path` in scope +//~| HELP did you mean to import `path`? /// [type@path::to::nonexistent::type] //~^ ERROR unresolved link -//~| NOTE `intra_link_errors` contains no item named `path` +//~| NOTE there is no item named `path` in scope +//~| HELP did you mean to import `path`? /// [std::io::not::here] //~^ ERROR unresolved link -//~| NOTE `io` contains no item named `not` +//~| NOTE there is no item named `not` in scope +//~| HELP did you mean to import `not`? /// [type@std::io::not::here] //~^ ERROR unresolved link -//~| NOTE `io` contains no item named `not` +//~| NOTE there is no item named `not` in scope +//~| HELP did you mean to import `not`? /// [std::io::Error::x] //~^ ERROR unresolved link diff --git a/src/test/rustdoc-ui/intra-link-errors.stderr b/src/test/rustdoc-ui/intra-link-errors.stderr index b63f799535a1f..f9af1a9fb9385 100644 --- a/src/test/rustdoc-ui/intra-link-errors.stderr +++ b/src/test/rustdoc-ui/intra-link-errors.stderr @@ -2,94 +2,103 @@ error: unresolved link to `path::to::nonexistent::module` --> $DIR/intra-link-errors.rs:7:6 | LL | /// [path::to::nonexistent::module] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope | note: the lint level is defined here --> $DIR/intra-link-errors.rs:1:9 | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ + = help: did you mean to import `path`? error: unresolved link to `path::to::nonexistent::macro` - --> $DIR/intra-link-errors.rs:11:6 + --> $DIR/intra-link-errors.rs:12:6 | LL | /// [path::to::nonexistent::macro!] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope + | + = help: did you mean to import `path`? error: unresolved link to `path::to::nonexistent::type` - --> $DIR/intra-link-errors.rs:15:6 + --> $DIR/intra-link-errors.rs:17:6 | LL | /// [type@path::to::nonexistent::type] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the module `intra_link_errors` contains no item named `path` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope + | + = help: did you mean to import `path`? error: unresolved link to `std::io::not::here` - --> $DIR/intra-link-errors.rs:19:6 + --> $DIR/intra-link-errors.rs:22:6 | LL | /// [std::io::not::here] - | ^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not` + | ^^^^^^^^^^^^^^^^^^ there is no item named `not` in scope + | + = help: did you mean to import `not`? error: unresolved link to `std::io::not::here` - --> $DIR/intra-link-errors.rs:23:6 + --> $DIR/intra-link-errors.rs:27:6 | LL | /// [type@std::io::not::here] - | ^^^^^^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not` + | ^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `not` in scope + | + = help: did you mean to import `not`? error: unresolved link to `std::io::Error::x` - --> $DIR/intra-link-errors.rs:27:6 + --> $DIR/intra-link-errors.rs:32:6 | LL | /// [std::io::Error::x] | ^^^^^^^^^^^^^^^^^ the struct `Error` has no field or associated item named `x` error: unresolved link to `std::io::ErrorKind::x` - --> $DIR/intra-link-errors.rs:31:6 + --> $DIR/intra-link-errors.rs:36:6 | LL | /// [std::io::ErrorKind::x] | ^^^^^^^^^^^^^^^^^^^^^ the enum `ErrorKind` has no variant or associated item named `x` error: unresolved link to `f::A` - --> $DIR/intra-link-errors.rs:35:6 + --> $DIR/intra-link-errors.rs:40:6 | LL | /// [f::A] | ^^^^ `f` is a function, not a module or type, and cannot have associated items error: unresolved link to `f::A` - --> $DIR/intra-link-errors.rs:39:6 + --> $DIR/intra-link-errors.rs:44:6 | LL | /// [f::A!] | ^^^^^ `f` is a function, not a module or type, and cannot have associated items error: unresolved link to `S::A` - --> $DIR/intra-link-errors.rs:43:6 + --> $DIR/intra-link-errors.rs:48:6 | LL | /// [S::A] | ^^^^ the struct `S` has no field or associated item named `A` error: unresolved link to `S::fmt` - --> $DIR/intra-link-errors.rs:47:6 + --> $DIR/intra-link-errors.rs:52:6 | LL | /// [S::fmt] | ^^^^^^ the struct `S` has no field or associated item named `fmt` error: unresolved link to `E::D` - --> $DIR/intra-link-errors.rs:51:6 + --> $DIR/intra-link-errors.rs:56:6 | LL | /// [E::D] | ^^^^ the enum `E` has no variant or associated item named `D` error: unresolved link to `u8::not_found` - --> $DIR/intra-link-errors.rs:55:6 + --> $DIR/intra-link-errors.rs:60:6 | LL | /// [u8::not_found] | ^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found` error: unresolved link to `std::primitive::u8::not_found` - --> $DIR/intra-link-errors.rs:59:6 + --> $DIR/intra-link-errors.rs:64:6 | LL | /// [std::primitive::u8::not_found] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found` error: unresolved link to `Vec::into_iter` - --> $DIR/intra-link-errors.rs:63:6 + --> $DIR/intra-link-errors.rs:68:6 | LL | /// [type@Vec::into_iter] | ^^^^^^^^^^^^^^^^^^^ @@ -98,7 +107,7 @@ LL | /// [type@Vec::into_iter] | help: to link to the associated function, add parentheses: `Vec::into_iter()` error: unresolved link to `S` - --> $DIR/intra-link-errors.rs:68:6 + --> $DIR/intra-link-errors.rs:73:6 | LL | /// [S!] | ^^ @@ -107,7 +116,7 @@ LL | /// [S!] | help: to link to the struct, prefix with `struct@`: `struct@S` error: unresolved link to `T::g` - --> $DIR/intra-link-errors.rs:86:6 + --> $DIR/intra-link-errors.rs:91:6 | LL | /// [type@T::g] | ^^^^^^^^^ @@ -116,13 +125,13 @@ LL | /// [type@T::g] | help: to link to the associated function, add parentheses: `T::g()` error: unresolved link to `T::h` - --> $DIR/intra-link-errors.rs:91:6 + --> $DIR/intra-link-errors.rs:96:6 | LL | /// [T::h!] | ^^^^^ the trait `T` has no macro named `h` error: unresolved link to `S::h` - --> $DIR/intra-link-errors.rs:78:6 + --> $DIR/intra-link-errors.rs:83:6 | LL | /// [type@S::h] | ^^^^^^^^^ @@ -131,7 +140,7 @@ LL | /// [type@S::h] | help: to link to the associated function, add parentheses: `S::h()` error: unresolved link to `m` - --> $DIR/intra-link-errors.rs:98:6 + --> $DIR/intra-link-errors.rs:103:6 | LL | /// [m()] | ^^^ diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr index d946aa939800c..57061b6778c29 100644 --- a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr @@ -2,13 +2,14 @@ error: unresolved link to `i` --> $DIR/intra-link-span-ice-55723.rs:9:10 | LL | /// (arr[i]) - | ^ the module `intra_link_span_ice_55723` contains no item named `i` + | ^ there is no item named `i` in scope | note: the lint level is defined here --> $DIR/intra-link-span-ice-55723.rs:1:9 | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ + = help: did you mean to import `i`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr index 76a2ac0c8cf02..0c934e3bb082c 100644 --- a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr +++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr @@ -2,33 +2,37 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning-crlf.rs:7:6 | LL | /// [error] - | ^^^^^ the module `intra_links_warning_crlf` contains no item named `error` + | ^^^^^ there is no item named `error` in scope | = note: `#[warn(broken_intra_doc_links)]` on by default + = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error1` --> $DIR/intra-links-warning-crlf.rs:12:11 | LL | /// docs [error1] - | ^^^^^^ the module `intra_links_warning_crlf` contains no item named `error1` + | ^^^^^^ there is no item named `error1` in scope | + = help: did you mean to import `error1`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error2` --> $DIR/intra-links-warning-crlf.rs:15:11 | LL | /// docs [error2] - | ^^^^^^ the module `intra_links_warning_crlf` contains no item named `error2` + | ^^^^^^ there is no item named `error2` in scope | + = help: did you mean to import `error2`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` --> $DIR/intra-links-warning-crlf.rs:23:20 | LL | * It also has an [error]. - | ^^^^^ the module `intra_links_warning_crlf` contains no item named `error` + | ^^^^^ there is no item named `error` in scope | + = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: 4 warnings emitted diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index 09db465df59fb..d64f62924d3c2 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -10,54 +10,67 @@ warning: unresolved link to `Bar::foo` --> $DIR/intra-links-warning.rs:3:35 | LL | //! Test with [Foo::baz], [Bar::foo], ... - | ^^^^^^^^ the module `intra_links_warning` contains no item named `Bar` + | ^^^^^^^^ there is no item named `Bar` in scope + | + = help: did you mean to import `Bar`? warning: unresolved link to `Uniooon::X` --> $DIR/intra-links-warning.rs:6:13 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^^^^^ the module `intra_links_warning` contains no item named `Uniooon` + | ^^^^^^^^^^ there is no item named `Uniooon` in scope + | + = help: did you mean to import `Uniooon`? warning: unresolved link to `Qux::Z` --> $DIR/intra-links-warning.rs:6:30 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^ the module `intra_links_warning` contains no item named `Qux` + | ^^^^^^ there is no item named `Qux` in scope + | + = help: did you mean to import `Qux`? warning: unresolved link to `Uniooon::X` --> $DIR/intra-links-warning.rs:10:14 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^^^^^ the module `intra_links_warning` contains no item named `Uniooon` + | ^^^^^^^^^^ there is no item named `Uniooon` in scope + | + = help: did you mean to import `Uniooon`? warning: unresolved link to `Qux::Z` --> $DIR/intra-links-warning.rs:10:31 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^ the module `intra_links_warning` contains no item named `Qux` + | ^^^^^^ there is no item named `Qux` in scope + | + = help: did you mean to import `Qux`? warning: unresolved link to `Qux:Y` --> $DIR/intra-links-warning.rs:14:13 | LL | /// [Qux:Y] - | ^^^^^ the module `intra_links_warning` contains no item named `Qux:Y` + | ^^^^^ there is no item named `Qux:Y` in scope | + = help: did you mean to import `Qux:Y`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` --> $DIR/intra-links-warning.rs:58:30 | LL | * time to introduce a link [error]*/ - | ^^^^^ the module `intra_links_warning` contains no item named `error` + | ^^^^^ there is no item named `error` in scope | + = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` --> $DIR/intra-links-warning.rs:64:30 | LL | * time to introduce a link [error] - | ^^^^^ the module `intra_links_warning` contains no item named `error` + | ^^^^^ there is no item named `error` in scope | + = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -70,7 +83,8 @@ LL | #[doc = "single line [error]"] single line [error] ^^^^^ - = note: the module `intra_links_warning` contains no item named `error` + = note: there is no item named `error` in scope + = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -83,7 +97,8 @@ LL | #[doc = "single line with \"escaping\" [error]"] single line with "escaping" [error] ^^^^^ - = note: the module `intra_links_warning` contains no item named `error` + = note: there is no item named `error` in scope + = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -98,47 +113,53 @@ LL | | /// [error] [error] ^^^^^ - = note: the module `intra_links_warning` contains no item named `error` + = note: there is no item named `error` in scope + = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error1` --> $DIR/intra-links-warning.rs:80:11 | LL | /// docs [error1] - | ^^^^^^ the module `intra_links_warning` contains no item named `error1` + | ^^^^^^ there is no item named `error1` in scope | + = help: did you mean to import `error1`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error2` --> $DIR/intra-links-warning.rs:82:11 | LL | /// docs [error2] - | ^^^^^^ the module `intra_links_warning` contains no item named `error2` + | ^^^^^^ there is no item named `error2` in scope | + = help: did you mean to import `error2`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarA` --> $DIR/intra-links-warning.rs:21:10 | LL | /// bar [BarA] bar - | ^^^^ the module `intra_links_warning` contains no item named `BarA` + | ^^^^ there is no item named `BarA` in scope | + = help: did you mean to import `BarA`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarB` --> $DIR/intra-links-warning.rs:27:9 | LL | * bar [BarB] bar - | ^^^^ the module `intra_links_warning` contains no item named `BarB` + | ^^^^ there is no item named `BarB` in scope | + = help: did you mean to import `BarB`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarC` --> $DIR/intra-links-warning.rs:34:6 | LL | bar [BarC] bar - | ^^^^ the module `intra_links_warning` contains no item named `BarC` + | ^^^^ there is no item named `BarC` in scope | + = help: did you mean to import `BarC`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarD` @@ -151,7 +172,8 @@ LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] bar [BarD] bar ^^^^ - = note: the module `intra_links_warning` contains no item named `BarD` + = note: there is no item named `BarD` in scope + = help: did you mean to import `BarD`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarF` @@ -167,7 +189,8 @@ LL | f!("Foo\nbar [BarF] bar\nbaz"); bar [BarF] bar ^^^^ - = note: the module `intra_links_warning` contains no item named `BarF` + = note: there is no item named `BarF` in scope + = help: did you mean to import `BarF`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index 4e9134ea469bd..1fe33b4116733 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -32,7 +32,7 @@ error: unresolved link to `error` --> $DIR/lint-group.rs:9:29 | LL | /// what up, let's make an [error] - | ^^^^^ the module `lint_group` contains no item named `error` + | ^^^^^ there is no item named `error` in scope | note: the lint level is defined here --> $DIR/lint-group.rs:7:9 @@ -40,6 +40,7 @@ note: the lint level is defined here LL | #![deny(rustdoc)] | ^^^^^^^ = note: `#[deny(broken_intra_doc_links)]` implied by `#[deny(rustdoc)]` + = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to 3 previous errors From 0193a8871cc2c2cca2de03243097519ce6c910ce Mon Sep 17 00:00:00 2001 From: Camelid Date: Fri, 2 Oct 2020 14:47:41 -0700 Subject: [PATCH 21/29] Remove unhelpful help message --- .../passes/collect_intra_doc_links.rs | 3 +- .../deny-intra-link-resolution-failure.stderr | 1 - src/test/rustdoc-ui/intra-link-errors.rs | 5 -- src/test/rustdoc-ui/intra-link-errors.stderr | 47 ++++++++----------- .../intra-link-span-ice-55723.stderr | 1 - .../intra-links-warning-crlf.stderr | 4 -- .../rustdoc-ui/intra-links-warning.stderr | 23 --------- src/test/rustdoc-ui/lint-group.stderr | 1 - 8 files changed, 21 insertions(+), 64 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 632e6c9f91c11..56585919ec0a9 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1585,13 +1585,14 @@ fn resolution_failure( } else { diag.note(¬e); } - diag.help(&format!("did you mean to import `{}`?", unresolved)); + // If the link has `::` in it, assume it was meant to be an intra-doc link. // Otherwise, the `[]` might be unrelated. // FIXME: don't show this for autolinks (`<>`), `()` style links, or reference links if !path_str.contains("::") { diag.help(r#"to escape `[` and `]` characters, add '\' before them like `\[` or `\]`"#); } + continue; } diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr index 96b805dbc82a3..889658b0867c4 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr @@ -9,7 +9,6 @@ note: the lint level is defined here | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ - = help: did you mean to import `v2`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-link-errors.rs b/src/test/rustdoc-ui/intra-link-errors.rs index babcc3c43b4ae..872fb70bfc5b6 100644 --- a/src/test/rustdoc-ui/intra-link-errors.rs +++ b/src/test/rustdoc-ui/intra-link-errors.rs @@ -7,27 +7,22 @@ /// [path::to::nonexistent::module] //~^ ERROR unresolved link //~| NOTE there is no item named `path` in scope -//~| HELP did you mean to import `path`? /// [path::to::nonexistent::macro!] //~^ ERROR unresolved link //~| NOTE there is no item named `path` in scope -//~| HELP did you mean to import `path`? /// [type@path::to::nonexistent::type] //~^ ERROR unresolved link //~| NOTE there is no item named `path` in scope -//~| HELP did you mean to import `path`? /// [std::io::not::here] //~^ ERROR unresolved link //~| NOTE there is no item named `not` in scope -//~| HELP did you mean to import `not`? /// [type@std::io::not::here] //~^ ERROR unresolved link //~| NOTE there is no item named `not` in scope -//~| HELP did you mean to import `not`? /// [std::io::Error::x] //~^ ERROR unresolved link diff --git a/src/test/rustdoc-ui/intra-link-errors.stderr b/src/test/rustdoc-ui/intra-link-errors.stderr index f9af1a9fb9385..1299ec5af4b43 100644 --- a/src/test/rustdoc-ui/intra-link-errors.stderr +++ b/src/test/rustdoc-ui/intra-link-errors.stderr @@ -9,96 +9,87 @@ note: the lint level is defined here | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ - = help: did you mean to import `path`? error: unresolved link to `path::to::nonexistent::macro` - --> $DIR/intra-link-errors.rs:12:6 + --> $DIR/intra-link-errors.rs:11:6 | LL | /// [path::to::nonexistent::macro!] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope - | - = help: did you mean to import `path`? error: unresolved link to `path::to::nonexistent::type` - --> $DIR/intra-link-errors.rs:17:6 + --> $DIR/intra-link-errors.rs:15:6 | LL | /// [type@path::to::nonexistent::type] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope - | - = help: did you mean to import `path`? error: unresolved link to `std::io::not::here` - --> $DIR/intra-link-errors.rs:22:6 + --> $DIR/intra-link-errors.rs:19:6 | LL | /// [std::io::not::here] | ^^^^^^^^^^^^^^^^^^ there is no item named `not` in scope - | - = help: did you mean to import `not`? error: unresolved link to `std::io::not::here` - --> $DIR/intra-link-errors.rs:27:6 + --> $DIR/intra-link-errors.rs:23:6 | LL | /// [type@std::io::not::here] | ^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `not` in scope - | - = help: did you mean to import `not`? error: unresolved link to `std::io::Error::x` - --> $DIR/intra-link-errors.rs:32:6 + --> $DIR/intra-link-errors.rs:27:6 | LL | /// [std::io::Error::x] | ^^^^^^^^^^^^^^^^^ the struct `Error` has no field or associated item named `x` error: unresolved link to `std::io::ErrorKind::x` - --> $DIR/intra-link-errors.rs:36:6 + --> $DIR/intra-link-errors.rs:31:6 | LL | /// [std::io::ErrorKind::x] | ^^^^^^^^^^^^^^^^^^^^^ the enum `ErrorKind` has no variant or associated item named `x` error: unresolved link to `f::A` - --> $DIR/intra-link-errors.rs:40:6 + --> $DIR/intra-link-errors.rs:35:6 | LL | /// [f::A] | ^^^^ `f` is a function, not a module or type, and cannot have associated items error: unresolved link to `f::A` - --> $DIR/intra-link-errors.rs:44:6 + --> $DIR/intra-link-errors.rs:39:6 | LL | /// [f::A!] | ^^^^^ `f` is a function, not a module or type, and cannot have associated items error: unresolved link to `S::A` - --> $DIR/intra-link-errors.rs:48:6 + --> $DIR/intra-link-errors.rs:43:6 | LL | /// [S::A] | ^^^^ the struct `S` has no field or associated item named `A` error: unresolved link to `S::fmt` - --> $DIR/intra-link-errors.rs:52:6 + --> $DIR/intra-link-errors.rs:47:6 | LL | /// [S::fmt] | ^^^^^^ the struct `S` has no field or associated item named `fmt` error: unresolved link to `E::D` - --> $DIR/intra-link-errors.rs:56:6 + --> $DIR/intra-link-errors.rs:51:6 | LL | /// [E::D] | ^^^^ the enum `E` has no variant or associated item named `D` error: unresolved link to `u8::not_found` - --> $DIR/intra-link-errors.rs:60:6 + --> $DIR/intra-link-errors.rs:55:6 | LL | /// [u8::not_found] | ^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found` error: unresolved link to `std::primitive::u8::not_found` - --> $DIR/intra-link-errors.rs:64:6 + --> $DIR/intra-link-errors.rs:59:6 | LL | /// [std::primitive::u8::not_found] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the builtin type `u8` has no associated item named `not_found` error: unresolved link to `Vec::into_iter` - --> $DIR/intra-link-errors.rs:68:6 + --> $DIR/intra-link-errors.rs:63:6 | LL | /// [type@Vec::into_iter] | ^^^^^^^^^^^^^^^^^^^ @@ -107,7 +98,7 @@ LL | /// [type@Vec::into_iter] | help: to link to the associated function, add parentheses: `Vec::into_iter()` error: unresolved link to `S` - --> $DIR/intra-link-errors.rs:73:6 + --> $DIR/intra-link-errors.rs:68:6 | LL | /// [S!] | ^^ @@ -116,7 +107,7 @@ LL | /// [S!] | help: to link to the struct, prefix with `struct@`: `struct@S` error: unresolved link to `T::g` - --> $DIR/intra-link-errors.rs:91:6 + --> $DIR/intra-link-errors.rs:86:6 | LL | /// [type@T::g] | ^^^^^^^^^ @@ -125,13 +116,13 @@ LL | /// [type@T::g] | help: to link to the associated function, add parentheses: `T::g()` error: unresolved link to `T::h` - --> $DIR/intra-link-errors.rs:96:6 + --> $DIR/intra-link-errors.rs:91:6 | LL | /// [T::h!] | ^^^^^ the trait `T` has no macro named `h` error: unresolved link to `S::h` - --> $DIR/intra-link-errors.rs:83:6 + --> $DIR/intra-link-errors.rs:78:6 | LL | /// [type@S::h] | ^^^^^^^^^ @@ -140,7 +131,7 @@ LL | /// [type@S::h] | help: to link to the associated function, add parentheses: `S::h()` error: unresolved link to `m` - --> $DIR/intra-link-errors.rs:103:6 + --> $DIR/intra-link-errors.rs:98:6 | LL | /// [m()] | ^^^ diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr index 57061b6778c29..1e4cfb5be012c 100644 --- a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr @@ -9,7 +9,6 @@ note: the lint level is defined here | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ - = help: did you mean to import `i`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr index 0c934e3bb082c..0bf820adbf6a8 100644 --- a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr +++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr @@ -5,7 +5,6 @@ LL | /// [error] | ^^^^^ there is no item named `error` in scope | = note: `#[warn(broken_intra_doc_links)]` on by default - = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error1` @@ -14,7 +13,6 @@ warning: unresolved link to `error1` LL | /// docs [error1] | ^^^^^^ there is no item named `error1` in scope | - = help: did you mean to import `error1`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error2` @@ -23,7 +21,6 @@ warning: unresolved link to `error2` LL | /// docs [error2] | ^^^^^^ there is no item named `error2` in scope | - = help: did you mean to import `error2`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -32,7 +29,6 @@ warning: unresolved link to `error` LL | * It also has an [error]. | ^^^^^ there is no item named `error` in scope | - = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: 4 warnings emitted diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index d64f62924d3c2..b1b89dad8a372 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -11,40 +11,30 @@ warning: unresolved link to `Bar::foo` | LL | //! Test with [Foo::baz], [Bar::foo], ... | ^^^^^^^^ there is no item named `Bar` in scope - | - = help: did you mean to import `Bar`? warning: unresolved link to `Uniooon::X` --> $DIR/intra-links-warning.rs:6:13 | LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^^^^^ there is no item named `Uniooon` in scope - | - = help: did you mean to import `Uniooon`? warning: unresolved link to `Qux::Z` --> $DIR/intra-links-warning.rs:6:30 | LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^ there is no item named `Qux` in scope - | - = help: did you mean to import `Qux`? warning: unresolved link to `Uniooon::X` --> $DIR/intra-links-warning.rs:10:14 | LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^^^^^ there is no item named `Uniooon` in scope - | - = help: did you mean to import `Uniooon`? warning: unresolved link to `Qux::Z` --> $DIR/intra-links-warning.rs:10:31 | LL | //! , [Uniooon::X] and [Qux::Z]. | ^^^^^^ there is no item named `Qux` in scope - | - = help: did you mean to import `Qux`? warning: unresolved link to `Qux:Y` --> $DIR/intra-links-warning.rs:14:13 @@ -52,7 +42,6 @@ warning: unresolved link to `Qux:Y` LL | /// [Qux:Y] | ^^^^^ there is no item named `Qux:Y` in scope | - = help: did you mean to import `Qux:Y`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -61,7 +50,6 @@ warning: unresolved link to `error` LL | * time to introduce a link [error]*/ | ^^^^^ there is no item named `error` in scope | - = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -70,7 +58,6 @@ warning: unresolved link to `error` LL | * time to introduce a link [error] | ^^^^^ there is no item named `error` in scope | - = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -84,7 +71,6 @@ LL | #[doc = "single line [error]"] single line [error] ^^^^^ = note: there is no item named `error` in scope - = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -98,7 +84,6 @@ LL | #[doc = "single line with \"escaping\" [error]"] single line with "escaping" [error] ^^^^^ = note: there is no item named `error` in scope - = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -114,7 +99,6 @@ LL | | /// [error] [error] ^^^^^ = note: there is no item named `error` in scope - = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error1` @@ -123,7 +107,6 @@ warning: unresolved link to `error1` LL | /// docs [error1] | ^^^^^^ there is no item named `error1` in scope | - = help: did you mean to import `error1`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error2` @@ -132,7 +115,6 @@ warning: unresolved link to `error2` LL | /// docs [error2] | ^^^^^^ there is no item named `error2` in scope | - = help: did you mean to import `error2`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarA` @@ -141,7 +123,6 @@ warning: unresolved link to `BarA` LL | /// bar [BarA] bar | ^^^^ there is no item named `BarA` in scope | - = help: did you mean to import `BarA`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarB` @@ -150,7 +131,6 @@ warning: unresolved link to `BarB` LL | * bar [BarB] bar | ^^^^ there is no item named `BarB` in scope | - = help: did you mean to import `BarB`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarC` @@ -159,7 +139,6 @@ warning: unresolved link to `BarC` LL | bar [BarC] bar | ^^^^ there is no item named `BarC` in scope | - = help: did you mean to import `BarC`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarD` @@ -173,7 +152,6 @@ LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] bar [BarD] bar ^^^^ = note: there is no item named `BarD` in scope - = help: did you mean to import `BarD`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarF` @@ -190,7 +168,6 @@ LL | f!("Foo\nbar [BarF] bar\nbaz"); bar [BarF] bar ^^^^ = note: there is no item named `BarF` in scope - = help: did you mean to import `BarF`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index 1fe33b4116733..1cdd786acb419 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -40,7 +40,6 @@ note: the lint level is defined here LL | #![deny(rustdoc)] | ^^^^^^^ = note: `#[deny(broken_intra_doc_links)]` implied by `#[deny(rustdoc)]` - = help: did you mean to import `error`? = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to 3 previous errors From 21fb9dfa8d49d6aa3e74dfcc7032badcd6f51b91 Mon Sep 17 00:00:00 2001 From: Camelid Date: Fri, 2 Oct 2020 18:00:57 -0700 Subject: [PATCH 22/29] Use old error when there's partial resolution The new error was confusing when there was partial resolution (something like `std::io::nonexistent`); the old one is better for those cases. --- src/librustdoc/passes/collect_intra_doc_links.rs | 15 ++++++++++----- src/test/rustdoc-ui/intra-link-errors.rs | 4 ++-- src/test/rustdoc-ui/intra-link-errors.stderr | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 56585919ec0a9..024d333d8710d 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1575,11 +1575,16 @@ fn resolution_failure( _ => None, }; // See if this was a module: `[path]` or `[std::io::nope]` - if let Some(_module) = last_found_module { - let note = format!( - "there is no item named `{}` in scope", - unresolved - ); + if let Some(module) = last_found_module { + let note = if partial_res.is_some() { + let module_name = collector.cx.tcx.item_name(module); + format!( + "the module `{}` contains no item named `{}`", + module_name, unresolved + ) + } else { + format!("there is no item named `{}` in scope", unresolved) + }; if let Some(span) = sp { diag.span_label(span, ¬e); } else { diff --git a/src/test/rustdoc-ui/intra-link-errors.rs b/src/test/rustdoc-ui/intra-link-errors.rs index 872fb70bfc5b6..701fd6991c4ac 100644 --- a/src/test/rustdoc-ui/intra-link-errors.rs +++ b/src/test/rustdoc-ui/intra-link-errors.rs @@ -18,11 +18,11 @@ /// [std::io::not::here] //~^ ERROR unresolved link -//~| NOTE there is no item named `not` in scope +//~| NOTE `io` contains no item named `not` /// [type@std::io::not::here] //~^ ERROR unresolved link -//~| NOTE there is no item named `not` in scope +//~| NOTE `io` contains no item named `not` /// [std::io::Error::x] //~^ ERROR unresolved link diff --git a/src/test/rustdoc-ui/intra-link-errors.stderr b/src/test/rustdoc-ui/intra-link-errors.stderr index 1299ec5af4b43..8b12c721f7860 100644 --- a/src/test/rustdoc-ui/intra-link-errors.stderr +++ b/src/test/rustdoc-ui/intra-link-errors.stderr @@ -26,13 +26,13 @@ error: unresolved link to `std::io::not::here` --> $DIR/intra-link-errors.rs:19:6 | LL | /// [std::io::not::here] - | ^^^^^^^^^^^^^^^^^^ there is no item named `not` in scope + | ^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not` error: unresolved link to `std::io::not::here` --> $DIR/intra-link-errors.rs:23:6 | LL | /// [type@std::io::not::here] - | ^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `not` in scope + | ^^^^^^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not` error: unresolved link to `std::io::Error::x` --> $DIR/intra-link-errors.rs:27:6 From aa9b718cf0d4157a81c5dcc8d59f2c4ed96b801e Mon Sep 17 00:00:00 2001 From: Camelid Date: Fri, 2 Oct 2020 19:53:09 -0700 Subject: [PATCH 23/29] Improve error messages --- .../passes/collect_intra_doc_links.rs | 9 +++-- .../deny-intra-link-resolution-failure.stderr | 2 +- src/test/rustdoc-ui/intra-link-errors.rs | 10 +++--- src/test/rustdoc-ui/intra-link-errors.stderr | 10 +++--- .../intra-link-span-ice-55723.stderr | 2 +- .../intra-links-warning-crlf.stderr | 8 ++--- .../rustdoc-ui/intra-links-warning.stderr | 36 +++++++++---------- src/test/rustdoc-ui/lint-group.stderr | 2 +- 8 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 024d333d8710d..f234dc5c03b31 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1577,13 +1577,12 @@ fn resolution_failure( // See if this was a module: `[path]` or `[std::io::nope]` if let Some(module) = last_found_module { let note = if partial_res.is_some() { + // Part of the link resolved; e.g. `std::io::nonexistent` let module_name = collector.cx.tcx.item_name(module); - format!( - "the module `{}` contains no item named `{}`", - module_name, unresolved - ) + format!("no item named `{}` in module `{}`", unresolved, module_name) } else { - format!("there is no item named `{}` in scope", unresolved) + // None of the link resolved; e.g. `Notimported` + format!("no item named `{}` in scope", unresolved) }; if let Some(span) = sp { diag.span_label(span, ¬e); diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr index 889658b0867c4..9ec9dd4bc9ab7 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr @@ -2,7 +2,7 @@ error: unresolved link to `v2` --> $DIR/deny-intra-link-resolution-failure.rs:3:6 | LL | /// [v2] - | ^^ there is no item named `v2` in scope + | ^^ no item named `v2` in scope | note: the lint level is defined here --> $DIR/deny-intra-link-resolution-failure.rs:1:9 diff --git a/src/test/rustdoc-ui/intra-link-errors.rs b/src/test/rustdoc-ui/intra-link-errors.rs index 701fd6991c4ac..ef928ae02f3e3 100644 --- a/src/test/rustdoc-ui/intra-link-errors.rs +++ b/src/test/rustdoc-ui/intra-link-errors.rs @@ -6,23 +6,23 @@ /// [path::to::nonexistent::module] //~^ ERROR unresolved link -//~| NOTE there is no item named `path` in scope +//~| NOTE no item named `path` in scope /// [path::to::nonexistent::macro!] //~^ ERROR unresolved link -//~| NOTE there is no item named `path` in scope +//~| NOTE no item named `path` in scope /// [type@path::to::nonexistent::type] //~^ ERROR unresolved link -//~| NOTE there is no item named `path` in scope +//~| NOTE no item named `path` in scope /// [std::io::not::here] //~^ ERROR unresolved link -//~| NOTE `io` contains no item named `not` +//~| NOTE no item named `not` in module `io` /// [type@std::io::not::here] //~^ ERROR unresolved link -//~| NOTE `io` contains no item named `not` +//~| NOTE no item named `not` in module `io` /// [std::io::Error::x] //~^ ERROR unresolved link diff --git a/src/test/rustdoc-ui/intra-link-errors.stderr b/src/test/rustdoc-ui/intra-link-errors.stderr index 8b12c721f7860..31e7fc48afde5 100644 --- a/src/test/rustdoc-ui/intra-link-errors.stderr +++ b/src/test/rustdoc-ui/intra-link-errors.stderr @@ -2,7 +2,7 @@ error: unresolved link to `path::to::nonexistent::module` --> $DIR/intra-link-errors.rs:7:6 | LL | /// [path::to::nonexistent::module] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope | note: the lint level is defined here --> $DIR/intra-link-errors.rs:1:9 @@ -14,25 +14,25 @@ error: unresolved link to `path::to::nonexistent::macro` --> $DIR/intra-link-errors.rs:11:6 | LL | /// [path::to::nonexistent::macro!] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope error: unresolved link to `path::to::nonexistent::type` --> $DIR/intra-link-errors.rs:15:6 | LL | /// [type@path::to::nonexistent::type] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ there is no item named `path` in scope + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `path` in scope error: unresolved link to `std::io::not::here` --> $DIR/intra-link-errors.rs:19:6 | LL | /// [std::io::not::here] - | ^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not` + | ^^^^^^^^^^^^^^^^^^ no item named `not` in module `io` error: unresolved link to `std::io::not::here` --> $DIR/intra-link-errors.rs:23:6 | LL | /// [type@std::io::not::here] - | ^^^^^^^^^^^^^^^^^^^^^^^ the module `io` contains no item named `not` + | ^^^^^^^^^^^^^^^^^^^^^^^ no item named `not` in module `io` error: unresolved link to `std::io::Error::x` --> $DIR/intra-link-errors.rs:27:6 diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr index 1e4cfb5be012c..d8afa9e7efd59 100644 --- a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr +++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr @@ -2,7 +2,7 @@ error: unresolved link to `i` --> $DIR/intra-link-span-ice-55723.rs:9:10 | LL | /// (arr[i]) - | ^ there is no item named `i` in scope + | ^ no item named `i` in scope | note: the lint level is defined here --> $DIR/intra-link-span-ice-55723.rs:1:9 diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr index 0bf820adbf6a8..67c48378fd2f4 100644 --- a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr +++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr @@ -2,7 +2,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning-crlf.rs:7:6 | LL | /// [error] - | ^^^^^ there is no item named `error` in scope + | ^^^^^ no item named `error` in scope | = note: `#[warn(broken_intra_doc_links)]` on by default = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -11,7 +11,7 @@ warning: unresolved link to `error1` --> $DIR/intra-links-warning-crlf.rs:12:11 | LL | /// docs [error1] - | ^^^^^^ there is no item named `error1` in scope + | ^^^^^^ no item named `error1` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -19,7 +19,7 @@ warning: unresolved link to `error2` --> $DIR/intra-links-warning-crlf.rs:15:11 | LL | /// docs [error2] - | ^^^^^^ there is no item named `error2` in scope + | ^^^^^^ no item named `error2` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -27,7 +27,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning-crlf.rs:23:20 | LL | * It also has an [error]. - | ^^^^^ there is no item named `error` in scope + | ^^^^^ no item named `error` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr index b1b89dad8a372..4cdb8bbdde782 100644 --- a/src/test/rustdoc-ui/intra-links-warning.stderr +++ b/src/test/rustdoc-ui/intra-links-warning.stderr @@ -10,37 +10,37 @@ warning: unresolved link to `Bar::foo` --> $DIR/intra-links-warning.rs:3:35 | LL | //! Test with [Foo::baz], [Bar::foo], ... - | ^^^^^^^^ there is no item named `Bar` in scope + | ^^^^^^^^ no item named `Bar` in scope warning: unresolved link to `Uniooon::X` --> $DIR/intra-links-warning.rs:6:13 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^^^^^ there is no item named `Uniooon` in scope + | ^^^^^^^^^^ no item named `Uniooon` in scope warning: unresolved link to `Qux::Z` --> $DIR/intra-links-warning.rs:6:30 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^ there is no item named `Qux` in scope + | ^^^^^^ no item named `Qux` in scope warning: unresolved link to `Uniooon::X` --> $DIR/intra-links-warning.rs:10:14 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^^^^^ there is no item named `Uniooon` in scope + | ^^^^^^^^^^ no item named `Uniooon` in scope warning: unresolved link to `Qux::Z` --> $DIR/intra-links-warning.rs:10:31 | LL | //! , [Uniooon::X] and [Qux::Z]. - | ^^^^^^ there is no item named `Qux` in scope + | ^^^^^^ no item named `Qux` in scope warning: unresolved link to `Qux:Y` --> $DIR/intra-links-warning.rs:14:13 | LL | /// [Qux:Y] - | ^^^^^ there is no item named `Qux:Y` in scope + | ^^^^^ no item named `Qux:Y` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -48,7 +48,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning.rs:58:30 | LL | * time to introduce a link [error]*/ - | ^^^^^ there is no item named `error` in scope + | ^^^^^ no item named `error` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -56,7 +56,7 @@ warning: unresolved link to `error` --> $DIR/intra-links-warning.rs:64:30 | LL | * time to introduce a link [error] - | ^^^^^ there is no item named `error` in scope + | ^^^^^ no item named `error` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -70,7 +70,7 @@ LL | #[doc = "single line [error]"] single line [error] ^^^^^ - = note: there is no item named `error` in scope + = note: no item named `error` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -83,7 +83,7 @@ LL | #[doc = "single line with \"escaping\" [error]"] single line with "escaping" [error] ^^^^^ - = note: there is no item named `error` in scope + = note: no item named `error` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error` @@ -98,14 +98,14 @@ LL | | /// [error] [error] ^^^^^ - = note: there is no item named `error` in scope + = note: no item named `error` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `error1` --> $DIR/intra-links-warning.rs:80:11 | LL | /// docs [error1] - | ^^^^^^ there is no item named `error1` in scope + | ^^^^^^ no item named `error1` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -113,7 +113,7 @@ warning: unresolved link to `error2` --> $DIR/intra-links-warning.rs:82:11 | LL | /// docs [error2] - | ^^^^^^ there is no item named `error2` in scope + | ^^^^^^ no item named `error2` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -121,7 +121,7 @@ warning: unresolved link to `BarA` --> $DIR/intra-links-warning.rs:21:10 | LL | /// bar [BarA] bar - | ^^^^ there is no item named `BarA` in scope + | ^^^^ no item named `BarA` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -129,7 +129,7 @@ warning: unresolved link to `BarB` --> $DIR/intra-links-warning.rs:27:9 | LL | * bar [BarB] bar - | ^^^^ there is no item named `BarB` in scope + | ^^^^ no item named `BarB` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -137,7 +137,7 @@ warning: unresolved link to `BarC` --> $DIR/intra-links-warning.rs:34:6 | LL | bar [BarC] bar - | ^^^^ there is no item named `BarC` in scope + | ^^^^ no item named `BarC` in scope | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` @@ -151,7 +151,7 @@ LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] bar [BarD] bar ^^^^ - = note: there is no item named `BarD` in scope + = note: no item named `BarD` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: unresolved link to `BarF` @@ -167,7 +167,7 @@ LL | f!("Foo\nbar [BarF] bar\nbaz"); bar [BarF] bar ^^^^ - = note: there is no item named `BarF` in scope + = note: no item named `BarF` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index 1cdd786acb419..32be90193fe90 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -32,7 +32,7 @@ error: unresolved link to `error` --> $DIR/lint-group.rs:9:29 | LL | /// what up, let's make an [error] - | ^^^^^ there is no item named `error` in scope + | ^^^^^ no item named `error` in scope | note: the lint level is defined here --> $DIR/lint-group.rs:7:9 From f2961638c8b9c4494b962236aabfa9daa531f029 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 2 Oct 2020 19:51:36 -0400 Subject: [PATCH 24/29] Place all-targets checking behind a flag This matches Cargo behavior and avoids the (somewhat expensive) double checking, as well as the unfortunate duplicate error messages (#76822, rust-lang/cargo#5128). --- src/bootstrap/CHANGELOG.md | 2 +- src/bootstrap/builder.rs | 2 +- src/bootstrap/check.rs | 69 +++++++++++++++++++++----------------- src/bootstrap/flags.rs | 10 +++++- 4 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index fe426c4cec768..c9c1f90277a9e 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Non-breaking changes since the last major version] -None. +- x.py check needs opt-in to check tests (--all-targets) [#77473](https://github.com/rust-lang/rust/pull/77473) ## [Version 2] - 2020-09-25 diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 4beeb9c87c4fd..6856cd338cfad 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -532,7 +532,7 @@ impl<'a> Builder<'a> { pub fn new(build: &Build) -> Builder<'_> { let (kind, paths) = match build.config.cmd { Subcommand::Build { ref paths } => (Kind::Build, &paths[..]), - Subcommand::Check { ref paths } => (Kind::Check, &paths[..]), + Subcommand::Check { ref paths, all_targets: _ } => (Kind::Check, &paths[..]), Subcommand::Clippy { ref paths } => (Kind::Clippy, &paths[..]), Subcommand::Fix { ref paths } => (Kind::Fix, &paths[..]), Subcommand::Doc { ref paths, .. } => (Kind::Doc, &paths[..]), diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index ead0bd0413b9c..371631154f72d 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -1,9 +1,12 @@ //! Implementation of compiling the compiler and standard library, in "check"-based modes. -use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, std_cargo}; use crate::config::TargetSelection; use crate::tool::{prepare_tool_cargo, SourceType}; +use crate::{ + builder::{Builder, Kind, RunConfig, ShouldRun, Step}, + Subcommand, +}; use crate::{Compiler, Mode}; use std::path::PathBuf; @@ -74,35 +77,37 @@ impl Step for Std { // // Currently only the "libtest" tree of crates does this. - let mut cargo = builder.cargo( - compiler, - Mode::Std, - SourceType::InTree, - target, - cargo_subcommand(builder.kind), - ); - std_cargo(builder, target, compiler.stage, &mut cargo); - cargo.arg("--all-targets"); + if let Subcommand::Check { all_targets: true, .. } = builder.config.cmd { + let mut cargo = builder.cargo( + compiler, + Mode::Std, + SourceType::InTree, + target, + cargo_subcommand(builder.kind), + ); + std_cargo(builder, target, compiler.stage, &mut cargo); + cargo.arg("--all-targets"); + + // Explicitly pass -p for all dependencies krates -- this will force cargo + // to also check the tests/benches/examples for these crates, rather + // than just the leaf crate. + for krate in builder.in_tree_crates("test") { + cargo.arg("-p").arg(krate.name); + } - // Explicitly pass -p for all dependencies krates -- this will force cargo - // to also check the tests/benches/examples for these crates, rather - // than just the leaf crate. - for krate in builder.in_tree_crates("test") { - cargo.arg("-p").arg(krate.name); + builder.info(&format!( + "Checking std test/bench/example targets ({} -> {})", + &compiler.host, target + )); + run_cargo( + builder, + cargo, + args(builder.kind), + &libstd_test_stamp(builder, compiler, target), + vec![], + true, + ); } - - builder.info(&format!( - "Checking std test/bench/example targets ({} -> {})", - &compiler.host, target - )); - run_cargo( - builder, - cargo, - args(builder.kind), - &libstd_test_stamp(builder, compiler, target), - vec![], - true, - ); } } @@ -143,7 +148,9 @@ impl Step for Rustc { cargo_subcommand(builder.kind), ); rustc_cargo(builder, &mut cargo, target); - cargo.arg("--all-targets"); + if let Subcommand::Check { all_targets: true, .. } = builder.config.cmd { + cargo.arg("--all-targets"); + } // Explicitly pass -p for all compiler krates -- this will force cargo // to also check the tests/benches/examples for these crates, rather @@ -205,7 +212,9 @@ macro_rules! tool_check_step { &[], ); - cargo.arg("--all-targets"); + if let Subcommand::Check { all_targets: true, .. } = builder.config.cmd { + cargo.arg("--all-targets"); + } builder.info(&format!( "Checking {} artifacts ({} -> {})", diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 795244e7cd4a4..c1a9d4fcd23fe 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -47,6 +47,9 @@ pub enum Subcommand { paths: Vec, }, Check { + // Whether to run checking over all targets (e.g., unit / integration + // tests). + all_targets: bool, paths: Vec, }, Clippy { @@ -250,6 +253,9 @@ To learn more about a subcommand, run `./x.py -h`", `//rustfix_missing_coverage.txt`", ); } + "check" => { + opts.optflag("", "all-targets", "Check all targets"); + } "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); } @@ -484,7 +490,9 @@ Arguments: let cmd = match subcommand.as_str() { "build" | "b" => Subcommand::Build { paths }, - "check" | "c" => Subcommand::Check { paths }, + "check" | "c" => { + Subcommand::Check { paths, all_targets: matches.opt_present("all-targets") } + } "clippy" => Subcommand::Clippy { paths }, "fix" => Subcommand::Fix { paths }, "test" | "t" => Subcommand::Test { From bcab97c12e7522c09de74f7f58a3f8e81ca2943f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 2 Oct 2020 19:53:05 -0400 Subject: [PATCH 25/29] Check all Cargo targets on CI --- src/ci/docker/host-x86_64/mingw-check/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index 8fc9a009dce01..b2aa5844e4766 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -24,7 +24,7 @@ COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/ ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ - python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ + python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu --all-targets && \ python3 ../x.py build --stage 0 src/tools/build-manifest && \ python3 ../x.py test --stage 0 src/tools/compiletest && \ python3 ../x.py test --stage 2 src/tools/tidy && \ From b22e039890a7c2697f207c5993e3a2162bd6ce62 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sat, 3 Oct 2020 10:46:08 -0400 Subject: [PATCH 26/29] Set `deny-warnings = false` in contributor defaults This makes it easier to make rapid changes without having to constantly fix warnings. --- src/bootstrap/defaults/config.toml.codegen | 6 ++++++ src/bootstrap/defaults/config.toml.compiler | 6 ++++++ src/bootstrap/defaults/config.toml.library | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/src/bootstrap/defaults/config.toml.codegen b/src/bootstrap/defaults/config.toml.codegen index a9505922ca7fc..007ea8ac5fb38 100644 --- a/src/bootstrap/defaults/config.toml.codegen +++ b/src/bootstrap/defaults/config.toml.codegen @@ -11,3 +11,9 @@ assertions = true debug-logging = true # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower. incremental = true + +[rust] +# This allows building even with warnings present. +# This is convenient especially for larger changes and refactoring, +# since it doesn't require constantly changing imports and variable names. +deny-warnings = false diff --git a/src/bootstrap/defaults/config.toml.compiler b/src/bootstrap/defaults/config.toml.compiler index 4772de8a2cb22..2899d9907f1e3 100644 --- a/src/bootstrap/defaults/config.toml.compiler +++ b/src/bootstrap/defaults/config.toml.compiler @@ -6,3 +6,9 @@ debug-logging = true # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower. incremental = true + +[rust] +# This allows building even with warnings present. +# This is convenient especially for larger changes and refactoring, +# since it doesn't require constantly changing imports and variable names. +deny-warnings = false diff --git a/src/bootstrap/defaults/config.toml.library b/src/bootstrap/defaults/config.toml.library index e4316f4d86440..ba630f96c499f 100644 --- a/src/bootstrap/defaults/config.toml.library +++ b/src/bootstrap/defaults/config.toml.library @@ -8,3 +8,7 @@ bench-stage = 0 [rust] # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower. incremental = true +# This allows building even with warnings present. +# This is convenient especially for larger changes and refactoring, +# since it doesn't require constantly changing imports and variable names. +deny-warnings = false From eaa0186662b0a494b2536f75f9e2811b6aa8366b Mon Sep 17 00:00:00 2001 From: ecstatic-morse Date: Sat, 3 Oct 2020 09:29:50 -0700 Subject: [PATCH 27/29] Add quotes around command in CHANGELOG --- src/bootstrap/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index c9c1f90277a9e..d8c704f451bfc 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Non-breaking changes since the last major version] -- x.py check needs opt-in to check tests (--all-targets) [#77473](https://github.com/rust-lang/rust/pull/77473) +- `x.py check` needs opt-in to check tests (--all-targets) [#77473](https://github.com/rust-lang/rust/pull/77473) ## [Version 2] - 2020-09-25 From 018d587bc1dcd39701c12c4baefc709987f68c70 Mon Sep 17 00:00:00 2001 From: Jake Vossen Date: Sat, 3 Oct 2020 13:12:08 -0600 Subject: [PATCH 28/29] fixed going over 100 chars in line --- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c95316c96abc4..238bce94cf505 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2067,7 +2067,9 @@ define_print_and_forward_display! { p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe") } ty::PredicateAtom::ClosureKind(closure_def_id, _closure_substs, kind) => { - p!("the closure `", print_value_path(closure_def_id, &[]), write("` implements the trait `{}`", kind)) + p!("the closure `", + print_value_path(closure_def_id, &[]), + write("` implements the trait `{}`", kind)) } ty::PredicateAtom::ConstEvaluatable(def, substs) => { p!("the constant `", print_value_path(def.did, substs), "` can be evaluated") From e41a14412e207aac5f7d686d395bc6a23f643dc9 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sat, 3 Oct 2020 16:13:06 +0100 Subject: [PATCH 29/29] Support vectors with fewer than 8 elements for simd_select_bitmask --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 10 +++++--- .../simd-intrinsic-generic-select.rs | 4 +-- .../simd-intrinsic-generic-select.stderr | 6 ++--- .../ui/simd/simd-intrinsic-generic-select.rs | 25 +++++++++++++++++++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 7f5b09eac4f9e..e76e86f56510b 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -793,14 +793,18 @@ fn generic_simd_intrinsic( require_simd!(arg_tys[1], "argument"); let v_len = arg_tys[1].simd_size(tcx); require!( - m_len == v_len, + // Allow masks for vectors with fewer than 8 elements to be + // represented with a u8 or i8. + m_len == v_len || (m_len == 8 && v_len < 8), "mismatched lengths: mask length `{}` != other vector length `{}`", m_len, v_len ); let i1 = bx.type_i1(); - let i1xn = bx.type_vector(i1, m_len); - let m_i1s = bx.bitcast(args[0].immediate(), i1xn); + let im = bx.type_ix(v_len); + let i1xn = bx.type_vector(i1, v_len); + let m_im = bx.trunc(args[0].immediate(), im); + let m_i1s = bx.bitcast(m_im, i1xn); return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate())); } diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs index a719b31415055..7d68af49e2868 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.rs @@ -49,8 +49,8 @@ fn main() { simd_select(m4, 0u32, 1u32); //~^ ERROR found non-SIMD `u32` - simd_select_bitmask(0u8, x, x); - //~^ ERROR mask length `8` != other vector length `4` + simd_select_bitmask(0u16, x, x); + //~^ ERROR mask length `16` != other vector length `4` // simd_select_bitmask(0u8, 1u32, 2u32); //~^ ERROR found non-SIMD `u32` diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr index f68c969d13ee3..a1ef0bb8ee03b 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-select.stderr @@ -22,11 +22,11 @@ error[E0511]: invalid monomorphization of `simd_select` intrinsic: expected SIMD LL | simd_select(m4, 0u32, 1u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `8` != other vector length `4` +error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: mismatched lengths: mask length `16` != other vector length `4` --> $DIR/simd-intrinsic-generic-select.rs:52:9 | -LL | simd_select_bitmask(0u8, x, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_select_bitmask(0u16, x, x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_select_bitmask` intrinsic: expected SIMD argument type, found non-SIMD `u32` --> $DIR/simd-intrinsic-generic-select.rs:55:9 diff --git a/src/test/ui/simd/simd-intrinsic-generic-select.rs b/src/test/ui/simd/simd-intrinsic-generic-select.rs index dc9ec5d2760fe..b850cf9750a1f 100644 --- a/src/test/ui/simd/simd-intrinsic-generic-select.rs +++ b/src/test/ui/simd/simd-intrinsic-generic-select.rs @@ -167,4 +167,29 @@ fn main() { let e = u32x8(8, 9, 10, 11, 4, 5, 6, 7); assert_eq!(r, e); } + + unsafe { + let a = u32x4(0, 1, 2, 3); + let b = u32x4(4, 5, 6, 7); + + let r: u32x4 = simd_select_bitmask(0u8, a, b); + let e = b; + assert_eq!(r, e); + + let r: u32x4 = simd_select_bitmask(0xfu8, a, b); + let e = a; + assert_eq!(r, e); + + let r: u32x4 = simd_select_bitmask(0b0101u8, a, b); + let e = u32x4(0, 5, 2, 7); + assert_eq!(r, e); + + let r: u32x4 = simd_select_bitmask(0b1010u8, a, b); + let e = u32x4(4, 1, 6, 3); + assert_eq!(r, e); + + let r: u32x4 = simd_select_bitmask(0b1100u8, a, b); + let e = u32x4(4, 5, 2, 3); + assert_eq!(r, e); + } }