From 3f557947abf99b262aab994e896522c76329d315 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Jan 2018 09:48:23 +0100 Subject: [PATCH 01/30] NonNull ended up landing in 1.25 --- src/libcore/ptr.rs | 36 ++++++++++++++++++------------------ src/libstd/panic.rs | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index fab5832d905df..607e4a1a9fa10 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2461,7 +2461,7 @@ impl<'a, T: ?Sized> From> for Unique { } /// Previous name of `NonNull`. -#[rustc_deprecated(since = "1.24", reason = "renamed to `NonNull`")] +#[rustc_deprecated(since = "1.25.0", reason = "renamed to `NonNull`")] #[unstable(feature = "shared", issue = "27730")] pub type Shared = NonNull; @@ -2482,12 +2482,12 @@ pub type Shared = NonNull; /// Usually this won't be necessary; covariance is correct for most safe abstractions, /// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they /// provide a public API that follows the normal shared XOR mutable rules of Rust. -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] pub struct NonNull { pointer: NonZero<*const T>, } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Debug for NonNull { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) @@ -2496,12 +2496,12 @@ impl fmt::Debug for NonNull { /// `NonNull` pointers are not `Send` because the data they reference may be aliased. // NB: This impl is unnecessary, but should provide better error messages. -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl !Send for NonNull { } /// `NonNull` pointers are not `Sync` because the data they reference may be aliased. // NB: This impl is unnecessary, but should provide better error messages. -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl !Sync for NonNull { } impl NonNull { @@ -2509,7 +2509,7 @@ impl NonNull { /// /// This is useful for initializing types which lazily allocate, like /// `Vec::new` does. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub fn dangling() -> Self { unsafe { let ptr = mem::align_of::() as *mut T; @@ -2524,19 +2524,19 @@ impl NonNull { /// # Safety /// /// `ptr` must be non-null. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { NonNull { pointer: NonZero::new_unchecked(ptr) } } /// Creates a new `NonNull` if `ptr` is non-null. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub fn new(ptr: *mut T) -> Option { NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz }) } /// Acquires the underlying `*mut` pointer. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub fn as_ptr(self) -> *mut T { self.pointer.get() as *mut T } @@ -2546,7 +2546,7 @@ impl NonNull { /// The resulting lifetime is bound to self so this behaves "as if" /// it were actually an instance of T that is getting borrowed. If a longer /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub unsafe fn as_ref(&self) -> &T { &*self.as_ptr() } @@ -2556,47 +2556,47 @@ impl NonNull { /// The resulting lifetime is bound to self so this behaves "as if" /// it were actually an instance of T that is getting borrowed. If a longer /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub unsafe fn as_mut(&mut self) -> &mut T { &mut *self.as_ptr() } } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl Clone for NonNull { fn clone(&self) -> Self { *self } } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl Copy for NonNull { } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl CoerceUnsized> for NonNull where T: Unsize { } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Pointer for NonNull { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl From> for NonNull { fn from(unique: Unique) -> Self { NonNull { pointer: unique.pointer } } } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl<'a, T: ?Sized> From<&'a mut T> for NonNull { fn from(reference: &'a mut T) -> Self { NonNull { pointer: NonZero::from(reference) } } } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl<'a, T: ?Sized> From<&'a T> for NonNull { fn from(reference: &'a T) -> Self { NonNull { pointer: NonZero::from(reference) } diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 560876006d3f3..112e110609310 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -198,7 +198,7 @@ impl UnwindSafe for *const T {} impl UnwindSafe for *mut T {} #[unstable(feature = "ptr_internals", issue = "0")] impl UnwindSafe for Unique {} -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl UnwindSafe for NonNull {} #[stable(feature = "catch_unwind", since = "1.9.0")] impl UnwindSafe for Mutex {} From ad37e3fc01b533994dfb30f703c28ecdbf66fe10 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Jan 2018 09:48:58 +0100 Subject: [PATCH 02/30] =?UTF-8?q?Move=20Debug=20for=C2=A0NonNull=20impl=20?= =?UTF-8?q?closer=20to=20other=20trait=20impls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libcore/ptr.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 607e4a1a9fa10..c3b7c4f5d2247 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2487,13 +2487,6 @@ pub struct NonNull { pointer: NonZero<*const T>, } -#[stable(feature = "nonnull", since = "1.25.0")] -impl fmt::Debug for NonNull { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Pointer::fmt(&self.as_ptr(), f) - } -} - /// `NonNull` pointers are not `Send` because the data they reference may be aliased. // NB: This impl is unnecessary, but should provide better error messages. #[stable(feature = "nonnull", since = "1.25.0")] @@ -2575,6 +2568,13 @@ impl Copy for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] impl CoerceUnsized> for NonNull where T: Unsize { } +#[stable(feature = "nonnull", since = "1.25.0")] +impl fmt::Debug for NonNull { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&self.as_ptr(), f) + } +} + #[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Pointer for NonNull { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { From 6461c9bdd35d6273b88f22fd5e8708eaf8949283 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Jan 2018 09:51:19 +0100 Subject: [PATCH 03/30] Implement Eq, PartialEq, Ord, PartialOrd, and Hash for NonNull<_> --- src/libcore/ptr.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index c3b7c4f5d2247..a0d716fb57405 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2582,6 +2582,37 @@ impl fmt::Pointer for NonNull { } } +#[stable(feature = "nonnull", since = "1.25.0")] +impl Eq for NonNull {} + +#[stable(feature = "nonnull", since = "1.25.0")] +impl PartialEq for NonNull { + fn eq(&self, other: &Self) -> bool { + self.as_ptr() == other.as_ptr() + } +} + +#[stable(feature = "nonnull", since = "1.25.0")] +impl Ord for NonNull { + fn cmp(&self, other: &Self) -> Ordering { + self.as_ptr().cmp(&other.as_ptr()) + } +} + +#[stable(feature = "nonnull", since = "1.25.0")] +impl PartialOrd for NonNull { + fn partial_cmp(&self, other: &Self) -> Option { + self.as_ptr().partial_cmp(&other.as_ptr()) + } +} + +#[stable(feature = "nonnull", since = "1.25.0")] +impl hash::Hash for NonNull { + fn hash(&self, state: &mut H) { + self.as_ptr().hash(state) + } +} + #[stable(feature = "nonnull", since = "1.25.0")] impl From> for NonNull { fn from(unique: Unique) -> Self { From b8ffc8a3d8c181e958d2ddf4f108f0cd3a108013 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Jan 2018 09:56:33 +0100 Subject: [PATCH 04/30] Add an unstable `cast() -> NonNull` method to `NonNull`. This is less verbose than going through raw pointers to cast with `as`. --- src/libcore/ptr.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index a0d716fb57405..3d84e910fe662 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2553,6 +2553,14 @@ impl NonNull { pub unsafe fn as_mut(&mut self) -> &mut T { &mut *self.as_ptr() } + + /// Cast to a pointer of another type + #[unstable(feature = "nonnull_cast", issue = "47653")] + pub fn cast(self) -> NonNull { + unsafe { + NonNull::new_unchecked(self.as_ptr() as *mut U) + } + } } #[stable(feature = "nonnull", since = "1.25.0")] From cfe53c066646857a19046ebaf0cdc410c3d9f034 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Mon, 29 Jan 2018 20:13:29 -0600 Subject: [PATCH 05/30] Export wasm source map when debug information is enabled We use binaryen's linker to produce a wasm file (via s2wasm). The wasm writer has capabilities to export source maps. The produced source map contains references to the original file, that might require additional source map file processing to include / package original files with it. --- src/librustc_binaryen/BinaryenWrapper.cpp | 34 +++++++++++++++++++++-- src/librustc_binaryen/lib.rs | 22 +++++++++++++++ src/librustc_trans/back/write.rs | 18 ++++++++++-- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/librustc_binaryen/BinaryenWrapper.cpp b/src/librustc_binaryen/BinaryenWrapper.cpp index d1095a7819d4a..55f11665f6d0b 100644 --- a/src/librustc_binaryen/BinaryenWrapper.cpp +++ b/src/librustc_binaryen/BinaryenWrapper.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include "s2wasm.h" @@ -24,6 +25,7 @@ using namespace wasm; struct BinaryenRustModule { BufferWithRandomAccess buffer; + std::string sourceMapJSON; }; struct BinaryenRustModuleOptions { @@ -36,6 +38,7 @@ struct BinaryenRustModuleOptions { bool ignoreUnknownSymbols; bool debugInfo; std::string startFunction; + std::string sourceMapUrl; BinaryenRustModuleOptions() : globalBase(0), @@ -46,7 +49,8 @@ struct BinaryenRustModuleOptions { importMemory(false), ignoreUnknownSymbols(false), debugInfo(false), - startFunction("") + startFunction(""), + sourceMapUrl("") {} }; @@ -73,6 +77,12 @@ BinaryenRustModuleOptionsSetStart(BinaryenRustModuleOptions *options, options->startFunction = start; } +extern "C" void +BinaryenRustModuleOptionsSetSourceMapUrl(BinaryenRustModuleOptions *options, + char *sourceMapUrl) { + options->sourceMapUrl = sourceMapUrl; +} + extern "C" void BinaryenRustModuleOptionsSetStackAllocation(BinaryenRustModuleOptions *options, uint64_t stack) { @@ -106,12 +116,20 @@ BinaryenRustModuleCreate(const BinaryenRustModuleOptions *options, { WasmBinaryWriter writer(&linker.getOutput().wasm, ret->buffer, options->debug); writer.setNamesSection(options->debugInfo); - // FIXME: support source maps? - // writer.setSourceMap(sourceMapStream.get(), sourceMapUrl); + + std::unique_ptr sourceMapStream = nullptr; + { + sourceMapStream = make_unique(); + writer.setSourceMap(sourceMapStream.get(), options->sourceMapUrl); + } // FIXME: support symbol maps? // writer.setSymbolMap(symbolMap); writer.write(); + + if (sourceMapStream) { + ret->sourceMapJSON = sourceMapStream->str(); + } } return ret.release(); } @@ -126,6 +144,16 @@ BinaryenRustModuleLen(const BinaryenRustModule *M) { return M->buffer.size(); } +extern "C" const char* +BinaryenRustModuleSourceMapPtr(const BinaryenRustModule *M) { + return M->sourceMapJSON.data(); +} + +extern "C" size_t +BinaryenRustModuleSourceMapLen(const BinaryenRustModule *M) { + return M->sourceMapJSON.length(); +} + extern "C" void BinaryenRustModuleFree(BinaryenRustModule *M) { delete M; diff --git a/src/librustc_binaryen/lib.rs b/src/librustc_binaryen/lib.rs index 6c7feb6a7a9d3..36174e11ba04a 100644 --- a/src/librustc_binaryen/lib.rs +++ b/src/librustc_binaryen/lib.rs @@ -51,6 +51,15 @@ impl Module { slice::from_raw_parts(ptr, len) } } + + /// Returns the data of the source map JSON. + pub fn source_map(&self) -> &[u8] { + unsafe { + let ptr = BinaryenRustModuleSourceMapPtr(self.ptr); + let len = BinaryenRustModuleSourceMapLen(self.ptr); + slice::from_raw_parts(ptr, len) + } + } } impl Drop for Module { @@ -94,6 +103,15 @@ impl ModuleOptions { self } + /// Configures a `sourceMappingURL` custom section value for the module. + pub fn source_map_url(&mut self, url: &str) -> &mut Self { + let url = CString::new(url).unwrap(); + unsafe { + BinaryenRustModuleOptionsSetSourceMapUrl(self.ptr, url.as_ptr()); + } + self + } + /// Configures how much stack is initially allocated for the module. 1MB is /// probably good enough for now. pub fn stack(&mut self, amt: u64) -> &mut Self { @@ -130,6 +148,8 @@ extern { -> *mut BinaryenRustModule; fn BinaryenRustModulePtr(module: *const BinaryenRustModule) -> *const u8; fn BinaryenRustModuleLen(module: *const BinaryenRustModule) -> usize; + fn BinaryenRustModuleSourceMapPtr(module: *const BinaryenRustModule) -> *const u8; + fn BinaryenRustModuleSourceMapLen(module: *const BinaryenRustModule) -> usize; fn BinaryenRustModuleFree(module: *mut BinaryenRustModule); fn BinaryenRustModuleOptionsCreate() @@ -138,6 +158,8 @@ extern { debuginfo: bool); fn BinaryenRustModuleOptionsSetStart(module: *mut BinaryenRustModuleOptions, start: *const libc::c_char); + fn BinaryenRustModuleOptionsSetSourceMapUrl(module: *mut BinaryenRustModuleOptions, + sourceMapUrl: *const libc::c_char); fn BinaryenRustModuleOptionsSetStackAllocation( module: *mut BinaryenRustModuleOptions, stack: u64, diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index a013af7a4600e..7a194a37c9c55 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -748,7 +748,10 @@ unsafe fn codegen(cgcx: &CodegenContext, if asm2wasm && config.emit_obj { let assembly = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); - binaryen_assemble(cgcx, diag_handler, &assembly, &obj_out); + let suffix = ".wasm.map"; // FIXME use target suffix + let map = cgcx.output_filenames.path(OutputType::Exe) + .with_extension(&suffix[1..]); + binaryen_assemble(cgcx, diag_handler, &assembly, &obj_out, &map); timeline.record("binaryen"); if !config.emit_asm { @@ -795,7 +798,8 @@ unsafe fn codegen(cgcx: &CodegenContext, fn binaryen_assemble(cgcx: &CodegenContext, handler: &Handler, assembly: &Path, - object: &Path) { + object: &Path, + map: &Path) { use rustc_binaryen::{Module, ModuleOptions}; let input = fs::read(&assembly).and_then(|contents| { @@ -804,6 +808,8 @@ fn binaryen_assemble(cgcx: &CodegenContext, let mut options = ModuleOptions::new(); if cgcx.debuginfo != config::NoDebugInfo { options.debuginfo(true); + let map_file_name = map.file_name().unwrap(); + options.source_map_url(map_file_name.to_str().unwrap()); } if cgcx.crate_types.contains(&config::CrateTypeExecutable) { options.start("main"); @@ -815,7 +821,13 @@ fn binaryen_assemble(cgcx: &CodegenContext, .map_err(|e| io::Error::new(io::ErrorKind::Other, e)) }); let err = assembled.and_then(|binary| { - fs::write(&object, binary.data()) + fs::write(&object, binary.data()).and_then(|()| { + if cgcx.debuginfo != config::NoDebugInfo { + fs::write(map, binary.source_map()) + } else { + Ok(()) + } + }) }); if let Err(e) = err { handler.err(&format!("failed to run binaryen assembler: {}", e)); From 8f9d91587fa1d2595405f8a1cc1c43e7b044be1a Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Wed, 31 Jan 2018 20:40:03 -0800 Subject: [PATCH 06/30] in which HirIdMap is introduced as an affordance for using HirIds more The glossaries in the draft rustc-guide book and librustc/README.md state that `NodeId` is being gradually phased out in favor of `HirId`; as such, the present author claims that we ought to have a typedef for efficient `HirId` maps and sets in the module for such, even if no use for them has been made as yet (compatibility constraints preventing the use of it in the author's present unit of work): it is important to create the psychological "affordance" (in James J. Gibson's sense) that `HirId`s are a thing that compiler developers can work with. --- src/librustc/util/nodemap.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index 674f67d5cd2f1..f98a8f834df8a 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -13,7 +13,7 @@ #![allow(non_snake_case)] use hir::def_id::DefId; -use hir::ItemLocalId; +use hir::{HirId, ItemLocalId}; use syntax::ast; pub use rustc_data_structures::fx::FxHashMap; @@ -21,10 +21,12 @@ pub use rustc_data_structures::fx::FxHashSet; pub type NodeMap = FxHashMap; pub type DefIdMap = FxHashMap; +pub type HirIdMap = FxHashMap; pub type ItemLocalMap = FxHashMap; pub type NodeSet = FxHashSet; pub type DefIdSet = FxHashSet; +pub type HirIdSet = FxHashSet; pub type ItemLocalSet = FxHashSet; pub fn NodeMap() -> NodeMap { FxHashMap() } From e4b1a7971d7b4ed61d27af44e3169cb26595ae13 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Wed, 31 Jan 2018 20:56:01 -0800 Subject: [PATCH 07/30] concerning well-formed suggestions for unused shorthand field patterns Previously, unused variables would get a note that the warning could be silenced by prefixing the variable with an underscore, but that doesn't work for field shorthand patterns, which the liveness analysis didn't know about. The "to avoid this warning" verbiage seemed unnecessary. Resolves #47390. --- src/librustc/middle/liveness.rs | 63 ++++++++++++++----- ...47390-unused-variable-in-struct-pattern.rs | 34 ++++++++++ ...0-unused-variable-in-struct-pattern.stderr | 40 ++++++++++++ src/test/ui/span/issue-24690.stderr | 3 +- 4 files changed, 124 insertions(+), 16 deletions(-) create mode 100644 src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs create mode 100644 src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 297586f140e34..10497c95e27d0 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -109,7 +109,7 @@ use self::VarKind::*; use hir::def::*; use ty::{self, TyCtxt}; use lint; -use util::nodemap::NodeMap; +use util::nodemap::{NodeMap, NodeSet}; use std::{fmt, usize}; use std::io::prelude::*; @@ -244,7 +244,8 @@ struct CaptureInfo { #[derive(Copy, Clone, Debug)] struct LocalInfo { id: NodeId, - name: ast::Name + name: ast::Name, + is_shorthand: bool, } #[derive(Copy, Clone, Debug)] @@ -333,6 +334,13 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> { } } + fn variable_is_shorthand(&self, var: Variable) -> bool { + match self.var_kinds[var.get()] { + Local(LocalInfo { is_shorthand, .. }) => is_shorthand, + Arg(..) | CleanExit => false + } + } + fn set_captures(&mut self, node_id: NodeId, cs: Vec) { self.capture_info_map.insert(node_id, Rc::new(cs)); } @@ -384,8 +392,9 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) { let name = path1.node; ir.add_live_node_for_node(p_id, VarDefNode(sp)); ir.add_variable(Local(LocalInfo { - id: p_id, - name, + id: p_id, + name, + is_shorthand: false, })); }); intravisit::walk_local(ir, local); @@ -393,6 +402,22 @@ fn visit_local<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, local: &'tcx hir::Local) { fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) { for pat in &arm.pats { + // for struct patterns, take note of which fields used shorthand (`x` + // rather than `x: x`) + // + // FIXME: according to the rust-lang-nursery/rustc-guide book and + // librustc/README.md, `NodeId`s are to be phased out in favor of + // `HirId`s; however, we need to match the signature of `each_binding`, + // which uses `NodeIds`. + let mut shorthand_field_ids = NodeSet(); + if let hir::PatKind::Struct(_, ref fields, _) = pat.node { + for field in fields { + if field.node.is_shorthand { + shorthand_field_ids.insert(field.node.pat.id); + } + } + } + pat.each_binding(|bm, p_id, sp, path1| { debug!("adding local variable {} from match with bm {:?}", p_id, bm); @@ -400,7 +425,8 @@ fn visit_arm<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, arm: &'tcx hir::Arm) { ir.add_live_node_for_node(p_id, VarDefNode(sp)); ir.add_variable(Local(LocalInfo { id: p_id, - name, + name: name, + is_shorthand: shorthand_field_ids.contains(&p_id) })); }) } @@ -1483,17 +1509,26 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.assigned_on_exit(ln, var).is_some() }; + let suggest_underscore_msg = format!("consider using `_{}` instead", + name); if is_assigned { - self.ir.tcx.lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp, - &format!("variable `{}` is assigned to, but never used", - name), - &format!("to avoid this warning, consider using `_{}` instead", - name)); + self.ir.tcx + .lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp, + &format!("variable `{}` is assigned to, but never used", + name), + &suggest_underscore_msg); } else if name != "self" { - self.ir.tcx.lint_node_note(lint::builtin::UNUSED_VARIABLES, id, sp, - &format!("unused variable: `{}`", name), - &format!("to avoid this warning, consider using `_{}` instead", - name)); + let msg = format!("unused variable: `{}`", name); + let mut err = self.ir.tcx + .struct_span_lint_node(lint::builtin::UNUSED_VARIABLES, id, sp, &msg); + if self.ir.variable_is_shorthand(var) { + err.span_suggestion(sp, "try ignoring the field", + format!("{}: _", name)); + } else { + err.span_suggestion_short(sp, &suggest_underscore_msg, + format!("_{}", name)); + } + err.emit() } } true diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs new file mode 100644 index 0000000000000..a68b4f7635292 --- /dev/null +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs @@ -0,0 +1,34 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// must-compile-successfully + +#![warn(unused)] // UI tests pass `-A unused` (#43896) + +struct SoulHistory { + corridors_of_light: usize, + hours_are_suns: bool, + endless_and_singing: bool +} + +fn main() { + let i_think_continually = 2; + let who_from_the_womb_remembered = SoulHistory { + corridors_of_light: 5, + hours_are_suns: true, + endless_and_singing: true + }; + + if let SoulHistory { corridors_of_light, + mut hours_are_suns, + endless_and_singing: true } = who_from_the_womb_remembered { + hours_are_suns = false; + } +} diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr new file mode 100644 index 0000000000000..694fe69e01648 --- /dev/null +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -0,0 +1,40 @@ +warning: unused variable: `i_think_continually` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:22:9 + | +22 | let i_think_continually = 2; + | ^^^^^^^^^^^^^^^^^^^ help: consider using `_i_think_continually` instead + | +note: lint level defined here + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9 + | +13 | #![warn(unused)] // UI tests pass `-A unused` (#43896) + | ^^^^^^ + = note: #[warn(unused_variables)] implied by #[warn(unused)] + +warning: unused variable: `corridors_of_light` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:29:26 + | +29 | if let SoulHistory { corridors_of_light, + | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _` + +warning: variable `hours_are_suns` is assigned to, but never used + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:30:26 + | +30 | mut hours_are_suns, + | ^^^^^^^^^^^^^^^^^^ + | + = note: consider using `_hours_are_suns` instead + +warning: value assigned to `hours_are_suns` is never read + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:32:9 + | +32 | hours_are_suns = false; + | ^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:13:9 + | +13 | #![warn(unused)] // UI tests pass `-A unused` (#43896) + | ^^^^^^ + = note: #[warn(unused_assignments)] implied by #[warn(unused)] + diff --git a/src/test/ui/span/issue-24690.stderr b/src/test/ui/span/issue-24690.stderr index 7e19c7492ce0b..31728dbf08db2 100644 --- a/src/test/ui/span/issue-24690.stderr +++ b/src/test/ui/span/issue-24690.stderr @@ -2,7 +2,7 @@ warning: unused variable: `theOtherTwo` --> $DIR/issue-24690.rs:23:9 | 23 | let theOtherTwo = 2; //~ WARN should have a snake case name - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ help: consider using `_theOtherTwo` instead | note: lint level defined here --> $DIR/issue-24690.rs:18:9 @@ -10,7 +10,6 @@ note: lint level defined here 18 | #![warn(unused)] | ^^^^^^ = note: #[warn(unused_variables)] implied by #[warn(unused)] - = note: to avoid this warning, consider using `_theOtherTwo` instead warning: variable `theTwo` should have a snake case name such as `the_two` --> $DIR/issue-24690.rs:22:9 From c1383e4dc4bd6598f5d73d2d6b1054f61b2b99d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 19 Jan 2018 19:57:10 -0800 Subject: [PATCH 08/30] Add filtering options to `rustc_on_unimplemented` - filter error on the evaluated value of `Self` - filter error on the evaluated value of the type arguments - add argument to include custom note in diagnostic - allow the parser to parse `Self` when processing attributes - add custom message to binops --- src/libcore/ops/arith.rs | 115 ++++++++++++++++-- src/libcore/ops/bit.rs | 30 +++-- src/librustc/traits/error_reporting.rs | 32 +++-- src/librustc/traits/on_unimplemented.rs | 34 ++++-- src/libsyntax/parse/attr.rs | 2 +- src/libsyntax/parse/parser.rs | 16 ++- .../anonymous-higher-ranked-lifetime.stderr | 66 ++-------- .../issue-39802-show-5-trait-impls.stderr | 18 +-- .../ui/did_you_mean/recursion_limit.stderr | 6 +- .../ui/feature-gate-abi_unadjusted.stderr | 2 +- src/test/ui/feature-gate-catch_expr.stderr | 2 +- src/test/ui/feature-gate-i128_type2.stderr | 10 +- src/test/ui/feature-gate-intrinsics.stderr | 4 +- .../ui/feature-gate-non_ascii_idents.stderr | 26 ++-- src/test/ui/feature-gate-repr128.stderr | 2 +- .../ui/feature-gate-unboxed-closures.stderr | 2 +- .../ui/feature-gate-untagged_unions.stderr | 6 +- src/test/ui/fmt/send-sync.stderr | 12 +- src/test/ui/generator/not-send-sync.stderr | 6 +- src/test/ui/impl-trait/auto-trait-leak.stderr | 12 +- src/test/ui/impl-trait/equality.stderr | 2 +- src/test/ui/issue-24424.stderr | 6 +- src/test/ui/lint/suggestions.stderr | 32 ++--- src/test/ui/lint/use_suggestion_json.stderr | 67 +--------- src/test/ui/macros/format-foreign.stderr | 10 +- .../ui/macros/format-unused-lables.stderr | 52 ++++---- src/test/ui/mismatched_types/E0631.stderr | 24 +--- src/test/ui/mismatched_types/binops.stderr | 8 +- .../mismatched_types/closure-arg-count.stderr | 6 +- .../closure-arg-type-mismatch.stderr | 12 +- .../mismatched_types/closure-mismatch.stderr | 12 +- .../ui/mismatched_types/fn-variance-1.stderr | 12 +- .../unboxed-closures-vtable-mismatch.stderr | 13 +- .../ui/on-unimplemented/multiple-impls.stderr | 18 +-- src/test/ui/on-unimplemented/on-impl.stderr | 6 +- src/test/ui/on-unimplemented/on-trait.stderr | 12 +- src/test/ui/span/issue-29595.stderr | 6 +- src/test/ui/span/multiline-span-simple.stderr | 2 +- .../suggestions/try-operator-on-main.stderr | 6 +- src/test/ui/type-check/issue-40294.stderr | 6 +- 40 files changed, 312 insertions(+), 403 deletions(-) diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs index 8b3d662a6db77..59a18d6cb75ed 100644 --- a/src/libcore/ops/arith.rs +++ b/src/libcore/ops/arith.rs @@ -75,7 +75,93 @@ /// ``` #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} + {RHS}`"] +#[rustc_on_unimplemented( + on( + any( + all(_Self="i128", RHS="i64"), + all(_Self="i128", RHS="i32"), + all(_Self="i128", RHS="i16"), + all(_Self="i128", RHS="i8"), + all(_Self="i64", RHS="i32"), + all(_Self="i64", RHS="i16"), + all(_Self="i64", RHS="i8"), + all(_Self="i32", RHS="i16"), + all(_Self="i32", RHS="i8"), + all(_Self="i16", RHS="i8"), + all(_Self="u128", RHS="u64"), + all(_Self="u128", RHS="u32"), + all(_Self="u128", RHS="u16"), + all(_Self="u128", RHS="u8"), + all(_Self="u64", RHS="u32"), + all(_Self="u64", RHS="u16"), + all(_Self="u64", RHS="u8"), + all(_Self="u32", RHS="u16"), + all(_Self="u32", RHS="u8"), + all(_Self="u16", RHS="u8"), + all(_Self="f64", RHS="i32"), + all(_Self="f64", RHS="i16"), + all(_Self="f64", RHS="i8"), + all(_Self="f64", RHS="u32"), + all(_Self="f64", RHS="u16"), + all(_Self="f64", RHS="u8"), + all(_Self="f32", RHS="i16"), + all(_Self="f32", RHS="i8"), + all(_Self="f32", RHS="u16"), + all(_Self="f32", RHS="u8"), + ), + message="cannot add `{RHS}` to `{Self}`", + label="no implementation for `{Self} + {RHS}`, but you can safely cast \ + `{RHS}` into `{Self}` using `as {Self}`", + ), + on( + any( + all(RHS="i128", _Self="i64"), + all(RHS="i128", _Self="i32"), + all(RHS="i128", _Self="i16"), + all(RHS="i128", _Self="i8"), + all(RHS="i64", _Self="i32"), + all(RHS="i64", _Self="i16"), + all(RHS="i64", _Self="i8"), + all(RHS="i32", _Self="i16"), + all(RHS="i32", _Self="i8"), + all(RHS="i16", _Self="i8"), + all(RHS="u128", _Self="u64"), + all(RHS="u128", _Self="u32"), + all(RHS="u128", _Self="u16"), + all(RHS="u128", _Self="u8"), + all(RHS="u64", _Self="u32"), + all(RHS="u64", _Self="u16"), + all(RHS="u64", _Self="u8"), + all(RHS="u32", _Self="u16"), + all(RHS="u32", _Self="u8"), + all(RHS="u16", _Self="u8"), + all(RHS="f64", _Self="i32"), + all(RHS="f64", _Self="i16"), + all(RHS="f64", _Self="i8"), + all(RHS="f64", _Self="u32"), + all(RHS="f64", _Self="u16"), + all(RHS="f64", _Self="u8"), + all(RHS="f32", _Self="i16"), + all(RHS="f32", _Self="i8"), + all(RHS="f32", _Self="u16"), + all(RHS="f32", _Self="u8"), + ), + message="cannot add `{RHS}` to `{Self}`", + label="no implementation for `{Self} + {RHS}`, but you can safely turn \ + `{Self}` into `{RHS}` using `as {RHS}`", + ), + on( + all(_Self="{integer}", RHS="{float}"), + message="cannot add a float to an integer", + label="no implementation for `{Self} + {RHS}`", + ), + on( + all(_Self="{float}", RHS="{integer}"), + message="cannot add an integer to a float", + label="no implementation for `{Self} + {RHS}`", + ), + message="cannot add `{RHS}` to `{Self}`", + label="no implementation for `{Self} + {RHS}`")] pub trait Add { /// The resulting type after applying the `+` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -170,7 +256,8 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "sub"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} - {RHS}`"] +#[rustc_on_unimplemented(message="cannot substract `{RHS}` from `{Self}`", + label="no implementation for `{Self} - {RHS}`")] pub trait Sub { /// The resulting type after applying the `-` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -287,7 +374,8 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "mul"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} * {RHS}`"] +#[rustc_on_unimplemented(message="cannot multiply `{RHS}` to `{Self}`", + label="no implementation for `{Self} * {RHS}`")] pub trait Mul { /// The resulting type after applying the `*` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -408,7 +496,8 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "div"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} / {RHS}`"] +#[rustc_on_unimplemented(message="cannot divide `{Self}` by `{RHS}`", + label="no implementation for `{Self} / {RHS}`")] pub trait Div { /// The resulting type after applying the `/` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -490,7 +579,8 @@ div_impl_float! { f32 f64 } /// ``` #[lang = "rem"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} % {RHS}`"] +#[rustc_on_unimplemented(message="cannot mod `{Self}` by `{RHS}`", + label="no implementation for `{Self} % {RHS}`")] pub trait Rem { /// The resulting type after applying the `%` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -647,7 +737,8 @@ neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "add_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} += {Rhs}`"] +#[rustc_on_unimplemented(message="cannot add-assign `{Rhs}` to `{Self}`", + label="no implementation for `{Self} += {Rhs}`")] pub trait AddAssign { /// Performs the `+=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -700,7 +791,8 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "sub_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} -= {Rhs}`"] +#[rustc_on_unimplemented(message="cannot substract-assign `{Rhs}` from `{Self}`", + label="no implementation for `{Self} -= {Rhs}`")] pub trait SubAssign { /// Performs the `-=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -744,7 +836,8 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "mul_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} *= {Rhs}`"] +#[rustc_on_unimplemented(message="cannot multiply-assign `{Rhs}` to `{Self}`", + label="no implementation for `{Self} *= {Rhs}`")] pub trait MulAssign { /// Performs the `*=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -788,7 +881,8 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "div_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} /= {Rhs}`"] +#[rustc_on_unimplemented(message="cannot divide-assign `{Self}` by `{Rhs}`", + label="no implementation for `{Self} /= {Rhs}`")] pub trait DivAssign { /// Performs the `/=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -835,7 +929,8 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "rem_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} %= {Rhs}`"] +#[rustc_on_unimplemented(message="cannot mod-assign `{Self}` by `{Rhs}``", + label="no implementation for `{Self} %= {Rhs}`")] pub trait RemAssign { /// Performs the `%=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] diff --git a/src/libcore/ops/bit.rs b/src/libcore/ops/bit.rs index 7ac5fc4debf14..a0ecd6cf75ce9 100644 --- a/src/libcore/ops/bit.rs +++ b/src/libcore/ops/bit.rs @@ -120,7 +120,8 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "bitand"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} & {RHS}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} & {RHS}`", + label="no implementation for `{Self} & {RHS}`")] pub trait BitAnd { /// The resulting type after applying the `&` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -201,7 +202,8 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "bitor"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} | {RHS}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} | {RHS}`", + label="no implementation for `{Self} | {RHS}`")] pub trait BitOr { /// The resulting type after applying the `|` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -285,7 +287,8 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "bitxor"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} ^ {RHS}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} ^ {RHS}`", + label="no implementation for `{Self} ^ {RHS}`")] pub trait BitXor { /// The resulting type after applying the `^` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -365,7 +368,8 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "shl"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} << {RHS}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} << {RHS}`", + label="no implementation for `{Self} << {RHS}`")] pub trait Shl { /// The resulting type after applying the `<<` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -466,7 +470,8 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 } /// ``` #[lang = "shr"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} >> {RHS}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} >> {RHS}`", + label="no implementation for `{Self} >> {RHS}`")] pub trait Shr { /// The resulting type after applying the `>>` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -579,7 +584,8 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } /// ``` #[lang = "bitand_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} &= {Rhs}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} &= {Rhs}`", + label="no implementation for `{Self} &= {Rhs}`")] pub trait BitAndAssign { /// Performs the `&=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -626,7 +632,8 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "bitor_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} |= {Rhs}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} |= {Rhs}`", + label="no implementation for `{Self} |= {Rhs}`")] pub trait BitOrAssign { /// Performs the `|=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -673,7 +680,8 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "bitxor_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} ^= {Rhs}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} ^= {Rhs}`", + label="no implementation for `{Self} ^= {Rhs}`")] pub trait BitXorAssign { /// Performs the `^=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -718,7 +726,8 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// ``` #[lang = "shl_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} <<= {Rhs}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} <<= {Rhs}`", + label="no implementation for `{Self} <<= {Rhs}`")] pub trait ShlAssign { /// Performs the `<<=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] @@ -784,7 +793,8 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } /// ``` #[lang = "shr_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented = "no implementation for `{Self} >>= {Rhs}`"] +#[rustc_on_unimplemented(message="no implementation for `{Self} >>= {Rhs}`", + label="no implementation for `{Self} >>= {Rhs}`")] pub trait ShrAssign { /// Performs the `>>=` operation. #[stable(feature = "op_assign_traits", since = "1.8.0")] diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index d65becb912a3c..f5ff122668558 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -348,7 +348,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { if direct { // this is a "direct", user-specified, rather than derived, // obligation. - flags.push(("direct", None)); + flags.push(("direct".to_string(), None)); } if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code { @@ -359,21 +359,35 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // Currently I'm leaving it for what I need for `try`. if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) { method = self.tcx.item_name(item); - flags.push(("from_method", None)); - flags.push(("from_method", Some(&*method))); + flags.push(("from_method".to_string(), None)); + flags.push(("from_method".to_string(), Some(method.to_string()))); } } if let Some(k) = obligation.cause.span.compiler_desugaring_kind() { desugaring = k.as_symbol().as_str(); - flags.push(("from_desugaring", None)); - flags.push(("from_desugaring", Some(&*desugaring))); + flags.push(("from_desugaring".to_string(), None)); + flags.push(("from_desugaring".to_string(), Some(desugaring.to_string()))); + } + let generics = self.tcx.generics_of(def_id); + let self_ty = trait_ref.self_ty(); + let self_ty_str = self_ty.to_string(); + // FIXME: remove once `Self` is accepted by the compiler + flags.push(("_Self".to_string(), Some(self_ty_str.clone()))); + flags.push(("Self".to_string(), Some(self_ty_str.clone()))); + + for param in generics.types.iter() { + let name = param.name.as_str().to_string(); + let ty = trait_ref.substs.type_for_def(param); + let ty_str = ty.to_string(); + flags.push((name.clone(), + Some(ty_str.clone()))); } if let Ok(Some(command)) = OnUnimplementedDirective::of_item( self.tcx, trait_ref.def_id, def_id ) { - command.evaluate(self.tcx, trait_ref, &flags) + command.evaluate(self.tcx, trait_ref, &flags[..]) } else { OnUnimplementedNote::empty() } @@ -549,7 +563,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { .map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t))) .unwrap_or((String::new(), String::new())); - let OnUnimplementedNote { message, label } + let OnUnimplementedNote { message, label, note } = self.on_unimplemented_note(trait_ref, obligation); let have_alt_message = message.is_some() || label.is_some(); @@ -578,6 +592,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_ref, trait_ref.self_ty())); } + if let Some(ref s) = note { + // If it has a custom "#[rustc_on_unimplemented]" note, let's display it + err.note(s.as_str()); + } self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err); diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 757b078086d9c..a493b7f0bb603 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -29,16 +29,18 @@ pub struct OnUnimplementedDirective { pub subcommands: Vec, pub message: Option, pub label: Option, + pub note: Option, } pub struct OnUnimplementedNote { pub message: Option, pub label: Option, + pub note: Option, } impl OnUnimplementedNote { pub fn empty() -> Self { - OnUnimplementedNote { message: None, label: None } + OnUnimplementedNote { message: None, label: None, note: None } } } @@ -89,6 +91,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { let mut message = None; let mut label = None; + let mut note = None; let mut subcommands = vec![]; for item in item_iter { if item.check_name("message") && message.is_none() { @@ -103,8 +106,14 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { tcx, trait_def_id, label_.as_str(), span)?); continue; } + } else if item.check_name("note") && note.is_none() { + if let Some(note_) = item.value_str() { + note = Some(OnUnimplementedFormatString::try_parse( + tcx, trait_def_id, note_.as_str(), span)?); + continue; + } } else if item.check_name("on") && is_root && - message.is_none() && label.is_none() + message.is_none() && label.is_none() && note.is_none() { if let Some(items) = item.meta_item_list() { if let Ok(subcommand) = @@ -128,7 +137,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { if errored { Err(ErrorReported) } else { - Ok(OnUnimplementedDirective { condition, message, label, subcommands }) + Ok(OnUnimplementedDirective { condition, message, label, subcommands, note }) } } @@ -154,7 +163,8 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { message: None, subcommands: vec![], label: Some(OnUnimplementedFormatString::try_parse( - tcx, trait_def_id, value.as_str(), attr.span)?) + tcx, trait_def_id, value.as_str(), attr.span)?), + note: None, })) } else { return Err(parse_error(tcx, attr.span, @@ -169,20 +179,21 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { pub fn evaluate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, trait_ref: ty::TraitRef<'tcx>, - options: &[(&str, Option<&str>)]) + options: &[(String, Option)]) -> OnUnimplementedNote { let mut message = None; let mut label = None; + let mut note = None; info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options); for command in self.subcommands.iter().chain(Some(self)).rev() { if let Some(ref condition) = command.condition { if !attr::eval_condition(condition, &tcx.sess.parse_sess, &mut |c| { - options.contains(&(&c.name().as_str(), - match c.value_str().map(|s| s.as_str()) { - Some(ref s) => Some(s), + options.contains(&(c.name().as_str().to_string(), + match c.value_str().map(|s| s.as_str().to_string()) { + Some(s) => Some(s), None => None })) }) { @@ -198,11 +209,16 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { if let Some(ref label_) = command.label { label = Some(label_.clone()); } + + if let Some(ref note_) = command.note { + note = Some(note_.clone()); + } } OnUnimplementedNote { label: label.map(|l| l.format(tcx, trait_ref)), - message: message.map(|m| m.format(tcx, trait_ref)) + message: message.map(|m| m.format(tcx, trait_ref)), + note: note.map(|n| n.format(tcx, trait_ref)), } } } diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 053746b579dcb..b01f479895b10 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -235,7 +235,7 @@ impl<'a> Parser<'a> { } let lo = self.span; - let ident = self.parse_ident()?; + let ident = self.parse_ident_attr()?; let node = self.parse_meta_item_kind()?; Ok(ast::MetaItem { name: ident.name, node: node, span: lo.to(self.prev_span) }) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b3c485a85c063..9e8c4d3de2220 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -762,13 +762,19 @@ impl<'a> Parser<'a> { } pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { - self.parse_ident_common(true) + self.parse_ident_common(true, false) } - fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { + pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> { + self.parse_ident_common(true, true) + } + + fn parse_ident_common(&mut self, recover: bool, accept_self: bool) -> PResult<'a, ast::Ident> { match self.token { token::Ident(i) => { - if self.token.is_reserved_ident() { + if self.token.is_reserved_ident() + && !(accept_self && i.name == keywords::SelfType.name()) + { let mut err = self.struct_span_err(self.span, &format!("expected identifier, found {}", self.this_token_descr())); @@ -2111,7 +2117,7 @@ impl<'a> Parser<'a> { self.bump(); Ok(Ident::with_empty_ctxt(name)) } else { - self.parse_ident_common(false) + self.parse_ident_common(false, false) } } @@ -2128,7 +2134,7 @@ impl<'a> Parser<'a> { hi = self.prev_span; (fieldname, self.parse_expr()?, false) } else { - let fieldname = self.parse_ident_common(false)?; + let fieldname = self.parse_ident_common(false, false)?; hi = self.prev_span; // Mimic `x: x` for the `x` field shorthand. diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr index 4bd3b684b7ba3..e364a4d8b1441 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr +++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr @@ -6,11 +6,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _` | -note: required by `f1` - --> $DIR/anonymous-higher-ranked-lifetime.rs:26:1 - | -26 | fn f1(_: F) where F: Fn(&(), &()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `f1` error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:13:5 @@ -20,11 +16,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _` | -note: required by `f2` - --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1 - | -27 | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `f2` error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5 @@ -34,11 +26,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&(), &'r ()) -> _` | -note: required by `f3` - --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1 - | -28 | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `f3` error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:15:5 @@ -48,11 +36,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _` | -note: required by `f4` - --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1 - | -29 | fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `f4` error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5 @@ -62,11 +46,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&'r (), &'r ()) -> _` | -note: required by `f5` - --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1 - | -30 | fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `f5` error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:17:5 @@ -76,11 +56,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&'r (), std::boxed::Box std::ops::Fn(&'s ()) + 'static>) -> _` | -note: required by `g1` - --> $DIR/anonymous-higher-ranked-lifetime.rs:33:1 - | -33 | fn g1(_: F) where F: Fn(&(), Box) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `g1` error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5 @@ -90,11 +66,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _` | -note: required by `g2` - --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1 - | -34 | fn g2(_: F) where F: Fn(&(), fn(&())) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `g2` error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:19:5 @@ -104,11 +76,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'s> fn(&'s (), std::boxed::Box std::ops::Fn(&'r ()) + 'static>) -> _` | -note: required by `g3` - --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1 - | -35 | fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `g3` error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5 @@ -118,11 +86,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _` | -note: required by `g4` - --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1 - | -36 | fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `g4` error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:21:5 @@ -132,11 +96,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _` | -note: required by `h1` - --> $DIR/anonymous-higher-ranked-lifetime.rs:39:1 - | -39 | fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `h1` error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5 @@ -146,11 +106,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _` | -note: required by `h2` - --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1 - | -40 | fn h2(_: F) where F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `h2` error: aborting due to 11 previous errors diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr index 7ca3e8728fd9c..d5c4add34b526 100644 --- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr +++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr @@ -10,11 +10,7 @@ error[E0277]: the trait bound `i8: Foo` is not satisfied > > > -note: required by `Foo::bar` - --> $DIR/issue-39802-show-5-trait-impls.rs:12:5 - | -12 | fn bar(&self){} - | ^^^^^^^^^^^^^ + = note: required by `Foo::bar` error[E0277]: the trait bound `u8: Foo` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:35:5 @@ -27,11 +23,7 @@ error[E0277]: the trait bound `u8: Foo` is not satisfied > > > -note: required by `Foo::bar` - --> $DIR/issue-39802-show-5-trait-impls.rs:12:5 - | -12 | fn bar(&self){} - | ^^^^^^^^^^^^^ + = note: required by `Foo::bar` error[E0277]: the trait bound `bool: Foo` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:36:5 @@ -45,11 +37,7 @@ error[E0277]: the trait bound `bool: Foo` is not satisfied > > and 2 others -note: required by `Foo::bar` - --> $DIR/issue-39802-show-5-trait-impls.rs:12:5 - | -12 | fn bar(&self){} - | ^^^^^^^^^^^^^ + = note: required by `Foo::bar` error: aborting due to 3 previous errors diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr index 2bc7e9e46e7c5..7fac604ba49d7 100644 --- a/src/test/ui/did_you_mean/recursion_limit.stderr +++ b/src/test/ui/did_you_mean/recursion_limit.stderr @@ -15,11 +15,7 @@ error[E0275]: overflow evaluating the requirement `K: std::marker::Send` = note: required because it appears within the type `C` = note: required because it appears within the type `B` = note: required because it appears within the type `A` -note: required by `is_send` - --> $DIR/recursion_limit.rs:41:1 - | -41 | fn is_send() { } - | ^^^^^^^^^^^^^^^^^^^^ + = note: required by `is_send` error: aborting due to previous error diff --git a/src/test/ui/feature-gate-abi_unadjusted.stderr b/src/test/ui/feature-gate-abi_unadjusted.stderr index b3f7cd218d3e9..3cc43847156a1 100644 --- a/src/test/ui/feature-gate-abi_unadjusted.stderr +++ b/src/test/ui/feature-gate-abi_unadjusted.stderr @@ -1,4 +1,4 @@ -error[E0658]: unadjusted ABI is an implementation detail and perma-unstable +error: unadjusted ABI is an implementation detail and perma-unstable --> $DIR/feature-gate-abi_unadjusted.rs:11:1 | 11 | / extern "unadjusted" fn foo() { diff --git a/src/test/ui/feature-gate-catch_expr.stderr b/src/test/ui/feature-gate-catch_expr.stderr index 4b3bfbbe27ac8..f486373d225c3 100644 --- a/src/test/ui/feature-gate-catch_expr.stderr +++ b/src/test/ui/feature-gate-catch_expr.stderr @@ -1,4 +1,4 @@ -error[E0658]: `catch` expression is experimental (see issue #31436) +error: `catch` expression is experimental (see issue #31436) --> $DIR/feature-gate-catch_expr.rs:12:24 | 12 | let catch_result = do catch { //~ ERROR `catch` expression is experimental diff --git a/src/test/ui/feature-gate-i128_type2.stderr b/src/test/ui/feature-gate-i128_type2.stderr index ee81a26921498..26653a5739b2c 100644 --- a/src/test/ui/feature-gate-i128_type2.stderr +++ b/src/test/ui/feature-gate-i128_type2.stderr @@ -1,4 +1,4 @@ -error[E0658]: 128-bit type is unstable (see issue #35118) +error: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:13:15 | 13 | fn test1() -> i128 { //~ ERROR 128-bit type is unstable @@ -6,7 +6,7 @@ error[E0658]: 128-bit type is unstable (see issue #35118) | = help: add #![feature(i128_type)] to the crate attributes to enable -error[E0658]: 128-bit type is unstable (see issue #35118) +error: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:17:17 | 17 | fn test1_2() -> u128 { //~ ERROR 128-bit type is unstable @@ -14,7 +14,7 @@ error[E0658]: 128-bit type is unstable (see issue #35118) | = help: add #![feature(i128_type)] to the crate attributes to enable -error[E0658]: 128-bit type is unstable (see issue #35118) +error: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:22:12 | 22 | let x: i128 = 0; //~ ERROR 128-bit type is unstable @@ -22,7 +22,7 @@ error[E0658]: 128-bit type is unstable (see issue #35118) | = help: add #![feature(i128_type)] to the crate attributes to enable -error[E0658]: 128-bit type is unstable (see issue #35118) +error: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:26:12 | 26 | let x: u128 = 0; //~ ERROR 128-bit type is unstable @@ -32,7 +32,7 @@ error[E0658]: 128-bit type is unstable (see issue #35118) error[E0601]: main function not found -error[E0658]: repr with 128-bit type is unstable (see issue #35118) +error: repr with 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:30:1 | 30 | / enum A { //~ ERROR 128-bit type is unstable diff --git a/src/test/ui/feature-gate-intrinsics.stderr b/src/test/ui/feature-gate-intrinsics.stderr index 918c749504aea..5382122e30edd 100644 --- a/src/test/ui/feature-gate-intrinsics.stderr +++ b/src/test/ui/feature-gate-intrinsics.stderr @@ -1,4 +1,4 @@ -error[E0658]: intrinsics are subject to change +error: intrinsics are subject to change --> $DIR/feature-gate-intrinsics.rs:11:1 | 11 | / extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change @@ -8,7 +8,7 @@ error[E0658]: intrinsics are subject to change | = help: add #![feature(intrinsics)] to the crate attributes to enable -error[E0658]: intrinsics are subject to change +error: intrinsics are subject to change --> $DIR/feature-gate-intrinsics.rs:15:1 | 15 | / extern "rust-intrinsic" fn baz() { //~ ERROR intrinsics are subject to change diff --git a/src/test/ui/feature-gate-non_ascii_idents.stderr b/src/test/ui/feature-gate-non_ascii_idents.stderr index deb707752b066..90d0b8daee71c 100644 --- a/src/test/ui/feature-gate-non_ascii_idents.stderr +++ b/src/test/ui/feature-gate-non_ascii_idents.stderr @@ -1,4 +1,4 @@ -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:11:1 | 11 | extern crate core as bäz; //~ ERROR non-ascii idents @@ -6,7 +6,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:13:5 | 13 | use föö::bar; //~ ERROR non-ascii idents @@ -14,7 +14,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:15:1 | 15 | mod föö { //~ ERROR non-ascii idents @@ -22,7 +22,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:19:1 | 19 | / fn bär( //~ ERROR non-ascii idents @@ -36,7 +36,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:20:5 | 20 | bäz: isize //~ ERROR non-ascii idents @@ -44,7 +44,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:22:9 | 22 | let _ö: isize; //~ ERROR non-ascii idents @@ -52,7 +52,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:25:10 | 25 | (_ä, _) => {} //~ ERROR non-ascii idents @@ -60,7 +60,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:29:1 | 29 | struct Föö { //~ ERROR non-ascii idents @@ -68,7 +68,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:30:5 | 30 | föö: isize //~ ERROR non-ascii idents @@ -76,7 +76,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:33:1 | 33 | enum Bär { //~ ERROR non-ascii idents @@ -84,7 +84,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:34:5 | 34 | Bäz { //~ ERROR non-ascii idents @@ -92,7 +92,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:35:9 | 35 | qüx: isize //~ ERROR non-ascii idents @@ -100,7 +100,7 @@ error[E0658]: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error[E0658]: non-ascii idents are not fully supported. (see issue #28979) +error: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:40:5 | 40 | fn qüx(); //~ ERROR non-ascii idents diff --git a/src/test/ui/feature-gate-repr128.stderr b/src/test/ui/feature-gate-repr128.stderr index 982ebb0101662..c59964887b58f 100644 --- a/src/test/ui/feature-gate-repr128.stderr +++ b/src/test/ui/feature-gate-repr128.stderr @@ -1,4 +1,4 @@ -error[E0658]: repr with 128-bit type is unstable (see issue #35118) +error: repr with 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-repr128.rs:12:1 | 12 | / enum A { //~ ERROR repr with 128-bit type is unstable diff --git a/src/test/ui/feature-gate-unboxed-closures.stderr b/src/test/ui/feature-gate-unboxed-closures.stderr index ca8a59249463d..b79165147e590 100644 --- a/src/test/ui/feature-gate-unboxed-closures.stderr +++ b/src/test/ui/feature-gate-unboxed-closures.stderr @@ -1,4 +1,4 @@ -error[E0658]: rust-call ABI is subject to change (see issue #29625) +error: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-unboxed-closures.rs:16:5 | 16 | / extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { diff --git a/src/test/ui/feature-gate-untagged_unions.stderr b/src/test/ui/feature-gate-untagged_unions.stderr index 14b66cb5c815a..26b698912bc95 100644 --- a/src/test/ui/feature-gate-untagged_unions.stderr +++ b/src/test/ui/feature-gate-untagged_unions.stderr @@ -1,4 +1,4 @@ -error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836) +error: unions with non-`Copy` fields are unstable (see issue #32836) --> $DIR/feature-gate-untagged_unions.rs:19:1 | 19 | / union U3 { //~ ERROR unions with non-`Copy` fields are unstable @@ -8,7 +8,7 @@ error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836) | = help: add #![feature(untagged_unions)] to the crate attributes to enable -error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836) +error: unions with non-`Copy` fields are unstable (see issue #32836) --> $DIR/feature-gate-untagged_unions.rs:23:1 | 23 | / union U4 { //~ ERROR unions with non-`Copy` fields are unstable @@ -18,7 +18,7 @@ error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836) | = help: add #![feature(untagged_unions)] to the crate attributes to enable -error[E0658]: unions with `Drop` implementations are unstable (see issue #32836) +error: unions with `Drop` implementations are unstable (see issue #32836) --> $DIR/feature-gate-untagged_unions.rs:27:1 | 27 | / union U5 { //~ ERROR unions with `Drop` implementations are unstable diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr index 4ec5c9ebd2712..9e0e563c35f65 100644 --- a/src/test/ui/fmt/send-sync.stderr +++ b/src/test/ui/fmt/send-sync.stderr @@ -12,11 +12,7 @@ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` = note: required because of the requirements on the impl of `std::marker::Send` for `&[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `std::fmt::Arguments<'_>` -note: required by `send` - --> $DIR/send-sync.rs:11:1 - | -11 | fn send(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `send` error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `std::fmt::Arguments<'_>` --> $DIR/send-sync.rs:19:5 @@ -32,11 +28,7 @@ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `&[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `std::fmt::Arguments<'_>` -note: required by `sync` - --> $DIR/send-sync.rs:12:1 - | -12 | fn sync(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `sync` error: aborting due to 2 previous errors diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index e65c8f1546e82..fd8f3b8e6463d 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -7,11 +7,7 @@ error[E0277]: the trait bound `std::cell::Cell: std::marker::Sync` is not s = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell` = note: required because of the requirements on the impl of `std::marker::Send` for `&std::cell::Cell` = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:26:17: 30:6 a:&std::cell::Cell _]` -note: required by `main::assert_send` - --> $DIR/not-send-sync.rs:17:5 - | -17 | fn assert_send(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `main::assert_send` error[E0277]: the trait bound `std::cell::Cell: std::marker::Sync` is not satisfied in `[generator@$DIR/not-send-sync.rs:19:17: 23:6 {std::cell::Cell, ()}]` --> $DIR/not-send-sync.rs:19:5 diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index 838a3002e3aa7..ffd6a3fe4ffb1 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -7,11 +7,7 @@ error[E0277]: the trait bound `std::rc::Rc>: std::marker::S = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:21:5: 21:22 p:std::rc::Rc>]` = note: required because it appears within the type `impl std::ops::Fn<(i32,)>` -note: required by `send` - --> $DIR/auto-trait-leak.rs:24:1 - | -24 | fn send(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `send` error[E0277]: the trait bound `std::rc::Rc>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>` --> $DIR/auto-trait-leak.rs:30:5 @@ -22,11 +18,7 @@ error[E0277]: the trait bound `std::rc::Rc>: std::marker::S = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:38:5: 38:22 p:std::rc::Rc>]` = note: required because it appears within the type `impl std::ops::Fn<(i32,)>` -note: required by `send` - --> $DIR/auto-trait-leak.rs:24:1 - | -24 | fn send(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `send` error[E0391]: unsupported cyclic reference between types/traits detected --> $DIR/auto-trait-leak.rs:44:1 diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index 3fc08a0900fb9..8ec819038031b 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -7,7 +7,7 @@ error[E0308]: mismatched types = note: expected type `i32` found type `u32` -error[E0277]: the trait bound `u32: std::ops::Add` is not satisfied +error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:34:11 | 34 | n + sum_to(n - 1) diff --git a/src/test/ui/issue-24424.stderr b/src/test/ui/issue-24424.stderr index 55af26dd91ea3..acdf348791b20 100644 --- a/src/test/ui/issue-24424.stderr +++ b/src/test/ui/issue-24424.stderr @@ -4,11 +4,7 @@ error[E0283]: type annotations required: cannot resolve `T0: Trait0<'l0>` 14 | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: required by `Trait0` - --> $DIR/issue-24424.rs:12:1 - | -12 | trait Trait0<'l0> {} - | ^^^^^^^^^^^^^^^^^ + = note: required by `Trait0` error: aborting due to previous error diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr index 8b30f552d3771..701a95222183a 100644 --- a/src/test/ui/lint/suggestions.stderr +++ b/src/test/ui/lint/suggestions.stderr @@ -1,7 +1,7 @@ warning: unnecessary parentheses around assigned value - --> $DIR/suggestions.rs:46:21 + --> $DIR/suggestions.rs:36:21 | -46 | let mut a = (1); // should suggest no `mut`, no parens +36 | let mut a = (1); // should suggest no `mut`, no parens | ^^^ help: remove these parentheses | note: lint level defined here @@ -11,17 +11,17 @@ note: lint level defined here | ^^^^^^^^^^^^^ warning: use of deprecated attribute `no_debug`: the `#[no_debug]` attribute was an experimental feature that has been deprecated due to lack of demand. See https://github.com/rust-lang/rust/issues/29721 - --> $DIR/suggestions.rs:41:1 + --> $DIR/suggestions.rs:31:1 | -41 | #[no_debug] // should suggest removal of deprecated attribute +31 | #[no_debug] // should suggest removal of deprecated attribute | ^^^^^^^^^^^ help: remove this attribute | = note: #[warn(deprecated)] on by default warning: variable does not need to be mutable - --> $DIR/suggestions.rs:46:13 + --> $DIR/suggestions.rs:36:13 | -46 | let mut a = (1); // should suggest no `mut`, no parens +36 | let mut a = (1); // should suggest no `mut`, no parens | ---^^ | | | help: remove this `mut` @@ -72,30 +72,18 @@ warning: function is marked #[no_mangle], but not exported | = note: #[warn(private_no_mangle_fns)] on by default -warning: static is marked #[no_mangle], but not exported - --> $DIR/suggestions.rs:31:18 - | -31 | #[no_mangle] pub static DAUNTLESS: bool = true; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: function is marked #[no_mangle], but not exported - --> $DIR/suggestions.rs:33:18 - | -33 | #[no_mangle] pub fn val_jean() {} - | ^^^^^^^^^^^^^^^^^^^^ - warning: denote infinite loops with `loop { ... }` - --> $DIR/suggestions.rs:44:5 + --> $DIR/suggestions.rs:34:5 | -44 | while true { // should suggest `loop` +34 | while true { // should suggest `loop` | ^^^^^^^^^^ help: use `loop` | = note: #[warn(while_true)] on by default warning: the `warp_factor:` in this pattern is redundant - --> $DIR/suggestions.rs:51:23 + --> $DIR/suggestions.rs:41:23 | -51 | Equinox { warp_factor: warp_factor } => {} // should suggest shorthand +41 | Equinox { warp_factor: warp_factor } => {} // should suggest shorthand | ------------^^^^^^^^^^^^ | | | help: remove this diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr index 86c2ad4c0e7a4..abbf3da513a6f 100644 --- a/src/test/ui/lint/use_suggestion_json.stderr +++ b/src/test/ui/lint/use_suggestion_json.stderr @@ -2,72 +2,7 @@ "message": "cannot find type `Iter` in this scope", "code": { "code": "E0412", - "explanation": " -The type name used is not in scope. - -Erroneous code examples: - -```compile_fail,E0412 -impl Something {} // error: type name `Something` is not in scope - -// or: - -trait Foo { - fn bar(N); // error: type name `N` is not in scope -} - -// or: - -fn foo(x: T) {} // type name `T` is not in scope -``` - -To fix this error, please verify you didn't misspell the type name, you did -declare it or imported it into the scope. Examples: - -``` -struct Something; - -impl Something {} // ok! - -// or: - -trait Foo { - type N; - - fn bar(_: Self::N); // ok! -} - -// or: - -fn foo(x: T) {} // ok! -``` - -Another case that causes this error is when a type is imported into a parent -module. To fix this, you can follow the suggestion and use File directly or -`use super::File;` which will import the types from the parent namespace. An -example that causes this error is below: - -```compile_fail,E0412 -use std::fs::File; - -mod foo { - fn some_function(f: File) {} -} -``` - -``` -use std::fs::File; - -mod foo { - // either - use super::File; - // or - // use std::fs::File; - fn foo(f: File) {} -} -# fn main() {} // don't insert it for us; that'll break imports -``` -" + "explanation": null }, "level": "error", "spans": [ diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr index f9852c5477332..d0229957b682e 100644 --- a/src/test/ui/macros/format-foreign.stderr +++ b/src/test/ui/macros/format-foreign.stderr @@ -1,8 +1,12 @@ error: multiple unused formatting arguments - --> $DIR/format-foreign.rs:12:30 + --> $DIR/format-foreign.rs:12:5 | -12 | println!("%.*3$s %s!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments - | -------------------------^^^^^^^^--^^^^^^^--^-- multiple unused arguments in this statement +12 | println!("%.*3$s %s!/n", "Hello,", "World", 4); + | ^^^^^^^^^^^^^^^^^^^^^^^^^--------^^-------^^-^^ + | | | | + | | | unused + | | unused + | unused | = help: `%.*3$s` should be written as `{:.2$}` = help: `%s` should be written as `{}` diff --git a/src/test/ui/macros/format-unused-lables.stderr b/src/test/ui/macros/format-unused-lables.stderr index 64ea5626c1d62..9efdca12dea03 100644 --- a/src/test/ui/macros/format-unused-lables.stderr +++ b/src/test/ui/macros/format-unused-lables.stderr @@ -1,43 +1,49 @@ error: multiple unused formatting arguments - --> $DIR/format-unused-lables.rs:12:22 + --> $DIR/format-unused-lables.rs:12:5 | 12 | println!("Test", 123, 456, 789); - | -----------------^^^--^^^--^^^-- multiple unused arguments in this statement + | ^^^^^^^^^^^^^^^^^---^^---^^---^^ + | | | | + | | | unused + | | unused + | unused | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: multiple unused formatting arguments - --> $DIR/format-unused-lables.rs:16:9 + --> $DIR/format-unused-lables.rs:14:5 | -15 | / println!("Test2", -16 | | 123, //~ ERROR multiple unused formatting arguments - | | ^^^ -17 | | 456, - | | ^^^ -18 | | 789 - | | ^^^ -19 | | ); - | |______- multiple unused arguments in this statement +14 | / println!("Test2", +15 | | 123, + | | --- unused +16 | | 456, + | | --- unused +17 | | 789 + | | --- unused +18 | | ); + | |______^ | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: named argument never used - --> $DIR/format-unused-lables.rs:21:35 + --> $DIR/format-unused-lables.rs:20:35 | -21 | println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used +20 | println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used | ^^^^^^ error: multiple unused formatting arguments - --> $DIR/format-unused-lables.rs:24:9 + --> $DIR/format-unused-lables.rs:22:5 | -23 | / println!("Some more $STUFF", -24 | | "woo!", //~ ERROR multiple unused formatting arguments - | | ^^^^^^ -25 | | STUFF= -26 | | "things" - | | ^^^^^^^^ -27 | | , UNUSED="args"); - | |_______________________^^^^^^_- multiple unused arguments in this statement +22 | / println!("Some more $STUFF", +23 | | "woo!", + | | ------ unused +24 | | STUFF= +25 | | "things" + | | -------- unused +26 | | , UNUSED="args"); + | |_______________________------_^ + | | + | unused | = help: `$STUFF` should be written as `{STUFF}` = note: shell formatting not supported; see the documentation for `std::fmt` diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr index 53f2f54325d57..442900e0a836a 100644 --- a/src/test/ui/mismatched_types/E0631.stderr +++ b/src/test/ui/mismatched_types/E0631.stderr @@ -6,11 +6,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `fn(usize) -> _` | -note: required by `foo` - --> $DIR/E0631.rs:13:1 - | -13 | fn foo(_: F) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `foo` error[E0631]: type mismatch in closure arguments --> $DIR/E0631.rs:18:5 @@ -20,11 +16,7 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `fn(usize) -> _` | -note: required by `bar` - --> $DIR/E0631.rs:14:1 - | -14 | fn bar>(_: F) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `bar` error[E0631]: type mismatch in function arguments --> $DIR/E0631.rs:19:5 @@ -35,11 +27,7 @@ error[E0631]: type mismatch in function arguments 19 | foo(f); //~ ERROR type mismatch | ^^^ expected signature of `fn(usize) -> _` | -note: required by `foo` - --> $DIR/E0631.rs:13:1 - | -13 | fn foo(_: F) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `foo` error[E0631]: type mismatch in function arguments --> $DIR/E0631.rs:20:5 @@ -50,11 +38,7 @@ error[E0631]: type mismatch in function arguments 20 | bar(f); //~ ERROR type mismatch | ^^^ expected signature of `fn(usize) -> _` | -note: required by `bar` - --> $DIR/E0631.rs:14:1 - | -14 | fn bar>(_: F) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `bar` error: aborting due to 4 previous errors diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr index 8541ad52e0177..57e66794a58a9 100644 --- a/src/test/ui/mismatched_types/binops.stderr +++ b/src/test/ui/mismatched_types/binops.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `{integer}: std::ops::Add>` is not satisfied +error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}` --> $DIR/binops.rs:12:7 | 12 | 1 + Some(1); //~ ERROR is not satisfied @@ -6,7 +6,7 @@ error[E0277]: the trait bound `{integer}: std::ops::Add>` is not implemented for `{integer}` -error[E0277]: the trait bound `usize: std::ops::Sub>` is not satisfied +error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize` --> $DIR/binops.rs:13:16 | 13 | 2 as usize - Some(1); //~ ERROR is not satisfied @@ -14,7 +14,7 @@ error[E0277]: the trait bound `usize: std::ops::Sub>` is not implemented for `usize` -error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied +error[E0277]: cannot multiply `()` to `{integer}` --> $DIR/binops.rs:14:7 | 14 | 3 * (); //~ ERROR is not satisfied @@ -22,7 +22,7 @@ error[E0277]: the trait bound `{integer}: std::ops::Mul<()>` is not satisfied | = help: the trait `std::ops::Mul<()>` is not implemented for `{integer}` -error[E0277]: the trait bound `{integer}: std::ops::Div<&str>` is not satisfied +error[E0277]: cannot divide `{integer}` by `&str` --> $DIR/binops.rs:15:7 | 15 | 4 / ""; //~ ERROR is not satisfied diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index be00ee4d74e7e..d904831ba4e32 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -46,11 +46,7 @@ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments | | | expected closure that takes 1 argument | -note: required by `f` - --> $DIR/closure-arg-count.rs:13:1 - | -13 | fn f>(_: F) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `f` error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments --> $DIR/closure-arg-count.rs:26:53 diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index dfd02fe23b686..77d3a33276737 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -31,11 +31,7 @@ error[E0631]: type mismatch in function arguments | expected signature of `for<'r> fn(*mut &'r u32) -> _` | found signature of `fn(*mut &'a u32) -> _` | -note: required by `baz` - --> $DIR/closure-arg-type-mismatch.rs:18:1 - | -18 | fn baz(_: F) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `baz` error[E0271]: type mismatch resolving `for<'r> >::Output == ()` --> $DIR/closure-arg-type-mismatch.rs:20:5 @@ -43,11 +39,7 @@ error[E0271]: type mismatch resolving `for<'r> $DIR/closure-arg-type-mismatch.rs:18:1 - | -18 | fn baz(_: F) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `baz` error: aborting due to 5 previous errors diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr index 01de7e0749500..99767ba1afaef 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-mismatch.stderr @@ -5,11 +5,7 @@ error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.r | ^^^ expected bound lifetime parameter, found concrete lifetime | = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` -note: required by `baz` - --> $DIR/closure-mismatch.rs:15:1 - | -15 | fn baz(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^ + = note: required by `baz` error[E0631]: type mismatch in closure arguments --> $DIR/closure-mismatch.rs:18:5 @@ -20,11 +16,7 @@ error[E0631]: type mismatch in closure arguments | expected signature of `for<'r> fn(&'r ()) -> _` | = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` -note: required by `baz` - --> $DIR/closure-mismatch.rs:15:1 - | -15 | fn baz(_: T) {} - | ^^^^^^^^^^^^^^^^^^^^ + = note: required by `baz` error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr index 64c260c30ed49..2a27ffd106247 100644 --- a/src/test/ui/mismatched_types/fn-variance-1.stderr +++ b/src/test/ui/mismatched_types/fn-variance-1.stderr @@ -7,11 +7,7 @@ error[E0631]: type mismatch in function arguments 21 | apply(&3, takes_mut); | ^^^^^ expected signature of `fn(&{integer}) -> _` | -note: required by `apply` - --> $DIR/fn-variance-1.rs:15:1 - | -15 | fn apply(t: T, f: F) where F: FnOnce(T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `apply` error[E0631]: type mismatch in function arguments --> $DIR/fn-variance-1.rs:25:5 @@ -22,11 +18,7 @@ error[E0631]: type mismatch in function arguments 25 | apply(&mut 3, takes_imm); | ^^^^^ expected signature of `fn(&mut {integer}) -> _` | -note: required by `apply` - --> $DIR/fn-variance-1.rs:15:1 - | -15 | fn apply(t: T, f: F) where F: FnOnce(T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `apply` error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr index 9c9bbd19c7552..8539c8818c025 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr @@ -1,17 +1,12 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/unboxed-closures-vtable-mismatch.rs:25:13 + --> $DIR/unboxed-closures-vtable-mismatch.rs:23:13 | -23 | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); +22 | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); | ----------------------------- found signature of `fn(usize, isize) -> _` -24 | //~^ NOTE found signature of `fn(usize, isize) -> _` -25 | let z = call_it(3, f); +23 | let z = call_it(3, f); | ^^^^^^^ expected signature of `fn(isize, isize) -> _` | -note: required by `call_it` - --> $DIR/unboxed-closures-vtable-mismatch.rs:17:1 - | -17 | fn call_itisize>(y: isize, mut f: F) -> isize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `call_it` error: aborting due to previous error diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr index cfac3981be284..1f71be446efb5 100644 --- a/src/test/ui/on-unimplemented/multiple-impls.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -5,11 +5,7 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied | ^^^^^^^^^^^^ trait message | = help: the trait `Index` is not implemented for `[i32]` -note: required by `Index::index` - --> $DIR/multiple-impls.rs:22:5 - | -22 | fn index(&self, index: Idx) -> &Self::Output; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `Index::index` error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/multiple-impls.rs:43:5 @@ -26,11 +22,7 @@ error[E0277]: the trait bound `[i32]: Index>` is not satisfied | ^^^^^^^^^^^^ on impl for Foo | = help: the trait `Index>` is not implemented for `[i32]` -note: required by `Index::index` - --> $DIR/multiple-impls.rs:22:5 - | -22 | fn index(&self, index: Idx) -> &Self::Output; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `Index::index` error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:46:5 @@ -47,11 +39,7 @@ error[E0277]: the trait bound `[i32]: Index>` is not satisfied | ^^^^^^^^^^^^ on impl for Bar | = help: the trait `Index>` is not implemented for `[i32]` -note: required by `Index::index` - --> $DIR/multiple-impls.rs:22:5 - | -22 | fn index(&self, index: Idx) -> &Self::Output; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `Index::index` error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:49:5 diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr index ed2da68f08167..c8c06bf44fd6f 100644 --- a/src/test/ui/on-unimplemented/on-impl.stderr +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -5,11 +5,7 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied | ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice | = help: the trait `Index` is not implemented for `[i32]` -note: required by `Index::index` - --> $DIR/on-impl.rs:19:5 - | -19 | fn index(&self, index: Idx) -> &Self::Output; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `Index::index` error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/on-impl.rs:32:5 diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr index 028200a5558c8..cde56022faea2 100644 --- a/src/test/ui/on-unimplemented/on-trait.stderr +++ b/src/test/ui/on-unimplemented/on-trait.stderr @@ -5,11 +5,7 @@ error[E0277]: the trait bound `std::option::Option>: MyFromIte | ^^^^^^^ a collection of type `std::option::Option>` cannot be built from an iterator over elements of type `&u8` | = help: the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option>` -note: required by `collect` - --> $DIR/on-trait.rs:31:1 - | -31 | fn collect, B: MyFromIterator>(it: I) -> B { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `collect` error[E0277]: the trait bound `std::string::String: Bar::Foo` is not satisfied --> $DIR/on-trait.rs:40:21 @@ -18,11 +14,7 @@ error[E0277]: the trait bound `std::string::String: Bar::Foo` is not | ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo` | = help: the trait `Bar::Foo` is not implemented for `std::string::String` -note: required by `foobar` - --> $DIR/on-trait.rs:21:1 - | -21 | fn foobar>() -> T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `foobar` error: aborting due to 2 previous errors diff --git a/src/test/ui/span/issue-29595.stderr b/src/test/ui/span/issue-29595.stderr index 9046b90f0e9c3..81ba0057d7173 100644 --- a/src/test/ui/span/issue-29595.stderr +++ b/src/test/ui/span/issue-29595.stderr @@ -4,11 +4,7 @@ error[E0277]: the trait bound `u8: Tr` is not satisfied 17 | let a: u8 = Tr::C; //~ ERROR the trait bound `u8: Tr` is not satisfied | ^^^^^ the trait `Tr` is not implemented for `u8` | -note: required by `Tr::C` - --> $DIR/issue-29595.rs:13:5 - | -13 | const C: Self; - | ^^^^^^^^^^^^^^ + = note: required by `Tr::C` error: aborting due to previous error diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr index b068798630ed8..b6182825fc278 100644 --- a/src/test/ui/span/multiline-span-simple.stderr +++ b/src/test/ui/span/multiline-span-simple.stderr @@ -1,4 +1,4 @@ -error[E0277]: the trait bound `u32: std::ops::Add<()>` is not satisfied +error[E0277]: cannot add `()` to `u32` --> $DIR/multiline-span-simple.rs:23:18 | 23 | foo(1 as u32 + //~ ERROR not satisfied diff --git a/src/test/ui/suggestions/try-operator-on-main.stderr b/src/test/ui/suggestions/try-operator-on-main.stderr index e97823a3d5d5b..36cdd558b0faf 100644 --- a/src/test/ui/suggestions/try-operator-on-main.stderr +++ b/src/test/ui/suggestions/try-operator-on-main.stderr @@ -22,11 +22,7 @@ error[E0277]: the trait bound `(): std::ops::Try` is not satisfied 25 | try_trait_generic::<()>(); //~ ERROR the trait bound | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()` | -note: required by `try_trait_generic` - --> $DIR/try-operator-on-main.rs:30:1 - | -30 | fn try_trait_generic() -> T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required by `try_trait_generic` error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` --> $DIR/try-operator-on-main.rs:32:5 diff --git a/src/test/ui/type-check/issue-40294.stderr b/src/test/ui/type-check/issue-40294.stderr index cf270afdeb173..2ca97aa3ef067 100644 --- a/src/test/ui/type-check/issue-40294.stderr +++ b/src/test/ui/type-check/issue-40294.stderr @@ -10,11 +10,7 @@ error[E0283]: type annotations required: cannot resolve `&'a T: Foo` 21 | | } | |_^ | -note: required by `Foo` - --> $DIR/issue-40294.rs:11:1 - | -11 | trait Foo: Sized { - | ^^^^^^^^^^^^^^^^ + = note: required by `Foo` error: aborting due to previous error From 4c92a02b64e5cb8cfb9b885638e1dfa2067cacd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 19 Jan 2018 20:28:09 -0800 Subject: [PATCH 09/30] Change rustc_on_unimplemented for Iterator and binops --- src/libcore/ops/arith.rs | 9 +-- .../anonymous-higher-ranked-lifetime.stderr | 66 +++++++++++++++---- .../issue-39802-show-5-trait-impls.stderr | 18 ++++- .../ui/did_you_mean/recursion_limit.stderr | 6 +- .../ui/feature-gate-abi_unadjusted.stderr | 2 +- src/test/ui/feature-gate-catch_expr.stderr | 2 +- src/test/ui/feature-gate-i128_type2.stderr | 10 +-- src/test/ui/feature-gate-intrinsics.stderr | 4 +- .../ui/feature-gate-non_ascii_idents.stderr | 26 ++++---- src/test/ui/feature-gate-repr128.stderr | 2 +- .../ui/feature-gate-unboxed-closures.stderr | 2 +- .../ui/feature-gate-untagged_unions.stderr | 6 +- src/test/ui/fmt/send-sync.stderr | 12 +++- src/test/ui/generator/not-send-sync.stderr | 6 +- src/test/ui/impl-trait/auto-trait-leak.stderr | 12 +++- src/test/ui/issue-24424.stderr | 6 +- src/test/ui/lint/suggestions.stderr | 32 ++++++--- src/test/ui/macros/format-foreign.stderr | 10 +-- .../ui/macros/format-unused-lables.stderr | 52 +++++++-------- src/test/ui/mismatched_types/E0631.stderr | 24 +++++-- .../mismatched_types/closure-arg-count.stderr | 56 ++++++++-------- .../closure-arg-type-mismatch.stderr | 12 +++- .../mismatched_types/closure-mismatch.stderr | 12 +++- .../ui/mismatched_types/fn-variance-1.stderr | 12 +++- .../unboxed-closures-vtable-mismatch.stderr | 13 ++-- .../multiple-impls-complex-filtering.rs | 61 +++++++++++++++++ .../multiple-impls-complex-filtering.stderr | 44 +++++++++++++ .../ui/on-unimplemented/multiple-impls.stderr | 18 ++++- src/test/ui/on-unimplemented/on-impl.stderr | 6 +- src/test/ui/on-unimplemented/on-trait.stderr | 12 +++- src/test/ui/span/issue-29595.stderr | 6 +- .../suggestions/try-operator-on-main.stderr | 6 +- src/test/ui/type-check/issue-40294.stderr | 6 +- 33 files changed, 418 insertions(+), 153 deletions(-) create mode 100644 src/test/ui/on-unimplemented/multiple-impls-complex-filtering.rs create mode 100644 src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs index 59a18d6cb75ed..47617b22dd34d 100644 --- a/src/libcore/ops/arith.rs +++ b/src/libcore/ops/arith.rs @@ -109,7 +109,6 @@ all(_Self="f32", RHS="u16"), all(_Self="f32", RHS="u8"), ), - message="cannot add `{RHS}` to `{Self}`", label="no implementation for `{Self} + {RHS}`, but you can safely cast \ `{RHS}` into `{Self}` using `as {Self}`", ), @@ -146,22 +145,20 @@ all(RHS="f32", _Self="u16"), all(RHS="f32", _Self="u8"), ), - message="cannot add `{RHS}` to `{Self}`", - label="no implementation for `{Self} + {RHS}`, but you can safely turn \ + label="no implementation for `{Self} + {RHS}`, but you can safely cast \ `{Self}` into `{RHS}` using `as {RHS}`", ), on( all(_Self="{integer}", RHS="{float}"), message="cannot add a float to an integer", - label="no implementation for `{Self} + {RHS}`", ), on( all(_Self="{float}", RHS="{integer}"), message="cannot add an integer to a float", - label="no implementation for `{Self} + {RHS}`", ), message="cannot add `{RHS}` to `{Self}`", - label="no implementation for `{Self} + {RHS}`")] + label="no implementation for `{Self} + {RHS}`", +)] pub trait Add { /// The resulting type after applying the `+` operator. #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr index e364a4d8b1441..4bd3b684b7ba3 100644 --- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr +++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr @@ -6,7 +6,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _` | - = note: required by `f1` +note: required by `f1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:26:1 + | +26 | fn f1(_: F) where F: Fn(&(), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:13:5 @@ -16,7 +20,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _` | - = note: required by `f2` +note: required by `f2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1 + | +27 | fn f2(_: F) where F: for<'a> Fn(&'a (), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5 @@ -26,7 +34,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&(), &'r ()) -> _` | - = note: required by `f3` +note: required by `f3` + --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1 + | +28 | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:15:5 @@ -36,7 +48,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _` | - = note: required by `f4` +note: required by `f4` + --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1 + | +29 | fn f4(_: F) where F: for<'r> Fn(&(), &'r ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5 @@ -46,7 +62,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&'r (), &'r ()) -> _` | - = note: required by `f5` +note: required by `f5` + --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1 + | +30 | fn f5(_: F) where F: for<'r> Fn(&'r (), &'r ()) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:17:5 @@ -56,7 +76,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&'r (), std::boxed::Box std::ops::Fn(&'s ()) + 'static>) -> _` | - = note: required by `g1` +note: required by `g1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:33:1 + | +33 | fn g1(_: F) where F: Fn(&(), Box) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5 @@ -66,7 +90,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _` | - = note: required by `g2` +note: required by `g2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1 + | +34 | fn g2(_: F) where F: Fn(&(), fn(&())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:19:5 @@ -76,7 +104,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'s> fn(&'s (), std::boxed::Box std::ops::Fn(&'r ()) + 'static>) -> _` | - = note: required by `g3` +note: required by `g3` + --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1 + | +35 | fn g3(_: F) where F: for<'s> Fn(&'s (), Box) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5 @@ -86,7 +118,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _` | - = note: required by `g4` +note: required by `g4` + --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1 + | +36 | fn g4(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:21:5 @@ -96,7 +132,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box std::ops::Fn(&'t0 ()) + 'static>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _` | - = note: required by `h1` +note: required by `h1` + --> $DIR/anonymous-higher-ranked-lifetime.rs:39:1 + | +39 | fn h1(_: F) where F: Fn(&(), Box, &(), fn(&(), &())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5 @@ -106,7 +146,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box std::ops::Fn(&'s ()) + 'static>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _` | - = note: required by `h2` +note: required by `h2` + --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1 + | +40 | fn h2(_: F) where F: for<'t0> Fn(&(), Box, &'t0 (), fn(&(), &())) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 11 previous errors diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr index d5c4add34b526..7ca3e8728fd9c 100644 --- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr +++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr @@ -10,7 +10,11 @@ error[E0277]: the trait bound `i8: Foo` is not satisfied > > > - = note: required by `Foo::bar` +note: required by `Foo::bar` + --> $DIR/issue-39802-show-5-trait-impls.rs:12:5 + | +12 | fn bar(&self){} + | ^^^^^^^^^^^^^ error[E0277]: the trait bound `u8: Foo` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:35:5 @@ -23,7 +27,11 @@ error[E0277]: the trait bound `u8: Foo` is not satisfied > > > - = note: required by `Foo::bar` +note: required by `Foo::bar` + --> $DIR/issue-39802-show-5-trait-impls.rs:12:5 + | +12 | fn bar(&self){} + | ^^^^^^^^^^^^^ error[E0277]: the trait bound `bool: Foo` is not satisfied --> $DIR/issue-39802-show-5-trait-impls.rs:36:5 @@ -37,7 +45,11 @@ error[E0277]: the trait bound `bool: Foo` is not satisfied > > and 2 others - = note: required by `Foo::bar` +note: required by `Foo::bar` + --> $DIR/issue-39802-show-5-trait-impls.rs:12:5 + | +12 | fn bar(&self){} + | ^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr index 7fac604ba49d7..2bc7e9e46e7c5 100644 --- a/src/test/ui/did_you_mean/recursion_limit.stderr +++ b/src/test/ui/did_you_mean/recursion_limit.stderr @@ -15,7 +15,11 @@ error[E0275]: overflow evaluating the requirement `K: std::marker::Send` = note: required because it appears within the type `C` = note: required because it appears within the type `B` = note: required because it appears within the type `A` - = note: required by `is_send` +note: required by `is_send` + --> $DIR/recursion_limit.rs:41:1 + | +41 | fn is_send() { } + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/feature-gate-abi_unadjusted.stderr b/src/test/ui/feature-gate-abi_unadjusted.stderr index 3cc43847156a1..b3f7cd218d3e9 100644 --- a/src/test/ui/feature-gate-abi_unadjusted.stderr +++ b/src/test/ui/feature-gate-abi_unadjusted.stderr @@ -1,4 +1,4 @@ -error: unadjusted ABI is an implementation detail and perma-unstable +error[E0658]: unadjusted ABI is an implementation detail and perma-unstable --> $DIR/feature-gate-abi_unadjusted.rs:11:1 | 11 | / extern "unadjusted" fn foo() { diff --git a/src/test/ui/feature-gate-catch_expr.stderr b/src/test/ui/feature-gate-catch_expr.stderr index f486373d225c3..4b3bfbbe27ac8 100644 --- a/src/test/ui/feature-gate-catch_expr.stderr +++ b/src/test/ui/feature-gate-catch_expr.stderr @@ -1,4 +1,4 @@ -error: `catch` expression is experimental (see issue #31436) +error[E0658]: `catch` expression is experimental (see issue #31436) --> $DIR/feature-gate-catch_expr.rs:12:24 | 12 | let catch_result = do catch { //~ ERROR `catch` expression is experimental diff --git a/src/test/ui/feature-gate-i128_type2.stderr b/src/test/ui/feature-gate-i128_type2.stderr index 26653a5739b2c..ee81a26921498 100644 --- a/src/test/ui/feature-gate-i128_type2.stderr +++ b/src/test/ui/feature-gate-i128_type2.stderr @@ -1,4 +1,4 @@ -error: 128-bit type is unstable (see issue #35118) +error[E0658]: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:13:15 | 13 | fn test1() -> i128 { //~ ERROR 128-bit type is unstable @@ -6,7 +6,7 @@ error: 128-bit type is unstable (see issue #35118) | = help: add #![feature(i128_type)] to the crate attributes to enable -error: 128-bit type is unstable (see issue #35118) +error[E0658]: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:17:17 | 17 | fn test1_2() -> u128 { //~ ERROR 128-bit type is unstable @@ -14,7 +14,7 @@ error: 128-bit type is unstable (see issue #35118) | = help: add #![feature(i128_type)] to the crate attributes to enable -error: 128-bit type is unstable (see issue #35118) +error[E0658]: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:22:12 | 22 | let x: i128 = 0; //~ ERROR 128-bit type is unstable @@ -22,7 +22,7 @@ error: 128-bit type is unstable (see issue #35118) | = help: add #![feature(i128_type)] to the crate attributes to enable -error: 128-bit type is unstable (see issue #35118) +error[E0658]: 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:26:12 | 26 | let x: u128 = 0; //~ ERROR 128-bit type is unstable @@ -32,7 +32,7 @@ error: 128-bit type is unstable (see issue #35118) error[E0601]: main function not found -error: repr with 128-bit type is unstable (see issue #35118) +error[E0658]: repr with 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-i128_type2.rs:30:1 | 30 | / enum A { //~ ERROR 128-bit type is unstable diff --git a/src/test/ui/feature-gate-intrinsics.stderr b/src/test/ui/feature-gate-intrinsics.stderr index 5382122e30edd..918c749504aea 100644 --- a/src/test/ui/feature-gate-intrinsics.stderr +++ b/src/test/ui/feature-gate-intrinsics.stderr @@ -1,4 +1,4 @@ -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-intrinsics.rs:11:1 | 11 | / extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change @@ -8,7 +8,7 @@ error: intrinsics are subject to change | = help: add #![feature(intrinsics)] to the crate attributes to enable -error: intrinsics are subject to change +error[E0658]: intrinsics are subject to change --> $DIR/feature-gate-intrinsics.rs:15:1 | 15 | / extern "rust-intrinsic" fn baz() { //~ ERROR intrinsics are subject to change diff --git a/src/test/ui/feature-gate-non_ascii_idents.stderr b/src/test/ui/feature-gate-non_ascii_idents.stderr index 90d0b8daee71c..deb707752b066 100644 --- a/src/test/ui/feature-gate-non_ascii_idents.stderr +++ b/src/test/ui/feature-gate-non_ascii_idents.stderr @@ -1,4 +1,4 @@ -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:11:1 | 11 | extern crate core as bäz; //~ ERROR non-ascii idents @@ -6,7 +6,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:13:5 | 13 | use föö::bar; //~ ERROR non-ascii idents @@ -14,7 +14,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:15:1 | 15 | mod föö { //~ ERROR non-ascii idents @@ -22,7 +22,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:19:1 | 19 | / fn bär( //~ ERROR non-ascii idents @@ -36,7 +36,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:20:5 | 20 | bäz: isize //~ ERROR non-ascii idents @@ -44,7 +44,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:22:9 | 22 | let _ö: isize; //~ ERROR non-ascii idents @@ -52,7 +52,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:25:10 | 25 | (_ä, _) => {} //~ ERROR non-ascii idents @@ -60,7 +60,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:29:1 | 29 | struct Föö { //~ ERROR non-ascii idents @@ -68,7 +68,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:30:5 | 30 | föö: isize //~ ERROR non-ascii idents @@ -76,7 +76,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:33:1 | 33 | enum Bär { //~ ERROR non-ascii idents @@ -84,7 +84,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:34:5 | 34 | Bäz { //~ ERROR non-ascii idents @@ -92,7 +92,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:35:9 | 35 | qüx: isize //~ ERROR non-ascii idents @@ -100,7 +100,7 @@ error: non-ascii idents are not fully supported. (see issue #28979) | = help: add #![feature(non_ascii_idents)] to the crate attributes to enable -error: non-ascii idents are not fully supported. (see issue #28979) +error[E0658]: non-ascii idents are not fully supported. (see issue #28979) --> $DIR/feature-gate-non_ascii_idents.rs:40:5 | 40 | fn qüx(); //~ ERROR non-ascii idents diff --git a/src/test/ui/feature-gate-repr128.stderr b/src/test/ui/feature-gate-repr128.stderr index c59964887b58f..982ebb0101662 100644 --- a/src/test/ui/feature-gate-repr128.stderr +++ b/src/test/ui/feature-gate-repr128.stderr @@ -1,4 +1,4 @@ -error: repr with 128-bit type is unstable (see issue #35118) +error[E0658]: repr with 128-bit type is unstable (see issue #35118) --> $DIR/feature-gate-repr128.rs:12:1 | 12 | / enum A { //~ ERROR repr with 128-bit type is unstable diff --git a/src/test/ui/feature-gate-unboxed-closures.stderr b/src/test/ui/feature-gate-unboxed-closures.stderr index b79165147e590..ca8a59249463d 100644 --- a/src/test/ui/feature-gate-unboxed-closures.stderr +++ b/src/test/ui/feature-gate-unboxed-closures.stderr @@ -1,4 +1,4 @@ -error: rust-call ABI is subject to change (see issue #29625) +error[E0658]: rust-call ABI is subject to change (see issue #29625) --> $DIR/feature-gate-unboxed-closures.rs:16:5 | 16 | / extern "rust-call" fn call_once(self, (a, b): (u32, u32)) -> u32 { diff --git a/src/test/ui/feature-gate-untagged_unions.stderr b/src/test/ui/feature-gate-untagged_unions.stderr index 26b698912bc95..14b66cb5c815a 100644 --- a/src/test/ui/feature-gate-untagged_unions.stderr +++ b/src/test/ui/feature-gate-untagged_unions.stderr @@ -1,4 +1,4 @@ -error: unions with non-`Copy` fields are unstable (see issue #32836) +error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836) --> $DIR/feature-gate-untagged_unions.rs:19:1 | 19 | / union U3 { //~ ERROR unions with non-`Copy` fields are unstable @@ -8,7 +8,7 @@ error: unions with non-`Copy` fields are unstable (see issue #32836) | = help: add #![feature(untagged_unions)] to the crate attributes to enable -error: unions with non-`Copy` fields are unstable (see issue #32836) +error[E0658]: unions with non-`Copy` fields are unstable (see issue #32836) --> $DIR/feature-gate-untagged_unions.rs:23:1 | 23 | / union U4 { //~ ERROR unions with non-`Copy` fields are unstable @@ -18,7 +18,7 @@ error: unions with non-`Copy` fields are unstable (see issue #32836) | = help: add #![feature(untagged_unions)] to the crate attributes to enable -error: unions with `Drop` implementations are unstable (see issue #32836) +error[E0658]: unions with `Drop` implementations are unstable (see issue #32836) --> $DIR/feature-gate-untagged_unions.rs:27:1 | 27 | / union U5 { //~ ERROR unions with `Drop` implementations are unstable diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr index 9e0e563c35f65..4ec5c9ebd2712 100644 --- a/src/test/ui/fmt/send-sync.stderr +++ b/src/test/ui/fmt/send-sync.stderr @@ -12,7 +12,11 @@ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` = note: required because of the requirements on the impl of `std::marker::Send` for `&[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `std::fmt::Arguments<'_>` - = note: required by `send` +note: required by `send` + --> $DIR/send-sync.rs:11:1 + | +11 | fn send(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` is not satisfied in `std::fmt::Arguments<'_>` --> $DIR/send-sync.rs:19:5 @@ -28,7 +32,11 @@ error[E0277]: the trait bound `*mut std::ops::Fn() + 'static: std::marker::Sync` = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `&[std::fmt::ArgumentV1<'_>]` = note: required because it appears within the type `std::fmt::Arguments<'_>` - = note: required by `sync` +note: required by `sync` + --> $DIR/send-sync.rs:12:1 + | +12 | fn sync(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index fd8f3b8e6463d..e65c8f1546e82 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -7,7 +7,11 @@ error[E0277]: the trait bound `std::cell::Cell: std::marker::Sync` is not s = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell` = note: required because of the requirements on the impl of `std::marker::Send` for `&std::cell::Cell` = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:26:17: 30:6 a:&std::cell::Cell _]` - = note: required by `main::assert_send` +note: required by `main::assert_send` + --> $DIR/not-send-sync.rs:17:5 + | +17 | fn assert_send(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `std::cell::Cell: std::marker::Sync` is not satisfied in `[generator@$DIR/not-send-sync.rs:19:17: 23:6 {std::cell::Cell, ()}]` --> $DIR/not-send-sync.rs:19:5 diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index ffd6a3fe4ffb1..838a3002e3aa7 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -7,7 +7,11 @@ error[E0277]: the trait bound `std::rc::Rc>: std::marker::S = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:21:5: 21:22 p:std::rc::Rc>]` = note: required because it appears within the type `impl std::ops::Fn<(i32,)>` - = note: required by `send` +note: required by `send` + --> $DIR/auto-trait-leak.rs:24:1 + | +24 | fn send(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `std::rc::Rc>: std::marker::Send` is not satisfied in `impl std::ops::Fn<(i32,)>` --> $DIR/auto-trait-leak.rs:30:5 @@ -18,7 +22,11 @@ error[E0277]: the trait bound `std::rc::Rc>: std::marker::S = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak.rs:38:5: 38:22 p:std::rc::Rc>]` = note: required because it appears within the type `impl std::ops::Fn<(i32,)>` - = note: required by `send` +note: required by `send` + --> $DIR/auto-trait-leak.rs:24:1 + | +24 | fn send(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0391]: unsupported cyclic reference between types/traits detected --> $DIR/auto-trait-leak.rs:44:1 diff --git a/src/test/ui/issue-24424.stderr b/src/test/ui/issue-24424.stderr index acdf348791b20..55af26dd91ea3 100644 --- a/src/test/ui/issue-24424.stderr +++ b/src/test/ui/issue-24424.stderr @@ -4,7 +4,11 @@ error[E0283]: type annotations required: cannot resolve `T0: Trait0<'l0>` 14 | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: required by `Trait0` +note: required by `Trait0` + --> $DIR/issue-24424.rs:12:1 + | +12 | trait Trait0<'l0> {} + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr index 701a95222183a..8b30f552d3771 100644 --- a/src/test/ui/lint/suggestions.stderr +++ b/src/test/ui/lint/suggestions.stderr @@ -1,7 +1,7 @@ warning: unnecessary parentheses around assigned value - --> $DIR/suggestions.rs:36:21 + --> $DIR/suggestions.rs:46:21 | -36 | let mut a = (1); // should suggest no `mut`, no parens +46 | let mut a = (1); // should suggest no `mut`, no parens | ^^^ help: remove these parentheses | note: lint level defined here @@ -11,17 +11,17 @@ note: lint level defined here | ^^^^^^^^^^^^^ warning: use of deprecated attribute `no_debug`: the `#[no_debug]` attribute was an experimental feature that has been deprecated due to lack of demand. See https://github.com/rust-lang/rust/issues/29721 - --> $DIR/suggestions.rs:31:1 + --> $DIR/suggestions.rs:41:1 | -31 | #[no_debug] // should suggest removal of deprecated attribute +41 | #[no_debug] // should suggest removal of deprecated attribute | ^^^^^^^^^^^ help: remove this attribute | = note: #[warn(deprecated)] on by default warning: variable does not need to be mutable - --> $DIR/suggestions.rs:36:13 + --> $DIR/suggestions.rs:46:13 | -36 | let mut a = (1); // should suggest no `mut`, no parens +46 | let mut a = (1); // should suggest no `mut`, no parens | ---^^ | | | help: remove this `mut` @@ -72,18 +72,30 @@ warning: function is marked #[no_mangle], but not exported | = note: #[warn(private_no_mangle_fns)] on by default +warning: static is marked #[no_mangle], but not exported + --> $DIR/suggestions.rs:31:18 + | +31 | #[no_mangle] pub static DAUNTLESS: bool = true; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: function is marked #[no_mangle], but not exported + --> $DIR/suggestions.rs:33:18 + | +33 | #[no_mangle] pub fn val_jean() {} + | ^^^^^^^^^^^^^^^^^^^^ + warning: denote infinite loops with `loop { ... }` - --> $DIR/suggestions.rs:34:5 + --> $DIR/suggestions.rs:44:5 | -34 | while true { // should suggest `loop` +44 | while true { // should suggest `loop` | ^^^^^^^^^^ help: use `loop` | = note: #[warn(while_true)] on by default warning: the `warp_factor:` in this pattern is redundant - --> $DIR/suggestions.rs:41:23 + --> $DIR/suggestions.rs:51:23 | -41 | Equinox { warp_factor: warp_factor } => {} // should suggest shorthand +51 | Equinox { warp_factor: warp_factor } => {} // should suggest shorthand | ------------^^^^^^^^^^^^ | | | help: remove this diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr index d0229957b682e..f9852c5477332 100644 --- a/src/test/ui/macros/format-foreign.stderr +++ b/src/test/ui/macros/format-foreign.stderr @@ -1,12 +1,8 @@ error: multiple unused formatting arguments - --> $DIR/format-foreign.rs:12:5 + --> $DIR/format-foreign.rs:12:30 | -12 | println!("%.*3$s %s!/n", "Hello,", "World", 4); - | ^^^^^^^^^^^^^^^^^^^^^^^^^--------^^-------^^-^^ - | | | | - | | | unused - | | unused - | unused +12 | println!("%.*3$s %s!/n", "Hello,", "World", 4); //~ ERROR multiple unused formatting arguments + | -------------------------^^^^^^^^--^^^^^^^--^-- multiple unused arguments in this statement | = help: `%.*3$s` should be written as `{:.2$}` = help: `%s` should be written as `{}` diff --git a/src/test/ui/macros/format-unused-lables.stderr b/src/test/ui/macros/format-unused-lables.stderr index 9efdca12dea03..64ea5626c1d62 100644 --- a/src/test/ui/macros/format-unused-lables.stderr +++ b/src/test/ui/macros/format-unused-lables.stderr @@ -1,49 +1,43 @@ error: multiple unused formatting arguments - --> $DIR/format-unused-lables.rs:12:5 + --> $DIR/format-unused-lables.rs:12:22 | 12 | println!("Test", 123, 456, 789); - | ^^^^^^^^^^^^^^^^^---^^---^^---^^ - | | | | - | | | unused - | | unused - | unused + | -----------------^^^--^^^--^^^-- multiple unused arguments in this statement | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: multiple unused formatting arguments - --> $DIR/format-unused-lables.rs:14:5 + --> $DIR/format-unused-lables.rs:16:9 | -14 | / println!("Test2", -15 | | 123, - | | --- unused -16 | | 456, - | | --- unused -17 | | 789 - | | --- unused -18 | | ); - | |______^ +15 | / println!("Test2", +16 | | 123, //~ ERROR multiple unused formatting arguments + | | ^^^ +17 | | 456, + | | ^^^ +18 | | 789 + | | ^^^ +19 | | ); + | |______- multiple unused arguments in this statement | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: named argument never used - --> $DIR/format-unused-lables.rs:20:35 + --> $DIR/format-unused-lables.rs:21:35 | -20 | println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used +21 | println!("Some stuff", UNUSED="args"); //~ ERROR named argument never used | ^^^^^^ error: multiple unused formatting arguments - --> $DIR/format-unused-lables.rs:22:5 + --> $DIR/format-unused-lables.rs:24:9 | -22 | / println!("Some more $STUFF", -23 | | "woo!", - | | ------ unused -24 | | STUFF= -25 | | "things" - | | -------- unused -26 | | , UNUSED="args"); - | |_______________________------_^ - | | - | unused +23 | / println!("Some more $STUFF", +24 | | "woo!", //~ ERROR multiple unused formatting arguments + | | ^^^^^^ +25 | | STUFF= +26 | | "things" + | | ^^^^^^^^ +27 | | , UNUSED="args"); + | |_______________________^^^^^^_- multiple unused arguments in this statement | = help: `$STUFF` should be written as `{STUFF}` = note: shell formatting not supported; see the documentation for `std::fmt` diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr index 442900e0a836a..53f2f54325d57 100644 --- a/src/test/ui/mismatched_types/E0631.stderr +++ b/src/test/ui/mismatched_types/E0631.stderr @@ -6,7 +6,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `fn(usize) -> _` | - = note: required by `foo` +note: required by `foo` + --> $DIR/E0631.rs:13:1 + | +13 | fn foo(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/E0631.rs:18:5 @@ -16,7 +20,11 @@ error[E0631]: type mismatch in closure arguments | | | expected signature of `fn(usize) -> _` | - = note: required by `bar` +note: required by `bar` + --> $DIR/E0631.rs:14:1 + | +14 | fn bar>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in function arguments --> $DIR/E0631.rs:19:5 @@ -27,7 +35,11 @@ error[E0631]: type mismatch in function arguments 19 | foo(f); //~ ERROR type mismatch | ^^^ expected signature of `fn(usize) -> _` | - = note: required by `foo` +note: required by `foo` + --> $DIR/E0631.rs:13:1 + | +13 | fn foo(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in function arguments --> $DIR/E0631.rs:20:5 @@ -38,7 +50,11 @@ error[E0631]: type mismatch in function arguments 20 | bar(f); //~ ERROR type mismatch | ^^^ expected signature of `fn(usize) -> _` | - = note: required by `bar` +note: required by `bar` + --> $DIR/E0631.rs:14:1 + | +14 | fn bar>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index d904831ba4e32..4e1523c79d2d4 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -14,7 +14,7 @@ error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument | | | expected closure that takes 2 arguments -error[E0593]: closure is expected to take 2 distinct arguments, but it takes a single 2-tuple as argument +error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument --> $DIR/closure-arg-count.rs:19:15 | 19 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); @@ -39,62 +39,58 @@ help: change the closure to take multiple arguments instead of a single tuple | ^^^^^^^^^^^^^^^ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:23:5 + --> $DIR/closure-arg-count.rs:21:5 | -23 | f(|| panic!()); +21 | f(|| panic!()); | ^ -- takes 0 arguments | | | expected closure that takes 1 argument | - = note: required by `f` +note: required by `f` + --> $DIR/closure-arg-count.rs:13:1 + | +13 | fn f>(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:26:53 +error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments + --> $DIR/closure-arg-count.rs:24:53 | -26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); - | ^^^ ------ takes 2 distinct arguments +24 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); + | ^^^ ------ help: consider changing the closure to accept a tuple: `|(i, x)|` | | - | expected closure that takes a single 2-tuple as argument -help: change the closure to accept a tuple instead of individual arguments - | -26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); - | ^^^^^^^^ + | expected closure that takes a single tuple as argument -error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:28:53 +error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments + --> $DIR/closure-arg-count.rs:26:53 | -28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); - | ^^^ ------------- takes 2 distinct arguments +26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); + | ^^^ ------------- help: consider changing the closure to accept a tuple: `|(i, x): (usize, _)|` | | - | expected closure that takes a single 2-tuple as argument -help: change the closure to accept a tuple instead of individual arguments - | -28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); - | ^^^^^^^^ + | expected closure that takes a single tuple as argument error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:30:53 + --> $DIR/closure-arg-count.rs:28:53 | -30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); +28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | ^^^ --------- takes 3 distinct arguments | | | expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:32:53 + --> $DIR/closure-arg-count.rs:30:53 | -32 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); +30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument ... -41 | fn foo() {} +37 | fn foo() {} | -------- takes 0 arguments error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:35:53 + --> $DIR/closure-arg-count.rs:33:53 | -34 | let bar = |i, x, y| i; +32 | let bar = |i, x, y| i; | --------- takes 3 distinct arguments -35 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); +33 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); | ^^^ expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr index 77d3a33276737..dfd02fe23b686 100644 --- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr @@ -31,7 +31,11 @@ error[E0631]: type mismatch in function arguments | expected signature of `for<'r> fn(*mut &'r u32) -> _` | found signature of `fn(*mut &'a u32) -> _` | - = note: required by `baz` +note: required by `baz` + --> $DIR/closure-arg-type-mismatch.rs:18:1 + | +18 | fn baz(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0271]: type mismatch resolving `for<'r> >::Output == ()` --> $DIR/closure-arg-type-mismatch.rs:20:5 @@ -39,7 +43,11 @@ error[E0271]: type mismatch resolving `for<'r> $DIR/closure-arg-type-mismatch.rs:18:1 + | +18 | fn baz(_: F) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 5 previous errors diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr index 99767ba1afaef..01de7e0749500 100644 --- a/src/test/ui/mismatched_types/closure-mismatch.stderr +++ b/src/test/ui/mismatched_types/closure-mismatch.stderr @@ -5,7 +5,11 @@ error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.r | ^^^ expected bound lifetime parameter, found concrete lifetime | = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` - = note: required by `baz` +note: required by `baz` + --> $DIR/closure-mismatch.rs:15:1 + | +15 | fn baz(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in closure arguments --> $DIR/closure-mismatch.rs:18:5 @@ -16,7 +20,11 @@ error[E0631]: type mismatch in closure arguments | expected signature of `for<'r> fn(&'r ()) -> _` | = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:18:9: 18:15]` - = note: required by `baz` +note: required by `baz` + --> $DIR/closure-mismatch.rs:15:1 + | +15 | fn baz(_: T) {} + | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr index 2a27ffd106247..64c260c30ed49 100644 --- a/src/test/ui/mismatched_types/fn-variance-1.stderr +++ b/src/test/ui/mismatched_types/fn-variance-1.stderr @@ -7,7 +7,11 @@ error[E0631]: type mismatch in function arguments 21 | apply(&3, takes_mut); | ^^^^^ expected signature of `fn(&{integer}) -> _` | - = note: required by `apply` +note: required by `apply` + --> $DIR/fn-variance-1.rs:15:1 + | +15 | fn apply(t: T, f: F) where F: FnOnce(T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0631]: type mismatch in function arguments --> $DIR/fn-variance-1.rs:25:5 @@ -18,7 +22,11 @@ error[E0631]: type mismatch in function arguments 25 | apply(&mut 3, takes_imm); | ^^^^^ expected signature of `fn(&mut {integer}) -> _` | - = note: required by `apply` +note: required by `apply` + --> $DIR/fn-variance-1.rs:15:1 + | +15 | fn apply(t: T, f: F) where F: FnOnce(T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr index 8539c8818c025..9c9bbd19c7552 100644 --- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr +++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr @@ -1,12 +1,17 @@ error[E0631]: type mismatch in closure arguments - --> $DIR/unboxed-closures-vtable-mismatch.rs:23:13 + --> $DIR/unboxed-closures-vtable-mismatch.rs:25:13 | -22 | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); +23 | let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y }); | ----------------------------- found signature of `fn(usize, isize) -> _` -23 | let z = call_it(3, f); +24 | //~^ NOTE found signature of `fn(usize, isize) -> _` +25 | let z = call_it(3, f); | ^^^^^^^ expected signature of `fn(isize, isize) -> _` | - = note: required by `call_it` +note: required by `call_it` + --> $DIR/unboxed-closures-vtable-mismatch.rs:17:1 + | +17 | fn call_itisize>(y: isize, mut f: F) -> isize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.rs b/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.rs new file mode 100644 index 0000000000000..b48b08daa1963 --- /dev/null +++ b/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.rs @@ -0,0 +1,61 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test if the on_unimplemented message override works + +#![feature(on_unimplemented)] +#![feature(rustc_attrs)] + +struct Foo(T); +struct Bar(T); + +#[rustc_on_unimplemented( + on(_Self="[i32]", label="trait label if i32"), + label="trait label", + message="trait message", +)] +trait Index { + type Output: ?Sized; + fn index(&self, index: Idx) -> &Self::Output; +} + +#[rustc_on_unimplemented( + label="impl foo {Self} {Idx} {Index}", +)] +impl Index> for [i32] { + type Output = i32; + fn index(&self, _index: Foo) -> &i32 { + loop {} + } +} + +#[rustc_on_unimplemented = "on impl for Bar"] +impl Index> for [i32] { + type Output = i32; + fn index(&self, _index: Bar) -> &i32 { + loop {} + } +} + +#[rustc_error] +fn main() { + Index::index(&[] as &[i32], 2usize); + Index::index(&[] as &[i32], 2u32); + Index::index(&[] as &[u32], 2u32); + //~^ ERROR E0277 + //~| ERROR E0277 + Index::index(&[] as &[i32], Foo(2usize)); + Index::index(&[] as &[i32], Foo(2u32)); + //~^ ERROR E0277 + //~| ERROR E0277 + Index::index(&[] as &[i32], Bar(2u32)); + //~^ ERROR E0277 + //~| ERROR E0277 +} diff --git a/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr b/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr new file mode 100644 index 0000000000000..2ea9b67f26025 --- /dev/null +++ b/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr @@ -0,0 +1,44 @@ +error[E0277]: trait message `[i32]` + --> $DIR/multiple-impls-complex-filtering.rs:46:5 + | +46 | Index::index(&[] as &[i32], 2usize); + | ^^^^^^^^^^^^ u32 message + | + = help: the trait `Index<_>` is not implemented for `[i32]` +note: required by `Index::index` + --> $DIR/multiple-impls-complex-filtering.rs:25:5 + | +25 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: trait message `[i32]` + --> $DIR/multiple-impls-complex-filtering.rs:46:5 + | +46 | Index::index(&[] as &[i32], 2usize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u32 message + | + = help: the trait `Index<_>` is not implemented for `[i32]` + +error[E0277]: trait message `[i32]` + --> $DIR/multiple-impls-complex-filtering.rs:47:5 + | +47 | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^ u32 message + | + = help: the trait `Index<_>` is not implemented for `[i32]` +note: required by `Index::index` + --> $DIR/multiple-impls-complex-filtering.rs:25:5 + | +25 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: trait message `[i32]` + --> $DIR/multiple-impls-complex-filtering.rs:47:5 + | +47 | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u32 message + | + = help: the trait `Index<_>` is not implemented for `[i32]` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr index 1f71be446efb5..cfac3981be284 100644 --- a/src/test/ui/on-unimplemented/multiple-impls.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -5,7 +5,11 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied | ^^^^^^^^^^^^ trait message | = help: the trait `Index` is not implemented for `[i32]` - = note: required by `Index::index` +note: required by `Index::index` + --> $DIR/multiple-impls.rs:22:5 + | +22 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/multiple-impls.rs:43:5 @@ -22,7 +26,11 @@ error[E0277]: the trait bound `[i32]: Index>` is not satisfied | ^^^^^^^^^^^^ on impl for Foo | = help: the trait `Index>` is not implemented for `[i32]` - = note: required by `Index::index` +note: required by `Index::index` + --> $DIR/multiple-impls.rs:22:5 + | +22 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:46:5 @@ -39,7 +47,11 @@ error[E0277]: the trait bound `[i32]: Index>` is not satisfied | ^^^^^^^^^^^^ on impl for Bar | = help: the trait `Index>` is not implemented for `[i32]` - = note: required by `Index::index` +note: required by `Index::index` + --> $DIR/multiple-impls.rs:22:5 + | +22 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:49:5 diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr index c8c06bf44fd6f..ed2da68f08167 100644 --- a/src/test/ui/on-unimplemented/on-impl.stderr +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -5,7 +5,11 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied | ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice | = help: the trait `Index` is not implemented for `[i32]` - = note: required by `Index::index` +note: required by `Index::index` + --> $DIR/on-impl.rs:19:5 + | +19 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/on-impl.rs:32:5 diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr index cde56022faea2..028200a5558c8 100644 --- a/src/test/ui/on-unimplemented/on-trait.stderr +++ b/src/test/ui/on-unimplemented/on-trait.stderr @@ -5,7 +5,11 @@ error[E0277]: the trait bound `std::option::Option>: MyFromIte | ^^^^^^^ a collection of type `std::option::Option>` cannot be built from an iterator over elements of type `&u8` | = help: the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option>` - = note: required by `collect` +note: required by `collect` + --> $DIR/on-trait.rs:31:1 + | +31 | fn collect, B: MyFromIterator>(it: I) -> B { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `std::string::String: Bar::Foo` is not satisfied --> $DIR/on-trait.rs:40:21 @@ -14,7 +18,11 @@ error[E0277]: the trait bound `std::string::String: Bar::Foo` is not | ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo` | = help: the trait `Bar::Foo` is not implemented for `std::string::String` - = note: required by `foobar` +note: required by `foobar` + --> $DIR/on-trait.rs:21:1 + | +21 | fn foobar>() -> T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/span/issue-29595.stderr b/src/test/ui/span/issue-29595.stderr index 81ba0057d7173..9046b90f0e9c3 100644 --- a/src/test/ui/span/issue-29595.stderr +++ b/src/test/ui/span/issue-29595.stderr @@ -4,7 +4,11 @@ error[E0277]: the trait bound `u8: Tr` is not satisfied 17 | let a: u8 = Tr::C; //~ ERROR the trait bound `u8: Tr` is not satisfied | ^^^^^ the trait `Tr` is not implemented for `u8` | - = note: required by `Tr::C` +note: required by `Tr::C` + --> $DIR/issue-29595.rs:13:5 + | +13 | const C: Self; + | ^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/try-operator-on-main.stderr b/src/test/ui/suggestions/try-operator-on-main.stderr index 36cdd558b0faf..e97823a3d5d5b 100644 --- a/src/test/ui/suggestions/try-operator-on-main.stderr +++ b/src/test/ui/suggestions/try-operator-on-main.stderr @@ -22,7 +22,11 @@ error[E0277]: the trait bound `(): std::ops::Try` is not satisfied 25 | try_trait_generic::<()>(); //~ ERROR the trait bound | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()` | - = note: required by `try_trait_generic` +note: required by `try_trait_generic` + --> $DIR/try-operator-on-main.rs:30:1 + | +30 | fn try_trait_generic() -> T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` --> $DIR/try-operator-on-main.rs:32:5 diff --git a/src/test/ui/type-check/issue-40294.stderr b/src/test/ui/type-check/issue-40294.stderr index 2ca97aa3ef067..cf270afdeb173 100644 --- a/src/test/ui/type-check/issue-40294.stderr +++ b/src/test/ui/type-check/issue-40294.stderr @@ -10,7 +10,11 @@ error[E0283]: type annotations required: cannot resolve `&'a T: Foo` 21 | | } | |_^ | - = note: required by `Foo` +note: required by `Foo` + --> $DIR/issue-40294.rs:11:1 + | +11 | trait Foo: Sized { + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error From 621e61bff92554d784aab13a507afcc0acdde53b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 20 Jan 2018 01:33:39 -0800 Subject: [PATCH 10/30] Add filter to detect local crates for rustc_on_unimplemented --- src/libcore/fmt/mod.rs | 17 ++- src/libcore/iter/iterator.rs | 9 +- src/librustc/traits/error_reporting.rs | 4 + src/librustc/traits/on_unimplemented.rs | 3 +- src/test/ui/impl-trait/equality.rs | 2 +- src/test/ui/lint/use_suggestion_json.stderr | 67 ++++++++++- src/test/ui/mismatched_types/binops.rs | 8 +- src/test/ui/mismatched_types/binops.stderr | 8 +- .../ui/on-unimplemented/auxiliary/no_debug.rs | 14 +++ .../multiple-impls-complex-filtering.stderr | 113 ++++++++++++++---- src/test/ui/on-unimplemented/no-debug.rs | 27 +++++ src/test/ui/on-unimplemented/no-debug.stderr | 38 ++++++ src/test/ui/span/multiline-span-simple.rs | 2 +- src/test/ui/span/multiline-span-simple.stderr | 2 +- src/test/ui/suggestions/iterate-str.rs | 19 +++ src/test/ui/suggestions/iterate-str.stderr | 13 ++ 16 files changed, 299 insertions(+), 47 deletions(-) create mode 100644 src/test/ui/on-unimplemented/auxiliary/no_debug.rs create mode 100644 src/test/ui/on-unimplemented/no-debug.rs create mode 100644 src/test/ui/on-unimplemented/no-debug.stderr create mode 100644 src/test/ui/suggestions/iterate-str.rs create mode 100644 src/test/ui/suggestions/iterate-str.stderr diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 6c8a1c3062b00..8ad5a9861a02f 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -530,9 +530,12 @@ impl<'a> Display for Arguments<'a> { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "`{Self}` cannot be formatted using `:?`; if it is \ - defined in your crate, add `#[derive(Debug)]` or \ - manually implement it"] +#[rustc_on_unimplemented( + on(crate_local, label="`{Self}` cannot be formatted using `:?`; \ + add `#[derive(Debug)]` or manually implement `{Debug}`"), + message="`{Self}` doesn't implement `{Debug}`", + label="`{Self}` cannot be formatted using `:?` because it doesn't implement `{Debug}`", +)] #[lang = "debug_trait"] pub trait Debug { /// Formats the value using the given formatter. @@ -593,9 +596,11 @@ pub trait Debug { /// /// println!("The origin is: {}", origin); /// ``` -#[rustc_on_unimplemented = "`{Self}` cannot be formatted with the default \ - formatter; try using `:?` instead if you are using \ - a format string"] +#[rustc_on_unimplemented( + message="`{Self}` doesn't implement `{Display}`", + label="`{Self}` cannot be formatted with the default formatter; \ + try using `:?` instead if you are using a format string", +)] #[stable(feature = "rust1", since = "1.0.0")] pub trait Display { /// Formats the value using the given formatter. diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 35cd7441c66bc..296fb8733ba6c 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -28,8 +28,13 @@ fn _assert_is_object_safe(_: &Iterator) {} /// [module-level documentation]: index.html /// [impl]: index.html#implementing-iterator #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \ - `.iter()` or a similar method"] +#[rustc_on_unimplemented( + on( + _Self="&str", + label="`{Self}` is not an iterator; try calling `.chars()` or `.bytes()`" + ), + label="`{Self}` is not an iterator; maybe try calling `.iter()` or a similar method" +)] #[doc(spotlight)] pub trait Iterator { /// The type of the elements being iterated over. diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index f5ff122668558..be7ecbce8af73 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -384,6 +384,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { Some(ty_str.clone()))); } + if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) { + flags.push(("crate_local".to_string(), None)); + } + if let Ok(Some(command)) = OnUnimplementedDirective::of_item( self.tcx, trait_ref.def_id, def_id ) { diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index a493b7f0bb603..8c2c1cfa45472 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -185,8 +185,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective { let mut message = None; let mut label = None; let mut note = None; - info!("evaluate({:?}, trait_ref={:?}, options={:?})", - self, trait_ref, options); + info!("evaluate({:?}, trait_ref={:?}, options={:?})", self, trait_ref, options); for command in self.subcommands.iter().chain(Some(self)).rev() { if let Some(ref condition) = command.condition { diff --git a/src/test/ui/impl-trait/equality.rs b/src/test/ui/impl-trait/equality.rs index 36df4f0eb4d46..9d9d4cef3119a 100644 --- a/src/test/ui/impl-trait/equality.rs +++ b/src/test/ui/impl-trait/equality.rs @@ -32,7 +32,7 @@ fn sum_to(n: u32) -> impl Foo { 0 } else { n + sum_to(n - 1) - //~^ ERROR the trait bound `u32: std::ops::Add` is not satisfied + //~^ ERROR cannot add `impl Foo` to `u32` } } diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr index abbf3da513a6f..86c2ad4c0e7a4 100644 --- a/src/test/ui/lint/use_suggestion_json.stderr +++ b/src/test/ui/lint/use_suggestion_json.stderr @@ -2,7 +2,72 @@ "message": "cannot find type `Iter` in this scope", "code": { "code": "E0412", - "explanation": null + "explanation": " +The type name used is not in scope. + +Erroneous code examples: + +```compile_fail,E0412 +impl Something {} // error: type name `Something` is not in scope + +// or: + +trait Foo { + fn bar(N); // error: type name `N` is not in scope +} + +// or: + +fn foo(x: T) {} // type name `T` is not in scope +``` + +To fix this error, please verify you didn't misspell the type name, you did +declare it or imported it into the scope. Examples: + +``` +struct Something; + +impl Something {} // ok! + +// or: + +trait Foo { + type N; + + fn bar(_: Self::N); // ok! +} + +// or: + +fn foo(x: T) {} // ok! +``` + +Another case that causes this error is when a type is imported into a parent +module. To fix this, you can follow the suggestion and use File directly or +`use super::File;` which will import the types from the parent namespace. An +example that causes this error is below: + +```compile_fail,E0412 +use std::fs::File; + +mod foo { + fn some_function(f: File) {} +} +``` + +``` +use std::fs::File; + +mod foo { + // either + use super::File; + // or + // use std::fs::File; + fn foo(f: File) {} +} +# fn main() {} // don't insert it for us; that'll break imports +``` +" }, "level": "error", "spans": [ diff --git a/src/test/ui/mismatched_types/binops.rs b/src/test/ui/mismatched_types/binops.rs index e45616cd67a81..5144b59955cc9 100644 --- a/src/test/ui/mismatched_types/binops.rs +++ b/src/test/ui/mismatched_types/binops.rs @@ -9,10 +9,10 @@ // except according to those terms. fn main() { - 1 + Some(1); //~ ERROR is not satisfied - 2 as usize - Some(1); //~ ERROR is not satisfied - 3 * (); //~ ERROR is not satisfied - 4 / ""; //~ ERROR is not satisfied + 1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}` + 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize` + 3 * (); //~ ERROR cannot multiply `()` to `{integer}` + 4 / ""; //~ ERROR cannot divide `{integer}` by `&str` 5 < String::new(); //~ ERROR is not satisfied 6 == Ok(1); //~ ERROR is not satisfied } diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr index 57e66794a58a9..1b7fba050636f 100644 --- a/src/test/ui/mismatched_types/binops.stderr +++ b/src/test/ui/mismatched_types/binops.stderr @@ -1,7 +1,7 @@ error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}` --> $DIR/binops.rs:12:7 | -12 | 1 + Some(1); //~ ERROR is not satisfied +12 | 1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}` | ^ no implementation for `{integer} + std::option::Option<{integer}>` | = help: the trait `std::ops::Add>` is not implemented for `{integer}` @@ -9,7 +9,7 @@ error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}` error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize` --> $DIR/binops.rs:13:16 | -13 | 2 as usize - Some(1); //~ ERROR is not satisfied +13 | 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize` | ^ no implementation for `usize - std::option::Option<{integer}>` | = help: the trait `std::ops::Sub>` is not implemented for `usize` @@ -17,7 +17,7 @@ error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize` error[E0277]: cannot multiply `()` to `{integer}` --> $DIR/binops.rs:14:7 | -14 | 3 * (); //~ ERROR is not satisfied +14 | 3 * (); //~ ERROR cannot multiply `()` to `{integer}` | ^ no implementation for `{integer} * ()` | = help: the trait `std::ops::Mul<()>` is not implemented for `{integer}` @@ -25,7 +25,7 @@ error[E0277]: cannot multiply `()` to `{integer}` error[E0277]: cannot divide `{integer}` by `&str` --> $DIR/binops.rs:15:7 | -15 | 4 / ""; //~ ERROR is not satisfied +15 | 4 / ""; //~ ERROR cannot divide `{integer}` by `&str` | ^ no implementation for `{integer} / &str` | = help: the trait `std::ops::Div<&str>` is not implemented for `{integer}` diff --git a/src/test/ui/on-unimplemented/auxiliary/no_debug.rs b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs new file mode 100644 index 0000000000000..0f833c6263722 --- /dev/null +++ b/src/test/ui/on-unimplemented/auxiliary/no_debug.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// ignore-tidy-linelength + +#![crate_type = "lib"] + +pub struct Bar; diff --git a/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr b/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr index 2ea9b67f26025..c4bac12eebdbe 100644 --- a/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr @@ -1,44 +1,107 @@ -error[E0277]: trait message `[i32]` - --> $DIR/multiple-impls-complex-filtering.rs:46:5 +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:49:5 | -46 | Index::index(&[] as &[i32], 2usize); - | ^^^^^^^^^^^^ u32 message +49 | Index::index(&[] as &[i32], 2usize); + | ^^^^^^^^^^^^ trait label if i32 | - = help: the trait `Index<_>` is not implemented for `[i32]` + = help: the trait `Index` is not implemented for `[i32]` note: required by `Index::index` - --> $DIR/multiple-impls-complex-filtering.rs:25:5 + --> $DIR/multiple-impls-complex-filtering.rs:26:5 | -25 | fn index(&self, index: Idx) -> &Self::Output; +26 | fn index(&self, index: Idx) -> &Self::Output; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: trait message `[i32]` - --> $DIR/multiple-impls-complex-filtering.rs:46:5 +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:49:5 | -46 | Index::index(&[] as &[i32], 2usize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u32 message +49 | Index::index(&[] as &[i32], 2usize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label if i32 | - = help: the trait `Index<_>` is not implemented for `[i32]` + = help: the trait `Index` is not implemented for `[i32]` -error[E0277]: trait message `[i32]` - --> $DIR/multiple-impls-complex-filtering.rs:47:5 +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:50:5 | -47 | Index::index(&[] as &[i32], 2u32); - | ^^^^^^^^^^^^ u32 message +50 | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^ trait label if i32 | - = help: the trait `Index<_>` is not implemented for `[i32]` + = help: the trait `Index` is not implemented for `[i32]` note: required by `Index::index` - --> $DIR/multiple-impls-complex-filtering.rs:25:5 + --> $DIR/multiple-impls-complex-filtering.rs:26:5 | -25 | fn index(&self, index: Idx) -> &Self::Output; +26 | fn index(&self, index: Idx) -> &Self::Output; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: trait message `[i32]` - --> $DIR/multiple-impls-complex-filtering.rs:47:5 +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:50:5 | -47 | Index::index(&[] as &[i32], 2u32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u32 message +50 | Index::index(&[] as &[i32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label if i32 | - = help: the trait `Index<_>` is not implemented for `[i32]` + = help: the trait `Index` is not implemented for `[i32]` -error: aborting due to 4 previous errors +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:51:5 + | +51 | Index::index(&[] as &[u32], 2u32); + | ^^^^^^^^^^^^ trait label + | + = help: the trait `Index<_>` is not implemented for `[u32]` +note: required by `Index::index` + --> $DIR/multiple-impls-complex-filtering.rs:26:5 + | +26 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: trait message + --> $DIR/multiple-impls-complex-filtering.rs:51:5 + | +51 | Index::index(&[] as &[u32], 2u32); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label + | + = help: the trait `Index<_>` is not implemented for `[u32]` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls-complex-filtering.rs:55:5 + | +55 | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^ impl foo [i32] Foo Index + | + = help: the trait `Index>` is not implemented for `[i32]` +note: required by `Index::index` + --> $DIR/multiple-impls-complex-filtering.rs:26:5 + | +26 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls-complex-filtering.rs:55:5 + | +55 | Index::index(&[] as &[i32], Foo(2u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl foo [i32] Foo Index + | + = help: the trait `Index>` is not implemented for `[i32]` + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls-complex-filtering.rs:58:5 + | +58 | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index>` is not implemented for `[i32]` +note: required by `Index::index` + --> $DIR/multiple-impls-complex-filtering.rs:26:5 + | +26 | fn index(&self, index: Idx) -> &Self::Output; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `[i32]: Index>` is not satisfied + --> $DIR/multiple-impls-complex-filtering.rs:58:5 + | +58 | Index::index(&[] as &[i32], Bar(2u32)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar + | + = help: the trait `Index>` is not implemented for `[i32]` + +error: aborting due to 10 previous errors diff --git a/src/test/ui/on-unimplemented/no-debug.rs b/src/test/ui/on-unimplemented/no-debug.rs new file mode 100644 index 0000000000000..fff6122c6b34b --- /dev/null +++ b/src/test/ui/on-unimplemented/no-debug.rs @@ -0,0 +1,27 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:no_debug.rs + +extern crate no_debug; + +use no_debug::Bar; + +struct Foo; + +fn main() { + println!("{:?} {:?}", Foo, Bar); + println!("{} {}", Foo, Bar); +} +//~^^^ ERROR `Foo` doesn't implement `std::fmt::Debug` +//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Debug` +//~^^^^ ERROR `Foo` doesn't implement `std::fmt::Display` +//~| ERROR `no_debug::Bar` doesn't implement `std::fmt::Display` + diff --git a/src/test/ui/on-unimplemented/no-debug.stderr b/src/test/ui/on-unimplemented/no-debug.stderr new file mode 100644 index 0000000000000..af5b1e91211fb --- /dev/null +++ b/src/test/ui/on-unimplemented/no-debug.stderr @@ -0,0 +1,38 @@ +error[E0277]: `Foo` doesn't implement `std::fmt::Debug` + --> $DIR/no-debug.rs:20:27 + | +20 | println!("{:?} {:?}", Foo, Bar); + | ^^^ `Foo` cannot be formatted using `:?`; add `#[derive(Debug)]` or manually implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `Foo` + = note: required by `std::fmt::Debug::fmt` + +error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Debug` + --> $DIR/no-debug.rs:20:32 + | +20 | println!("{:?} {:?}", Foo, Bar); + | ^^^ `no_debug::Bar` cannot be formatted using `:?` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `no_debug::Bar` + = note: required by `std::fmt::Debug::fmt` + +error[E0277]: `Foo` doesn't implement `std::fmt::Display` + --> $DIR/no-debug.rs:21:23 + | +21 | println!("{} {}", Foo, Bar); + | ^^^ `Foo` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string + | + = help: the trait `std::fmt::Display` is not implemented for `Foo` + = note: required by `std::fmt::Display::fmt` + +error[E0277]: `no_debug::Bar` doesn't implement `std::fmt::Display` + --> $DIR/no-debug.rs:21:28 + | +21 | println!("{} {}", Foo, Bar); + | ^^^ `no_debug::Bar` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string + | + = help: the trait `std::fmt::Display` is not implemented for `no_debug::Bar` + = note: required by `std::fmt::Display::fmt` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/span/multiline-span-simple.rs b/src/test/ui/span/multiline-span-simple.rs index f8e4cbcbf191f..dd09534480e10 100644 --- a/src/test/ui/span/multiline-span-simple.rs +++ b/src/test/ui/span/multiline-span-simple.rs @@ -20,7 +20,7 @@ fn main() { let x = 1; let y = 2; let z = 3; - foo(1 as u32 + //~ ERROR not satisfied + foo(1 as u32 + //~ ERROR cannot add `()` to `u32` bar(x, diff --git a/src/test/ui/span/multiline-span-simple.stderr b/src/test/ui/span/multiline-span-simple.stderr index b6182825fc278..a18dfeb31d9ef 100644 --- a/src/test/ui/span/multiline-span-simple.stderr +++ b/src/test/ui/span/multiline-span-simple.stderr @@ -1,7 +1,7 @@ error[E0277]: cannot add `()` to `u32` --> $DIR/multiline-span-simple.rs:23:18 | -23 | foo(1 as u32 + //~ ERROR not satisfied +23 | foo(1 as u32 + //~ ERROR cannot add `()` to `u32` | ^ no implementation for `u32 + ()` | = help: the trait `std::ops::Add<()>` is not implemented for `u32` diff --git a/src/test/ui/suggestions/iterate-str.rs b/src/test/ui/suggestions/iterate-str.rs new file mode 100644 index 0000000000000..1022491b84a36 --- /dev/null +++ b/src/test/ui/suggestions/iterate-str.rs @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + for c in "foobarbaz" { + println!("{}", c); + } + //~^^^ ERROR the trait bound `&str: std::iter::Iterator` is not satisfied + //~| NOTE `&str` is not an iterator; try calling `.chars()` or `.bytes()` + //~| HELP the trait `std::iter::Iterator` is not implemented for `&str` + //~| NOTE required by `std::iter::IntoIterator::into_iter` +} diff --git a/src/test/ui/suggestions/iterate-str.stderr b/src/test/ui/suggestions/iterate-str.stderr new file mode 100644 index 0000000000000..59da6d70c0236 --- /dev/null +++ b/src/test/ui/suggestions/iterate-str.stderr @@ -0,0 +1,13 @@ +error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied + --> $DIR/iterate-str.rs:12:5 + | +12 | / for c in "foobarbaz" { +13 | | println!("{}", c); +14 | | } + | |_____^ `&str` is not an iterator; try calling `.chars()` or `.bytes()` + | + = help: the trait `std::iter::Iterator` is not implemented for `&str` + = note: required by `std::iter::IntoIterator::into_iter` + +error: aborting due to previous error + From 2dee07b12a2dd08a281a84146dc7085299389add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 20 Jan 2018 02:36:39 -0800 Subject: [PATCH 11/30] Remove cast suggestions --- src/libcore/ops/arith.rs | 72 ------------ .../multiple-impls-complex-filtering.rs | 61 ---------- .../multiple-impls-complex-filtering.stderr | 107 ------------------ 3 files changed, 240 deletions(-) delete mode 100644 src/test/ui/on-unimplemented/multiple-impls-complex-filtering.rs delete mode 100644 src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs index 47617b22dd34d..d0d0c09869e9d 100644 --- a/src/libcore/ops/arith.rs +++ b/src/libcore/ops/arith.rs @@ -76,78 +76,6 @@ #[lang = "add"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_on_unimplemented( - on( - any( - all(_Self="i128", RHS="i64"), - all(_Self="i128", RHS="i32"), - all(_Self="i128", RHS="i16"), - all(_Self="i128", RHS="i8"), - all(_Self="i64", RHS="i32"), - all(_Self="i64", RHS="i16"), - all(_Self="i64", RHS="i8"), - all(_Self="i32", RHS="i16"), - all(_Self="i32", RHS="i8"), - all(_Self="i16", RHS="i8"), - all(_Self="u128", RHS="u64"), - all(_Self="u128", RHS="u32"), - all(_Self="u128", RHS="u16"), - all(_Self="u128", RHS="u8"), - all(_Self="u64", RHS="u32"), - all(_Self="u64", RHS="u16"), - all(_Self="u64", RHS="u8"), - all(_Self="u32", RHS="u16"), - all(_Self="u32", RHS="u8"), - all(_Self="u16", RHS="u8"), - all(_Self="f64", RHS="i32"), - all(_Self="f64", RHS="i16"), - all(_Self="f64", RHS="i8"), - all(_Self="f64", RHS="u32"), - all(_Self="f64", RHS="u16"), - all(_Self="f64", RHS="u8"), - all(_Self="f32", RHS="i16"), - all(_Self="f32", RHS="i8"), - all(_Self="f32", RHS="u16"), - all(_Self="f32", RHS="u8"), - ), - label="no implementation for `{Self} + {RHS}`, but you can safely cast \ - `{RHS}` into `{Self}` using `as {Self}`", - ), - on( - any( - all(RHS="i128", _Self="i64"), - all(RHS="i128", _Self="i32"), - all(RHS="i128", _Self="i16"), - all(RHS="i128", _Self="i8"), - all(RHS="i64", _Self="i32"), - all(RHS="i64", _Self="i16"), - all(RHS="i64", _Self="i8"), - all(RHS="i32", _Self="i16"), - all(RHS="i32", _Self="i8"), - all(RHS="i16", _Self="i8"), - all(RHS="u128", _Self="u64"), - all(RHS="u128", _Self="u32"), - all(RHS="u128", _Self="u16"), - all(RHS="u128", _Self="u8"), - all(RHS="u64", _Self="u32"), - all(RHS="u64", _Self="u16"), - all(RHS="u64", _Self="u8"), - all(RHS="u32", _Self="u16"), - all(RHS="u32", _Self="u8"), - all(RHS="u16", _Self="u8"), - all(RHS="f64", _Self="i32"), - all(RHS="f64", _Self="i16"), - all(RHS="f64", _Self="i8"), - all(RHS="f64", _Self="u32"), - all(RHS="f64", _Self="u16"), - all(RHS="f64", _Self="u8"), - all(RHS="f32", _Self="i16"), - all(RHS="f32", _Self="i8"), - all(RHS="f32", _Self="u16"), - all(RHS="f32", _Self="u8"), - ), - label="no implementation for `{Self} + {RHS}`, but you can safely cast \ - `{Self}` into `{RHS}` using `as {RHS}`", - ), on( all(_Self="{integer}", RHS="{float}"), message="cannot add a float to an integer", diff --git a/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.rs b/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.rs deleted file mode 100644 index b48b08daa1963..0000000000000 --- a/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test if the on_unimplemented message override works - -#![feature(on_unimplemented)] -#![feature(rustc_attrs)] - -struct Foo(T); -struct Bar(T); - -#[rustc_on_unimplemented( - on(_Self="[i32]", label="trait label if i32"), - label="trait label", - message="trait message", -)] -trait Index { - type Output: ?Sized; - fn index(&self, index: Idx) -> &Self::Output; -} - -#[rustc_on_unimplemented( - label="impl foo {Self} {Idx} {Index}", -)] -impl Index> for [i32] { - type Output = i32; - fn index(&self, _index: Foo) -> &i32 { - loop {} - } -} - -#[rustc_on_unimplemented = "on impl for Bar"] -impl Index> for [i32] { - type Output = i32; - fn index(&self, _index: Bar) -> &i32 { - loop {} - } -} - -#[rustc_error] -fn main() { - Index::index(&[] as &[i32], 2usize); - Index::index(&[] as &[i32], 2u32); - Index::index(&[] as &[u32], 2u32); - //~^ ERROR E0277 - //~| ERROR E0277 - Index::index(&[] as &[i32], Foo(2usize)); - Index::index(&[] as &[i32], Foo(2u32)); - //~^ ERROR E0277 - //~| ERROR E0277 - Index::index(&[] as &[i32], Bar(2u32)); - //~^ ERROR E0277 - //~| ERROR E0277 -} diff --git a/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr b/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr deleted file mode 100644 index c4bac12eebdbe..0000000000000 --- a/src/test/ui/on-unimplemented/multiple-impls-complex-filtering.stderr +++ /dev/null @@ -1,107 +0,0 @@ -error[E0277]: trait message - --> $DIR/multiple-impls-complex-filtering.rs:49:5 - | -49 | Index::index(&[] as &[i32], 2usize); - | ^^^^^^^^^^^^ trait label if i32 - | - = help: the trait `Index` is not implemented for `[i32]` -note: required by `Index::index` - --> $DIR/multiple-impls-complex-filtering.rs:26:5 - | -26 | fn index(&self, index: Idx) -> &Self::Output; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0277]: trait message - --> $DIR/multiple-impls-complex-filtering.rs:49:5 - | -49 | Index::index(&[] as &[i32], 2usize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label if i32 - | - = help: the trait `Index` is not implemented for `[i32]` - -error[E0277]: trait message - --> $DIR/multiple-impls-complex-filtering.rs:50:5 - | -50 | Index::index(&[] as &[i32], 2u32); - | ^^^^^^^^^^^^ trait label if i32 - | - = help: the trait `Index` is not implemented for `[i32]` -note: required by `Index::index` - --> $DIR/multiple-impls-complex-filtering.rs:26:5 - | -26 | fn index(&self, index: Idx) -> &Self::Output; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0277]: trait message - --> $DIR/multiple-impls-complex-filtering.rs:50:5 - | -50 | Index::index(&[] as &[i32], 2u32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label if i32 - | - = help: the trait `Index` is not implemented for `[i32]` - -error[E0277]: trait message - --> $DIR/multiple-impls-complex-filtering.rs:51:5 - | -51 | Index::index(&[] as &[u32], 2u32); - | ^^^^^^^^^^^^ trait label - | - = help: the trait `Index<_>` is not implemented for `[u32]` -note: required by `Index::index` - --> $DIR/multiple-impls-complex-filtering.rs:26:5 - | -26 | fn index(&self, index: Idx) -> &Self::Output; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0277]: trait message - --> $DIR/multiple-impls-complex-filtering.rs:51:5 - | -51 | Index::index(&[] as &[u32], 2u32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait label - | - = help: the trait `Index<_>` is not implemented for `[u32]` - -error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls-complex-filtering.rs:55:5 - | -55 | Index::index(&[] as &[i32], Foo(2u32)); - | ^^^^^^^^^^^^ impl foo [i32] Foo Index - | - = help: the trait `Index>` is not implemented for `[i32]` -note: required by `Index::index` - --> $DIR/multiple-impls-complex-filtering.rs:26:5 - | -26 | fn index(&self, index: Idx) -> &Self::Output; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls-complex-filtering.rs:55:5 - | -55 | Index::index(&[] as &[i32], Foo(2u32)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl foo [i32] Foo Index - | - = help: the trait `Index>` is not implemented for `[i32]` - -error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls-complex-filtering.rs:58:5 - | -58 | Index::index(&[] as &[i32], Bar(2u32)); - | ^^^^^^^^^^^^ on impl for Bar - | - = help: the trait `Index>` is not implemented for `[i32]` -note: required by `Index::index` - --> $DIR/multiple-impls-complex-filtering.rs:26:5 - | -26 | fn index(&self, index: Idx) -> &Self::Output; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls-complex-filtering.rs:58:5 - | -58 | Index::index(&[] as &[i32], Bar(2u32)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar - | - = help: the trait `Index>` is not implemented for `[i32]` - -error: aborting due to 10 previous errors - From 27a23db66032be9be96e697fdda50e73b0b90cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 22 Jan 2018 19:03:51 -0800 Subject: [PATCH 12/30] Rework `parse_ident_attr` --- src/libsyntax/parse/parser.rs | 51 ++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9e8c4d3de2220..5b55f0f232877 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -761,29 +761,37 @@ impl<'a> Parser<'a> { }) } + fn expected_ident_found(&self) -> DiagnosticBuilder<'a> { + let mut err = self.struct_span_err(self.span, + &format!("expected identifier, found {}", + self.this_token_descr())); + if let Some(token_descr) = self.token_descr() { + err.span_label(self.span, format!("expected identifier, found {}", token_descr)); + } else { + err.span_label(self.span, "expected identifier"); + } + err + } + pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> { - self.parse_ident_common(true, false) + self.parse_ident_common(true) } pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> { - self.parse_ident_common(true, true) + match self.token { + token::Ident(i) if i.name == keywords::SelfType.name() { + self.bump(); + Ok(i) + } + _ => self.parse_ident(), + } } - fn parse_ident_common(&mut self, recover: bool, accept_self: bool) -> PResult<'a, ast::Ident> { + fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { match self.token { token::Ident(i) => { - if self.token.is_reserved_ident() - && !(accept_self && i.name == keywords::SelfType.name()) - { - let mut err = self.struct_span_err(self.span, - &format!("expected identifier, found {}", - self.this_token_descr())); - if let Some(token_descr) = self.token_descr() { - err.span_label(self.span, format!("expected identifier, found {}", - token_descr)); - } else { - err.span_label(self.span, "expected identifier"); - } + if self.token.is_reserved_ident() { + let mut err = self.expected_ident_found(); if recover { err.emit(); } else { @@ -797,14 +805,7 @@ impl<'a> Parser<'a> { Err(if self.prev_token_kind == PrevTokenKind::DocComment { self.span_fatal_err(self.prev_span, Error::UselessDocComment) } else { - let mut err = self.fatal(&format!("expected identifier, found `{}`", - self.this_token_to_string())); - if let Some(token_descr) = self.token_descr() { - err.span_label(self.span, format!("expected identifier, found {}", - token_descr)); - } else { - err.span_label(self.span, "expected identifier"); - } + let mut err = self.expected_ident_found(); if self.token == token::Underscore { err.note("`_` is a wildcard pattern, not an identifier"); } @@ -2117,7 +2118,7 @@ impl<'a> Parser<'a> { self.bump(); Ok(Ident::with_empty_ctxt(name)) } else { - self.parse_ident_common(false, false) + self.parse_ident_common(false) } } @@ -2134,7 +2135,7 @@ impl<'a> Parser<'a> { hi = self.prev_span; (fieldname, self.parse_expr()?, false) } else { - let fieldname = self.parse_ident_common(false, false)?; + let fieldname = self.parse_ident_common(false)?; hi = self.prev_span; // Mimic `x: x` for the `x` field shorthand. From f7c61783e4cbc169955c7e633ecf629ed901a54e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 22 Jan 2018 19:13:06 -0800 Subject: [PATCH 13/30] Fix tests --- src/libsyntax/parse/parser.rs | 2 +- src/test/compile-fail/const-eval-overflow-4b.rs | 2 +- src/test/compile-fail/ufcs-qpath-self-mismatch.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5b55f0f232877..380170207301a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -779,7 +779,7 @@ impl<'a> Parser<'a> { pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> { match self.token { - token::Ident(i) if i.name == keywords::SelfType.name() { + token::Ident(i) if i.name == keywords::SelfType.name() => { self.bump(); Ok(i) } diff --git a/src/test/compile-fail/const-eval-overflow-4b.rs b/src/test/compile-fail/const-eval-overflow-4b.rs index 02072e9a1a1f6..6028df1883967 100644 --- a/src/test/compile-fail/const-eval-overflow-4b.rs +++ b/src/test/compile-fail/const-eval-overflow-4b.rs @@ -22,7 +22,7 @@ const A_I8_T : [u32; (i8::MAX as i8 + 1u8) as usize] //~^ ERROR mismatched types //~| expected i8, found u8 - //~| ERROR the trait bound `i8: std::ops::Add` is not satisfied + //~| ERROR cannot add `u8` to `i8` = [0; (i8::MAX as usize) + 1]; diff --git a/src/test/compile-fail/ufcs-qpath-self-mismatch.rs b/src/test/compile-fail/ufcs-qpath-self-mismatch.rs index 94a98b1582af1..caf510071bd68 100644 --- a/src/test/compile-fail/ufcs-qpath-self-mismatch.rs +++ b/src/test/compile-fail/ufcs-qpath-self-mismatch.rs @@ -12,7 +12,7 @@ use std::ops::Add; fn main() { >::add(1, 2); - //~^ ERROR `i32: std::ops::Add` is not satisfied + //~^ ERROR cannot add `u32` to `i32` >::add(1u32, 2); //~^ ERROR mismatched types >::add(1, 2u32); From 378e73e6db0b4d47586f4e3ec975e43ef530ac99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 1 Feb 2018 12:12:55 -0800 Subject: [PATCH 14/30] Remove support for `Self` in attributes --- src/librustc/traits/error_reporting.rs | 2 -- src/libsyntax/parse/parser.rs | 8 +------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index be7ecbce8af73..d5ac63431445e 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -372,9 +372,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let generics = self.tcx.generics_of(def_id); let self_ty = trait_ref.self_ty(); let self_ty_str = self_ty.to_string(); - // FIXME: remove once `Self` is accepted by the compiler flags.push(("_Self".to_string(), Some(self_ty_str.clone()))); - flags.push(("Self".to_string(), Some(self_ty_str.clone()))); for param in generics.types.iter() { let name = param.name.as_str().to_string(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 380170207301a..9d573ea0e7c03 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -778,13 +778,7 @@ impl<'a> Parser<'a> { } pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> { - match self.token { - token::Ident(i) if i.name == keywords::SelfType.name() => { - self.bump(); - Ok(i) - } - _ => self.parse_ident(), - } + self.parse_ident() } fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { From fd3f2312a75bcc4c8121ad324a012c3b8befb61c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 1 Feb 2018 14:16:53 -0800 Subject: [PATCH 15/30] Fix test after rebase --- src/libsyntax/parse/attr.rs | 2 +- src/libsyntax/parse/parser.rs | 4 -- .../mismatched_types/closure-arg-count.stderr | 50 +++++++++++-------- src/test/ui/suggestions/for-c-in-str.stderr | 2 +- src/test/ui/suggestions/iterate-str.rs | 19 ------- src/test/ui/suggestions/iterate-str.stderr | 13 ----- 6 files changed, 31 insertions(+), 59 deletions(-) delete mode 100644 src/test/ui/suggestions/iterate-str.rs delete mode 100644 src/test/ui/suggestions/iterate-str.stderr diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index b01f479895b10..053746b579dcb 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -235,7 +235,7 @@ impl<'a> Parser<'a> { } let lo = self.span; - let ident = self.parse_ident_attr()?; + let ident = self.parse_ident()?; let node = self.parse_meta_item_kind()?; Ok(ast::MetaItem { name: ident.name, node: node, span: lo.to(self.prev_span) }) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9d573ea0e7c03..4c61ab6bd7810 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -777,10 +777,6 @@ impl<'a> Parser<'a> { self.parse_ident_common(true) } - pub fn parse_ident_attr(&mut self) -> PResult<'a, ast::Ident> { - self.parse_ident() - } - fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, ast::Ident> { match self.token { token::Ident(i) => { diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index 4e1523c79d2d4..be00ee4d74e7e 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -14,7 +14,7 @@ error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument | | | expected closure that takes 2 arguments -error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument +error[E0593]: closure is expected to take 2 distinct arguments, but it takes a single 2-tuple as argument --> $DIR/closure-arg-count.rs:19:15 | 19 | [1, 2, 3].sort_by(|(tuple, tuple2)| panic!()); @@ -39,9 +39,9 @@ help: change the closure to take multiple arguments instead of a single tuple | ^^^^^^^^^^^^^^^ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:21:5 + --> $DIR/closure-arg-count.rs:23:5 | -21 | f(|| panic!()); +23 | f(|| panic!()); | ^ -- takes 0 arguments | | | expected closure that takes 1 argument @@ -52,45 +52,53 @@ note: required by `f` 13 | fn f>(_: F) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:24:53 +error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments + --> $DIR/closure-arg-count.rs:26:53 | -24 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); - | ^^^ ------ help: consider changing the closure to accept a tuple: `|(i, x)|` +26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x| i); + | ^^^ ------ takes 2 distinct arguments | | - | expected closure that takes a single tuple as argument + | expected closure that takes a single 2-tuple as argument +help: change the closure to accept a tuple instead of individual arguments + | +26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); + | ^^^^^^^^ -error[E0593]: closure is expected to take a single tuple as argument, but it takes 2 distinct arguments - --> $DIR/closure-arg-count.rs:26:53 +error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments + --> $DIR/closure-arg-count.rs:28:53 | -26 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); - | ^^^ ------------- help: consider changing the closure to accept a tuple: `|(i, x): (usize, _)|` +28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i: usize, x| i); + | ^^^ ------------- takes 2 distinct arguments | | - | expected closure that takes a single tuple as argument + | expected closure that takes a single 2-tuple as argument +help: change the closure to accept a tuple instead of individual arguments + | +28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|(i, x)| i); + | ^^^^^^^^ error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:28:53 + --> $DIR/closure-arg-count.rs:30:53 | -28 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); +30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i); | ^^^ --------- takes 3 distinct arguments | | | expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments - --> $DIR/closure-arg-count.rs:30:53 + --> $DIR/closure-arg-count.rs:32:53 | -30 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); +32 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument ... -37 | fn foo() {} +41 | fn foo() {} | -------- takes 0 arguments error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments - --> $DIR/closure-arg-count.rs:33:53 + --> $DIR/closure-arg-count.rs:35:53 | -32 | let bar = |i, x, y| i; +34 | let bar = |i, x, y| i; | --------- takes 3 distinct arguments -33 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); +35 | let _it = vec![1, 2, 3].into_iter().enumerate().map(bar); | ^^^ expected closure that takes a single 2-tuple as argument error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments diff --git a/src/test/ui/suggestions/for-c-in-str.stderr b/src/test/ui/suggestions/for-c-in-str.stderr index 7a6dc9a504029..88a7b1b49d62d 100644 --- a/src/test/ui/suggestions/for-c-in-str.stderr +++ b/src/test/ui/suggestions/for-c-in-str.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied --> $DIR/for-c-in-str.rs:14:14 | 14 | for c in "asdf" { - | ^^^^^^ `&str` is not an iterator; maybe try calling `.iter()` or a similar method + | ^^^^^^ `&str` is not an iterator; try calling `.chars()` or `.bytes()` | = help: the trait `std::iter::Iterator` is not implemented for `&str` = note: required by `std::iter::IntoIterator::into_iter` diff --git a/src/test/ui/suggestions/iterate-str.rs b/src/test/ui/suggestions/iterate-str.rs deleted file mode 100644 index 1022491b84a36..0000000000000 --- a/src/test/ui/suggestions/iterate-str.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn main() { - for c in "foobarbaz" { - println!("{}", c); - } - //~^^^ ERROR the trait bound `&str: std::iter::Iterator` is not satisfied - //~| NOTE `&str` is not an iterator; try calling `.chars()` or `.bytes()` - //~| HELP the trait `std::iter::Iterator` is not implemented for `&str` - //~| NOTE required by `std::iter::IntoIterator::into_iter` -} diff --git a/src/test/ui/suggestions/iterate-str.stderr b/src/test/ui/suggestions/iterate-str.stderr deleted file mode 100644 index 59da6d70c0236..0000000000000 --- a/src/test/ui/suggestions/iterate-str.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0277]: the trait bound `&str: std::iter::Iterator` is not satisfied - --> $DIR/iterate-str.rs:12:5 - | -12 | / for c in "foobarbaz" { -13 | | println!("{}", c); -14 | | } - | |_____^ `&str` is not an iterator; try calling `.chars()` or `.bytes()` - | - = help: the trait `std::iter::Iterator` is not implemented for `&str` - = note: required by `std::iter::IntoIterator::into_iter` - -error: aborting due to previous error - From dde361128157a0845fb51d11dcd121c3491dd4a7 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 27 Jan 2018 18:58:59 +0100 Subject: [PATCH 16/30] Fix rendering issues on mobile --- src/librustdoc/html/static/main.js | 26 ++++++++++++++++++++++ src/librustdoc/html/static/rustdoc.css | 8 ++++--- src/librustdoc/html/static/themes/dark.css | 2 +- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 0f9e7001c159b..ba9bcb7af7ae0 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -47,6 +47,8 @@ // 2 for "In Return Types" var currentTab = 0; + var themesWidth = null; + function hasClass(elem, className) { if (elem && className && elem.className) { var elemClass = elem.className; @@ -121,10 +123,25 @@ sidebar.appendChild(div); } } + var themeChoices = document.getElementById("theme-choices"); + if (themeChoices) { + if (!themesWidth) { + var savedState = themeChoices.style.display; + themeChoices.style.display = 'block'; + themesWidth = themeChoices.offsetWidth + 'px'; + themeChoices.style.display = savedState; + } + themeChoices.style.position = "fixed"; + themeChoices.style.width = themesWidth; + themeChoices.style.top = '78px'; + themeChoices.style.left = '250px'; + } document.getElementsByTagName("body")[0].style.marginTop = '45px'; var themePicker = document.getElementById("theme-picker"); if (themePicker) { themePicker.style.position = "fixed"; + themePicker.style.top = "50px"; + themePicker.style.left = "250px"; } } @@ -143,6 +160,15 @@ var themePicker = document.getElementById("theme-picker"); if (themePicker) { themePicker.style.position = "absolute"; + themePicker.style.top = null; + themePicker.style.left = null; + } + var themeChoices = document.getElementById("theme-choices"); + if (themeChoices) { + themeChoices.style.position = 'absolute'; + themeChoices.style.width = null; + themeChoices.style.top = null; + themeChoices.style.left = null; } } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index d2eeb2e15b3dd..cb6f5d836b8a7 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -856,6 +856,7 @@ span.since { display: block; border-bottom: 1px solid; border-right: 1px solid; + height: 45px; } .sidebar-elems { @@ -875,7 +876,8 @@ span.since { } nav.sub { - margin: 0 auto; + width: calc(100% - 32px); + float: right; } .content { @@ -1184,8 +1186,8 @@ kbd { @media (max-width: 700px) { .theme-picker { - left: 109px; - top: 7px; + left: 10px; + top: 54px; z-index: 1; } } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index 4c6bcab72b7c9..907a6e4fcb4a0 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -383,6 +383,6 @@ kbd { @media (max-width: 700px) { #theme-picker { - background: #353535; + background: #f0f0f0; } } From c26abe75bcc4201c8f94d278f9da8645c4a8f718 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 4 Feb 2018 13:38:39 +0100 Subject: [PATCH 17/30] Fix not selectable search input --- src/librustdoc/html/static/rustdoc.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index cb6f5d836b8a7..fc5444b6b788d 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -884,6 +884,11 @@ span.since { margin-left: 0px; } + #main { + margin-top: 50px; + padding: 0; + } + .content .in-band { width: 100%; } From 8a587e67afcd99e800eb0783a090f8b163cdfb10 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 4 Feb 2018 13:47:35 +0100 Subject: [PATCH 18/30] Improve big sidebar elements display --- src/librustdoc/html/static/rustdoc.css | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index fc5444b6b788d..6d95123e63c65 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -1035,6 +1035,24 @@ h4 > .important-traits { .show-it { display: block; + width: 246px; + } + + .show-it > .block.items { + margin: 8px 0; + } + + .show-it > .block.items > ul { + margin: 0; + } + + .show-it > .block.items > ul > li { + text-align: center; + margin: 2px 0; + } + + .show-it > .block.items > ul > li > a { + font-size: 21px; } /* Because of ios, we need to actually have a full height sidebar title so the From a1809d57840a19e28e93b437a7d029be3656acb8 Mon Sep 17 00:00:00 2001 From: oberien Date: Thu, 18 Jan 2018 18:40:08 +0100 Subject: [PATCH 19/30] Implement TrustedLen for Take and Take --- src/libcore/iter/mod.rs | 3 +++ src/libcore/iter/range.rs | 3 +++ src/libcore/iter/sources.rs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 7314fac282b66..bf8367d85fd10 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -2322,6 +2322,9 @@ impl ExactSizeIterator for Take where I: ExactSizeIterator {} #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for Take where I: FusedIterator {} +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Take {} + /// An iterator to maintain state while iterating another iterator. /// /// This `struct` is created by the [`scan`] method on [`Iterator`]. See its diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 66a76a24df45a..5af6df3e1cb47 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -325,6 +325,9 @@ impl Iterator for ops::RangeFrom { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for ops::RangeFrom {} +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for ops::RangeFrom {} + #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] impl Iterator for ops::RangeInclusive { type Item = A; diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index b405f35d5e4db..b05a893e66104 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -44,6 +44,9 @@ impl DoubleEndedIterator for Repeat { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for Repeat {} +#[unstable(feature = "trusted_len", issue = "37572")] +unsafe impl TrustedLen for Repeat {} + /// Creates a new iterator that endlessly repeats a single element. /// /// The `repeat()` function repeats a single value over and over and over and From 75474ff1323c2968bb2dafc8b8f0af4817a89d01 Mon Sep 17 00:00:00 2001 From: oberien Date: Fri, 2 Feb 2018 09:31:56 +0100 Subject: [PATCH 20/30] TrustedLen for Repeat / RangeFrom test cases --- src/libcore/tests/iter.rs | 43 ++++++++++++++++++++++++++ src/test/codegen/repeat-trusted-len.rs | 23 ++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/test/codegen/repeat-trusted-len.rs diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index e52e119ff59b9..f6b12fbb2dd11 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1371,6 +1371,29 @@ fn test_range_from_nth() { assert_eq!(r, 16..); assert_eq!(r.nth(10), Some(26)); assert_eq!(r, 27..); + + assert_eq!((0..).size_hint(), (usize::MAX, None)); +} + +fn is_trusted_len(_: I) {} + +#[test] +fn test_range_from_take() { + let mut it = (0..).take(3); + assert_eq!(it.next(), Some(0)); + assert_eq!(it.next(), Some(1)); + assert_eq!(it.next(), Some(2)); + assert_eq!(it.next(), None); + is_trusted_len((0..).take(3)); + assert_eq!((0..).take(3).size_hint(), (3, Some(3))); + assert_eq!((0..).take(0).size_hint(), (0, Some(0))); + assert_eq!((0..).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX))); +} + +#[test] +fn test_range_from_take_collect() { + let v: Vec<_> = (0..).take(3).collect(); + assert_eq!(v, vec![0, 1, 2]); } #[test] @@ -1465,6 +1488,26 @@ fn test_repeat() { assert_eq!(it.next(), Some(42)); assert_eq!(it.next(), Some(42)); assert_eq!(it.next(), Some(42)); + assert_eq!(repeat(42).size_hint(), (usize::MAX, None)); +} + +#[test] +fn test_repeat_take() { + let mut it = repeat(42).take(3); + assert_eq!(it.next(), Some(42)); + assert_eq!(it.next(), Some(42)); + assert_eq!(it.next(), Some(42)); + assert_eq!(it.next(), None); + is_trusted_len(repeat(42).take(3)); + assert_eq!(repeat(42).take(3).size_hint(), (3, Some(3))); + assert_eq!(repeat(42).take(0).size_hint(), (0, Some(0))); + assert_eq!(repeat(42).take(usize::MAX).size_hint(), (usize::MAX, Some(usize::MAX))); +} + +#[test] +fn test_repeat_take_collect() { + let v: Vec<_> = repeat(42).take(3).collect(); + assert_eq!(v, vec![42, 42, 42]); } #[test] diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs new file mode 100644 index 0000000000000..43872f15d51e2 --- /dev/null +++ b/src/test/codegen/repeat-trusted-len.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -O +// ignore-tidy-linelength + +#![crate_type = "lib"] + +use std::iter; + +// CHECK-LABEL: @repeat_take_collect +#[no_mangle] +pub fn repeat_take_collect() -> Vec { +// CHECK: call void @llvm.memset.p0i8 + iter::repeat(42).take(100000).collect() +} From 6caec2c0494a173f696e5a63583ff35d1bd106aa Mon Sep 17 00:00:00 2001 From: oberien Date: Sun, 4 Feb 2018 16:04:06 +0100 Subject: [PATCH 21/30] Document TrustedLen guarantees more explicitly --- src/libcore/iter/traits.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs index 11e668d228c48..be4889f24877c 100644 --- a/src/libcore/iter/traits.rs +++ b/src/libcore/iter/traits.rs @@ -970,9 +970,11 @@ impl<'a, I: FusedIterator + ?Sized> FusedIterator for &'a mut I {} /// The iterator reports a size hint where it is either exact /// (lower bound is equal to upper bound), or the upper bound is [`None`]. /// The upper bound must only be [`None`] if the actual iterator length is -/// larger than [`usize::MAX`]. +/// larger than [`usize::MAX`]. In that case, the lower bound must be +/// [`usize::MAX`], resulting in a [`.size_hint`] of `(usize::MAX, None)`. /// -/// The iterator must produce exactly the number of elements it reported. +/// The iterator must produce exactly the number of elements it reported +/// or diverge before reaching the end. /// /// # Safety /// From c83dd0306215e21ce5f8dab92edcc3ac9795f3da Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 5 Feb 2018 17:31:46 +0100 Subject: [PATCH 22/30] Clarify 'trait bounds ignored' wording --- src/librustc_typeck/collect.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 7a91827faef83..8b0d4248bbf28 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -388,8 +388,7 @@ fn ensure_no_ty_param_bounds(tcx: TyCtxt, // part of this PR. Still, convert to warning to // make bootstrapping easier. span_warn!(tcx.sess, span, E0122, - "trait bounds are not (yet) enforced \ - in {} definitions", + "trait bounds are ignored in {} definitions", thing); } } From 27a4e73ca54f454d16cab7942ef9b27d5c942a32 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 5 Feb 2018 10:48:22 -0800 Subject: [PATCH 23/30] rustc: Add `#[rustc_args_required_const]` This commit adds a new unstable attribute to the compiler which requires that arguments to a function are always provided as constants. The primary use case for this is SIMD intrinsics where arguments are defined by vendors to be constant and in LLVM they indeed must be constant as well. For now this is mostly just a semantic guarantee in rustc that an argument is a constant when invoked, phases like trans don't actually take advantage of it yet. This means that we'll be able to use this in stdsimd but we won't be able to remove the `constify_*` macros just yet. Hopefully soon though! --- src/librustc_mir/transform/promote_consts.rs | 19 ++++---- src/librustc_mir/transform/qualify_consts.rs | 45 +++++++++++++++++-- .../compile-fail/rustc-args-required-const.rs | 36 +++++++++++++++ 3 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 src/test/compile-fail/rustc-args-required-const.rs diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 1545040f2da79..b732eeb624c6d 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -71,9 +71,12 @@ pub enum Candidate { /// Borrow of a constant temporary. Ref(Location), - /// Array of indices found in the third argument of - /// a call to one of the simd_shuffleN intrinsics. - ShuffleIndices(BasicBlock) + /// Currently applied to function calls where the callee has the unstable + /// `#[rustc_args_required_const]` attribute as well as the SIMD shuffle + /// intrinsic. The intrinsic requires the arguments are indeed constant and + /// the attribute currently provides the semantic requirement that arguments + /// must be constant. + Argument { bb: BasicBlock, index: usize }, } struct TempCollector<'tcx> { @@ -303,10 +306,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { _ => bug!() } } - Candidate::ShuffleIndices(bb) => { + Candidate::Argument { bb, index } => { match self.source[bb].terminator_mut().kind { TerminatorKind::Call { ref mut args, .. } => { - Rvalue::Use(mem::replace(&mut args[2], new_operand)) + Rvalue::Use(mem::replace(&mut args[index], new_operand)) } _ => bug!() } @@ -359,15 +362,15 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, } (statement.source_info.span, dest.ty(mir, tcx).to_ty(tcx)) } - Candidate::ShuffleIndices(bb) => { + Candidate::Argument { bb, index } => { let terminator = mir[bb].terminator(); let ty = match terminator.kind { TerminatorKind::Call { ref args, .. } => { - args[2].ty(mir, tcx) + args[index].ty(mir, tcx) } _ => { span_bug!(terminator.source_info.span, - "expected simd_shuffleN call to promote"); + "expected call argument to promote"); } }; (terminator.source_info.span, ty) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index da76adfd48f3f..297e0e491f694 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -17,6 +17,7 @@ use rustc_data_structures::bitvec::BitVector; use rustc_data_structures::indexed_set::IdxSetBuf; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_data_structures::fx::FxHashSet; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::middle::const_val::ConstVal; @@ -30,6 +31,7 @@ use rustc::mir::visit::{PlaceContext, Visitor}; use rustc::middle::lang_items; use syntax::abi::Abi; use syntax::attr; +use syntax::ast::LitKind; use syntax::feature_gate::UnstableFeatures; use syntax_pos::{Span, DUMMY_SP}; @@ -407,7 +409,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { _ => {} } } - Candidate::ShuffleIndices(_) => {} + Candidate::Argument { .. } => {} } } @@ -730,8 +732,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { self.visit_operand(func, location); let fn_ty = func.ty(self.mir, self.tcx); + let mut callee_def_id = None; let (mut is_shuffle, mut is_const_fn) = (false, None); if let ty::TyFnDef(def_id, _) = fn_ty.sty { + callee_def_id = Some(def_id); match self.tcx.fn_sig(def_id).abi() { Abi::RustIntrinsic | Abi::PlatformIntrinsic => { @@ -754,17 +758,39 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } } + let constant_arguments = callee_def_id.and_then(|id| { + args_required_const(self.tcx, id) + }); for (i, arg) in args.iter().enumerate() { self.nest(|this| { this.visit_operand(arg, location); - if is_shuffle && i == 2 && this.mode == Mode::Fn { - let candidate = Candidate::ShuffleIndices(bb); + if this.mode != Mode::Fn { + return + } + let candidate = Candidate::Argument { bb, index: i }; + if is_shuffle && i == 2 { if this.can_promote() { this.promotion_candidates.push(candidate); } else { span_err!(this.tcx.sess, this.span, E0526, "shuffle indices are not constant"); } + return + } + + let constant_arguments = match constant_arguments.as_ref() { + Some(s) => s, + None => return, + }; + if !constant_arguments.contains(&i) { + return + } + if this.can_promote() { + this.promotion_candidates.push(candidate); + } else { + this.tcx.sess.span_err(this.span, + &format!("argument {} is required to be a constant", + i + 1)); } }); } @@ -1085,3 +1111,16 @@ impl MirPass for QualifyAndPromoteConstants { } } } + +fn args_required_const(tcx: TyCtxt, def_id: DefId) -> Option> { + let attrs = tcx.get_attrs(def_id); + let attr = attrs.iter().find(|a| a.check_name("rustc_args_required_const"))?; + let mut ret = FxHashSet(); + for meta in attr.meta_item_list()? { + match meta.literal()?.node { + LitKind::Int(a, _) => { ret.insert(a as usize); } + _ => return None, + } + } + Some(ret) +} diff --git a/src/test/compile-fail/rustc-args-required-const.rs b/src/test/compile-fail/rustc-args-required-const.rs new file mode 100644 index 0000000000000..aac9299eaafb9 --- /dev/null +++ b/src/test/compile-fail/rustc-args-required-const.rs @@ -0,0 +1,36 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(attr_literals, rustc_attrs, const_fn)] + +#[rustc_args_required_const(0)] +fn foo(_a: i32) { +} + +#[rustc_args_required_const(1)] +fn bar(_a: i32, _b: i32) { +} + +const A: i32 = 3; + +const fn baz() -> i32 { + 3 +} + +fn main() { + foo(2); + foo(2 + 3); + foo(baz()); + let a = 4; + foo(A); + foo(a); //~ ERROR: argument 1 is required to be a constant + bar(a, 3); + bar(a, a); //~ ERROR: argument 2 is required to be a constant +} From 2aae22746e70eea96b0959f6e7b603576e14f3bb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 5 Feb 2018 21:20:57 +0100 Subject: [PATCH 24/30] Warn about more ignored bounds on type aliases --- src/librustc_typeck/collect.rs | 35 ++++++++----------- src/test/compile-fail/dst-bad-assign-3.rs | 2 +- .../compile-fail/private-in-public-warn.rs | 2 +- src/test/ui/param-bounds-ignored.rs | 33 +++++++++++++++++ src/test/ui/param-bounds-ignored.stderr | 18 ++++++++++ 5 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 src/test/ui/param-bounds-ignored.rs create mode 100644 src/test/ui/param-bounds-ignored.stderr diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 8b0d4248bbf28..ecef168dcadd2 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -355,40 +355,35 @@ fn is_param<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -fn ensure_no_ty_param_bounds(tcx: TyCtxt, - span: Span, - generics: &hir::Generics, - thing: &'static str) { +fn ensure_no_param_bounds(tcx: TyCtxt, + span: Span, + generics: &hir::Generics, + thing: &'static str) { let mut warn = false; for ty_param in generics.ty_params() { - for bound in ty_param.bounds.iter() { - match *bound { - hir::TraitTyParamBound(..) => { - warn = true; - } - hir::RegionTyParamBound(..) => { } - } + if !ty_param.bounds.is_empty() { + warn = true; } } - for predicate in generics.where_clause.predicates.iter() { - match *predicate { - hir::WherePredicate::BoundPredicate(..) => { - warn = true; - } - hir::WherePredicate::RegionPredicate(..) => { } - hir::WherePredicate::EqPredicate(..) => { } + for lft_param in generics.lifetimes() { + if !lft_param.bounds.is_empty() { + warn = true; } } + if !generics.where_clause.predicates.is_empty() { + warn = true; + } + if warn { // According to accepted RFC #XXX, we should // eventually accept these, but it will not be // part of this PR. Still, convert to warning to // make bootstrapping easier. span_warn!(tcx.sess, span, E0122, - "trait bounds are ignored in {} definitions", + "bounds are ignored in {}", thing); } } @@ -454,7 +449,7 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) { } }, hir::ItemTy(_, ref generics) => { - ensure_no_ty_param_bounds(tcx, it.span, generics, "type"); + ensure_no_param_bounds(tcx, it.span, generics, "type aliases"); tcx.generics_of(def_id); tcx.type_of(def_id); tcx.predicates_of(def_id); diff --git a/src/test/compile-fail/dst-bad-assign-3.rs b/src/test/compile-fail/dst-bad-assign-3.rs index 1c3bad5ba5643..759da7b2bde21 100644 --- a/src/test/compile-fail/dst-bad-assign-3.rs +++ b/src/test/compile-fail/dst-bad-assign-3.rs @@ -13,7 +13,7 @@ #![feature(unsized_tuple_coercion)] type Fat = (isize, &'static str, T); -//~^ WARNING trait bounds are not (yet) enforced +//~^ WARNING bounds are ignored #[derive(PartialEq,Eq)] struct Bar; diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs index dfcf4dc01b8ab..aa91ce27c379a 100644 --- a/src/test/compile-fail/private-in-public-warn.rs +++ b/src/test/compile-fail/private-in-public-warn.rs @@ -58,7 +58,7 @@ mod traits { pub trait PubTr {} pub type Alias = T; //~ ERROR private trait `traits::PrivTr` in public interface - //~^ WARN trait bounds are not (yet) enforced in type definitions + //~^ WARN bounds are ignored in type aliases //~| WARNING hard error pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error diff --git a/src/test/ui/param-bounds-ignored.rs b/src/test/ui/param-bounds-ignored.rs new file mode 100644 index 0000000000000..9e09102f2d439 --- /dev/null +++ b/src/test/ui/param-bounds-ignored.rs @@ -0,0 +1,33 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// must-compile-successfully + +use std::rc::Rc; + +type SVec = Vec; +type VVec<'b, 'a: 'b> = Vec<&'a i32>; +type WVec<'b, T: 'b> = Vec; + +fn foo<'a>(y: &'a i32) { + // If the bounds above would matter, the code below would be rejected. + let mut x : SVec<_> = Vec::new(); + x.push(Rc::new(42)); + + let mut x : VVec<'static, 'a> = Vec::new(); + x.push(y); + + let mut x : WVec<'static, & 'a i32> = Vec::new(); + x.push(y); +} + +fn main() { + foo(&42); +} diff --git a/src/test/ui/param-bounds-ignored.stderr b/src/test/ui/param-bounds-ignored.stderr new file mode 100644 index 0000000000000..a14d416aaa733 --- /dev/null +++ b/src/test/ui/param-bounds-ignored.stderr @@ -0,0 +1,18 @@ +warning[E0122]: bounds are ignored in type aliases + --> $DIR/param-bounds-ignored.rs:15:1 + | +15 | type SVec = Vec; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning[E0122]: bounds are ignored in type aliases + --> $DIR/param-bounds-ignored.rs:16:1 + | +16 | type VVec<'b, 'a: 'b> = Vec<&'a i32>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning[E0122]: bounds are ignored in type aliases + --> $DIR/param-bounds-ignored.rs:17:1 + | +17 | type WVec<'b, T: 'b> = Vec; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + From b55e07ee50c9e4d00b6fc13dc27d45bd03a7965d Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Mon, 5 Feb 2018 18:09:51 -0800 Subject: [PATCH 25/30] correct E0619 span re method call receivers whose type must be known Previously, when the type of a method receiver could not be determined, the error message would, potentially confusingly, highlight the span of the entire method call. Resolves #36598, resolves #42234. --- src/librustc_typeck/check/mod.rs | 2 +- .../span/issue-42234-unknown-receiver-type.rs | 27 +++++++++++++++++++ .../issue-42234-unknown-receiver-type.stderr | 15 +++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/span/issue-42234-unknown-receiver-type.rs create mode 100644 src/test/ui/span/issue-42234-unknown-receiver-type.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 363d4a9dc0cd3..f044b2c711e20 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2925,7 +2925,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let rcvr = &args[0]; let rcvr_t = self.check_expr_with_needs(&rcvr, needs); // no need to check for bot/err -- callee does that - let rcvr_t = self.structurally_resolved_type(expr.span, rcvr_t); + let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t); let method = match self.lookup_method(rcvr_t, segment, diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.rs b/src/test/ui/span/issue-42234-unknown-receiver-type.rs new file mode 100644 index 0000000000000..d9cdd99c245e6 --- /dev/null +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.rs @@ -0,0 +1,27 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// When the type of a method call's receiver is unknown, the span should point +// to the receiver (and not the entire call, as was previously the case before +// the fix of which this tests). + +fn shines_a_beacon_through_the_darkness() { + let x: Option<_> = None; + x.unwrap().method_that_could_exist_on_some_type(); + //~^ ERROR 17:5: 17:15: the type of this value must be known in this context +} + +fn courier_to_des_moines_and_points_west(data: &[u32]) -> String { + data.iter() //~ ERROR 22:5: 23:20: the type of this value must be known in this context + .sum::<_>() + .to_string() +} + +fn main() {} diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr new file mode 100644 index 0000000000000..ed756cdc553ce --- /dev/null +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr @@ -0,0 +1,15 @@ +error[E0619]: the type of this value must be known in this context + --> $DIR/issue-42234-unknown-receiver-type.rs:17:5 + | +17 | x.unwrap().method_that_could_exist_on_some_type(); + | ^^^^^^^^^^ + +error[E0619]: the type of this value must be known in this context + --> $DIR/issue-42234-unknown-receiver-type.rs:22:5 + | +22 | / data.iter() //~ ERROR 22:5: 23:20: the type of this value must be known in this context +23 | | .sum::<_>() + | |___________________^ + +error: aborting due to 2 previous errors + From 2cff123416cf62648ddbe7aab387aabe1a01314f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sun, 4 Feb 2018 22:22:26 +0530 Subject: [PATCH 26/30] Add -Zepoch --- src/librustc/lib.rs | 1 + src/librustc/session/config.rs | 45 ++++++++++++++++++++++++++++++++-- src/librustc/session/mod.rs | 7 +++++- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index db6863d6dadc2..a7a2619505931 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -58,6 +58,7 @@ #![feature(macro_vis_matcher)] #![feature(match_default_bindings)] #![feature(never_type)] +#![feature(non_exhaustive)] #![feature(nonzero)] #![feature(quote)] #![feature(refcell_replace_swap)] diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 9543d01597d04..f1590f4aced45 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -112,6 +112,31 @@ pub enum OutputType { DepInfo, } +/// The epoch of the compiler (RFC 2052) +#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq)] +#[non_exhaustive] +pub enum Epoch { + // epochs must be kept in order, newest to oldest + + /// The 2015 epoch + Epoch2015, + /// The 2018 epoch + Epoch2018, + + // when adding new epochs, be sure to update: + // + // - the list in the `parse_epoch` static + // - the match in the `parse_epoch` function + // - add a `rust_####()` function to the session + // - update the enum in Cargo's sources as well + // + // When -Zepoch becomes --epoch, there will + // also be a check for the epoch being nightly-only + // somewhere. That will need to be updated + // whenever we're stabilizing/introducing a new epoch + // as well as changing the default Cargo template. +} + impl_stable_hash_for!(enum self::OutputType { Bitcode, Assembly, @@ -802,11 +827,13 @@ macro_rules! options { Some("`string` or `string=string`"); pub const parse_lto: Option<&'static str> = Some("one of `thin`, `fat`, or omitted"); + pub const parse_epoch: Option<&'static str> = + Some("one of: `2015`, `2018`"); } #[allow(dead_code)] mod $mod_set { - use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto}; + use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer, Lto, Epoch}; use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel}; use std::path::PathBuf; @@ -1010,6 +1037,15 @@ macro_rules! options { }; true } + + fn parse_epoch(slot: &mut Epoch, v: Option<&str>) -> bool { + match v { + Some("2015") => *slot = Epoch::Epoch2015, + Some("2018") => *slot = Epoch::Epoch2018, + _ => return false, + } + true + } } ) } @@ -1297,6 +1333,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, `everybody_loops` (all function bodies replaced with `loop {}`), `hir` (the HIR), `hir,identified`, or `hir,typed` (HIR with types for each node)."), + epoch: Epoch = (Epoch::Epoch2015, parse_epoch, [TRACKED], + "The epoch to build Rust with. Newer epochs may include features + that require breaking changes. The default epoch is 2015 (the first + epoch). Crates compiled with different epochs can be linked together."), } pub fn default_lib_output() -> CrateType { @@ -2088,7 +2128,7 @@ mod dep_tracking { use std::path::PathBuf; use std::collections::hash_map::DefaultHasher; use super::{Passes, CrateType, OptLevel, DebugInfoLevel, Lto, - OutputTypes, Externs, ErrorOutputType, Sanitizer}; + OutputTypes, Externs, ErrorOutputType, Sanitizer, Epoch}; use syntax::feature_gate::UnstableFeatures; use rustc_back::{PanicStrategy, RelroLevel}; @@ -2150,6 +2190,7 @@ mod dep_tracking { impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind); impl_dep_tracking_hash_via_hash!(Sanitizer); impl_dep_tracking_hash_via_hash!(Option); + impl_dep_tracking_hash_via_hash!(Epoch); impl_dep_tracking_hash_for_sortable_vec_of!(String); impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index f4a00a43d8d92..9d7a9acc3d533 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -19,7 +19,7 @@ use lint; use middle::allocator::AllocatorKind; use middle::dependency_format; use session::search_paths::PathKind; -use session::config::{BorrowckMode, DebugInfoLevel, OutputType}; +use session::config::{BorrowckMode, DebugInfoLevel, OutputType, Epoch}; use ty::tls; use util::nodemap::{FxHashMap, FxHashSet}; use util::common::{duration_to_secs_str, ErrorReported}; @@ -864,6 +864,11 @@ impl Session { pub fn teach(&self, code: &DiagnosticId) -> bool { self.opts.debugging_opts.teach && !self.parse_sess.span_diagnostic.code_emitted(code) } + + /// Are we allowed to use features from the Rust 2018 epoch? + pub fn rust_2018(&self) -> bool { + self.opts.debugging_opts.epoch >= Epoch::Epoch2018 + } } pub fn build_session(sopts: config::Options, From d0ab8f03bbc0e0694b6b8c411c5b39b89c2fe821 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 5 Feb 2018 01:45:43 +0530 Subject: [PATCH 27/30] Convert tyvar_behind_raw_pointer to hard error for the 2018 epoch --- src/librustc_typeck/check/method/probe.rs | 18 ++++++++++++------ src/librustc_typeck/diagnostics.rs | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index c88bbd03af82b..e8c3966f23f08 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -326,13 +326,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if reached_raw_pointer && !self.tcx.sess.features.borrow().arbitrary_self_types { // this case used to be allowed by the compiler, - // so we do a future-compat lint here + // so we do a future-compat lint here for the 2015 epoch // (see https://github.com/rust-lang/rust/issues/46906) - self.tcx.lint_node( - lint::builtin::TYVAR_BEHIND_RAW_POINTER, - scope_expr_id, - span, - &format!("the type of this value must be known in this context")); + if self.tcx.sess.rust_2018() { + span_err!(self.tcx.sess, span, E0908, + "the type of this value must be known \ + to call a method on a raw pointer on it"); + } else { + self.tcx.lint_node( + lint::builtin::TYVAR_BEHIND_RAW_POINTER, + scope_expr_id, + span, + &format!("the type of this value must be known in this context")); + } } else { let t = self.structurally_resolved_type(span, final_ty); assert_eq!(t, self.tcx.types.err); diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index ac7f54250d32b..ea9b5473ed103 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4777,4 +4777,5 @@ register_diagnostics! { E0641, // cannot cast to/from a pointer with an unknown kind E0645, // trait aliases not finished E0907, // type inside generator must be known in this context + E0908, // methods on raw pointers can only be called if the pointer type is fully known } From ac183f83df4bf43bc5d8c5e5f2c5d4297a0b3755 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Feb 2018 16:28:25 +0100 Subject: [PATCH 28/30] improve wording: bounds -> generic bounds --- src/librustc_typeck/collect.rs | 2 +- src/test/ui/param-bounds-ignored.stderr | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ecef168dcadd2..d5328a18c2240 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -383,7 +383,7 @@ fn ensure_no_param_bounds(tcx: TyCtxt, // part of this PR. Still, convert to warning to // make bootstrapping easier. span_warn!(tcx.sess, span, E0122, - "bounds are ignored in {}", + "generic bounds are ignored in {}", thing); } } diff --git a/src/test/ui/param-bounds-ignored.stderr b/src/test/ui/param-bounds-ignored.stderr index a14d416aaa733..19aa9c5d6e562 100644 --- a/src/test/ui/param-bounds-ignored.stderr +++ b/src/test/ui/param-bounds-ignored.stderr @@ -1,16 +1,16 @@ -warning[E0122]: bounds are ignored in type aliases +warning[E0122]: generic bounds are ignored in type aliases --> $DIR/param-bounds-ignored.rs:15:1 | 15 | type SVec = Vec; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning[E0122]: bounds are ignored in type aliases +warning[E0122]: generic bounds are ignored in type aliases --> $DIR/param-bounds-ignored.rs:16:1 | 16 | type VVec<'b, 'a: 'b> = Vec<&'a i32>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning[E0122]: bounds are ignored in type aliases +warning[E0122]: generic bounds are ignored in type aliases --> $DIR/param-bounds-ignored.rs:17:1 | 17 | type WVec<'b, T: 'b> = Vec; From 83a9f4980ec8e9a97fffdc262c88b8ad47549014 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 5 Feb 2018 02:00:37 +0530 Subject: [PATCH 29/30] Fill in long diagnostic --- src/librustc_typeck/diagnostics.rs | 50 +++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index ea9b5473ed103..f59948e9fc42f 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4698,6 +4698,55 @@ element type `T`. Also note that the error is conservatively reported even when the alignment of the zero-sized type is less than or equal to the data field's alignment. "##, + + +E0908: r##" +A method was called on a raw pointer whose inner type wasn't completely known. + +For example, you may have done something like: + +```compile_fail +# #![deny(warnings)] +let foo = &1; +let bar = foo as *const _; +if bar.is_null() { + // ... +} +``` + +Here, the type of `bar` isn't known; it could be a pointer to anything. Instead, +specify a type for the pointer (preferably something that makes sense for the +thing you're pointing to): + +``` +let foo = &1; +let bar = foo as *const i32; +if bar.is_null() { + // ... +} +``` + +Even though `is_null()` exists as a method on any raw pointer, Rust shows this +error because Rust allows for `self` to have arbitrary types (behind the +arbitrary_self_types feature flag). + +This means that someone can specify such a function: + +```ignore (cannot-doctest-feature-doesnt-exist-yet) +impl Foo { + fn is_null(self: *const Self) -> bool { + // do something else + } +} +``` + +and now when you call `.is_null()` on a raw pointer to `Foo`, there's ambiguity. + +Given that we don't know what type the pointer is, and there's potential +ambiguity for some types, we disallow calling methods on raw pointers when +the type is unknown. +"##, + } register_diagnostics! { @@ -4777,5 +4826,4 @@ register_diagnostics! { E0641, // cannot cast to/from a pointer with an unknown kind E0645, // trait aliases not finished E0907, // type inside generator must be known in this context - E0908, // methods on raw pointers can only be called if the pointer type is fully known } From b8aa8cadd6e868e74becaffaae17b64aeb66d004 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 5 Feb 2018 17:04:50 -0500 Subject: [PATCH 30/30] Add tests for -Zepoch using tyvar_raw_pointer --- .../epoch-raw-pointer-method-2015.rs | 23 +++++++++++++++++++ .../epoch-raw-pointer-method-2018.rs | 22 ++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/test/compile-fail/epoch-raw-pointer-method-2015.rs create mode 100644 src/test/compile-fail/epoch-raw-pointer-method-2018.rs diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2015.rs b/src/test/compile-fail/epoch-raw-pointer-method-2015.rs new file mode 100644 index 0000000000000..a71db040b50e7 --- /dev/null +++ b/src/test/compile-fail/epoch-raw-pointer-method-2015.rs @@ -0,0 +1,23 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength +// compile-flags: -Zepoch=2015 -Zunstable-options + +// tests that epochs work with the tyvar warning-turned-error + +#[deny(warnings)] +fn main() { + let x = 0; + let y = &x as *const _; + let _ = y.is_null(); + //~^ error: the type of this value must be known in this context [tyvar_behind_raw_pointer] + //~^^ warning: this was previously accepted +} diff --git a/src/test/compile-fail/epoch-raw-pointer-method-2018.rs b/src/test/compile-fail/epoch-raw-pointer-method-2018.rs new file mode 100644 index 0000000000000..c4815de2306e9 --- /dev/null +++ b/src/test/compile-fail/epoch-raw-pointer-method-2018.rs @@ -0,0 +1,22 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength +// compile-flags: -Zepoch=2018 -Zunstable-options + +// tests that epochs work with the tyvar warning-turned-error + +#[deny(warnings)] +fn main() { + let x = 0; + let y = &x as *const _; + let _ = y.is_null(); + //~^ error: the type of this value must be known to call a method on a raw pointer on it [E0908] +}