diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index bb6041d7f3196..7cfc5385e2104 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -59,13 +59,13 @@ def v(*args): o("lld", "rust.lld", "build lld") o("lldb", "rust.lldb", "build lldb") o("missing-tools", "dist.missing-tools", "allow failures when building tools") -o("use-libcxx", "llvm.use_libcxx", "build LLVM with libc++") +o("use-libcxx", "llvm.use-libcxx", "build LLVM with libc++") o("cflags", "llvm.cflags", "build LLVM with these extra compiler flags") o("cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags") o("ldflags", "llvm.ldflags", "build LLVM with these extra linker flags") -o("llvm-libunwind", "rust.llvm_libunwind", "use LLVM libunwind") +o("llvm-libunwind", "rust.llvm-libunwind", "use LLVM libunwind") # Optimization and debugging options. These may be overridden by the release # channel, etc. diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index c086bf2cf402a..f3b2a73d3c5dc 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -4,10 +4,10 @@ //! our CI. use std::env; -//use std::ffi::OsString; +use std::ffi::OsString; use std::fmt; use std::fs; -//use std::iter; +use std::iter; use std::path::{Path, PathBuf}; use std::process::Command; @@ -204,8 +204,8 @@ impl Step for Cargo { } /// Runs `cargo test` for `cargo` packaged with Rust. - fn run(self, _builder: &Builder<'_>) { - /*let compiler = builder.compiler(self.stage, self.host); + fn run(self, builder: &Builder<'_>) { + let compiler = builder.compiler(self.stage, self.host); builder.ensure(tool::Cargo { compiler, @@ -235,7 +235,7 @@ impl Step for Cargo { cargo.env("PATH", &path_for_cargo(builder, compiler)); - try_run(builder, &mut cargo.into());*/ + try_run(builder, &mut cargo.into()); } } @@ -590,14 +590,14 @@ impl Step for Clippy { } } -//fn path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString { -// // Configure PATH to find the right rustc. NB. we have to use PATH -// // and not RUSTC because the Cargo test suite has tests that will -// // fail if rustc is not spelled `rustc`. -// let path = builder.sysroot(compiler).join("bin"); -// let old_path = env::var_os("PATH").unwrap_or_default(); -// env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("") -//} +fn path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString { + // Configure PATH to find the right rustc. NB. we have to use PATH + // and not RUSTC because the Cargo test suite has tests that will + // fail if rustc is not spelled `rustc`. + let path = builder.sysroot(compiler).join("bin"); + let old_path = env::var_os("PATH").unwrap_or_default(); + env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("") +} #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct RustdocTheme { diff --git a/src/ci/run.sh b/src/ci/run.sh index 4afd61bf8a7ba..73c3a964f5396 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -37,8 +37,6 @@ if [ "$DIST_SRC" = "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src" fi -RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.parallel-compiler" - # If we're deploying artifacts then we set the release channel, otherwise if # we're not deploying then we want to be sure to enable all assertions because # we'll be running tests @@ -46,8 +44,13 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.parallel-compiler" # FIXME: need a scheme for changing this `nightly` value to `beta` and `stable` # either automatically or manually. export RUST_RELEASE_CHANNEL=nightly + +# Always set the release channel for bootstrap; this is normally not important (i.e., only dist +# builds would seem to matter) but in practice bootstrap wants to know whether we're targeting +# master, beta, or stable with a build to determine whether to run some checks (notably toolstate). +RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL" + if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-static-stdcpp" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.remap-debuginfo" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --debuginfo-level-std=1" @@ -55,6 +58,9 @@ if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then if [ "$NO_LLVM_ASSERTIONS" = "1" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions" elif [ "$DEPLOY_ALT" != "" ]; then + if [ "$NO_PARALLEL_COMPILER" = "" ]; then + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.parallel-compiler" + fi RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir" fi diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs index e6e3454b36f81..dcdd26634de46 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -165,6 +165,62 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> { self } + /// Marks the struct as non-exhaustive, indicating to the reader that there are some other + /// fields that are not shown in the debug representation. + /// + /// # Examples + /// + /// ``` + /// # #![feature(debug_non_exhaustive)] + /// use std::fmt; + /// + /// struct Bar { + /// bar: i32, + /// hidden: f32, + /// } + /// + /// impl fmt::Debug for Bar { + /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + /// fmt.debug_struct("Bar") + /// .field("bar", &self.bar) + /// .finish_non_exhaustive() // Show that some other field(s) exist. + /// } + /// } + /// + /// assert_eq!( + /// format!("{:?}", Bar { bar: 10, hidden: 1.0 }), + /// "Bar { bar: 10, .. }", + /// ); + /// ``` + #[unstable(feature = "debug_non_exhaustive", issue = "67364")] + pub fn finish_non_exhaustive(&mut self) -> fmt::Result { + self.result = self.result.and_then(|_| { + // Draw non-exhaustive dots (`..`), and open brace if necessary (no fields). + if self.is_pretty() { + if !self.has_fields { + self.fmt.write_str(" {\n")?; + } + let mut slot = None; + let mut state = Default::default(); + let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state); + writer.write_str("..\n")?; + } else { + if self.has_fields { + self.fmt.write_str(", ..")?; + } else { + self.fmt.write_str(" { ..")?; + } + } + if self.is_pretty() { + self.fmt.write_str("}")? + } else { + self.fmt.write_str(" }")?; + } + Ok(()) + }); + self.result + } + /// Finishes output and returns any error encountered. /// /// # Examples @@ -194,15 +250,16 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> { /// ``` #[stable(feature = "debug_builders", since = "1.2.0")] pub fn finish(&mut self) -> fmt::Result { - if self.has_fields { - self.result = self.result.and_then(|_| { + self.result = self.result.and_then(|_| { + if self.has_fields { if self.is_pretty() { - self.fmt.write_str("}") + self.fmt.write_str("}")? } else { - self.fmt.write_str(" }") + self.fmt.write_str(" }")?; } - }); - } + } + Ok(()) + }); self.result } diff --git a/src/libcore/tests/fmt/builders.rs b/src/libcore/tests/fmt/builders.rs index 255724432816d..8f426abe43ffa 100644 --- a/src/libcore/tests/fmt/builders.rs +++ b/src/libcore/tests/fmt/builders.rs @@ -93,6 +93,89 @@ mod debug_struct { }", format!("{:#?}", Bar)); } + + #[test] + fn test_only_non_exhaustive() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Foo") + .finish_non_exhaustive() + } + } + + + assert_eq!("Foo { .. }", format!("{:?}", Foo)); + assert_eq!( +"Foo { + .. +}", + format!("{:#?}", Foo)); + } + + #[test] + fn test_multiple_and_non_exhaustive() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Foo") + .field("bar", &true) + .field("baz", &format_args!("{}/{}", 10, 20)) + .finish_non_exhaustive() + } + } + + assert_eq!("Foo { bar: true, baz: 10/20, .. }", format!("{:?}", Foo)); + assert_eq!( +"Foo { + bar: true, + baz: 10/20, + .. +}", + format!("{:#?}", Foo)); + } + + #[test] + fn test_nested_non_exhaustive() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Foo") + .field("bar", &true) + .field("baz", &format_args!("{}/{}", 10, 20)) + .finish_non_exhaustive() + } + } + + struct Bar; + + impl fmt::Debug for Bar { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Bar") + .field("foo", &Foo) + .field("hello", &"world") + .finish_non_exhaustive() + } + } + + assert_eq!("Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }", + format!("{:?}", Bar)); + assert_eq!( +"Bar { + foo: Foo { + bar: true, + baz: 10/20, + .. + }, + hello: \"world\", + .. +}", + format!("{:#?}", Bar)); + } + } mod debug_tuple { diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index b28ed2eaa0876..904c37fe54255 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -5,6 +5,7 @@ #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(debug_map_key_value)] +#![feature(debug_non_exhaustive)] #![feature(dec2flt)] #![feature(exact_size_is_empty)] #![feature(fixed_size_array)] diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index aa7f4f2155dd1..d952bf7ab9e25 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -3,7 +3,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; -use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, AtomicUsize, Ordering}; +use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, AtomicU64, Ordering}; use rustc_data_structures::sharded::{self, Sharded}; use std::sync::atomic::Ordering::SeqCst; use std::env; @@ -485,8 +485,8 @@ impl DepGraph { if cfg!(debug_assertions) { let current_dep_graph = &self.data.as_ref().unwrap().current; - Some((current_dep_graph.total_read_count.load(SeqCst) as u64, - current_dep_graph.total_duplicate_read_count.load(SeqCst) as u64)) + Some((current_dep_graph.total_read_count.load(SeqCst), + current_dep_graph.total_duplicate_read_count.load(SeqCst))) } else { None } @@ -970,8 +970,8 @@ pub(super) struct CurrentDepGraph { /// These are simple counters that are for profiling and /// debugging and only active with `debug_assertions`. - total_read_count: AtomicUsize, - total_duplicate_read_count: AtomicUsize, + total_read_count: AtomicU64, + total_duplicate_read_count: AtomicU64, } impl CurrentDepGraph { @@ -1012,8 +1012,8 @@ impl CurrentDepGraph { )), anon_id_seed: stable_hasher.finish(), forbidden_edge, - total_read_count: AtomicUsize::new(0), - total_duplicate_read_count: AtomicUsize::new(0), + total_read_count: AtomicU64::new(0), + total_duplicate_read_count: AtomicU64::new(0), } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 78a31f4e54466..15bbfa7860fa7 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -212,6 +212,17 @@ pub enum AssocKind { Type } +impl AssocKind { + pub fn suggestion_descr(&self) -> &'static str { + match self { + ty::AssocKind::Method => "method call", + ty::AssocKind::Type | + ty::AssocKind::OpaqueTy => "associated type", + ty::AssocKind::Const => "associated constant", + } + } +} + impl AssocItem { pub fn def_kind(&self) -> DefKind { match self.kind { diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 02611a36aaebc..fb541637e5f79 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -24,7 +24,6 @@ #![feature(integer_atomics)] #![feature(test)] #![feature(associated_type_bounds)] -#![feature(cfg_target_has_atomic)] #![cfg_attr(unix, feature(libc))] diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index c4aed0628ba42..6a19f52897e5d 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -317,9 +317,7 @@ cfg_if! { pub use parking_lot::MutexGuard as LockGuard; pub use parking_lot::MappedMutexGuard as MappedLockGuard; - pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32}; - #[cfg(target_has_atomic = "64")] - pub use std::sync::atomic::{AtomicU64}; + pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64}; pub use crossbeam_utils::atomic::AtomicCell; diff --git a/src/librustc_session/config.rs b/src/librustc_session/config.rs index 359c8b3e73a90..7f3bab8f23299 100644 --- a/src/librustc_session/config.rs +++ b/src/librustc_session/config.rs @@ -1358,11 +1358,11 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "prints the LLVM optimization passes being run"), ast_json: bool = (false, parse_bool, [UNTRACKED], "print the AST as JSON and halt"), - // We default to min(4, vCPUs) here since we want to avoid spawning *too* - // many threads -- that causes scalability issues due to contention on - // the jobserver pipe (at least) -- but 4 is a reasonable amount on systems - // with lots of cores. - threads: usize = (std::cmp::min(::num_cpus::get(), 4), parse_threads, [UNTRACKED], + // We default to 1 here since we want to behave like + // a sequential compiler for now. This'll likely be adjusted + // in the future. Note that -Zthreads=0 is the way to get + // the num_cpus behavior. + threads: usize = (1, parse_threads, [UNTRACKED], "use a thread pool with N threads"), ast_json_noexpand: bool = (false, parse_bool, [UNTRACKED], "print the pre-expansion AST as JSON and halt"), diff --git a/src/librustc_session/session.rs b/src/librustc_session/session.rs index 4e72249aed129..150d207e5bfe9 100644 --- a/src/librustc_session/session.rs +++ b/src/librustc_session/session.rs @@ -14,7 +14,7 @@ use rustc_errors::ErrorReported; use rustc_data_structures::base_n; use rustc_data_structures::sync::{ - self, Lrc, Lock, OneThread, Once, AtomicUsize, Ordering, + self, Lrc, Lock, OneThread, Once, AtomicU64, AtomicUsize, Ordering, Ordering::SeqCst, }; use rustc_data_structures::impl_stable_hash_via_hash; @@ -119,7 +119,7 @@ pub struct Session { /// If `-zprint-fuel=crate`, `Some(crate)`. pub print_fuel_crate: Option, /// Always set to zero and incremented so that we can print fuel expended by a crate. - pub print_fuel: AtomicUsize, + pub print_fuel: AtomicU64, /// Loaded up early on in the initialization of this `Session` to avoid /// false positives about a job server in our environment. @@ -1116,7 +1116,7 @@ fn build_session_( out_of_fuel: false, }); let print_fuel_crate = sopts.debugging_opts.print_fuel.clone(); - let print_fuel = AtomicUsize::new(0); + let print_fuel = AtomicU64::new(0); let working_dir = env::current_dir().unwrap_or_else(|e| parse_sess.span_diagnostic diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index fc7d19766373a..19441be87b959 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -1425,8 +1425,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field: ast::Ident, ) -> Ty<'tcx> { let expr_t = self.check_expr_with_needs(base, needs); - let expr_t = self.structurally_resolved_type(base.span, - expr_t); + let expr_t = self.structurally_resolved_type(base.span, expr_t); let mut private_candidate = None; let mut autoderef = self.autoderef(expr.span, expr_t); while let Some((base_t, _)) = autoderef.next() { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index f4b53b4d10604..9cd8c9abfd783 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -15,7 +15,7 @@ use rustc::traits::Obligation; use rustc::ty::{self, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable}; use rustc::ty::print::with_crate_prefix; use syntax_pos::{Span, FileName}; -use syntax::ast; +use syntax::{ast, source_map}; use syntax::util::lev_distance; use rustc_error_codes::*; @@ -79,37 +79,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } - let print_disambiguation_help = | - err: &mut DiagnosticBuilder<'_>, - trait_name: String, - | { - err.help(&format!( - "to disambiguate the method call, write `{}::{}({}{})` instead", - trait_name, - item_name, - if rcvr_ty.is_region_ptr() && args.is_some() { - if rcvr_ty.is_mutable_ptr() { - "&mut " - } else { - "&" - } - } else { - "" - }, - args.map(|arg| arg - .iter() - .map(|arg| self.tcx.sess.source_map().span_to_snippet(arg.span) - .unwrap_or_else(|_| "...".to_owned())) - .collect::>() - .join(", ") - ).unwrap_or_else(|| "...".to_owned()) - )); - }; - let report_candidates = | span: Span, err: &mut DiagnosticBuilder<'_>, mut sources: Vec, + sugg_span: Span, | { sources.sort(); sources.dedup(); @@ -150,15 +124,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - let note_str = if sources.len() > 1 { - format!("candidate #{} is defined in an impl{} for the type `{}`", - idx + 1, - insertion, - impl_ty) + let (note_str, idx) = if sources.len() > 1 { + (format!( + "candidate #{} is defined in an impl{} for the type `{}`", + idx + 1, + insertion, + impl_ty, + ), Some(idx + 1)) } else { - format!("the candidate is defined in an impl{} for the type `{}`", - insertion, - impl_ty) + (format!( + "the candidate is defined in an impl{} for the type `{}`", + insertion, + impl_ty, + ), None) }; if let Some(note_span) = note_span { // We have a span pointing to the method. Show note with snippet. @@ -168,7 +146,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.note(¬e_str); } if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) { - print_disambiguation_help(err, self.tcx.def_path_str(trait_ref.def_id)); + let path = self.tcx.def_path_str(trait_ref.def_id); + + let ty = match item.kind { + ty::AssocKind::Const | + ty::AssocKind::Type | + ty::AssocKind::OpaqueTy => rcvr_ty, + ty::AssocKind::Method => self.tcx.fn_sig(item.def_id) + .inputs() + .skip_binder() + .get(0) + .filter(|ty| ty.is_region_ptr() && !rcvr_ty.is_region_ptr()) + .map(|ty| *ty) + .unwrap_or(rcvr_ty), + }; + print_disambiguation_help( + item_name, + args, + err, + path, + ty, + item.kind, + sugg_span, + idx, + self.tcx.sess.source_map(), + ); } } CandidateSource::TraitSource(trait_did) => { @@ -182,19 +184,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let item_span = self.tcx.sess.source_map() .def_span(self.tcx.def_span(item.def_id)); - if sources.len() > 1 { + let idx = if sources.len() > 1 { span_note!(err, item_span, "candidate #{} is defined in the trait `{}`", idx + 1, self.tcx.def_path_str(trait_did)); + Some(idx + 1) } else { span_note!(err, item_span, "the candidate is defined in the trait `{}`", self.tcx.def_path_str(trait_did)); - } - print_disambiguation_help(err, self.tcx.def_path_str(trait_did)); + None + }; + let path = self.tcx.def_path_str(trait_did); + print_disambiguation_help( + item_name, + args, + err, + path, + rcvr_ty, + item.kind, + sugg_span, + idx, + self.tcx.sess.source_map(), + ); } } } @@ -203,6 +218,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; + let sugg_span = if let SelfSource::MethodCall(expr) = source { + // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing. + self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)).span + } else { + span + }; + match error { MethodError::NoMatch(NoMatchData { static_candidates: static_sources, @@ -495,9 +517,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )); } - report_candidates(span, &mut err, static_sources); + report_candidates(span, &mut err, static_sources, sugg_span); } else if static_sources.len() > 1 { - report_candidates(span, &mut err, static_sources); + report_candidates(span, &mut err, static_sources, sugg_span); } if !unsatisfied_predicates.is_empty() { @@ -584,7 +606,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "multiple applicable items in scope"); err.span_label(span, format!("multiple `{}` found", item_name)); - report_candidates(span, &mut err, sources); + report_candidates(span, &mut err, sources, sugg_span); err.emit(); } @@ -1123,3 +1145,56 @@ impl hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'tcx> { hir::intravisit::NestedVisitorMap::None } } + +fn print_disambiguation_help( + item_name: ast::Ident, + args: Option<&'tcx [hir::Expr]>, + err: &mut DiagnosticBuilder<'_>, + trait_name: String, + rcvr_ty: Ty<'_>, + kind: ty::AssocKind, + span: Span, + candidate: Option, + source_map: &source_map::SourceMap, +) { + let mut applicability = Applicability::MachineApplicable; + let sugg_args = if let (ty::AssocKind::Method, Some(args)) = (kind, args) { + format!( + "({}{})", + if rcvr_ty.is_region_ptr() { + if rcvr_ty.is_mutable_ptr() { + "&mut " + } else { + "&" + } + } else { + "" + }, + args.iter() + .map(|arg| source_map.span_to_snippet(arg.span) + .unwrap_or_else(|_| { + applicability = Applicability::HasPlaceholders; + "_".to_owned() + })) + .collect::>() + .join(", "), + ) + } else { + String::new() + }; + let sugg = format!("{}::{}{}", trait_name, item_name, sugg_args); + err.span_suggestion( + span, + &format!( + "disambiguate the {} for {}", + kind.suggestion_descr(), + if let Some(candidate) = candidate { + format!("candidate #{}", candidate) + } else { + "the candidate".to_string() + }, + ), + sugg, + applicability, + ); +} diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs index d5f4ece726bea..a9d88370c612f 100644 --- a/src/libstd/net/addr.rs +++ b/src/libstd/net/addr.rs @@ -4,7 +4,7 @@ use crate::hash; use crate::io; use crate::iter; use crate::mem; -use crate::net::{hton, ntoh, IpAddr, Ipv4Addr, Ipv6Addr}; +use crate::net::{htons, ntohs, IpAddr, Ipv4Addr, Ipv6Addr}; use crate::option; use crate::slice; use crate::sys::net::netc as c; @@ -276,7 +276,7 @@ impl SocketAddrV4 { SocketAddrV4 { inner: c::sockaddr_in { sin_family: c::AF_INET as c::sa_family_t, - sin_port: hton(port), + sin_port: htons(port), sin_addr: *ip.as_inner(), ..unsafe { mem::zeroed() } }, @@ -326,7 +326,7 @@ impl SocketAddrV4 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn port(&self) -> u16 { - ntoh(self.inner.sin_port) + ntohs(self.inner.sin_port) } /// Changes the port number associated with this socket address. @@ -342,7 +342,7 @@ impl SocketAddrV4 { /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] pub fn set_port(&mut self, new_port: u16) { - self.inner.sin_port = hton(new_port); + self.inner.sin_port = htons(new_port); } } @@ -368,7 +368,7 @@ impl SocketAddrV6 { SocketAddrV6 { inner: c::sockaddr_in6 { sin6_family: c::AF_INET6 as c::sa_family_t, - sin6_port: hton(port), + sin6_port: htons(port), sin6_addr: *ip.as_inner(), sin6_flowinfo: flowinfo, sin6_scope_id: scope_id, @@ -420,7 +420,7 @@ impl SocketAddrV6 { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn port(&self) -> u16 { - ntoh(self.inner.sin6_port) + ntohs(self.inner.sin6_port) } /// Changes the port number associated with this socket address. @@ -436,7 +436,7 @@ impl SocketAddrV6 { /// ``` #[stable(feature = "sockaddr_setters", since = "1.9.0")] pub fn set_port(&mut self, new_port: u16) { - self.inner.sin6_port = hton(new_port); + self.inner.sin6_port = htons(new_port); } /// Returns the flow information associated with this address. diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs index b68146939fdcc..8652ed8b046bb 100644 --- a/src/libstd/net/mod.rs +++ b/src/libstd/net/mod.rs @@ -85,21 +85,10 @@ pub enum Shutdown { Both, } -#[doc(hidden)] -trait NetInt { - fn from_be(i: Self) -> Self; - fn to_be(&self) -> Self; -} -macro_rules! doit { - ($($t:ident)*) => ($(impl NetInt for $t { - fn from_be(i: Self) -> Self { <$t>::from_be(i) } - fn to_be(&self) -> Self { <$t>::to_be(*self) } - })*) -} -doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } - -fn hton(i: I) -> I { i.to_be() } -fn ntoh(i: I) -> I { I::from_be(i) } +#[inline] +const fn htons(i: u16) -> u16 { i.to_be() } +#[inline] +const fn ntohs(i: u16) -> u16 { u16::from_be(i) } fn each_addr(addr: A, mut f: F) -> io::Result where F: FnMut(io::Result<&SocketAddr>) -> io::Result diff --git a/src/test/ui/associated-const/associated-const-ambiguity-report.stderr b/src/test/ui/associated-const/associated-const-ambiguity-report.stderr index bb217bd182db6..92a8d19021a2c 100644 --- a/src/test/ui/associated-const/associated-const-ambiguity-report.stderr +++ b/src/test/ui/associated-const/associated-const-ambiguity-report.stderr @@ -9,13 +9,19 @@ note: candidate #1 is defined in an impl of the trait `Foo` for the type `i32` | LL | const ID: i32 = 1; | ^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `Foo::ID(...)` instead note: candidate #2 is defined in an impl of the trait `Bar` for the type `i32` --> $DIR/associated-const-ambiguity-report.rs:14:5 | LL | const ID: i32 = 3; | ^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `Bar::ID(...)` instead +help: disambiguate the associated constant for candidate #1 + | +LL | const X: i32 = Foo::ID; + | ^^^^^^^ +help: disambiguate the associated constant for candidate #2 + | +LL | const X: i32 = Bar::ID; + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0034.stderr b/src/test/ui/error-codes/E0034.stderr index a58d16bfafb59..6db2ef5051d83 100644 --- a/src/test/ui/error-codes/E0034.stderr +++ b/src/test/ui/error-codes/E0034.stderr @@ -9,13 +9,19 @@ note: candidate #1 is defined in an impl of the trait `Trait1` for the type `Tes | LL | fn foo() {} | ^^^^^^^^ - = help: to disambiguate the method call, write `Trait1::foo(...)` instead note: candidate #2 is defined in an impl of the trait `Trait2` for the type `Test` --> $DIR/E0034.rs:16:5 | LL | fn foo() {} | ^^^^^^^^ - = help: to disambiguate the method call, write `Trait2::foo(...)` instead +help: disambiguate the method call for candidate #1 + | +LL | Trait1::foo() + | ^^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | Trait2::foo() + | ^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/inference/inference_unstable_featured.stderr b/src/test/ui/inference/inference_unstable_featured.stderr index b06a6298a571c..fa908440e41ea 100644 --- a/src/test/ui/inference/inference_unstable_featured.stderr +++ b/src/test/ui/inference/inference_unstable_featured.stderr @@ -5,9 +5,15 @@ LL | assert_eq!('x'.ipu_flatten(), 0); | ^^^^^^^^^^^ multiple `ipu_flatten` found | = note: candidate #1 is defined in an impl of the trait `inference_unstable_iterator::IpuIterator` for the type `char` - = help: to disambiguate the method call, write `inference_unstable_iterator::IpuIterator::ipu_flatten('x')` instead = note: candidate #2 is defined in an impl of the trait `inference_unstable_itertools::IpuItertools` for the type `char` - = help: to disambiguate the method call, write `inference_unstable_itertools::IpuItertools::ipu_flatten('x')` instead +help: disambiguate the method call for candidate #1 + | +LL | assert_eq!(inference_unstable_iterator::IpuIterator::ipu_flatten(&'x'), 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | assert_eq!(inference_unstable_itertools::IpuItertools::ipu_flatten(&'x'), 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-18446.stderr b/src/test/ui/issues/issue-18446.stderr index e6afc4c13a912..3422add9dd96b 100644 --- a/src/test/ui/issues/issue-18446.stderr +++ b/src/test/ui/issues/issue-18446.stderr @@ -2,7 +2,10 @@ error[E0034]: multiple applicable items in scope --> $DIR/issue-18446.rs:18:7 | LL | x.foo(); - | ^^^ multiple `foo` found + | --^^^-- + | | | + | | multiple `foo` found + | help: disambiguate the method call for candidate #2: `T::foo(&x)` | note: candidate #1 is defined in an impl for the type `dyn T` --> $DIR/issue-18446.rs:9:5 @@ -14,7 +17,6 @@ note: candidate #2 is defined in the trait `T` | LL | fn foo(&self); | ^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `T::foo(&x)` instead error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3702-2.stderr b/src/test/ui/issues/issue-3702-2.stderr index 4d0ff750c254c..b18e407c3d464 100644 --- a/src/test/ui/issues/issue-3702-2.stderr +++ b/src/test/ui/issues/issue-3702-2.stderr @@ -9,13 +9,19 @@ note: candidate #1 is defined in an impl of the trait `ToPrimitive` for the type | LL | fn to_int(&self) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `ToPrimitive::to_int(&self)` instead note: candidate #2 is defined in an impl of the trait `Add` for the type `isize` --> $DIR/issue-3702-2.rs:14:5 | LL | fn to_int(&self) -> isize { *self } | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `Add::to_int(&self)` instead +help: disambiguate the method call for candidate #1 + | +LL | ToPrimitive::to_int(&self) + other.to_int() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | Add::to_int(&self) + other.to_int() + | ^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr b/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr index c7bb653dc1f14..feaf3dc753ffb 100644 --- a/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr +++ b/src/test/ui/issues/issue-65634-raw-ident-suggestion.stderr @@ -9,13 +9,19 @@ note: candidate #1 is defined in an impl of the trait `async` for the type `r#fn | LL | fn r#struct(&self) { | ^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `async::r#struct(r#fn {})` instead note: candidate #2 is defined in an impl of the trait `await` for the type `r#fn` --> $DIR/issue-65634-raw-ident-suggestion.rs:10:5 | LL | fn r#struct(&self) { | ^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `await::r#struct(r#fn {})` instead +help: disambiguate the method call for candidate #1 + | +LL | async::r#struct(&r#fn {}); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | await::r#struct(&r#fn {}); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr b/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr index 9f46a722a508e..fa3add81a28f5 100644 --- a/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-cross-crate.stderr @@ -9,9 +9,15 @@ note: candidate #1 is defined in an impl of the trait `Me2` for the type `usize` | LL | impl Me2 for usize { fn me(&self) -> usize { *self } } | ^^^^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `Me2::me(1_usize)` instead = note: candidate #2 is defined in an impl of the trait `ambig_impl_2_lib::Me` for the type `usize` - = help: to disambiguate the method call, write `ambig_impl_2_lib::Me::me(1_usize)` instead +help: disambiguate the method call for candidate #1 + | +LL | fn main() { Me2::me(&1_usize); } + | ^^^^^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | fn main() { ambig_impl_2_lib::Me::me(&1_usize); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr b/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr index 6c493c67e29d9..b6c81c2377ee4 100644 --- a/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-from-bounds.stderr @@ -9,13 +9,19 @@ note: candidate #1 is defined in the trait `A` | LL | trait A { fn foo(&self); } | ^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `A::foo(t)` instead note: candidate #2 is defined in the trait `B` --> $DIR/method-ambig-two-traits-from-bounds.rs:2:11 | LL | trait B { fn foo(&self); } | ^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `B::foo(t)` instead +help: disambiguate the method call for candidate #1 + | +LL | A::foo(t); + | ^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | B::foo(t); + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr index 0b3724e030fa4..71c65f7ccc68d 100644 --- a/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls.stderr @@ -9,13 +9,19 @@ note: candidate #1 is defined in an impl of the trait `A` for the type `AB` | LL | fn foo(self) {} | ^^^^^^^^^^^^ - = help: to disambiguate the method call, write `A::foo(AB {})` instead note: candidate #2 is defined in an impl of the trait `B` for the type `AB` --> $DIR/method-ambig-two-traits-from-impls.rs:11:5 | LL | fn foo(self) {} | ^^^^^^^^^^^^ - = help: to disambiguate the method call, write `B::foo(AB {})` instead +help: disambiguate the method call for candidate #1 + | +LL | A::foo(AB {}); + | ^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | B::foo(AB {}); + | ^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr index 81c99b33c813e..44f85071505d2 100644 --- a/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-from-impls2.stderr @@ -9,13 +9,19 @@ note: candidate #1 is defined in an impl of the trait `A` for the type `AB` | LL | fn foo() {} | ^^^^^^^^ - = help: to disambiguate the method call, write `A::foo(...)` instead note: candidate #2 is defined in an impl of the trait `B` for the type `AB` --> $DIR/method-ambig-two-traits-from-impls2.rs:11:5 | LL | fn foo() {} | ^^^^^^^^ - = help: to disambiguate the method call, write `B::foo(...)` instead +help: disambiguate the method call for candidate #1 + | +LL | A::foo(); + | ^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | B::foo(); + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr b/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr index dc8aef2503739..3dbb17371004a 100644 --- a/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr +++ b/src/test/ui/methods/method-ambig-two-traits-with-default-method.stderr @@ -9,13 +9,19 @@ note: candidate #1 is defined in an impl of the trait `Foo` for the type `usize` | LL | trait Foo { fn method(&self) {} } | ^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `Foo::method(1_usize)` instead note: candidate #2 is defined in an impl of the trait `Bar` for the type `usize` --> $DIR/method-ambig-two-traits-with-default-method.rs:6:13 | LL | trait Bar { fn method(&self) {} } | ^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `Bar::method(1_usize)` instead +help: disambiguate the method call for candidate #1 + | +LL | Foo::method(&1_usize); + | ^^^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | Bar::method(&1_usize); + | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index c9d7da84e09f4..e7f295df8c482 100644 --- a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -25,19 +25,28 @@ note: candidate #1 is defined in an impl of the trait `internal::X` for the type | LL | fn foo(self: Smaht) -> u64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `internal::X::foo(x)` instead note: candidate #2 is defined in an impl of the trait `nuisance_foo::NuisanceFoo` for the type `_` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:70:9 | LL | fn foo(self) {} | ^^^^^^^^^^^^ - = help: to disambiguate the method call, write `nuisance_foo::NuisanceFoo::foo(x)` instead note: candidate #3 is defined in the trait `FinalFoo` --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:57:5 | LL | fn foo(&self) -> u8; | ^^^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `FinalFoo::foo(x)` instead +help: disambiguate the method call for candidate #1 + | +LL | let z = internal::X::foo(x); + | ^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | let z = nuisance_foo::NuisanceFoo::foo(x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #3 + | +LL | let z = FinalFoo::foo(x); + | ^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:137:24 diff --git a/src/test/ui/span/issue-37767.stderr b/src/test/ui/span/issue-37767.stderr index 0bbff45436c23..9ed6c8b826f79 100644 --- a/src/test/ui/span/issue-37767.stderr +++ b/src/test/ui/span/issue-37767.stderr @@ -9,13 +9,19 @@ note: candidate #1 is defined in the trait `A` | LL | fn foo(&mut self) {} | ^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `A::foo(&a)` instead note: candidate #2 is defined in the trait `B` --> $DIR/issue-37767.rs:6:5 | LL | fn foo(&mut self) {} | ^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `B::foo(&a)` instead +help: disambiguate the method call for candidate #1 + | +LL | A::foo(&a) + | ^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | B::foo(&a) + | ^^^^^^^^^^ error[E0034]: multiple applicable items in scope --> $DIR/issue-37767.rs:22:7 @@ -28,13 +34,19 @@ note: candidate #1 is defined in the trait `C` | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `C::foo(&a)` instead note: candidate #2 is defined in the trait `D` --> $DIR/issue-37767.rs:18:5 | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `D::foo(&a)` instead +help: disambiguate the method call for candidate #1 + | +LL | C::foo(&a) + | ^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | D::foo(&a) + | ^^^^^^^^^^ error[E0034]: multiple applicable items in scope --> $DIR/issue-37767.rs:34:7 @@ -47,13 +59,19 @@ note: candidate #1 is defined in the trait `E` | LL | fn foo(self) {} | ^^^^^^^^^^^^ - = help: to disambiguate the method call, write `E::foo(a)` instead note: candidate #2 is defined in the trait `F` --> $DIR/issue-37767.rs:30:5 | LL | fn foo(self) {} | ^^^^^^^^^^^^ - = help: to disambiguate the method call, write `F::foo(a)` instead +help: disambiguate the method call for candidate #1 + | +LL | E::foo(a) + | ^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | F::foo(a) + | ^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 36db5bea86294..53a6238422b57 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -10,24 +10,33 @@ note: candidate #1 is defined in the trait `CtxtFn` | LL | fn f9(_: usize) -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `CtxtFn::f9(u, 342)` instead note: candidate #2 is defined in the trait `OtherTrait` --> $DIR/issue-7575.rs:8:5 | LL | fn f9(_: usize) -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `OtherTrait::f9(u, 342)` instead note: candidate #3 is defined in the trait `UnusedTrait` --> $DIR/issue-7575.rs:17:5 | LL | fn f9(_: usize) -> usize; | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `UnusedTrait::f9(u, 342)` instead = help: items from traits can only be used if the trait is implemented and in scope = note: the following traits define an item `f9`, perhaps you need to implement one of them: candidate #1: `CtxtFn` candidate #2: `OtherTrait` candidate #3: `UnusedTrait` +help: disambiguate the method call for candidate #1 + | +LL | u.f8(42) + CtxtFn::f9(u, 342) + m.fff(42) + | ^^^^^^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | u.f8(42) + OtherTrait::f9(u, 342) + m.fff(42) + | ^^^^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #3 + | +LL | u.f8(42) + UnusedTrait::f9(u, 342) + m.fff(42) + | ^^^^^^^^^^^^^^^^^^^^^^^ error[E0599]: no method named `fff` found for type `Myisize` in the current scope --> $DIR/issue-7575.rs:62:30 @@ -60,8 +69,11 @@ note: the candidate is defined in the trait `ManyImplTrait` | LL | fn is_str() -> bool { | ^^^^^^^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `ManyImplTrait::is_str(t)` instead = help: items from traits can only be used if the type parameter is bounded by the trait +help: disambiguate the method call for the candidate + | +LL | ManyImplTrait::is_str(t) + | help: the following trait defines an item `is_str`, perhaps you need to restrict type parameter `T` with it: | LL | fn param_bound(t: T) -> bool { diff --git a/src/test/ui/traits/cycle-cache-err-60010.rs b/src/test/ui/traits/cycle-cache-err-60010.rs index ebed4a02d0f33..cbddef082be67 100644 --- a/src/test/ui/traits/cycle-cache-err-60010.rs +++ b/src/test/ui/traits/cycle-cache-err-60010.rs @@ -28,7 +28,7 @@ struct SalsaStorage { } impl Database for RootDatabase { - type Storage = SalsaStorage; + type Storage = SalsaStorage; //~ ERROR overflow } impl HasQueryGroup for RootDatabase {} impl Query for ParseQuery diff --git a/src/test/ui/traits/cycle-cache-err-60010.stderr b/src/test/ui/traits/cycle-cache-err-60010.stderr index 2fc26bb11e3e3..295845b1146ef 100644 --- a/src/test/ui/traits/cycle-cache-err-60010.stderr +++ b/src/test/ui/traits/cycle-cache-err-60010.stderr @@ -6,6 +6,22 @@ LL | _parse: >::Data, | = note: required because of the requirements on the impl of `Query` for `ParseQuery` -error: aborting due to previous error +error[E0275]: overflow evaluating the requirement `Runtime: std::panic::RefUnwindSafe` + --> $DIR/cycle-cache-err-60010.rs:31:5 + | +LL | type Storage; + | ------- associated type defined here +... +LL | impl Database for RootDatabase { + | ------------------------------ in this `impl` item +LL | type Storage = SalsaStorage; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: required because it appears within the type `RootDatabase` + = note: required because of the requirements on the impl of `SourceDatabase` for `RootDatabase` + = note: required because of the requirements on the impl of `Query` for `ParseQuery` + = note: required because it appears within the type `SalsaStorage` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/src/test/ui/traits/trait-alias-ambiguous.stderr b/src/test/ui/traits/trait-alias-ambiguous.stderr index cde7dd0824924..48a029104aeca 100644 --- a/src/test/ui/traits/trait-alias-ambiguous.stderr +++ b/src/test/ui/traits/trait-alias-ambiguous.stderr @@ -9,13 +9,19 @@ note: candidate #1 is defined in an impl of the trait `inner::A` for the type `u | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `inner::A::foo(t)` instead note: candidate #2 is defined in an impl of the trait `inner::B` for the type `u8` --> $DIR/trait-alias-ambiguous.rs:11:9 | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ - = help: to disambiguate the method call, write `inner::B::foo(t)` instead +help: disambiguate the method call for candidate #1 + | +LL | inner::A::foo(&t); + | ^^^^^^^^^^^^^^^^^ +help: disambiguate the method call for candidate #2 + | +LL | inner::B::foo(&t); + | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error