From 79388aa067e27824973f8f25fd6c4775d35388fd Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Tue, 25 May 2021 23:27:26 -0400 Subject: [PATCH 01/37] Add future_prelude_collision lint --- compiler/rustc_lint_defs/src/builtin.rs | 45 +++++++++++++++++ compiler/rustc_span/src/symbol.rs | 2 + compiler/rustc_typeck/src/check/method/mod.rs | 49 ++++++++++++++++++- 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 352146d64635..168ea713d194 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3001,6 +3001,7 @@ declare_lint_pass! { PROC_MACRO_BACK_COMPAT, OR_PATTERNS_BACK_COMPAT, LARGE_ASSIGNMENTS, + FUTURE_PRELUDE_COLLISION, ] } @@ -3240,3 +3241,47 @@ declare_lint! { Allow, "detects usage of old versions of or-patterns", } + +declare_lint! { + /// The `future_prelude_collision` lint detects the usage of trait methods which are ambiguous + /// with traits added to the prelude in future editions. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(future_prelude_collision)] + /// + /// trait Foo { + /// fn try_into(self) -> Result; + /// } + /// + /// impl Foo for &str { + /// fn try_into(self) -> Result { + /// Ok(String::from(self)) + /// } + /// } + /// + /// fn main() { + /// let x: String = "3".try_into().unwrap(); + /// // ^^^^^^^^ + /// // This call to try_into matches both Foo:try_into and TryInto::try_into as + /// // `TryInto` has been added to the Rust prelude in 2021 edition. + /// println!("{}", x); + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// In Rust 2021, one of the important introductions is the [prelude changes], which add + /// `TryFrom` and `TryInto` into the standard library's prelude. Since this results in an + /// amiguity as to which method to call when an existing `try_from` or `try_into` method is + /// called via dot-call syntax. + /// + /// [prelude changes]: https://blog.rust-lang.org/inside-rust/2021/03/04/planning-rust-2021.html#prelude-changes + pub FUTURE_PRELUDE_COLLISION, + Warn, + "detects the usage of trait methods which are ambiguous with traits added to the \ + prelude in future editions", +} diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index fb37c5e9c1ef..8019569ab9bd 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1236,7 +1236,9 @@ symbols! { truncf32, truncf64, try_blocks, + try_from, try_from_trait, + try_into, try_into_trait, try_trait_v2, tt, diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 427102afee10..164b1a4910bc 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -21,7 +21,8 @@ use rustc_middle::ty::subst::Subst; use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TypeFoldable, WithConstness}; -use rustc_span::symbol::Ident; +use rustc_session::lint::builtin::FUTURE_PRELUDE_COLLISION; +use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_trait_selection::traits; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; @@ -198,6 +199,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pick = self.lookup_probe(span, segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?; + if let sym::try_from | sym::try_into = segment.ident.name { + if let probe::PickKind::TraitPick = pick.kind { + if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { + self.tcx.struct_span_lint_hir( + FUTURE_PRELUDE_COLLISION, + call_expr.hir_id, + call_expr.span, + |lint| { + let sp = call_expr.span; + let trait_name = + self.tcx.def_path_str(pick.item.container.assert_trait()); + + let mut lint = lint.build(&format!( + "trait method `{}` will become ambiguous in Rust 2021", + segment.ident.name + )); + + if let Ok(self_expr) = + self.sess().source_map().span_to_snippet(self_expr.span) + { + lint.span_suggestion( + sp, + "disambiguate the associated function", + format!( + "{}::{}({})", + trait_name, segment.ident.name, self_expr, + ), + Applicability::MachineApplicable, + ); + } else { + lint.span_help( + sp, + &format!( + "disambiguate the associated function with `{}::{}(...)`", + trait_name, segment.ident, + ), + ); + } + + lint.emit(); + }, + ); + } + } + } + for import_id in &pick.import_ids { debug!("used_trait_import: {:?}", import_id); Lrc::get_mut(&mut self.typeck_results.borrow_mut().used_trait_imports) From 01bdb8e38a5ba8c0db8ccaaeab66b1edd315aeca Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Wed, 26 May 2021 00:53:30 -0400 Subject: [PATCH 02/37] Disable `future_prelude_collision` for 2021 edition --- compiler/rustc_typeck/src/check/method/mod.rs | 88 ++++++++++--------- 1 file changed, 46 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 164b1a4910bc..ba4635cc1bf4 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -22,6 +22,7 @@ use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TypeFoldable, WithConstness}; use rustc_session::lint::builtin::FUTURE_PRELUDE_COLLISION; +use rustc_span::edition::Edition; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_trait_selection::traits; @@ -199,48 +200,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pick = self.lookup_probe(span, segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?; - if let sym::try_from | sym::try_into = segment.ident.name { - if let probe::PickKind::TraitPick = pick.kind { - if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { - self.tcx.struct_span_lint_hir( - FUTURE_PRELUDE_COLLISION, - call_expr.hir_id, - call_expr.span, - |lint| { - let sp = call_expr.span; - let trait_name = - self.tcx.def_path_str(pick.item.container.assert_trait()); - - let mut lint = lint.build(&format!( - "trait method `{}` will become ambiguous in Rust 2021", - segment.ident.name - )); - - if let Ok(self_expr) = - self.sess().source_map().span_to_snippet(self_expr.span) - { - lint.span_suggestion( - sp, - "disambiguate the associated function", - format!( - "{}::{}({})", - trait_name, segment.ident.name, self_expr, - ), - Applicability::MachineApplicable, - ); - } else { - lint.span_help( - sp, - &format!( - "disambiguate the associated function with `{}::{}(...)`", - trait_name, segment.ident, - ), - ); - } - - lint.emit(); - }, - ); + if span.edition() < Edition::Edition2021 { + if let sym::try_from | sym::try_into = segment.ident.name { + if let probe::PickKind::TraitPick = pick.kind { + if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) + { + self.tcx.struct_span_lint_hir( + FUTURE_PRELUDE_COLLISION, + call_expr.hir_id, + call_expr.span, + |lint| { + let sp = call_expr.span; + let trait_name = + self.tcx.def_path_str(pick.item.container.assert_trait()); + + let mut lint = lint.build(&format!( + "trait method `{}` will become ambiguous in Rust 2021", + segment.ident.name + )); + + if let Ok(self_expr) = + self.sess().source_map().span_to_snippet(self_expr.span) + { + lint.span_suggestion( + sp, + "disambiguate the associated function", + format!( + "{}::{}({})", + trait_name, segment.ident.name, self_expr, + ), + Applicability::MachineApplicable, + ); + } else { + lint.span_help( + sp, + &format!( + "disambiguate the associated function with `{}::{}(...)`", + trait_name, segment.ident, + ), + ); + } + + lint.emit(); + }, + ); + } } } } From a9dc234c436b17896e3109a88c12c093db515666 Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Wed, 26 May 2021 21:52:56 -0400 Subject: [PATCH 03/37] Add docs for FnCtxt::resolve_ufcs --- compiler/rustc_typeck/src/check/method/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index ba4635cc1bf4..d2bd4b0dd32a 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -468,6 +468,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(InferOk { obligations, value: callee }) } + /// Performs "universal function call" lookup. If lookup is successful, it will return the type + /// of definition and the [`DefId`] of the found definition. + /// + /// # Arguments + /// + /// Given a function call like `Foo::bar::(...)`: + /// + /// * `self`: the surrounding `FnCtxt` (!) + /// * `span`: the span of the entire function call + /// * `method_name`: the identifier of the function within the container type (`bar`) + /// * `self_ty`: the type to search within (`Foo`) + /// * `expr_id`: the [`hir::HirId`] of the expression composing the entire call #[instrument(level = "debug", skip(self))] pub fn resolve_ufcs( &self, From 1626e1938ab6378c2b44891a1e4bd73c3f96719c Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Wed, 26 May 2021 23:00:19 -0400 Subject: [PATCH 04/37] Add support for associated functions to `future_prelude_collision` lint --- compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_typeck/src/check/method/mod.rs | 29 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8019569ab9bd..19f55c47d581 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -587,6 +587,7 @@ symbols! { from, from_desugaring, from_generator, + from_iter, from_method, from_output, from_residual, diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index d2bd4b0dd32a..1960e757bad5 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -201,7 +201,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.lookup_probe(span, segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?; if span.edition() < Edition::Edition2021 { - if let sym::try_from | sym::try_into = segment.ident.name { + if let sym::try_into = segment.ident.name { if let probe::PickKind::TraitPick = pick.kind { if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { @@ -526,6 +526,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr_id, ProbeScope::TraitsInScope, )?; + + if span.edition() < Edition::Edition2021 { + if let sym::try_into | sym::try_from | sym::from_iter = method_name.name { + if let probe::PickKind::TraitPick = pick.kind { + if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { + tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| { + let trait_name = tcx.def_path_str(pick.item.container.assert_trait()); + + let mut lint = lint.build(&format!( + "trait method `{}` will become ambiguous in Rust 2021", + method_name.name + )); + + lint.span_suggestion( + span, + "disambiguate the associated function", + format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,), + Applicability::MachineApplicable, + ); + + lint.emit(); + }); + } + } + } + } + debug!("resolve_ufcs: pick={:?}", pick); { let mut typeck_results = self.typeck_results.borrow_mut(); From c341d5b9d7ebf0f2a2000de81fe236ae2f3445b0 Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Wed, 26 May 2021 23:27:24 -0400 Subject: [PATCH 05/37] Improve documentation for `future_prelude_collision` lint --- compiler/rustc_lint_defs/src/builtin.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 168ea713d194..cfa7c160b0ff 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3275,9 +3275,10 @@ declare_lint! { /// ### Explanation /// /// In Rust 2021, one of the important introductions is the [prelude changes], which add - /// `TryFrom` and `TryInto` into the standard library's prelude. Since this results in an - /// amiguity as to which method to call when an existing `try_from` or `try_into` method is - /// called via dot-call syntax. + /// `TryFrom`, `TryInto`, and `FromIterator` into the standard library's prelude. Since this + /// results in an amiguity as to which method/function to call when an existing `try_into` + /// method is called via dot-call syntax or a `try_from`/`from_iter` associated function + /// is called directly on a type. /// /// [prelude changes]: https://blog.rust-lang.org/inside-rust/2021/03/04/planning-rust-2021.html#prelude-changes pub FUTURE_PRELUDE_COLLISION, From 35af38353e928c0d244e9bf0daaeaea8bf064fbf Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Thu, 27 May 2021 00:30:55 -0400 Subject: [PATCH 06/37] Add UI tests for `future_prelude_collision` lint --- compiler/rustc_typeck/src/check/method/mod.rs | 2 +- .../ui/lint/future-prelude-collision.fixed | 57 +++++++++++++++++++ src/test/ui/lint/future-prelude-collision.rs | 57 +++++++++++++++++++ .../ui/lint/future-prelude-collision.stderr | 28 +++++++++ 4 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/lint/future-prelude-collision.fixed create mode 100644 src/test/ui/lint/future-prelude-collision.rs create mode 100644 src/test/ui/lint/future-prelude-collision.stderr diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 1960e757bad5..1d9ee4595d10 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -535,7 +535,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_name = tcx.def_path_str(pick.item.container.assert_trait()); let mut lint = lint.build(&format!( - "trait method `{}` will become ambiguous in Rust 2021", + "trait-associated function `{}` will become ambiguous in Rust 2021", method_name.name )); diff --git a/src/test/ui/lint/future-prelude-collision.fixed b/src/test/ui/lint/future-prelude-collision.fixed new file mode 100644 index 000000000000..06d0bb015383 --- /dev/null +++ b/src/test/ui/lint/future-prelude-collision.fixed @@ -0,0 +1,57 @@ +// run-rustfix +// edition:2018 +// check-pass + +trait TryIntoU32 { + fn try_into(self) -> Result; +} + +impl TryIntoU32 for u8 { + fn try_into(self) -> Result { + Ok(self as u32) + } +} + +trait TryFromU8: Sized { + fn try_from(x: u8) -> Result; +} + +impl TryFromU8 for u32 { + fn try_from(x: u8) -> Result { + Ok(x as u32) + } +} + +trait FromByteIterator { + fn from_iter(iter: T) -> Self + where T: Iterator; +} + +impl FromByteIterator for Vec { + fn from_iter(iter: T) -> Self + where T: Iterator + { + iter.collect() + } +} + +fn main() { + // test dot-call that will break in 2021 edition + let _: u32 = TryIntoU32::try_into(3u8).unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + + // test associated function call that will break in 2021 edition + let _ = ::try_from(3u8).unwrap(); + //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + + // test reverse turbofish too + let _ = as FromByteIterator>::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter()); + //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + + // negative testing lint (this line should *not* emit a warning) + let _: u32 = TryFromU8::try_from(3u8).unwrap(); + + // test type omission + let _: u32 = <_ as TryFromU8>::try_from(3u8).unwrap(); + //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 +} diff --git a/src/test/ui/lint/future-prelude-collision.rs b/src/test/ui/lint/future-prelude-collision.rs new file mode 100644 index 000000000000..61658ac2725d --- /dev/null +++ b/src/test/ui/lint/future-prelude-collision.rs @@ -0,0 +1,57 @@ +// run-rustfix +// edition:2018 +// check-pass + +trait TryIntoU32 { + fn try_into(self) -> Result; +} + +impl TryIntoU32 for u8 { + fn try_into(self) -> Result { + Ok(self as u32) + } +} + +trait TryFromU8: Sized { + fn try_from(x: u8) -> Result; +} + +impl TryFromU8 for u32 { + fn try_from(x: u8) -> Result { + Ok(x as u32) + } +} + +trait FromByteIterator { + fn from_iter(iter: T) -> Self + where T: Iterator; +} + +impl FromByteIterator for Vec { + fn from_iter(iter: T) -> Self + where T: Iterator + { + iter.collect() + } +} + +fn main() { + // test dot-call that will break in 2021 edition + let _: u32 = 3u8.try_into().unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + + // test associated function call that will break in 2021 edition + let _ = u32::try_from(3u8).unwrap(); + //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + + // test reverse turbofish too + let _ = >::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter()); + //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + + // negative testing lint (this line should *not* emit a warning) + let _: u32 = TryFromU8::try_from(3u8).unwrap(); + + // test type omission + let _: u32 = <_>::try_from(3u8).unwrap(); + //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 +} diff --git a/src/test/ui/lint/future-prelude-collision.stderr b/src/test/ui/lint/future-prelude-collision.stderr new file mode 100644 index 000000000000..79f4f1412d2f --- /dev/null +++ b/src/test/ui/lint/future-prelude-collision.stderr @@ -0,0 +1,28 @@ +warning: trait method `try_into` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision.rs:40:18 + | +LL | let _: u32 = 3u8.try_into().unwrap(); + | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)` + | + = note: `#[warn(future_prelude_collision)]` on by default + +warning: trait-associated function `try_from` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision.rs:44:13 + | +LL | let _ = u32::try_from(3u8).unwrap(); + | ^^^^^^^^^^^^^ help: disambiguate the associated function: `::try_from` + +warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision.rs:48:13 + | +LL | let _ = >::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter()); + | ^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as FromByteIterator>::from_iter` + +warning: trait-associated function `try_from` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision.rs:55:18 + | +LL | let _: u32 = <_>::try_from(3u8).unwrap(); + | ^^^^^^^^^^^^^ help: disambiguate the associated function: `<_ as TryFromU8>::try_from` + +warning: 4 warnings emitted + From c41a157b908743812fc179e64654dbe0a65caaca Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Thu, 27 May 2021 00:56:37 -0400 Subject: [PATCH 07/37] Fix incorrect argument description on FnCtxt::resolve_ufcs --- compiler/rustc_typeck/src/check/method/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 1d9ee4595d10..ced08734bcf3 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -469,14 +469,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Performs "universal function call" lookup. If lookup is successful, it will return the type - /// of definition and the [`DefId`] of the found definition. + /// of definition and the [`DefId`] of the found function definition. /// /// # Arguments /// /// Given a function call like `Foo::bar::(...)`: /// /// * `self`: the surrounding `FnCtxt` (!) - /// * `span`: the span of the entire function call + /// * `span`: the span of the call, excluding arguments (`Foo::bar::`) /// * `method_name`: the identifier of the function within the container type (`bar`) /// * `self_ty`: the type to search within (`Foo`) /// * `expr_id`: the [`hir::HirId`] of the expression composing the entire call From 327697a540cfab44c7d9c9c7c62948f8f9667fc5 Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Thu, 27 May 2021 13:28:55 -0400 Subject: [PATCH 08/37] Fix autoderef and autoref for `future_prelude_collision` lint --- compiler/rustc_typeck/src/check/method/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index ced08734bcf3..c04979ed75c8 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -11,6 +11,7 @@ pub use self::CandidateSource::*; pub use self::MethodError::*; use crate::check::FnCtxt; +use rustc_ast::ast::Mutability; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; @@ -222,12 +223,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span) { + let derefs = "*".repeat(pick.autoderefs); + let self_adjusted = match pick.autoref_or_ptr_adjustment { + Some(probe::AutorefOrPtrAdjustment::Autoref { + mutbl: Mutability::Mut, .. + }) => format!("&mut {}{}", derefs, self_expr), + Some(probe::AutorefOrPtrAdjustment::Autoref { + mutbl: Mutability::Not, .. + }) => format!("&{}{}", derefs, self_expr), + Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None + => format!("{}{}", derefs, self_expr), + }; lint.span_suggestion( sp, "disambiguate the associated function", format!( "{}::{}({})", - trait_name, segment.ident.name, self_expr, + trait_name, segment.ident.name, self_adjusted, ), Applicability::MachineApplicable, ); From eb5e0af3a990747174fb8ee84fbfe52e57f00ecf Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Thu, 27 May 2021 13:38:06 -0400 Subject: [PATCH 09/37] Add autoderef and autoref tests for `future_prelude_collision` lint --- .../ui/lint/future-prelude-collision.fixed | 15 +++++++++++++ src/test/ui/lint/future-prelude-collision.rs | 15 +++++++++++++ .../ui/lint/future-prelude-collision.stderr | 22 ++++++++++++++----- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/test/ui/lint/future-prelude-collision.fixed b/src/test/ui/lint/future-prelude-collision.fixed index 06d0bb015383..6858616adde1 100644 --- a/src/test/ui/lint/future-prelude-collision.fixed +++ b/src/test/ui/lint/future-prelude-collision.fixed @@ -12,6 +12,13 @@ impl TryIntoU32 for u8 { } } +// needed for autoref test +impl TryIntoU32 for &f32 { + fn try_into(self) -> Result { + Ok(*self as u32) + } +} + trait TryFromU8: Sized { fn try_from(x: u8) -> Result; } @@ -54,4 +61,12 @@ fn main() { // test type omission let _: u32 = <_ as TryFromU8>::try_from(3u8).unwrap(); //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + + // test autoderef + let _: u32 = TryIntoU32::try_into(*(&3u8)).unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + + // test autoref + let _: u32 = TryIntoU32::try_into(&3.0).unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 } diff --git a/src/test/ui/lint/future-prelude-collision.rs b/src/test/ui/lint/future-prelude-collision.rs index 61658ac2725d..ba02757ab327 100644 --- a/src/test/ui/lint/future-prelude-collision.rs +++ b/src/test/ui/lint/future-prelude-collision.rs @@ -12,6 +12,13 @@ impl TryIntoU32 for u8 { } } +// needed for autoref test +impl TryIntoU32 for &f32 { + fn try_into(self) -> Result { + Ok(*self as u32) + } +} + trait TryFromU8: Sized { fn try_from(x: u8) -> Result; } @@ -54,4 +61,12 @@ fn main() { // test type omission let _: u32 = <_>::try_from(3u8).unwrap(); //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + + // test autoderef + let _: u32 = (&3u8).try_into().unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + + // test autoref + let _: u32 = 3.0.try_into().unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 } diff --git a/src/test/ui/lint/future-prelude-collision.stderr b/src/test/ui/lint/future-prelude-collision.stderr index 79f4f1412d2f..3a3c04a093d8 100644 --- a/src/test/ui/lint/future-prelude-collision.stderr +++ b/src/test/ui/lint/future-prelude-collision.stderr @@ -1,5 +1,5 @@ warning: trait method `try_into` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:40:18 + --> $DIR/future-prelude-collision.rs:47:18 | LL | let _: u32 = 3u8.try_into().unwrap(); | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)` @@ -7,22 +7,34 @@ LL | let _: u32 = 3u8.try_into().unwrap(); = note: `#[warn(future_prelude_collision)]` on by default warning: trait-associated function `try_from` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:44:13 + --> $DIR/future-prelude-collision.rs:51:13 | LL | let _ = u32::try_from(3u8).unwrap(); | ^^^^^^^^^^^^^ help: disambiguate the associated function: `::try_from` warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:48:13 + --> $DIR/future-prelude-collision.rs:55:13 | LL | let _ = >::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter()); | ^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as FromByteIterator>::from_iter` warning: trait-associated function `try_from` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:55:18 + --> $DIR/future-prelude-collision.rs:62:18 | LL | let _: u32 = <_>::try_from(3u8).unwrap(); | ^^^^^^^^^^^^^ help: disambiguate the associated function: `<_ as TryFromU8>::try_from` -warning: 4 warnings emitted +warning: trait method `try_into` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision.rs:66:18 + | +LL | let _: u32 = (&3u8).try_into().unwrap(); + | ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(*(&3u8))` + +warning: trait method `try_into` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision.rs:70:18 + | +LL | let _: u32 = 3.0.try_into().unwrap(); + | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(&3.0)` + +warning: 6 warnings emitted From 93c60f26bfe5a6ae07774fb9aa03f3cacd48bae4 Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Thu, 27 May 2021 14:54:16 -0400 Subject: [PATCH 10/37] Fix missing generic parameters from `future_prelude_collision` lint suggestion --- compiler/rustc_typeck/src/check/method/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index c04979ed75c8..9497f939b3d2 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -544,7 +544,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let probe::PickKind::TraitPick = pick.kind { if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| { - let trait_name = tcx.def_path_str(pick.item.container.assert_trait()); + let trait_def_id = pick.item.container.assert_trait(); + let trait_generics = tcx.generics_of(trait_def_id); + let parameter_count = trait_generics.count() - (trait_generics.has_self as usize); + + let trait_name = if parameter_count == 0 { + tcx.def_path_str(trait_def_id) + } else { + format!( + "{}<{}>", + tcx.def_path_str(trait_def_id), + std::iter::repeat("_").take(parameter_count).collect::>().join(", ") + ) + }; let mut lint = lint.build(&format!( "trait-associated function `{}` will become ambiguous in Rust 2021", From cb4999242d4921988b371dc62e40c877e7097a1f Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Thu, 27 May 2021 22:29:22 -0400 Subject: [PATCH 11/37] Fix `future_prelude_collision` lint breaking for pointer mutabilty coercion --- compiler/rustc_typeck/src/check/method/mod.rs | 193 ++++++++++-------- .../ui/lint/future-prelude-collision.fixed | 11 + src/test/ui/lint/future-prelude-collision.rs | 11 + .../ui/lint/future-prelude-collision.stderr | 20 +- 4 files changed, 144 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 9497f939b3d2..a1383fc4af0a 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -203,60 +203,81 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if span.edition() < Edition::Edition2021 { if let sym::try_into = segment.ident.name { - if let probe::PickKind::TraitPick = pick.kind { - if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) - { - self.tcx.struct_span_lint_hir( - FUTURE_PRELUDE_COLLISION, - call_expr.hir_id, - call_expr.span, - |lint| { - let sp = call_expr.span; - let trait_name = - self.tcx.def_path_str(pick.item.container.assert_trait()); - - let mut lint = lint.build(&format!( - "trait method `{}` will become ambiguous in Rust 2021", - segment.ident.name - )); - - if let Ok(self_expr) = - self.sess().source_map().span_to_snippet(self_expr.span) - { - let derefs = "*".repeat(pick.autoderefs); - let self_adjusted = match pick.autoref_or_ptr_adjustment { - Some(probe::AutorefOrPtrAdjustment::Autoref { - mutbl: Mutability::Mut, .. - }) => format!("&mut {}{}", derefs, self_expr), - Some(probe::AutorefOrPtrAdjustment::Autoref { - mutbl: Mutability::Not, .. - }) => format!("&{}{}", derefs, self_expr), - Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None - => format!("{}{}", derefs, self_expr), + if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { + self.tcx.struct_span_lint_hir( + FUTURE_PRELUDE_COLLISION, + call_expr.hir_id, + call_expr.span, + |lint| { + let sp = call_expr.span; + let type_name = self.tcx.def_path_str(pick.item.container.id()); + let type_generics = self.tcx.generics_of(pick.item.container.id()); + let parameter_count = + type_generics.count() - (type_generics.has_self as usize); + let trait_name = if parameter_count == 0 { + type_name + } else { + format!( + "{}<{}>", + type_name, + std::iter::repeat("_") + .take(parameter_count) + .collect::>() + .join(", ") + ) + }; + + let mut lint = lint.build(&format!( + "trait method `{}` will become ambiguous in Rust 2021", + segment.ident.name + )); + + if let Ok(self_expr) = + self.sess().source_map().span_to_snippet(self_expr.span) + { + let derefs = "*".repeat(pick.autoderefs); + + let autoref = match pick.autoref_or_ptr_adjustment { + Some(probe::AutorefOrPtrAdjustment::Autoref { + mutbl: Mutability::Mut, + .. + }) => "&mut ", + Some(probe::AutorefOrPtrAdjustment::Autoref { + mutbl: Mutability::Not, + .. + }) => "&", + Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "", + }; + let self_adjusted = + if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) = + pick.autoref_or_ptr_adjustment + { + format!("{}{} as *const _", derefs, self_expr) + } else { + format!("{}{}{}", autoref, derefs, self_expr) }; - lint.span_suggestion( - sp, - "disambiguate the associated function", - format!( - "{}::{}({})", - trait_name, segment.ident.name, self_adjusted, - ), - Applicability::MachineApplicable, - ); - } else { - lint.span_help( - sp, - &format!( - "disambiguate the associated function with `{}::{}(...)`", - trait_name, segment.ident, - ), - ); - } - - lint.emit(); - }, - ); - } + lint.span_suggestion( + sp, + "disambiguate the associated function", + format!( + "{}::{}({})", + trait_name, segment.ident.name, self_adjusted, + ), + Applicability::MachineApplicable, + ); + } else { + lint.span_help( + sp, + &format!( + "disambiguate the associated function with `{}::{}(...)`", + trait_name, segment.ident, + ), + ); + } + + lint.emit(); + }, + ); } } } @@ -541,38 +562,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if span.edition() < Edition::Edition2021 { if let sym::try_into | sym::try_from | sym::from_iter = method_name.name { - if let probe::PickKind::TraitPick = pick.kind { - if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { - tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| { - let trait_def_id = pick.item.container.assert_trait(); - let trait_generics = tcx.generics_of(trait_def_id); - let parameter_count = trait_generics.count() - (trait_generics.has_self as usize); - - let trait_name = if parameter_count == 0 { - tcx.def_path_str(trait_def_id) - } else { - format!( - "{}<{}>", - tcx.def_path_str(trait_def_id), - std::iter::repeat("_").take(parameter_count).collect::>().join(", ") - ) - }; - - let mut lint = lint.build(&format!( - "trait-associated function `{}` will become ambiguous in Rust 2021", - method_name.name - )); - - lint.span_suggestion( - span, - "disambiguate the associated function", - format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,), - Applicability::MachineApplicable, - ); + if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { + tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| { + // "type" refers to either a type or, more likely, a trait from which + // the associated function or method is from. + let type_name = tcx.def_path_str(pick.item.container.id()); + let type_generics = tcx.generics_of(pick.item.container.id()); + + let parameter_count = + type_generics.count() - (type_generics.has_self as usize); + let trait_name = if parameter_count == 0 { + type_name + } else { + format!( + "{}<{}>", + type_name, + std::iter::repeat("_") + .take(parameter_count) + .collect::>() + .join(", ") + ) + }; + + let mut lint = lint.build(&format!( + "trait-associated function `{}` will become ambiguous in Rust 2021", + method_name.name + )); + + lint.span_suggestion( + span, + "disambiguate the associated function", + format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,), + Applicability::MachineApplicable, + ); - lint.emit(); - }); - } + lint.emit(); + }); } } } diff --git a/src/test/ui/lint/future-prelude-collision.fixed b/src/test/ui/lint/future-prelude-collision.fixed index 6858616adde1..2a0f74edc09a 100644 --- a/src/test/ui/lint/future-prelude-collision.fixed +++ b/src/test/ui/lint/future-prelude-collision.fixed @@ -29,6 +29,12 @@ impl TryFromU8 for u32 { } } +impl TryIntoU32 for *const u16 { + fn try_into(self) -> Result { + Ok(unsafe { *self } as u32) + } +} + trait FromByteIterator { fn from_iter(iter: T) -> Self where T: Iterator; @@ -69,4 +75,9 @@ fn main() { // test autoref let _: u32 = TryIntoU32::try_into(&3.0).unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + + let mut data = 3u16; + let mut_ptr = std::ptr::addr_of_mut!(data); + let _: u32 = TryIntoU32::try_into(mut_ptr as *const _).unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 } diff --git a/src/test/ui/lint/future-prelude-collision.rs b/src/test/ui/lint/future-prelude-collision.rs index ba02757ab327..9a38bc065bf6 100644 --- a/src/test/ui/lint/future-prelude-collision.rs +++ b/src/test/ui/lint/future-prelude-collision.rs @@ -29,6 +29,12 @@ impl TryFromU8 for u32 { } } +impl TryIntoU32 for *const u16 { + fn try_into(self) -> Result { + Ok(unsafe { *self } as u32) + } +} + trait FromByteIterator { fn from_iter(iter: T) -> Self where T: Iterator; @@ -69,4 +75,9 @@ fn main() { // test autoref let _: u32 = 3.0.try_into().unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + + let mut data = 3u16; + let mut_ptr = std::ptr::addr_of_mut!(data); + let _: u32 = mut_ptr.try_into().unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 } diff --git a/src/test/ui/lint/future-prelude-collision.stderr b/src/test/ui/lint/future-prelude-collision.stderr index 3a3c04a093d8..13c8b8afddfb 100644 --- a/src/test/ui/lint/future-prelude-collision.stderr +++ b/src/test/ui/lint/future-prelude-collision.stderr @@ -1,5 +1,5 @@ warning: trait method `try_into` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:47:18 + --> $DIR/future-prelude-collision.rs:53:18 | LL | let _: u32 = 3u8.try_into().unwrap(); | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)` @@ -7,34 +7,40 @@ LL | let _: u32 = 3u8.try_into().unwrap(); = note: `#[warn(future_prelude_collision)]` on by default warning: trait-associated function `try_from` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:51:13 + --> $DIR/future-prelude-collision.rs:57:13 | LL | let _ = u32::try_from(3u8).unwrap(); | ^^^^^^^^^^^^^ help: disambiguate the associated function: `::try_from` warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:55:13 + --> $DIR/future-prelude-collision.rs:61:13 | LL | let _ = >::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter()); | ^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as FromByteIterator>::from_iter` warning: trait-associated function `try_from` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:62:18 + --> $DIR/future-prelude-collision.rs:68:18 | LL | let _: u32 = <_>::try_from(3u8).unwrap(); | ^^^^^^^^^^^^^ help: disambiguate the associated function: `<_ as TryFromU8>::try_from` warning: trait method `try_into` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:66:18 + --> $DIR/future-prelude-collision.rs:72:18 | LL | let _: u32 = (&3u8).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(*(&3u8))` warning: trait method `try_into` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:70:18 + --> $DIR/future-prelude-collision.rs:76:18 | LL | let _: u32 = 3.0.try_into().unwrap(); | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(&3.0)` -warning: 6 warnings emitted +warning: trait method `try_into` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision.rs:81:18 + | +LL | let _: u32 = mut_ptr.try_into().unwrap(); + | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(mut_ptr as *const _)` + +warning: 7 warnings emitted From 4a21a0bebc0493c963525d827c34e62a726be249 Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Thu, 27 May 2021 23:39:07 -0400 Subject: [PATCH 12/37] Fix `future_prelude_collision` not maintaining type aliases --- compiler/rustc_typeck/src/check/expr.rs | 3 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 49 +++++++++++-------- compiler/rustc_typeck/src/check/method/mod.rs | 28 ++++++++--- compiler/rustc_typeck/src/check/pat.rs | 7 ++- .../ui/lint/future-prelude-collision.fixed | 4 ++ src/test/ui/lint/future-prelude-collision.rs | 4 ++ .../ui/lint/future-prelude-collision.stderr | 8 ++- 7 files changed, 71 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index d0cbb58fb10e..e6a2c5d5d14d 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -466,7 +466,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; - let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span); + let (res, opt_ty, segs) = + self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span); let ty = match res { Res::Err => { self.set_tainted_by_errors(); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 96569ae0e772..8e33f4f9e12f 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -906,13 +906,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Resolves an associated value path into a base type and associated constant, or method /// resolution. The newly resolved definition is written into `type_dependent_defs`. - pub fn resolve_ty_and_res_ufcs( + pub fn resolve_ty_and_res_fully_qualified_call( &self, qpath: &'tcx QPath<'tcx>, hir_id: hir::HirId, span: Span, ) -> (Res, Option>, &'tcx [hir::PathSegment<'tcx>]) { - debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span); + debug!( + "resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}", + qpath, hir_id, span + ); let (ty, qself, item_segment) = match *qpath { QPath::Resolved(ref opt_qself, ref path) => { return ( @@ -922,7 +925,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment), - QPath::LangItem(..) => bug!("`resolve_ty_and_res_ufcs` called on `LangItem`"), + QPath::LangItem(..) => { + bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`") + } }; if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id) { @@ -932,25 +937,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return (def, Some(ty), slice::from_ref(&**item_segment)); } let item_name = item_segment.ident; - let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| { - let result = match error { - method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)), - _ => Err(ErrorReported), - }; - if item_name.name != kw::Empty { - if let Some(mut e) = self.report_method_error( - span, - ty, - item_name, - SelfSource::QPath(qself), - error, - None, - ) { - e.emit(); + let result = self + .resolve_fully_qualified_call(span, item_name, ty, qself.span, hir_id) + .or_else(|error| { + let result = match error { + method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)), + _ => Err(ErrorReported), + }; + if item_name.name != kw::Empty { + if let Some(mut e) = self.report_method_error( + span, + ty, + item_name, + SelfSource::QPath(qself), + error, + None, + ) { + e.emit(); + } } - } - result - }); + result + }); if result.is_ok() { self.maybe_lint_bare_trait(qpath, hir_id); diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index a1383fc4af0a..2198455c1634 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -501,8 +501,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Some(InferOk { obligations, value: callee }) } - /// Performs "universal function call" lookup. If lookup is successful, it will return the type - /// of definition and the [`DefId`] of the found function definition. + /// Performs a [full-qualified function call] (formerly "universal function call") lookup. If + /// lookup is successful, it will return the type of definition and the [`DefId`] of the found + /// function definition. + /// + /// [full-qualified function call]: https://doc.rust-lang.org/reference/expressions/call-expr.html#disambiguating-function-calls /// /// # Arguments /// @@ -512,17 +515,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// * `span`: the span of the call, excluding arguments (`Foo::bar::`) /// * `method_name`: the identifier of the function within the container type (`bar`) /// * `self_ty`: the type to search within (`Foo`) + /// * `self_ty_span` the span for the type being searched within (span of `Foo`) /// * `expr_id`: the [`hir::HirId`] of the expression composing the entire call #[instrument(level = "debug", skip(self))] - pub fn resolve_ufcs( + pub fn resolve_fully_qualified_call( &self, span: Span, method_name: Ident, self_ty: Ty<'tcx>, + self_ty_span: Span, expr_id: hir::HirId, ) -> Result<(DefKind, DefId), MethodError<'tcx>> { debug!( - "resolve_ufcs: method_name={:?} self_ty={:?} expr_id={:?}", + "resolve_fully_qualified_call: method_name={:?} self_ty={:?} expr_id={:?}", method_name, self_ty, expr_id, ); @@ -589,6 +594,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method_name.name )); + let self_ty = self + .sess() + .source_map() + .span_to_snippet(self_ty_span) + .unwrap_or_else(|_| self_ty.to_string()); + lint.span_suggestion( span, "disambiguate the associated function", @@ -602,18 +613,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - debug!("resolve_ufcs: pick={:?}", pick); + debug!("resolve_fully_qualified_call: pick={:?}", pick); { let mut typeck_results = self.typeck_results.borrow_mut(); let used_trait_imports = Lrc::get_mut(&mut typeck_results.used_trait_imports).unwrap(); for import_id in pick.import_ids { - debug!("resolve_ufcs: used_trait_import: {:?}", import_id); + debug!("resolve_fully_qualified_call: used_trait_import: {:?}", import_id); used_trait_imports.insert(import_id); } } let def_kind = pick.item.kind.as_def_kind(); - debug!("resolve_ufcs: def_kind={:?}, def_id={:?}", def_kind, pick.item.def_id); + debug!( + "resolve_fully_qualified_call: def_kind={:?}, def_id={:?}", + def_kind, pick.item.def_id + ); tcx.check_stability(pick.item.def_id, Some(expr_id), span, Some(method_name.span)); Ok((def_kind, pick.item.def_id)) } diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 3ac760e23634..2879614d0c80 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -160,7 +160,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ti: TopInfo<'tcx>, ) { let path_res = match &pat.kind { - PatKind::Path(qpath) => Some(self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span)), + PatKind::Path(qpath) => { + Some(self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span)) + } _ => None, }; let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res)); @@ -904,7 +906,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Resolve the path and check the definition for errors. - let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span); + let (res, opt_ty, segments) = + self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span); if res == Res::Err { self.set_tainted_by_errors(); on_error(); diff --git a/src/test/ui/lint/future-prelude-collision.fixed b/src/test/ui/lint/future-prelude-collision.fixed index 2a0f74edc09a..922c0d54a007 100644 --- a/src/test/ui/lint/future-prelude-collision.fixed +++ b/src/test/ui/lint/future-prelude-collision.fixed @@ -80,4 +80,8 @@ fn main() { let mut_ptr = std::ptr::addr_of_mut!(data); let _: u32 = TryIntoU32::try_into(mut_ptr as *const _).unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + + type U32Alias = u32; + let _ = ::try_from(3u8).unwrap(); + //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 } diff --git a/src/test/ui/lint/future-prelude-collision.rs b/src/test/ui/lint/future-prelude-collision.rs index 9a38bc065bf6..154dde16d9e9 100644 --- a/src/test/ui/lint/future-prelude-collision.rs +++ b/src/test/ui/lint/future-prelude-collision.rs @@ -80,4 +80,8 @@ fn main() { let mut_ptr = std::ptr::addr_of_mut!(data); let _: u32 = mut_ptr.try_into().unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + + type U32Alias = u32; + let _ = U32Alias::try_from(3u8).unwrap(); + //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 } diff --git a/src/test/ui/lint/future-prelude-collision.stderr b/src/test/ui/lint/future-prelude-collision.stderr index 13c8b8afddfb..9c92074c36f5 100644 --- a/src/test/ui/lint/future-prelude-collision.stderr +++ b/src/test/ui/lint/future-prelude-collision.stderr @@ -42,5 +42,11 @@ warning: trait method `try_into` will become ambiguous in Rust 2021 LL | let _: u32 = mut_ptr.try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(mut_ptr as *const _)` -warning: 7 warnings emitted +warning: trait-associated function `try_from` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision.rs:85:13 + | +LL | let _ = U32Alias::try_from(3u8).unwrap(); + | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `::try_from` + +warning: 8 warnings emitted From 64c61a32f6051fe769928b09bfb6e829b74d6f5e Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Fri, 28 May 2021 00:55:32 -0400 Subject: [PATCH 13/37] Fix `future_prelude_collision` adding unneeded generic arguments --- compiler/rustc_typeck/src/check/method/mod.rs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 2198455c1634..4a855d6e4083 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -210,22 +210,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_expr.span, |lint| { let sp = call_expr.span; - let type_name = self.tcx.def_path_str(pick.item.container.id()); - let type_generics = self.tcx.generics_of(pick.item.container.id()); - let parameter_count = - type_generics.count() - (type_generics.has_self as usize); - let trait_name = if parameter_count == 0 { - type_name - } else { - format!( - "{}<{}>", - type_name, - std::iter::repeat("_") - .take(parameter_count) - .collect::>() - .join(", ") - ) - }; + let trait_name = self.tcx.def_path_str(pick.item.container.id()); let mut lint = lint.build(&format!( "trait method `{}` will become ambiguous in Rust 2021", From 32408cf0d9cf997d6665ae7cff1b9f9c3c034832 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 4 Jun 2021 15:07:51 -0400 Subject: [PATCH 14/37] move test to rust-2021 directory --- src/test/ui/{lint => rust-2021}/future-prelude-collision.fixed | 0 src/test/ui/{lint => rust-2021}/future-prelude-collision.rs | 0 src/test/ui/{lint => rust-2021}/future-prelude-collision.stderr | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/{lint => rust-2021}/future-prelude-collision.fixed (100%) rename src/test/ui/{lint => rust-2021}/future-prelude-collision.rs (100%) rename src/test/ui/{lint => rust-2021}/future-prelude-collision.stderr (100%) diff --git a/src/test/ui/lint/future-prelude-collision.fixed b/src/test/ui/rust-2021/future-prelude-collision.fixed similarity index 100% rename from src/test/ui/lint/future-prelude-collision.fixed rename to src/test/ui/rust-2021/future-prelude-collision.fixed diff --git a/src/test/ui/lint/future-prelude-collision.rs b/src/test/ui/rust-2021/future-prelude-collision.rs similarity index 100% rename from src/test/ui/lint/future-prelude-collision.rs rename to src/test/ui/rust-2021/future-prelude-collision.rs diff --git a/src/test/ui/lint/future-prelude-collision.stderr b/src/test/ui/rust-2021/future-prelude-collision.stderr similarity index 100% rename from src/test/ui/lint/future-prelude-collision.stderr rename to src/test/ui/rust-2021/future-prelude-collision.stderr From 19ba219e99f2f78fea290716759aa1856172332f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 4 Jun 2021 15:31:18 -0400 Subject: [PATCH 15/37] add inherent-method-collision test --- .../ui/rust-2021/inherent-method-collision.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/rust-2021/inherent-method-collision.rs diff --git a/src/test/ui/rust-2021/inherent-method-collision.rs b/src/test/ui/rust-2021/inherent-method-collision.rs new file mode 100644 index 000000000000..c638351d5fc0 --- /dev/null +++ b/src/test/ui/rust-2021/inherent-method-collision.rs @@ -0,0 +1,15 @@ +// Test that we do NOT warn for inherent methods invoked via `T::` form. +// +// check-pass + +#![deny(future_prelude_collision)] + +pub struct MySeq {} + +impl MySeq { + pub fn from_iter(_: impl IntoIterator) {} +} + +fn main() { + MySeq::from_iter(Some(22)); +} From 8d42f3da6358e80c0f13dc057152e04b7283def8 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 14 Jun 2021 13:17:15 -0400 Subject: [PATCH 16/37] don't warn for fully qual inherent methods But do continue to warn for trait methods. --- compiler/rustc_typeck/src/check/method/mod.rs | 10 +++++++++- .../ui/rust-2021/generic-type-collision.fixed | 16 ++++++++++++++++ src/test/ui/rust-2021/generic-type-collision.rs | 16 ++++++++++++++++ .../ui/rust-2021/generic-type-collision.stderr | 10 ++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/rust-2021/generic-type-collision.fixed create mode 100644 src/test/ui/rust-2021/generic-type-collision.rs create mode 100644 src/test/ui/rust-2021/generic-type-collision.stderr diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 4a855d6e4083..f321d62edf6d 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -10,6 +10,7 @@ pub use self::suggest::{SelfSource, TraitInfo}; pub use self::CandidateSource::*; pub use self::MethodError::*; +use crate::check::method::probe::PickKind; use crate::check::FnCtxt; use rustc_ast::ast::Mutability; use rustc_data_structures::sync::Lrc; @@ -552,7 +553,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if span.edition() < Edition::Edition2021 { if let sym::try_into | sym::try_from | sym::from_iter = method_name.name { - if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { + // No need to warn if either: + // + // * The method comes from std/core, since ten it's the built-in trait. + // * This is an inherent method called on a specific type, like `Vec::foo(...)`, + // since such methods take precedence over trait methods. + if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) + && !matches!(pick.kind, PickKind::InherentImplPick) + { tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| { // "type" refers to either a type or, more likely, a trait from which // the associated function or method is from. diff --git a/src/test/ui/rust-2021/generic-type-collision.fixed b/src/test/ui/rust-2021/generic-type-collision.fixed new file mode 100644 index 000000000000..1ae2b95d515d --- /dev/null +++ b/src/test/ui/rust-2021/generic-type-collision.fixed @@ -0,0 +1,16 @@ +// check-pass +// run-rustfix +// edition 2018 + +trait MyTrait { + fn from_iter(x: Option); +} + +impl MyTrait<()> for Vec { + fn from_iter(_: Option<()>) {} +} + +fn main() { + as MyTrait<_>>::from_iter(None); + //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 +} diff --git a/src/test/ui/rust-2021/generic-type-collision.rs b/src/test/ui/rust-2021/generic-type-collision.rs new file mode 100644 index 000000000000..e203656163c6 --- /dev/null +++ b/src/test/ui/rust-2021/generic-type-collision.rs @@ -0,0 +1,16 @@ +// check-pass +// run-rustfix +// edition 2018 + +trait MyTrait { + fn from_iter(x: Option); +} + +impl MyTrait<()> for Vec { + fn from_iter(_: Option<()>) {} +} + +fn main() { + >::from_iter(None); + //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 +} diff --git a/src/test/ui/rust-2021/generic-type-collision.stderr b/src/test/ui/rust-2021/generic-type-collision.stderr new file mode 100644 index 000000000000..3acc6185a61b --- /dev/null +++ b/src/test/ui/rust-2021/generic-type-collision.stderr @@ -0,0 +1,10 @@ +warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 + --> $DIR/generic-type-collision.rs:14:5 + | +LL | >::from_iter(None); + | ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as MyTrait<_>>::from_iter` + | + = note: `#[warn(future_prelude_collision)]` on by default + +warning: 1 warning emitted + From 17ab9c0ff985dfa31235bcfd44b57ef15610e9b9 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 14 Jun 2021 13:43:58 -0400 Subject: [PATCH 17/37] extract Rust 2021 prelude logic to its own module --- compiler/rustc_typeck/src/check/method/mod.rs | 135 ++------------ .../src/check/method/prelude2021.rs | 167 ++++++++++++++++++ 2 files changed, 178 insertions(+), 124 deletions(-) create mode 100644 compiler/rustc_typeck/src/check/method/prelude2021.rs diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index f321d62edf6d..e956637dec1d 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -3,6 +3,7 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/method-lookup.html mod confirm; +mod prelude2021; pub mod probe; mod suggest; @@ -10,9 +11,7 @@ pub use self::suggest::{SelfSource, TraitInfo}; pub use self::CandidateSource::*; pub use self::MethodError::*; -use crate::check::method::probe::PickKind; use crate::check::FnCtxt; -use rustc_ast::ast::Mutability; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; @@ -23,9 +22,7 @@ use rustc_middle::ty::subst::Subst; use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TypeFoldable, WithConstness}; -use rustc_session::lint::builtin::FUTURE_PRELUDE_COLLISION; -use rustc_span::edition::Edition; -use rustc_span::symbol::{sym, Ident}; +use rustc_span::symbol::Ident; use rustc_span::Span; use rustc_trait_selection::traits; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; @@ -202,71 +199,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pick = self.lookup_probe(span, segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?; - if span.edition() < Edition::Edition2021 { - if let sym::try_into = segment.ident.name { - if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { - self.tcx.struct_span_lint_hir( - FUTURE_PRELUDE_COLLISION, - call_expr.hir_id, - call_expr.span, - |lint| { - let sp = call_expr.span; - let trait_name = self.tcx.def_path_str(pick.item.container.id()); - - let mut lint = lint.build(&format!( - "trait method `{}` will become ambiguous in Rust 2021", - segment.ident.name - )); - - if let Ok(self_expr) = - self.sess().source_map().span_to_snippet(self_expr.span) - { - let derefs = "*".repeat(pick.autoderefs); - - let autoref = match pick.autoref_or_ptr_adjustment { - Some(probe::AutorefOrPtrAdjustment::Autoref { - mutbl: Mutability::Mut, - .. - }) => "&mut ", - Some(probe::AutorefOrPtrAdjustment::Autoref { - mutbl: Mutability::Not, - .. - }) => "&", - Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "", - }; - let self_adjusted = - if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) = - pick.autoref_or_ptr_adjustment - { - format!("{}{} as *const _", derefs, self_expr) - } else { - format!("{}{}{}", autoref, derefs, self_expr) - }; - lint.span_suggestion( - sp, - "disambiguate the associated function", - format!( - "{}::{}({})", - trait_name, segment.ident.name, self_adjusted, - ), - Applicability::MachineApplicable, - ); - } else { - lint.span_help( - sp, - &format!( - "disambiguate the associated function with `{}::{}(...)`", - trait_name, segment.ident, - ), - ); - } - - lint.emit(); - }, - ); - } - } - } + self.lint_dot_call_from_2018(self_ty, segment, span, call_expr, self_expr, &pick); for import_id in &pick.import_ids { debug!("used_trait_import: {:?}", import_id); @@ -551,60 +484,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ProbeScope::TraitsInScope, )?; - if span.edition() < Edition::Edition2021 { - if let sym::try_into | sym::try_from | sym::from_iter = method_name.name { - // No need to warn if either: - // - // * The method comes from std/core, since ten it's the built-in trait. - // * This is an inherent method called on a specific type, like `Vec::foo(...)`, - // since such methods take precedence over trait methods. - if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) - && !matches!(pick.kind, PickKind::InherentImplPick) - { - tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| { - // "type" refers to either a type or, more likely, a trait from which - // the associated function or method is from. - let type_name = tcx.def_path_str(pick.item.container.id()); - let type_generics = tcx.generics_of(pick.item.container.id()); - - let parameter_count = - type_generics.count() - (type_generics.has_self as usize); - let trait_name = if parameter_count == 0 { - type_name - } else { - format!( - "{}<{}>", - type_name, - std::iter::repeat("_") - .take(parameter_count) - .collect::>() - .join(", ") - ) - }; - - let mut lint = lint.build(&format!( - "trait-associated function `{}` will become ambiguous in Rust 2021", - method_name.name - )); - - let self_ty = self - .sess() - .source_map() - .span_to_snippet(self_ty_span) - .unwrap_or_else(|_| self_ty.to_string()); - - lint.span_suggestion( - span, - "disambiguate the associated function", - format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,), - Applicability::MachineApplicable, - ); - - lint.emit(); - }); - } - } - } + self.lint_fully_qualified_call_from_2018( + span, + method_name, + self_ty, + self_ty_span, + expr_id, + &pick, + ); debug!("resolve_fully_qualified_call: pick={:?}", pick); { diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs new file mode 100644 index 000000000000..b141a4f6f89d --- /dev/null +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -0,0 +1,167 @@ +use rustc_ast::Mutability; +use rustc_errors::Applicability; +use rustc_hir as hir; +use rustc_middle::ty::Ty; +use rustc_session::lint::builtin::FUTURE_PRELUDE_COLLISION; +use rustc_span::symbol::{sym, Ident}; +use rustc_span::Span; + +use crate::check::{ + method::probe::{self, Pick}, + FnCtxt, +}; + +impl<'a, 'tcx> FnCtxt<'a, 'tcx> { + pub(super) fn lint_dot_call_from_2018( + &self, + self_ty: Ty<'tcx>, + segment: &hir::PathSegment<'_>, + span: Span, + call_expr: &'tcx hir::Expr<'tcx>, + self_expr: &'tcx hir::Expr<'tcx>, + pick: &Pick<'tcx>, + ) { + debug!( + "lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})", + segment.ident, self_ty, call_expr, self_expr + ); + + // Rust 2021 and later is already using the new prelude + if span.rust_2021() { + return; + } + + // These are the method names that were added to prelude in Rust 2021 + if !matches!(segment.ident.name, sym::try_into) { + return; + } + + // No need to lint if method came from std/core, as that will now be in the prelude + if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { + return; + } + + self.tcx.struct_span_lint_hir( + FUTURE_PRELUDE_COLLISION, + call_expr.hir_id, + call_expr.span, + |lint| { + let sp = call_expr.span; + let trait_name = self.tcx.def_path_str(pick.item.container.id()); + + let mut lint = lint.build(&format!( + "trait method `{}` will become ambiguous in Rust 2021", + segment.ident.name + )); + + if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span) { + let derefs = "*".repeat(pick.autoderefs); + + let autoref = match pick.autoref_or_ptr_adjustment { + Some(probe::AutorefOrPtrAdjustment::Autoref { + mutbl: Mutability::Mut, + .. + }) => "&mut ", + Some(probe::AutorefOrPtrAdjustment::Autoref { + mutbl: Mutability::Not, + .. + }) => "&", + Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "", + }; + let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) = + pick.autoref_or_ptr_adjustment + { + format!("{}{} as *const _", derefs, self_expr) + } else { + format!("{}{}{}", autoref, derefs, self_expr) + }; + lint.span_suggestion( + sp, + "disambiguate the associated function", + format!("{}::{}({})", trait_name, segment.ident.name, self_adjusted,), + Applicability::MachineApplicable, + ); + } else { + lint.span_help( + sp, + &format!( + "disambiguate the associated function with `{}::{}(...)`", + trait_name, segment.ident, + ), + ); + } + + lint.emit(); + }, + ); + } + + pub(super) fn lint_fully_qualified_call_from_2018( + &self, + span: Span, + method_name: Ident, + self_ty: Ty<'tcx>, + self_ty_span: Span, + expr_id: hir::HirId, + pick: &Pick<'tcx>, + ) { + // Rust 2021 and later is already using the new prelude + if span.rust_2021() { + return; + } + + // These are the fully qualified methods added to prelude in Rust 2021 + if !matches!(method_name.name, sym::try_into | sym::try_from | sym::from_iter) { + return; + } + + // No need to lint if method came from std/core, as that will now be in the prelude + if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) { + return; + } + + // No need to lint if this is an inherent method called on a specific type, like `Vec::foo(...)`, + // since such methods take precedence over trait methods. + if matches!(pick.kind, probe::PickKind::InherentImplPick) { + return; + } + + self.tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| { + // "type" refers to either a type or, more likely, a trait from which + // the associated function or method is from. + let type_name = self.tcx.def_path_str(pick.item.container.id()); + let type_generics = self.tcx.generics_of(pick.item.container.id()); + + let parameter_count = type_generics.count() - (type_generics.has_self as usize); + let trait_name = if parameter_count == 0 { + type_name + } else { + format!( + "{}<{}>", + type_name, + std::iter::repeat("_").take(parameter_count).collect::>().join(", ") + ) + }; + + let mut lint = lint.build(&format!( + "trait-associated function `{}` will become ambiguous in Rust 2021", + method_name.name + )); + + let self_ty = self + .sess() + .source_map() + .span_to_snippet(self_ty_span) + .unwrap_or_else(|_| self_ty.to_string()); + + lint.span_suggestion( + span, + "disambiguate the associated function", + format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,), + Applicability::MachineApplicable, + ); + + lint.emit(); + }); + } +} From 3efa5b4b83b3fe72570d50ce73b8382875a4bdfa Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Mon, 14 Jun 2021 22:43:19 -0400 Subject: [PATCH 18/37] Emit additional arguments in `future_prelude_collision` lint --- compiler/rustc_typeck/src/check/expr.rs | 2 +- compiler/rustc_typeck/src/check/method/mod.rs | 6 ++++-- .../src/check/method/prelude2021.rs | 17 ++++++++++++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index e6a2c5d5d14d..28ab6b151331 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -941,7 +941,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // no need to check for bot/err -- callee does that let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t); - let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) { + let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr, args) { Ok(method) => { // We could add a "consider `foo::`" suggestion here, but I wasn't able to // trigger this codepath causing `structuraly_resolved_type` to emit an error. diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index e956637dec1d..be6bc625d893 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -174,7 +174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// # Arguments /// - /// Given a method call like `foo.bar::(...)`: + /// Given a method call like `foo.bar::(a, b + 1, ...)`: /// /// * `self`: the surrounding `FnCtxt` (!) /// * `self_ty`: the (unadjusted) type of the self expression (`foo`) @@ -182,6 +182,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// * `span`: the span for the method call /// * `call_expr`: the complete method call: (`foo.bar::(...)`) /// * `self_expr`: the self expression (`foo`) + /// * `args`: the expressions of the arguments (`a, b + 1, ...`) #[instrument(level = "debug", skip(self, call_expr, self_expr))] pub fn lookup_method( &self, @@ -190,6 +191,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, call_expr: &'tcx hir::Expr<'tcx>, self_expr: &'tcx hir::Expr<'tcx>, + args: &'tcx [hir::Expr<'tcx>], ) -> Result, MethodError<'tcx>> { debug!( "lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})", @@ -199,7 +201,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pick = self.lookup_probe(span, segment.ident, self_ty, call_expr, ProbeScope::TraitsInScope)?; - self.lint_dot_call_from_2018(self_ty, segment, span, call_expr, self_expr, &pick); + self.lint_dot_call_from_2018(self_ty, segment, span, call_expr, self_expr, &pick, args); for import_id in &pick.import_ids { debug!("used_trait_import: {:?}", import_id); diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index b141a4f6f89d..b7e41525bde4 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -20,6 +20,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_expr: &'tcx hir::Expr<'tcx>, self_expr: &'tcx hir::Expr<'tcx>, pick: &Pick<'tcx>, + args: &'tcx [hir::Expr<'tcx>], ) { debug!( "lookup(method_name={}, self_ty={:?}, call_expr={:?}, self_expr={:?})", @@ -75,10 +76,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { format!("{}{}{}", autoref, derefs, self_expr) }; + let args = args + .iter() + .skip(1) + .map(|arg| { + format!( + ", {}", + self.sess().source_map().span_to_snippet(arg.span).unwrap() + ) + }) + .collect::(); + lint.span_suggestion( sp, "disambiguate the associated function", - format!("{}::{}({})", trait_name, segment.ident.name, self_adjusted,), + format!( + "{}::{}({}{})", + trait_name, segment.ident.name, self_adjusted, args + ), Applicability::MachineApplicable, ); } else { From 56108f67b13416636508fbfd15442a9e18a70e28 Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Tue, 15 Jun 2021 01:31:00 -0400 Subject: [PATCH 19/37] Add future_prelude_collision to 2021 compat group * Add to 2021 compatibility group * Set default to Allow --- compiler/rustc_lint_defs/src/builtin.rs | 6 ++- .../rust-2021/future-prelude-collision.fixed | 9 ++++ .../ui/rust-2021/future-prelude-collision.rs | 9 ++++ .../rust-2021/future-prelude-collision.stderr | 45 +++++++++++++++---- .../ui/rust-2021/generic-type-collision.fixed | 2 + .../ui/rust-2021/generic-type-collision.rs | 2 + .../rust-2021/generic-type-collision.stderr | 10 ++++- 7 files changed, 71 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index cfa7c160b0ff..bef675563a45 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3282,7 +3282,11 @@ declare_lint! { /// /// [prelude changes]: https://blog.rust-lang.org/inside-rust/2021/03/04/planning-rust-2021.html#prelude-changes pub FUTURE_PRELUDE_COLLISION, - Warn, + Allow, "detects the usage of trait methods which are ambiguous with traits added to the \ prelude in future editions", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #85684 ", + edition: Some(Edition::Edition2021), + }; } diff --git a/src/test/ui/rust-2021/future-prelude-collision.fixed b/src/test/ui/rust-2021/future-prelude-collision.fixed index 922c0d54a007..9ede9f3a2fb4 100644 --- a/src/test/ui/rust-2021/future-prelude-collision.fixed +++ b/src/test/ui/rust-2021/future-prelude-collision.fixed @@ -1,6 +1,7 @@ // run-rustfix // edition:2018 // check-pass +#![warn(future_prelude_collision)] trait TryIntoU32 { fn try_into(self) -> Result; @@ -52,14 +53,17 @@ fn main() { // test dot-call that will break in 2021 edition let _: u32 = TryIntoU32::try_into(3u8).unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! // test associated function call that will break in 2021 edition let _ = ::try_from(3u8).unwrap(); //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! // test reverse turbofish too let _ = as FromByteIterator>::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter()); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! // negative testing lint (this line should *not* emit a warning) let _: u32 = TryFromU8::try_from(3u8).unwrap(); @@ -67,21 +71,26 @@ fn main() { // test type omission let _: u32 = <_ as TryFromU8>::try_from(3u8).unwrap(); //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! // test autoderef let _: u32 = TryIntoU32::try_into(*(&3u8)).unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! // test autoref let _: u32 = TryIntoU32::try_into(&3.0).unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! let mut data = 3u16; let mut_ptr = std::ptr::addr_of_mut!(data); let _: u32 = TryIntoU32::try_into(mut_ptr as *const _).unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! type U32Alias = u32; let _ = ::try_from(3u8).unwrap(); //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! } diff --git a/src/test/ui/rust-2021/future-prelude-collision.rs b/src/test/ui/rust-2021/future-prelude-collision.rs index 154dde16d9e9..914e910396a6 100644 --- a/src/test/ui/rust-2021/future-prelude-collision.rs +++ b/src/test/ui/rust-2021/future-prelude-collision.rs @@ -1,6 +1,7 @@ // run-rustfix // edition:2018 // check-pass +#![warn(future_prelude_collision)] trait TryIntoU32 { fn try_into(self) -> Result; @@ -52,14 +53,17 @@ fn main() { // test dot-call that will break in 2021 edition let _: u32 = 3u8.try_into().unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! // test associated function call that will break in 2021 edition let _ = u32::try_from(3u8).unwrap(); //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! // test reverse turbofish too let _ = >::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter()); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! // negative testing lint (this line should *not* emit a warning) let _: u32 = TryFromU8::try_from(3u8).unwrap(); @@ -67,21 +71,26 @@ fn main() { // test type omission let _: u32 = <_>::try_from(3u8).unwrap(); //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! // test autoderef let _: u32 = (&3u8).try_into().unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! // test autoref let _: u32 = 3.0.try_into().unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! let mut data = 3u16; let mut_ptr = std::ptr::addr_of_mut!(data); let _: u32 = mut_ptr.try_into().unwrap(); //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! type U32Alias = u32; let _ = U32Alias::try_from(3u8).unwrap(); //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! } diff --git a/src/test/ui/rust-2021/future-prelude-collision.stderr b/src/test/ui/rust-2021/future-prelude-collision.stderr index 9c92074c36f5..190145ef4dbf 100644 --- a/src/test/ui/rust-2021/future-prelude-collision.stderr +++ b/src/test/ui/rust-2021/future-prelude-collision.stderr @@ -1,52 +1,79 @@ warning: trait method `try_into` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:53:18 + --> $DIR/future-prelude-collision.rs:54:18 | LL | let _: u32 = 3u8.try_into().unwrap(); | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)` | - = note: `#[warn(future_prelude_collision)]` on by default +note: the lint level is defined here + --> $DIR/future-prelude-collision.rs:4:9 + | +LL | #![warn(future_prelude_collision)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 warning: trait-associated function `try_from` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:57:13 + --> $DIR/future-prelude-collision.rs:59:13 | LL | let _ = u32::try_from(3u8).unwrap(); | ^^^^^^^^^^^^^ help: disambiguate the associated function: `::try_from` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:61:13 + --> $DIR/future-prelude-collision.rs:64:13 | LL | let _ = >::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter()); | ^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as FromByteIterator>::from_iter` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 warning: trait-associated function `try_from` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:68:18 + --> $DIR/future-prelude-collision.rs:72:18 | LL | let _: u32 = <_>::try_from(3u8).unwrap(); | ^^^^^^^^^^^^^ help: disambiguate the associated function: `<_ as TryFromU8>::try_from` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 warning: trait method `try_into` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:72:18 + --> $DIR/future-prelude-collision.rs:77:18 | LL | let _: u32 = (&3u8).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(*(&3u8))` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 warning: trait method `try_into` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:76:18 + --> $DIR/future-prelude-collision.rs:82:18 | LL | let _: u32 = 3.0.try_into().unwrap(); | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(&3.0)` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 warning: trait method `try_into` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:81:18 + --> $DIR/future-prelude-collision.rs:88:18 | LL | let _: u32 = mut_ptr.try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(mut_ptr as *const _)` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 warning: trait-associated function `try_from` will become ambiguous in Rust 2021 - --> $DIR/future-prelude-collision.rs:85:13 + --> $DIR/future-prelude-collision.rs:93:13 | LL | let _ = U32Alias::try_from(3u8).unwrap(); | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `::try_from` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 warning: 8 warnings emitted diff --git a/src/test/ui/rust-2021/generic-type-collision.fixed b/src/test/ui/rust-2021/generic-type-collision.fixed index 1ae2b95d515d..00fb128a981e 100644 --- a/src/test/ui/rust-2021/generic-type-collision.fixed +++ b/src/test/ui/rust-2021/generic-type-collision.fixed @@ -1,6 +1,7 @@ // check-pass // run-rustfix // edition 2018 +#![warn(future_prelude_collision)] trait MyTrait { fn from_iter(x: Option); @@ -13,4 +14,5 @@ impl MyTrait<()> for Vec { fn main() { as MyTrait<_>>::from_iter(None); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! } diff --git a/src/test/ui/rust-2021/generic-type-collision.rs b/src/test/ui/rust-2021/generic-type-collision.rs index e203656163c6..406fba4d2479 100644 --- a/src/test/ui/rust-2021/generic-type-collision.rs +++ b/src/test/ui/rust-2021/generic-type-collision.rs @@ -1,6 +1,7 @@ // check-pass // run-rustfix // edition 2018 +#![warn(future_prelude_collision)] trait MyTrait { fn from_iter(x: Option); @@ -13,4 +14,5 @@ impl MyTrait<()> for Vec { fn main() { >::from_iter(None); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! } diff --git a/src/test/ui/rust-2021/generic-type-collision.stderr b/src/test/ui/rust-2021/generic-type-collision.stderr index 3acc6185a61b..9374379d2476 100644 --- a/src/test/ui/rust-2021/generic-type-collision.stderr +++ b/src/test/ui/rust-2021/generic-type-collision.stderr @@ -1,10 +1,16 @@ warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 - --> $DIR/generic-type-collision.rs:14:5 + --> $DIR/generic-type-collision.rs:15:5 | LL | >::from_iter(None); | ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: ` as MyTrait<_>>::from_iter` | - = note: `#[warn(future_prelude_collision)]` on by default +note: the lint level is defined here + --> $DIR/generic-type-collision.rs:4:9 + | +LL | #![warn(future_prelude_collision)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 warning: 1 warning emitted From 23259660030a583dd78f0d8f263ab5811fc9f75b Mon Sep 17 00:00:00 2001 From: Vikram Pal Date: Sat, 19 Dec 2020 08:50:33 +0000 Subject: [PATCH 20/37] Implement printing of stack traces on LLVM segfaults and aborts --- compiler/rustc_driver/src/lib.rs | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index c8891734ccec..f2206746e266 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1312,10 +1312,55 @@ pub fn init_env_logger(env: &str) { tracing::subscriber::set_global_default(subscriber).unwrap(); } +extern "C" { + // Only available in glibc + fn backtrace_symbols_fd(buffer: *const *mut libc::c_void, size: libc::c_int, fd: libc::c_int); +} + +#[cfg(unix)] +fn print_stack_trace(_: libc::c_int) { + unsafe { + static mut STACK_TRACE: [*mut libc::c_void; 256] = [std::ptr::null_mut(); 256]; + let depth = libc::backtrace(STACK_TRACE.as_mut_ptr(), 256); + if depth == 0 { + return; + } + backtrace_symbols_fd(STACK_TRACE.as_ptr(), depth, 2); + } +} + +#[cfg(unix)] +// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the +// process, print a stack trace and then exit. +fn print_stack_trace_on_error_signal() { + unsafe { + const ALT_STACK_SIZE: usize = libc::MINSIGSTKSZ + 64 * 1024; + let mut alt_stack: libc::stack_t = std::mem::zeroed(); + alt_stack.ss_sp = + std::alloc::alloc(std::alloc::Layout::from_size_align_unchecked(ALT_STACK_SIZE, 1)) + as *mut libc::c_void; + alt_stack.ss_size = ALT_STACK_SIZE; + libc::sigaltstack(&mut alt_stack, std::ptr::null_mut()); + + let mut sa: libc::sigaction = std::mem::zeroed(); + sa.sa_sigaction = + print_stack_trace as fn(libc::c_int) as *mut libc::c_void as libc::sighandler_t; + sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK; + libc::sigemptyset(&mut sa.sa_mask); + libc::sigaction(libc::SIGSEGV, &sa, std::ptr::null_mut()); + } +} + +#[cfg(windows)] +// When an error signal (such as SIGABRT or SIGSEGV) is delivered to the +// process, print a stack trace and then exit. +fn print_stack_trace_on_error_signal() {} + pub fn main() -> ! { let start_time = Instant::now(); let start_rss = get_resident_set_size(); init_rustc_env_logger(); + print_stack_trace_on_error_signal(); let mut callbacks = TimePassesCallbacks::default(); install_ice_hook(); let exit_code = catch_with_exit_code(|| { From ec6a85a5365374886fe4b1e2f4feb1d9270ec5da Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Fri, 2 Apr 2021 16:03:53 -0700 Subject: [PATCH 21/37] Small fixes --- compiler/rustc_driver/src/lib.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index f2206746e266..dba95a888261 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1312,16 +1312,17 @@ pub fn init_env_logger(env: &str) { tracing::subscriber::set_global_default(subscriber).unwrap(); } +#[cfg(unix)] extern "C" { - // Only available in glibc fn backtrace_symbols_fd(buffer: *const *mut libc::c_void, size: libc::c_int, fd: libc::c_int); } #[cfg(unix)] -fn print_stack_trace(_: libc::c_int) { +extern "C" fn print_stack_trace(_: libc::c_int) { + const MAX_FRAMES: usize = 256; + static mut STACK_TRACE: [*mut libc::c_void; MAX_FRAMES] = [std::ptr::null_mut(); MAX_FRAMES]; unsafe { - static mut STACK_TRACE: [*mut libc::c_void; 256] = [std::ptr::null_mut(); 256]; - let depth = libc::backtrace(STACK_TRACE.as_mut_ptr(), 256); + let depth = libc::backtrace(STACK_TRACE.as_mut_ptr(), MAX_FRAMES as i32); if depth == 0 { return; } @@ -1332,35 +1333,34 @@ fn print_stack_trace(_: libc::c_int) { #[cfg(unix)] // When an error signal (such as SIGABRT or SIGSEGV) is delivered to the // process, print a stack trace and then exit. -fn print_stack_trace_on_error_signal() { +fn install_signal_handler() { unsafe { const ALT_STACK_SIZE: usize = libc::MINSIGSTKSZ + 64 * 1024; let mut alt_stack: libc::stack_t = std::mem::zeroed(); alt_stack.ss_sp = - std::alloc::alloc(std::alloc::Layout::from_size_align_unchecked(ALT_STACK_SIZE, 1)) + std::alloc::alloc(std::alloc::Layout::from_size_align(ALT_STACK_SIZE, 1).unwrap()) as *mut libc::c_void; alt_stack.ss_size = ALT_STACK_SIZE; libc::sigaltstack(&mut alt_stack, std::ptr::null_mut()); let mut sa: libc::sigaction = std::mem::zeroed(); - sa.sa_sigaction = - print_stack_trace as fn(libc::c_int) as *mut libc::c_void as libc::sighandler_t; + sa.sa_sigaction = print_stack_trace as libc::sighandler_t; sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK; libc::sigemptyset(&mut sa.sa_mask); libc::sigaction(libc::SIGSEGV, &sa, std::ptr::null_mut()); } } -#[cfg(windows)] +#[cfg(not(unix))] // When an error signal (such as SIGABRT or SIGSEGV) is delivered to the // process, print a stack trace and then exit. -fn print_stack_trace_on_error_signal() {} +fn install_signal_handler() {} pub fn main() -> ! { let start_time = Instant::now(); let start_rss = get_resident_set_size(); init_rustc_env_logger(); - print_stack_trace_on_error_signal(); + install_signal_handler(); let mut callbacks = TimePassesCallbacks::default(); install_ice_hook(); let exit_code = catch_with_exit_code(|| { From a89c7e1f612a9189b4d3cf8cb8630fddc0b60fc6 Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Wed, 16 Jun 2021 18:44:26 -0700 Subject: [PATCH 22/37] add regression test for issue #37508 --- .../thread-local/thread-local-issue-37508.rs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/test/ui/thread-local/thread-local-issue-37508.rs diff --git a/src/test/ui/thread-local/thread-local-issue-37508.rs b/src/test/ui/thread-local/thread-local-issue-37508.rs new file mode 100644 index 000000000000..219108c77f7e --- /dev/null +++ b/src/test/ui/thread-local/thread-local-issue-37508.rs @@ -0,0 +1,36 @@ +// only-x86_64 +// compile-flags: -Ccode-model=large --crate-type lib +// build-pass +// +// Regression test for issue #37508 + +#![no_main] +#![no_std] +#![feature(thread_local, lang_items)] + +#[lang = "eh_personality"] +extern "C" fn eh_personality() {} + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(_panic: &PanicInfo<'_>) -> ! { + loop {} +} + +pub struct BB; + +#[thread_local] +static mut KEY: Key = Key { inner: BB, dtor_running: false }; + +pub unsafe fn set() -> Option<&'static BB> { + if KEY.dtor_running { + return None; + } + Some(&KEY.inner) +} + +pub struct Key { + inner: BB, + dtor_running: bool, +} From dbc9da7962b7282c5752a7bc2c9907694b7c158c Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 17 Jun 2021 06:10:38 -0400 Subject: [PATCH 23/37] WIP: Find the imports that were used to reach a method And add tests for some corner cases we have to consider. --- .../src/check/method/prelude2021.rs | 39 +++++++++++--- .../future-prelude-collision-imported.rs | 52 +++++++++++++++++++ .../future-prelude-collision-shadow.rs | 33 ++++++++++++ 3 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/rust-2021/future-prelude-collision-imported.rs create mode 100644 src/test/ui/rust-2021/future-prelude-collision-shadow.rs diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index b7e41525bde4..987ec032476d 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -1,3 +1,5 @@ +use hir::def_id::DefId; +use hir::HirId; use rustc_ast::Mutability; use rustc_errors::Applicability; use rustc_hir as hir; @@ -48,7 +50,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_expr.span, |lint| { let sp = call_expr.span; - let trait_name = self.tcx.def_path_str(pick.item.container.id()); + let trait_name = + self.trait_path_or_bare_name(call_expr.hir_id, pick.item.container.id()); let mut lint = lint.build(&format!( "trait method `{}` will become ambiguous in Rust 2021", @@ -144,16 +147,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| { // "type" refers to either a type or, more likely, a trait from which // the associated function or method is from. - let type_name = self.tcx.def_path_str(pick.item.container.id()); - let type_generics = self.tcx.generics_of(pick.item.container.id()); + let trait_path = self.trait_path_or_bare_name(expr_id, pick.item.container.id()); + let trait_generics = self.tcx.generics_of(pick.item.container.id()); - let parameter_count = type_generics.count() - (type_generics.has_self as usize); + let parameter_count = trait_generics.count() - (trait_generics.has_self as usize); let trait_name = if parameter_count == 0 { - type_name + trait_path } else { format!( "{}<{}>", - type_name, + trait_path, std::iter::repeat("_").take(parameter_count).collect::>().join(", ") ) }; @@ -179,4 +182,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint.emit(); }); } + + fn trait_path_or_bare_name(&self, expr_hir_id: HirId, trait_def_id: DefId) -> String { + self.trait_path(expr_hir_id, trait_def_id).unwrap_or_else(|| { + let key = self.tcx.def_key(trait_def_id); + format!("{}", key.disambiguated_data.data) + }) + } + + fn trait_path(&self, expr_hir_id: HirId, trait_def_id: DefId) -> Option { + let applicable_traits = self.tcx.in_scope_traits(expr_hir_id)?; + let applicable_trait = applicable_traits.iter().find(|t| t.def_id == trait_def_id)?; + if applicable_trait.import_ids.is_empty() { + // The trait was declared within the module, we only need to use its name. + return None; + } + + for &import_id in &applicable_trait.import_ids { + let hir_id = self.tcx.hir().local_def_id_to_hir_id(import_id); + let item = self.tcx.hir().expect_item(hir_id); + debug!(?item, ?import_id, "import_id"); + } + + return None; + } } diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.rs b/src/test/ui/rust-2021/future-prelude-collision-imported.rs new file mode 100644 index 000000000000..e85a0bd725d4 --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-imported.rs @@ -0,0 +1,52 @@ +// run-rustfix +// edition:2018 +// check-pass +#![warn(future_prelude_collision)] +#![allow(dead_code)] + +mod m { + pub trait TryIntoU32 { + fn try_into(self) -> Result; + } + + impl TryIntoU32 for u8 { + fn try_into(self) -> Result { + Ok(self as u32) + } + } + + pub trait AnotherTrick {} +} + +mod a { + use crate::m::TryIntoU32; + + fn main() { + // In this case, we can just use `TryIntoU32` + let _: u32 = 3u8.try_into().unwrap(); + } +} + +mod b { + use crate::m::AnotherTrick as TryIntoU32; + use crate::m::TryIntoU32 as _; + + fn main() { + // In this case, a `TryIntoU32::try_into` rewrite will not work, and we need to use + // the path `crate::m::TryIntoU32` (with which it was imported). + let _: u32 = 3u8.try_into().unwrap(); + } +} + +mod c { + use super::m::TryIntoU32 as _; + use crate::m::AnotherTrick as TryIntoU32; + + fn main() { + // In this case, a `TryIntoU32::try_into` rewrite will not work, and we need to use + // the path `super::m::TryIntoU32` (with which it was imported). + let _: u32 = 3u8.try_into().unwrap(); + } +} + +fn main() {} diff --git a/src/test/ui/rust-2021/future-prelude-collision-shadow.rs b/src/test/ui/rust-2021/future-prelude-collision-shadow.rs new file mode 100644 index 000000000000..ef19cf4d1e6a --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.rs @@ -0,0 +1,33 @@ +// run-rustfix +// edition:2018 +// check-pass +#![warn(future_prelude_collision)] +#![allow(dead_code)] + +mod m { + pub trait TryIntoU32 { + fn try_into(self) -> Result; + } + + impl TryIntoU32 for u8 { + fn try_into(self) -> Result { + Ok(self as u32) + } + } + + pub trait AnotherTrick {} +} + +mod d { + use crate::m::AnotherTrick as TryIntoU32; + use crate::m::*; + + fn main() { + // Here, `TryIntoU32` is imported but shadowed, but in that case we don't permit its methods + // to be available. + let _: u32 = 3u8.try_into().unwrap(); + //~^ ERROR no method name `try_into` found + } +} + +fn main() {} From 9bee7f0d0e1fee2a6a3ec2d04689d94ec238f034 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 18 Jun 2021 13:19:08 -0400 Subject: [PATCH 24/37] WIP: identify the case where we need to serialize path --- .../src/check/method/prelude2021.rs | 50 +++++++++++++++---- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index 987ec032476d..5f6731b6c521 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -1,10 +1,12 @@ use hir::def_id::DefId; use hir::HirId; +use hir::ItemKind; use rustc_ast::Mutability; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_middle::ty::Ty; use rustc_session::lint::builtin::FUTURE_PRELUDE_COLLISION; +use rustc_span::symbol::kw::Underscore; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; @@ -51,7 +53,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |lint| { let sp = call_expr.span; let trait_name = - self.trait_path_or_bare_name(call_expr.hir_id, pick.item.container.id()); + self.trait_path_or_bare_name(span, call_expr.hir_id, pick.item.container.id()); let mut lint = lint.build(&format!( "trait method `{}` will become ambiguous in Rust 2021", @@ -147,7 +149,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| { // "type" refers to either a type or, more likely, a trait from which // the associated function or method is from. - let trait_path = self.trait_path_or_bare_name(expr_id, pick.item.container.id()); + let trait_path = self.trait_path_or_bare_name(span, expr_id, pick.item.container.id()); let trait_generics = self.tcx.generics_of(pick.item.container.id()); let parameter_count = trait_generics.count() - (trait_generics.has_self as usize); @@ -183,14 +185,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); } - fn trait_path_or_bare_name(&self, expr_hir_id: HirId, trait_def_id: DefId) -> String { - self.trait_path(expr_hir_id, trait_def_id).unwrap_or_else(|| { + fn trait_path_or_bare_name( + &self, + span: Span, + expr_hir_id: HirId, + trait_def_id: DefId, + ) -> String { + self.trait_path(span, expr_hir_id, trait_def_id).unwrap_or_else(|| { let key = self.tcx.def_key(trait_def_id); format!("{}", key.disambiguated_data.data) }) } - fn trait_path(&self, expr_hir_id: HirId, trait_def_id: DefId) -> Option { + fn trait_path(&self, span: Span, expr_hir_id: HirId, trait_def_id: DefId) -> Option { let applicable_traits = self.tcx.in_scope_traits(expr_hir_id)?; let applicable_trait = applicable_traits.iter().find(|t| t.def_id == trait_def_id)?; if applicable_trait.import_ids.is_empty() { @@ -198,12 +205,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } - for &import_id in &applicable_trait.import_ids { - let hir_id = self.tcx.hir().local_def_id_to_hir_id(import_id); - let item = self.tcx.hir().expect_item(hir_id); - debug!(?item, ?import_id, "import_id"); + let import_items: Vec<_> = applicable_trait + .import_ids + .iter() + .map(|&import_id| { + let hir_id = self.tcx.hir().local_def_id_to_hir_id(import_id); + self.tcx.hir().expect_item(hir_id) + }) + .collect(); + + // Find an identifier with which this trait was imported (note that `_` doesn't count). + let any_id = import_items + .iter() + .filter_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None }) + .next(); + if let Some(any_id) = any_id { + return Some(format!("{}", any_id)); } - return None; + // All that is left is `_`! We need to use the full path. It doesn't matter which one we pick, + // so just take the first one. + match import_items[0].kind { + ItemKind::Use(path, _) => { + // FIXME: serialize path into something readable like a::b, there must be a fn for this + debug!("no name for trait, found import of path: {:?}", path); + return None; + } + _ => { + span_bug!(span, "unexpected item kind, expected a use: {:?}", import_items[0].kind); + } + } } } From 20915d471a523ac8f489461e741098d38dae136f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 18 Jun 2021 15:29:45 -0700 Subject: [PATCH 25/37] Resolve intra-doc links in summary desc Before: ![rustdoc-intra-doc-link-summary-before](https://user-images.githubusercontent.com/1593513/122623069-9d995e80-d04f-11eb-8d46-ec2ec126bb5e.png) After: ![rustdoc-intra-doc-link-summary](https://user-images.githubusercontent.com/1593513/122623076-a4c06c80-d04f-11eb-967a-f5916871c34b.png) --- src/librustdoc/clean/types.rs | 27 +++++++++++++++++++++++++++ src/librustdoc/formats/cache.rs | 7 ++++--- src/librustdoc/html/markdown.rs | 25 +++++++++++++++++++++---- src/librustdoc/html/render/cache.rs | 13 +++++++++---- 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 6a7c3f8caa49..66f62d97b047 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -523,6 +523,33 @@ impl Item { .collect() } + /// Find a list of all link names, without finding their href. + /// + /// This is used for generating summary text, which does not include + /// the link text, but does need to know which `[]`-bracketed names + /// are actually links. + crate fn link_names(&self, cache: &Cache) -> Vec { + cache + .intra_doc_links + .get(&self.def_id) + .map_or(&[][..], |v| v.as_slice()) + .iter() + .filter_map(|ItemLink { link: s, link_text, did, fragment }| { + // FIXME(83083): using fragments as a side-channel for + // primitive names is very unfortunate + if did.is_some() || fragment.is_some() { + Some(RenderedLink { + original_text: s.clone(), + new_text: link_text.clone(), + href: String::new(), + }) + } else { + None + } + }) + .collect() + } + crate fn is_crate(&self) -> bool { self.is_mod() && self.def_id.as_real().map_or(false, |did| did.index == CRATE_DEF_INDEX) } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 5734a4a98e2b..811f68292010 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -292,13 +292,14 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // which should not be indexed. The crate-item itself is // inserted later on when serializing the search-index. if item.def_id.index().map_or(false, |idx| idx != CRATE_DEF_INDEX) { + let desc = item.doc_value().map_or_else(String::new, |x| { + short_markdown_summary(&x.as_str(), &item.link_names(&self.cache)) + }); self.cache.search_index.push(IndexItem { ty: item.type_(), name: s.to_string(), path: path.join("::"), - desc: item - .doc_value() - .map_or_else(String::new, |x| short_markdown_summary(&x.as_str())), + desc, parent, parent_idx: None, search_type: get_index_search_type(&item, &self.empty_cache, self.tcx), diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 00a91e07d65e..bafb522f3633 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1051,7 +1051,11 @@ impl MarkdownSummaryLine<'_> { /// /// Returns a tuple of the rendered HTML string and whether the output was shortened /// due to the provided `length_limit`. -fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool) { +fn markdown_summary_with_limit( + md: &str, + link_names: &[RenderedLink], + length_limit: usize, +) -> (String, bool) { if md.is_empty() { return (String::new(), false); } @@ -1065,7 +1069,20 @@ fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool) *text_length += text.len(); } - 'outer: for event in Parser::new_ext(md, summary_opts()) { + let mut replacer = |broken_link: BrokenLink<'_>| { + if let Some(link) = + link_names.iter().find(|link| &*link.original_text == broken_link.reference) + { + Some((link.href.as_str().into(), link.new_text.as_str().into())) + } else { + None + } + }; + + let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer)); + let p = LinkReplacer::new(p, link_names); + + 'outer: for event in p { match &event { Event::Text(text) => { for word in text.split_inclusive(char::is_whitespace) { @@ -1121,8 +1138,8 @@ fn markdown_summary_with_limit(md: &str, length_limit: usize) -> (String, bool) /// Will shorten to 59 or 60 characters, including an ellipsis (…) if it was shortened. /// /// See [`markdown_summary_with_limit`] for details about what is rendered and what is not. -crate fn short_markdown_summary(markdown: &str) -> String { - let (mut s, was_shortened) = markdown_summary_with_limit(markdown, 59); +crate fn short_markdown_summary(markdown: &str, link_names: &[RenderedLink]) -> String { + let (mut s, was_shortened) = markdown_summary_with_limit(markdown, link_names, 59); if was_shortened { s.push('…'); diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 3e056c4b67a7..5b3c445013b5 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -34,11 +34,14 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< // has since been learned. for &(did, ref item) in &cache.orphan_impl_items { if let Some(&(ref fqp, _)) = cache.paths.get(&did) { + let desc = item + .doc_value() + .map_or_else(String::new, |s| short_markdown_summary(&s, &item.link_names(&cache))); cache.search_index.push(IndexItem { ty: item.type_(), name: item.name.unwrap().to_string(), path: fqp[..fqp.len() - 1].join("::"), - desc: item.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s)), + desc, parent: Some(did.into()), parent_idx: None, search_type: get_index_search_type(&item, cache, tcx), @@ -47,6 +50,11 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< } } + let crate_doc = krate + .module + .doc_value() + .map_or_else(String::new, |s| short_markdown_summary(&s, &krate.module.link_names(&cache))); + let Cache { ref mut search_index, ref paths, .. } = *cache; // Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias, @@ -100,9 +108,6 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< crate_items.push(&*item); } - let crate_doc = - krate.module.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s)); - struct CrateData<'a> { doc: String, items: Vec<&'a IndexItem>, From f67585d494fd92347e4954a240ddde14dcbd711b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 18 Jun 2021 17:47:05 -0700 Subject: [PATCH 26/37] Update test cases for intra-doc links in summaries --- src/librustdoc/html/markdown/tests.rs | 4 +++- src/test/rustdoc-js/summaries.js | 2 +- src/test/rustdoc-js/summaries.rs | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index ac3ea4c8c5f6..d10da64ccfaa 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -221,7 +221,7 @@ fn test_header_ids_multiple_blocks() { #[test] fn test_short_markdown_summary() { fn t(input: &str, expect: &str) { - let output = short_markdown_summary(input); + let output = short_markdown_summary(input, &[][..]); assert_eq!(output, expect, "original: {}", input); } @@ -232,6 +232,7 @@ fn test_short_markdown_summary() { t("Hard-break \nsummary", "Hard-break summary"); t("hello [Rust] :)\n\n[Rust]: https://www.rust-lang.org", "hello Rust :)"); t("hello [Rust](https://www.rust-lang.org \"Rust\") :)", "hello Rust :)"); + t("dud [link]", "dud [link]"); t("code `let x = i32;` ...", "code let x = i32; …"); t("type `Type<'static>` ...", "type Type<'static> …"); t("# top header", "top header"); @@ -259,6 +260,7 @@ fn test_plain_text_summary() { t("Hard-break \nsummary", "Hard-break summary"); t("hello [Rust] :)\n\n[Rust]: https://www.rust-lang.org", "hello Rust :)"); t("hello [Rust](https://www.rust-lang.org \"Rust\") :)", "hello Rust :)"); + t("dud [link]", "dud [link]"); t("code `let x = i32;` ...", "code `let x = i32;` …"); t("type `Type<'static>` ...", "type `Type<'static>` …"); t("# top header", "top header"); diff --git a/src/test/rustdoc-js/summaries.js b/src/test/rustdoc-js/summaries.js index f175e47342df..dfb11e80414c 100644 --- a/src/test/rustdoc-js/summaries.js +++ b/src/test/rustdoc-js/summaries.js @@ -5,7 +5,7 @@ const QUERY = ['summaries', 'summaries::Sidebar', 'summaries::Sidebar2']; const EXPECTED = [ { 'others': [ - { 'path': '', 'name': 'summaries', 'desc': 'This summary has a link and code.' }, + { 'path': '', 'name': 'summaries', 'desc': 'This summary has a link, [code], and Sidebar2 intra-doc.' }, ], }, { diff --git a/src/test/rustdoc-js/summaries.rs b/src/test/rustdoc-js/summaries.rs index beb91e286b61..418c9f8d0edd 100644 --- a/src/test/rustdoc-js/summaries.rs +++ b/src/test/rustdoc-js/summaries.rs @@ -1,9 +1,11 @@ #![crate_type = "lib"] #![crate_name = "summaries"] -//! This *summary* has a [link] and `code`. +//! This *summary* has a [link], [`code`], and [`Sidebar2`] intra-doc. //! -//! This is the second paragraph. +//! This is the second paragraph. It should not be rendered. +//! To test that intra-doc links are resolved properly, [`code`] should render +//! the square brackets, and [`Sidebar2`] should not. //! //! [link]: https://example.com From b18704dd58047e0ade59a425740b8a41ba1bd14b Mon Sep 17 00:00:00 2001 From: jam1garner <8260240+jam1garner@users.noreply.github.com> Date: Sat, 19 Jun 2021 18:42:24 -0400 Subject: [PATCH 27/37] Fix future_prelude_collision for object calls and use as _ --- .../src/check/method/prelude2021.rs | 195 +++++++++++++----- .../future-prelude-collision-imported.fixed | 59 ++++++ .../future-prelude-collision-imported.rs | 7 + .../future-prelude-collision-imported.stderr | 34 +++ .../future-prelude-collision-shadow.fixed | 33 +++ .../future-prelude-collision-shadow.rs | 4 +- .../future-prelude-collision-shadow.stderr | 40 ++++ 7 files changed, 313 insertions(+), 59 deletions(-) create mode 100644 src/test/ui/rust-2021/future-prelude-collision-imported.fixed create mode 100644 src/test/ui/rust-2021/future-prelude-collision-imported.stderr create mode 100644 src/test/ui/rust-2021/future-prelude-collision-shadow.fixed create mode 100644 src/test/ui/rust-2021/future-prelude-collision-shadow.stderr diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index 5f6731b6c521..0750567d3dd6 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -4,7 +4,7 @@ use hir::ItemKind; use rustc_ast::Mutability; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{Ref, Ty}; use rustc_session::lint::builtin::FUTURE_PRELUDE_COLLISION; use rustc_span::symbol::kw::Underscore; use rustc_span::symbol::{sym, Ident}; @@ -46,21 +46,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - self.tcx.struct_span_lint_hir( - FUTURE_PRELUDE_COLLISION, - call_expr.hir_id, - call_expr.span, - |lint| { - let sp = call_expr.span; - let trait_name = - self.trait_path_or_bare_name(span, call_expr.hir_id, pick.item.container.id()); - - let mut lint = lint.build(&format!( - "trait method `{}` will become ambiguous in Rust 2021", - segment.ident.name - )); - - if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span) { + if matches!(pick.kind, probe::PickKind::InherentImplPick | probe::PickKind::ObjectPick) { + // avoid repeatedly adding unneeded `&*`s + if pick.autoderefs == 1 + && matches!( + pick.autoref_or_ptr_adjustment, + Some(probe::AutorefOrPtrAdjustment::Autoref { .. }) + ) + && matches!(self_ty.kind(), Ref(..)) + { + return; + } + // Inherent impls only require not relying on autoref and autoderef in order to + // ensure that the trait implementation won't be used + self.tcx.struct_span_lint_hir( + FUTURE_PRELUDE_COLLISION, + self_expr.hir_id, + self_expr.span, + |lint| { + let sp = self_expr.span; + + let mut lint = lint.build(&format!( + "trait method `{}` will become ambiguous in Rust 2021", + segment.ident.name + )); + let derefs = "*".repeat(pick.autoderefs); let autoref = match pick.autoref_or_ptr_adjustment { @@ -74,46 +84,115 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) => "&", Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "", }; - let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) = - pick.autoref_or_ptr_adjustment + if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span) { - format!("{}{} as *const _", derefs, self_expr) + let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) = + pick.autoref_or_ptr_adjustment + { + format!("{}{} as *const _", derefs, self_expr) + } else { + format!("{}{}{}", autoref, derefs, self_expr) + }; + + lint.span_suggestion( + sp, + "disambiguate the method call", + format!("({})", self_adjusted), + Applicability::MachineApplicable, + ); } else { - format!("{}{}{}", autoref, derefs, self_expr) - }; - let args = args - .iter() - .skip(1) - .map(|arg| { - format!( - ", {}", - self.sess().source_map().span_to_snippet(arg.span).unwrap() - ) - }) - .collect::(); - - lint.span_suggestion( - sp, - "disambiguate the associated function", - format!( - "{}::{}({}{})", - trait_name, segment.ident.name, self_adjusted, args - ), - Applicability::MachineApplicable, - ); - } else { - lint.span_help( - sp, - &format!( - "disambiguate the associated function with `{}::{}(...)`", - trait_name, segment.ident, - ), + let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) = + pick.autoref_or_ptr_adjustment + { + format!("{}(...) as *const _", derefs) + } else { + format!("{}{}...", autoref, derefs) + }; + lint.span_help( + sp, + &format!("disambiguate the method call with `({})`", self_adjusted,), + ); + } + + lint.emit(); + }, + ); + } else { + // trait implementations require full disambiguation to not clash with the new prelude + // additions (i.e. convert from dot-call to fully-qualified call) + self.tcx.struct_span_lint_hir( + FUTURE_PRELUDE_COLLISION, + call_expr.hir_id, + call_expr.span, + |lint| { + let sp = call_expr.span; + let trait_name = self.trait_path_or_bare_name( + span, + call_expr.hir_id, + pick.item.container.id(), ); - } - lint.emit(); - }, - ); + let mut lint = lint.build(&format!( + "trait method `{}` will become ambiguous in Rust 2021", + segment.ident.name + )); + + if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span) + { + let derefs = "*".repeat(pick.autoderefs); + + let autoref = match pick.autoref_or_ptr_adjustment { + Some(probe::AutorefOrPtrAdjustment::Autoref { + mutbl: Mutability::Mut, + .. + }) => "&mut ", + Some(probe::AutorefOrPtrAdjustment::Autoref { + mutbl: Mutability::Not, + .. + }) => "&", + Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "", + }; + let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) = + pick.autoref_or_ptr_adjustment + { + format!("{}{} as *const _", derefs, self_expr) + } else { + format!("{}{}{}", autoref, derefs, self_expr) + }; + let args = args + .iter() + .skip(1) + .map(|arg| { + format!( + ", {}", + self.sess().source_map().span_to_snippet(arg.span).unwrap() + ) + }) + .collect::(); + + lint.span_suggestion( + sp, + "disambiguate the associated function", + format!( + "{}::{}({}{})", + trait_name, segment.ident.name, self_adjusted, args + ), + Applicability::MachineApplicable, + ); + } else { + lint.span_help( + sp, + &format!( + "disambiguate the associated function with `{}::{}(...)`", + trait_name, segment.ident, + ), + ); + } + + lint.emit(); + }, + ); + } } pub(super) fn lint_fully_qualified_call_from_2018( @@ -226,11 +305,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // All that is left is `_`! We need to use the full path. It doesn't matter which one we pick, // so just take the first one. match import_items[0].kind { - ItemKind::Use(path, _) => { - // FIXME: serialize path into something readable like a::b, there must be a fn for this - debug!("no name for trait, found import of path: {:?}", path); - return None; - } + ItemKind::Use(path, _) => Some( + path.segments + .iter() + .map(|segment| segment.ident.to_string()) + .collect::>() + .join("::"), + ), _ => { span_bug!(span, "unexpected item kind, expected a use: {:?}", import_items[0].kind); } diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.fixed b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed new file mode 100644 index 000000000000..4f8fd9b345b2 --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed @@ -0,0 +1,59 @@ +// run-rustfix +// edition:2018 +// check-pass +#![warn(future_prelude_collision)] +#![allow(dead_code)] +#![allow(unused_imports)] + +mod m { + pub trait TryIntoU32 { + fn try_into(self) -> Result; + } + + impl TryIntoU32 for u8 { + fn try_into(self) -> Result { + Ok(self as u32) + } + } + + pub trait AnotherTrick {} +} + +mod a { + use crate::m::TryIntoU32; + + fn main() { + // In this case, we can just use `TryIntoU32` + let _: u32 = TryIntoU32::try_into(3u8).unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + } +} + +mod b { + use crate::m::AnotherTrick as TryIntoU32; + use crate::m::TryIntoU32 as _; + + fn main() { + // In this case, a `TryIntoU32::try_into` rewrite will not work, and we need to use + // the path `crate::m::TryIntoU32` (with which it was imported). + let _: u32 = crate::m::TryIntoU32::try_into(3u8).unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + } +} + +mod c { + use super::m::TryIntoU32 as _; + use crate::m::AnotherTrick as TryIntoU32; + + fn main() { + // In this case, a `TryIntoU32::try_into` rewrite will not work, and we need to use + // the path `super::m::TryIntoU32` (with which it was imported). + let _: u32 = super::m::TryIntoU32::try_into(3u8).unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + } +} + +fn main() {} diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.rs b/src/test/ui/rust-2021/future-prelude-collision-imported.rs index e85a0bd725d4..2ce1be6151b1 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-imported.rs +++ b/src/test/ui/rust-2021/future-prelude-collision-imported.rs @@ -3,6 +3,7 @@ // check-pass #![warn(future_prelude_collision)] #![allow(dead_code)] +#![allow(unused_imports)] mod m { pub trait TryIntoU32 { @@ -24,6 +25,8 @@ mod a { fn main() { // In this case, we can just use `TryIntoU32` let _: u32 = 3u8.try_into().unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! } } @@ -35,6 +38,8 @@ mod b { // In this case, a `TryIntoU32::try_into` rewrite will not work, and we need to use // the path `crate::m::TryIntoU32` (with which it was imported). let _: u32 = 3u8.try_into().unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! } } @@ -46,6 +51,8 @@ mod c { // In this case, a `TryIntoU32::try_into` rewrite will not work, and we need to use // the path `super::m::TryIntoU32` (with which it was imported). let _: u32 = 3u8.try_into().unwrap(); + //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021 + //~^^ WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! } } diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr new file mode 100644 index 000000000000..3903cbfe8249 --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr @@ -0,0 +1,34 @@ +warning: trait method `try_into` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision-imported.rs:27:22 + | +LL | let _: u32 = 3u8.try_into().unwrap(); + | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)` + | +note: the lint level is defined here + --> $DIR/future-prelude-collision-imported.rs:4:9 + | +LL | #![warn(future_prelude_collision)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 + +warning: trait method `try_into` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision-imported.rs:40:22 + | +LL | let _: u32 = 3u8.try_into().unwrap(); + | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `crate::m::TryIntoU32::try_into(3u8)` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 + +warning: trait method `try_into` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision-imported.rs:53:22 + | +LL | let _: u32 = 3u8.try_into().unwrap(); + | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `super::m::TryIntoU32::try_into(3u8)` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 + +warning: 3 warnings emitted + diff --git a/src/test/ui/rust-2021/future-prelude-collision-shadow.fixed b/src/test/ui/rust-2021/future-prelude-collision-shadow.fixed new file mode 100644 index 000000000000..588ab6255fa5 --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.fixed @@ -0,0 +1,33 @@ +// run-rustfix +// edition:2018 +#![warn(future_prelude_collision)] +#![allow(dead_code)] +#![allow(unused_imports)] + +mod m { + pub trait TryIntoU32 { + fn try_into(self) -> Result; + } + + impl TryIntoU32 for u8 { + fn try_into(self) -> Result { + Ok(self as u32) + } + } + + pub trait AnotherTrick {} +} + +mod d { + use crate::m::AnotherTrick as TryIntoU32; + use crate::m::*; + + fn main() { + // Here, `TryIntoU32` is imported but shadowed, but in that case we don't permit its methods + // to be available. + let _: u32 = 3u8.try_into().unwrap(); + //~^ ERROR no method named `try_into` found for type `u8` in the current scope + } +} + +fn main() {} diff --git a/src/test/ui/rust-2021/future-prelude-collision-shadow.rs b/src/test/ui/rust-2021/future-prelude-collision-shadow.rs index ef19cf4d1e6a..588ab6255fa5 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-shadow.rs +++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.rs @@ -1,8 +1,8 @@ // run-rustfix // edition:2018 -// check-pass #![warn(future_prelude_collision)] #![allow(dead_code)] +#![allow(unused_imports)] mod m { pub trait TryIntoU32 { @@ -26,7 +26,7 @@ mod d { // Here, `TryIntoU32` is imported but shadowed, but in that case we don't permit its methods // to be available. let _: u32 = 3u8.try_into().unwrap(); - //~^ ERROR no method name `try_into` found + //~^ ERROR no method named `try_into` found for type `u8` in the current scope } } diff --git a/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr b/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr new file mode 100644 index 000000000000..3019b2aa5e21 --- /dev/null +++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr @@ -0,0 +1,40 @@ +error[E0599]: no method named `try_into` found for type `u8` in the current scope + --> $DIR/future-prelude-collision-shadow.rs:28:26 + | +LL | let _: u32 = 3u8.try_into().unwrap(); + | ^^^^^^^^ method not found in `u8` + | + ::: $SRC_DIR/core/src/convert/mod.rs:LL:COL + | +LL | fn try_into(self) -> Result; + | -------- + | | + | the method is available for `Box` here + | the method is available for `Pin` here + | the method is available for `Arc` here + | the method is available for `Rc` here + | + = help: items from traits can only be used if the trait is in scope + = note: the following traits are implemented but not in scope; perhaps add a `use` for one of them: + candidate #1: `use crate::m::TryIntoU32;` + candidate #2: `use std::convert::TryInto;` +help: consider wrapping the receiver expression with the appropriate type + | +LL | let _: u32 = Box::new(3u8).try_into().unwrap(); + | ^^^^^^^^^ ^ +help: consider wrapping the receiver expression with the appropriate type + | +LL | let _: u32 = Pin::new(3u8).try_into().unwrap(); + | ^^^^^^^^^ ^ +help: consider wrapping the receiver expression with the appropriate type + | +LL | let _: u32 = Arc::new(3u8).try_into().unwrap(); + | ^^^^^^^^^ ^ +help: consider wrapping the receiver expression with the appropriate type + | +LL | let _: u32 = Rc::new(3u8).try_into().unwrap(); + | ^^^^^^^^ ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. From 3dc47e2c098e0b80019e2e1ca622d6af504f6494 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 21 Jun 2021 10:58:10 -0400 Subject: [PATCH 28/37] do not run rustfix for future-prelude-collision-shadow --- .../future-prelude-collision-shadow.fixed | 33 ------------------- .../future-prelude-collision-shadow.rs | 1 - .../future-prelude-collision-shadow.stderr | 2 +- 3 files changed, 1 insertion(+), 35 deletions(-) delete mode 100644 src/test/ui/rust-2021/future-prelude-collision-shadow.fixed diff --git a/src/test/ui/rust-2021/future-prelude-collision-shadow.fixed b/src/test/ui/rust-2021/future-prelude-collision-shadow.fixed deleted file mode 100644 index 588ab6255fa5..000000000000 --- a/src/test/ui/rust-2021/future-prelude-collision-shadow.fixed +++ /dev/null @@ -1,33 +0,0 @@ -// run-rustfix -// edition:2018 -#![warn(future_prelude_collision)] -#![allow(dead_code)] -#![allow(unused_imports)] - -mod m { - pub trait TryIntoU32 { - fn try_into(self) -> Result; - } - - impl TryIntoU32 for u8 { - fn try_into(self) -> Result { - Ok(self as u32) - } - } - - pub trait AnotherTrick {} -} - -mod d { - use crate::m::AnotherTrick as TryIntoU32; - use crate::m::*; - - fn main() { - // Here, `TryIntoU32` is imported but shadowed, but in that case we don't permit its methods - // to be available. - let _: u32 = 3u8.try_into().unwrap(); - //~^ ERROR no method named `try_into` found for type `u8` in the current scope - } -} - -fn main() {} diff --git a/src/test/ui/rust-2021/future-prelude-collision-shadow.rs b/src/test/ui/rust-2021/future-prelude-collision-shadow.rs index 588ab6255fa5..c9d2529341f4 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-shadow.rs +++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.rs @@ -1,4 +1,3 @@ -// run-rustfix // edition:2018 #![warn(future_prelude_collision)] #![allow(dead_code)] diff --git a/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr b/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr index 3019b2aa5e21..ad9b8af00e46 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr +++ b/src/test/ui/rust-2021/future-prelude-collision-shadow.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `try_into` found for type `u8` in the current scope - --> $DIR/future-prelude-collision-shadow.rs:28:26 + --> $DIR/future-prelude-collision-shadow.rs:27:26 | LL | let _: u32 = 3u8.try_into().unwrap(); | ^^^^^^^^ method not found in `u8` From 186c09ae8381e0c8fb43c1d47341649d214362ad Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 21 Jun 2021 11:55:07 -0400 Subject: [PATCH 29/37] add test for `dyn` collisions --- .../ui/rust-2021/inherent-dyn-collision.fixed | 53 +++++++++++++++++++ .../ui/rust-2021/inherent-dyn-collision.rs | 53 +++++++++++++++++++ .../rust-2021/inherent-dyn-collision.stderr | 16 ++++++ 3 files changed, 122 insertions(+) create mode 100644 src/test/ui/rust-2021/inherent-dyn-collision.fixed create mode 100644 src/test/ui/rust-2021/inherent-dyn-collision.rs create mode 100644 src/test/ui/rust-2021/inherent-dyn-collision.stderr diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.fixed b/src/test/ui/rust-2021/inherent-dyn-collision.fixed new file mode 100644 index 000000000000..cbb6e9659dff --- /dev/null +++ b/src/test/ui/rust-2021/inherent-dyn-collision.fixed @@ -0,0 +1,53 @@ +// Test case where the method we want is an inherent method on a +// dyn Trait. In that case, the fix is to insert `*` on the receiver. +// +// check-pass +// run-rustfix +// edition:2018 + +#![warn(future_prelude_collision)] + +trait TryIntoU32 { + fn try_into(&self) -> Result; +} + +impl TryIntoU32 for u8 { + // note: &self + fn try_into(&self) -> Result { + Ok(22) + } +} + +mod inner { + use super::get_dyn_trait; + + // note: this does nothing, but is copying from ffishim's problem of + // having a struct of the same name as the trait in-scope, while *also* + // implementing the trait for that struct but **without** importing the + // trait itself into scope + struct TryIntoU32; + + impl super::TryIntoU32 for TryIntoU32 { + fn try_into(&self) -> Result { + Ok(0) + } + } + + // this is where the gross part happens. since `get_dyn_trait` returns + // a Box, it can still call the method for `dyn Trait` without + // `Trait` being in-scope. it might even be possible to make the trait itself + // entirely unreference-able from the callsite? + pub fn test() -> u32 { + (&*get_dyn_trait()).try_into().unwrap() + //~^ WARNING trait method `try_into` will become ambiguous + //~| WARNING this was previously accepted + } +} + +fn get_dyn_trait() -> Box { + Box::new(3u8) as Box +} + +fn main() { + dbg!(inner::test()); +} diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.rs b/src/test/ui/rust-2021/inherent-dyn-collision.rs new file mode 100644 index 000000000000..1c9929eff91d --- /dev/null +++ b/src/test/ui/rust-2021/inherent-dyn-collision.rs @@ -0,0 +1,53 @@ +// Test case where the method we want is an inherent method on a +// dyn Trait. In that case, the fix is to insert `*` on the receiver. +// +// check-pass +// run-rustfix +// edition:2018 + +#![warn(future_prelude_collision)] + +trait TryIntoU32 { + fn try_into(&self) -> Result; +} + +impl TryIntoU32 for u8 { + // note: &self + fn try_into(&self) -> Result { + Ok(22) + } +} + +mod inner { + use super::get_dyn_trait; + + // note: this does nothing, but is copying from ffishim's problem of + // having a struct of the same name as the trait in-scope, while *also* + // implementing the trait for that struct but **without** importing the + // trait itself into scope + struct TryIntoU32; + + impl super::TryIntoU32 for TryIntoU32 { + fn try_into(&self) -> Result { + Ok(0) + } + } + + // this is where the gross part happens. since `get_dyn_trait` returns + // a Box, it can still call the method for `dyn Trait` without + // `Trait` being in-scope. it might even be possible to make the trait itself + // entirely unreference-able from the callsite? + pub fn test() -> u32 { + get_dyn_trait().try_into().unwrap() + //~^ WARNING trait method `try_into` will become ambiguous + //~| WARNING this was previously accepted + } +} + +fn get_dyn_trait() -> Box { + Box::new(3u8) as Box +} + +fn main() { + dbg!(inner::test()); +} diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.stderr b/src/test/ui/rust-2021/inherent-dyn-collision.stderr new file mode 100644 index 000000000000..3d7637100c2c --- /dev/null +++ b/src/test/ui/rust-2021/inherent-dyn-collision.stderr @@ -0,0 +1,16 @@ +warning: trait method `try_into` will become ambiguous in Rust 2021 + --> $DIR/inherent-dyn-collision.rs:41:9 + | +LL | get_dyn_trait().try_into().unwrap() + | ^^^^^^^^^^^^^^^ help: disambiguate the method call: `(&*get_dyn_trait())` + | +note: the lint level is defined here + --> $DIR/inherent-dyn-collision.rs:8:9 + | +LL | #![warn(future_prelude_collision)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition! + = note: for more information, see issue #85684 + +warning: 1 warning emitted + From 200fdaac777b8c0a4d5cf2be86f639c61358d518 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 19 Jun 2021 07:01:37 +0800 Subject: [PATCH 30/37] Specify the kind of the item for E0121 --- compiler/rustc_hir/src/hir.rs | 21 ++++++++++ compiler/rustc_typeck/src/astconv/mod.rs | 1 + compiler/rustc_typeck/src/collect.rs | 41 +++++++++++++++----- compiler/rustc_typeck/src/collect/type_of.rs | 37 +++++++++++++----- 4 files changed, 81 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index bb8d6386d8a7..a7ce92ea5791 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2815,6 +2815,27 @@ impl ItemKind<'_> { _ => return None, }) } + + pub fn descr(&self) -> &'static str { + match self { + ItemKind::ExternCrate(..) => "extern crate", + ItemKind::Use(..) => "`use` import", + ItemKind::Static(..) => "static item", + ItemKind::Const(..) => "constant item", + ItemKind::Fn(..) => "function", + ItemKind::Mod(..) => "module", + ItemKind::ForeignMod { .. } => "extern block", + ItemKind::GlobalAsm(..) => "global asm item", + ItemKind::TyAlias(..) => "type alias", + ItemKind::OpaqueTy(..) => "opaque type", + ItemKind::Enum(..) => "enum", + ItemKind::Struct(..) => "struct", + ItemKind::Union(..) => "union", + ItemKind::Trait(..) => "trait", + ItemKind::TraitAlias(..) => "trait alias", + ItemKind::Impl(..) => "implementation", + } + } } /// A reference from an trait to one of its associated items. This diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index ef1956210448..10a7d69d5d3b 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2418,6 +2418,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { visitor.0, true, hir_ty, + "function", ); } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index ae61dd1cfce4..f741606370fb 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -145,6 +145,7 @@ crate fn placeholder_type_error( placeholder_types: Vec, suggest: bool, hir_ty: Option<&hir::Ty<'_>>, + kind: &'static str, ) { if placeholder_types.is_empty() { return; @@ -174,7 +175,7 @@ crate fn placeholder_type_error( )); } - let mut err = bad_placeholder_type(tcx, placeholder_types); + let mut err = bad_placeholder_type(tcx, placeholder_types, kind); // Suggest, but only if it is not a function in const or static if suggest { @@ -236,7 +237,15 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_item(item); - placeholder_type_error(tcx, Some(generics.span), generics.params, visitor.0, suggest, None); + placeholder_type_error( + tcx, + Some(generics.span), + generics.params, + visitor.0, + suggest, + None, + item.kind.descr(), + ); } impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { @@ -302,13 +311,17 @@ impl Visitor<'tcx> for CollectItemTypesVisitor<'tcx> { fn bad_placeholder_type( tcx: TyCtxt<'tcx>, mut spans: Vec, + kind: &'static str, ) -> rustc_errors::DiagnosticBuilder<'tcx> { + let kind = if kind.ends_with('s') { format!("{}es", kind) } else { format!("{}s", kind) }; + spans.sort(); let mut err = struct_span_err!( tcx.sess, spans.clone(), E0121, - "the type placeholder `_` is not allowed within types on item signatures", + "the type placeholder `_` is not allowed within types on item signatures for {}", + kind ); for span in spans { err.span_label(span, "not allowed in type signatures"); @@ -382,7 +395,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { _: Option<&ty::GenericParamDef>, span: Span, ) -> &'tcx Const<'tcx> { - bad_placeholder_type(self.tcx(), vec![span]).emit(); + bad_placeholder_type(self.tcx(), vec![span], "generic").emit(); // Typeck doesn't expect erased regions to be returned from `type_of`. let ty = self.tcx.fold_regions(ty, &mut false, |r, _| match r { ty::ReErased => self.tcx.lifetimes.re_static, @@ -746,7 +759,15 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { hir::ForeignItemKind::Static(..) => { let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_foreign_item(item); - placeholder_type_error(tcx, None, &[], visitor.0, false, None); + placeholder_type_error( + tcx, + None, + &[], + visitor.0, + false, + None, + "static variable", + ); } _ => (), } @@ -846,7 +867,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { // Account for `const C: _;`. let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, &[], visitor.0, false, None); + placeholder_type_error(tcx, None, &[], visitor.0, false, None, "constant"); } hir::TraitItemKind::Type(_, Some(_)) => { @@ -855,7 +876,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { // Account for `type T = _;`. let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, &[], visitor.0, false, None); + placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type"); } hir::TraitItemKind::Type(_, None) => { @@ -865,7 +886,7 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) { let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_trait_item(trait_item); - placeholder_type_error(tcx, None, &[], visitor.0, false, None); + placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type"); } }; @@ -887,7 +908,7 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) { let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_impl_item(impl_item); - placeholder_type_error(tcx, None, &[], visitor.0, false, None); + placeholder_type_error(tcx, None, &[], visitor.0, false, None, "associated type"); } hir::ImplItemKind::Const(..) => {} } @@ -1711,7 +1732,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_ty(ty); - let mut diag = bad_placeholder_type(tcx, visitor.0); + let mut diag = bad_placeholder_type(tcx, visitor.0, "return type"); let ret_ty = fn_sig.output(); if ret_ty != tcx.ty_error() { if !ret_ty.is_closure() { diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index abe5d69a3b3c..78fa8074a64c 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -285,7 +285,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { TraitItemKind::Const(ref ty, body_id) => body_id .and_then(|body_id| { if is_suggestable_infer_ty(ty) { - Some(infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)) + Some(infer_placeholder_type( + tcx, def_id, body_id, ty.span, item.ident, "constant", + )) } else { None } @@ -304,7 +306,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } ImplItemKind::Const(ref ty, body_id) => { if is_suggestable_infer_ty(ty) { - infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident) + infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant") } else { icx.to_ty(ty) } @@ -320,9 +322,25 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { Node::Item(item) => { match item.kind { - ItemKind::Static(ref ty, .., body_id) | ItemKind::Const(ref ty, body_id) => { + ItemKind::Static(ref ty, .., body_id) => { if is_suggestable_infer_ty(ty) { - infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident) + infer_placeholder_type( + tcx, + def_id, + body_id, + ty.span, + item.ident, + "static variable", + ) + } else { + icx.to_ty(ty) + } + } + ItemKind::Const(ref ty, body_id) => { + if is_suggestable_infer_ty(ty) { + infer_placeholder_type( + tcx, def_id, body_id, ty.span, item.ident, "constant", + ) } else { icx.to_ty(ty) } @@ -742,13 +760,14 @@ fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty concrete_ty } -fn infer_placeholder_type( - tcx: TyCtxt<'_>, +fn infer_placeholder_type<'a>( + tcx: TyCtxt<'a>, def_id: LocalDefId, body_id: hir::BodyId, span: Span, item_ident: Ident, -) -> Ty<'_> { + kind: &'static str, +) -> Ty<'a> { // Attempts to make the type nameable by turning FnDefs into FnPtrs. struct MakeNameable<'tcx> { success: bool, @@ -802,7 +821,7 @@ fn infer_placeholder_type( if let Some(sugg_ty) = sugg_ty { err.span_suggestion( span, - "provide a type for the item", + &format!("provide a type for the {item}", item = kind), format!("{}: {}", item_ident, sugg_ty), Applicability::MachineApplicable, ); @@ -816,7 +835,7 @@ fn infer_placeholder_type( err.emit_unless(ty.references_error()); } None => { - let mut diag = bad_placeholder_type(tcx, vec![span]); + let mut diag = bad_placeholder_type(tcx, vec![span], kind); if !ty.references_error() { let mut mk_nameable = MakeNameable::new(tcx); From 9b6c7ffa0601643aa1724d6552b276a7f4496aa0 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 19 Jun 2021 07:02:40 +0800 Subject: [PATCH 31/37] Updated tests to reflect specified types in E0121 --- src/test/ui/did_you_mean/bad-assoc-ty.rs | 20 +- src/test/ui/did_you_mean/bad-assoc-ty.stderr | 20 +- src/test/ui/error-codes/E0121.stderr | 4 +- src/test/ui/fn/issue-80179.rs | 4 +- src/test/ui/fn/issue-80179.stderr | 4 +- .../issue-69396-const-no-type-in-macro.rs | 2 +- .../issue-69396-const-no-type-in-macro.stderr | 4 +- src/test/ui/self/self-infer.rs | 4 +- src/test/ui/self/self-infer.stderr | 4 +- src/test/ui/suggestions/const-no-type.rs | 8 +- src/test/ui/suggestions/const-no-type.stderr | 8 +- src/test/ui/suggestions/unnamable-types.rs | 10 +- .../ui/suggestions/unnamable-types.stderr | 10 +- src/test/ui/typeck/issue-74086.rs | 2 +- src/test/ui/typeck/issue-74086.stderr | 2 +- src/test/ui/typeck/issue-75883.rs | 4 +- src/test/ui/typeck/issue-75883.stderr | 4 +- src/test/ui/typeck/issue-80779.rs | 4 +- src/test/ui/typeck/issue-80779.stderr | 4 +- src/test/ui/typeck/issue-81885.rs | 6 +- src/test/ui/typeck/issue-81885.stderr | 6 +- ...-83621-placeholder-static-in-extern.stderr | 2 +- .../ui/typeck/type-placeholder-fn-in-const.rs | 6 +- .../type-placeholder-fn-in-const.stderr | 6 +- ...eck_type_placeholder_item.full_tait.stderr | 218 +++++++++--------- ...peck_type_placeholder_item.min_tait.stderr | 218 +++++++++--------- .../ui/typeck/typeck_type_placeholder_item.rs | 121 +++++----- .../typeck_type_placeholder_item_help.rs | 12 +- .../typeck_type_placeholder_item_help.stderr | 12 +- 29 files changed, 363 insertions(+), 366 deletions(-) diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.rs b/src/test/ui/did_you_mean/bad-assoc-ty.rs index 99ebe84cd9d8..1b6bcfbb9fcd 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.rs +++ b/src/test/ui/did_you_mean/bad-assoc-ty.rs @@ -16,7 +16,7 @@ type D = (u8, u8)::AssocTy; type E = _::AssocTy; //~^ ERROR missing angle brackets in associated item path -//~| ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures for type aliases type F = &'static (u8)::AssocTy; //~^ ERROR missing angle brackets in associated item path @@ -47,37 +47,37 @@ type I = ty!()::AssocTy; trait K {} fn foo>(x: X) {} -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn bar(_: F) where F: Fn() -> _ {} -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn baz _>(_: F) {} -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions struct L(F) where F: Fn() -> _; -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for structs struct M where F: Fn() -> _ { -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for structs a: F, } enum N where F: Fn() -> _ { -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for enums Foo(F), } union O where F: Fn() -> _ { -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for unions foo: F, } trait P where F: Fn() -> _ { -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for traits } trait Q { fn foo(_: F) where F: Fn() -> _ {} - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions } fn main() {} diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index fc5f218c04f1..8db9652b1ead 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -81,7 +81,7 @@ error[E0223]: ambiguous associated type LL | type D = (u8, u8)::AssocTy; | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<(u8, u8) as Trait>::AssocTy` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for type aliases --> $DIR/bad-assoc-ty.rs:17:10 | LL | type E = _::AssocTy; @@ -122,7 +122,7 @@ error[E0223]: ambiguous associated type LL | type I = ty!()::AssocTy; | ^^^^^^^^^^^^^^ help: use fully-qualified syntax: `::AssocTy` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/bad-assoc-ty.rs:49:13 | LL | fn foo>(x: X) {} @@ -135,7 +135,7 @@ help: use type parameters instead LL | fn foo, T>(x: X) {} | ^ ^ ^^^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/bad-assoc-ty.rs:52:34 | LL | fn bar(_: F) where F: Fn() -> _ {} @@ -146,7 +146,7 @@ help: use type parameters instead LL | fn bar(_: F) where F: Fn() -> T {} | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/bad-assoc-ty.rs:55:19 | LL | fn baz _>(_: F) {} @@ -157,7 +157,7 @@ help: use type parameters instead LL | fn baz T, T>(_: F) {} | ^^^^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs --> $DIR/bad-assoc-ty.rs:58:33 | LL | struct L(F) where F: Fn() -> _; @@ -168,7 +168,7 @@ help: use type parameters instead LL | struct L(F) where F: Fn() -> T; | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs --> $DIR/bad-assoc-ty.rs:60:30 | LL | struct M where F: Fn() -> _ { @@ -179,7 +179,7 @@ help: use type parameters instead LL | struct M where F: Fn() -> T { | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for enums --> $DIR/bad-assoc-ty.rs:64:28 | LL | enum N where F: Fn() -> _ { @@ -190,7 +190,7 @@ help: use type parameters instead LL | enum N where F: Fn() -> T { | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for unions --> $DIR/bad-assoc-ty.rs:69:29 | LL | union O where F: Fn() -> _ { @@ -201,7 +201,7 @@ help: use type parameters instead LL | union O where F: Fn() -> T { | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for traits --> $DIR/bad-assoc-ty.rs:74:29 | LL | trait P where F: Fn() -> _ { @@ -212,7 +212,7 @@ help: use type parameters instead LL | trait P where F: Fn() -> T { | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/bad-assoc-ty.rs:79:38 | LL | fn foo(_: F) where F: Fn() -> _ {} diff --git a/src/test/ui/error-codes/E0121.stderr b/src/test/ui/error-codes/E0121.stderr index 246f69558ff0..cc0c2df72ea7 100644 --- a/src/test/ui/error-codes/E0121.stderr +++ b/src/test/ui/error-codes/E0121.stderr @@ -1,4 +1,4 @@ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/E0121.rs:1:13 | LL | fn foo() -> _ { 5 } @@ -7,7 +7,7 @@ LL | fn foo() -> _ { 5 } | not allowed in type signatures | help: replace with the correct return type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/E0121.rs:3:13 | LL | static BAR: _ = "test"; diff --git a/src/test/ui/fn/issue-80179.rs b/src/test/ui/fn/issue-80179.rs index 7609b1525cc9..550974bf7788 100644 --- a/src/test/ui/fn/issue-80179.rs +++ b/src/test/ui/fn/issue-80179.rs @@ -8,7 +8,7 @@ fn returns_i32() -> i32 { } fn returns_fn_ptr() -> _ { -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures [E0121] +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types [E0121] //~| NOTE not allowed in type signatures //~| HELP replace with the correct return type //~| SUGGESTION fn() -> i32 @@ -16,7 +16,7 @@ fn returns_fn_ptr() -> _ { } fn returns_closure() -> _ { -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures [E0121] +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types [E0121] //~| NOTE not allowed in type signatures //~| HELP consider using an `Fn`, `FnMut`, or `FnOnce` trait bound //~| NOTE for more information on `Fn` traits and closure types, see diff --git a/src/test/ui/fn/issue-80179.stderr b/src/test/ui/fn/issue-80179.stderr index 63571e71b34f..96d0f02b01af 100644 --- a/src/test/ui/fn/issue-80179.stderr +++ b/src/test/ui/fn/issue-80179.stderr @@ -1,4 +1,4 @@ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/issue-80179.rs:10:24 | LL | fn returns_fn_ptr() -> _ { @@ -7,7 +7,7 @@ LL | fn returns_fn_ptr() -> _ { | not allowed in type signatures | help: replace with the correct return type: `fn() -> i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/issue-80179.rs:18:25 | LL | fn returns_closure() -> _ { diff --git a/src/test/ui/issues/issue-69396-const-no-type-in-macro.rs b/src/test/ui/issues/issue-69396-const-no-type-in-macro.rs index 69fc0c1cbb96..6880e1a46293 100644 --- a/src/test/ui/issues/issue-69396-const-no-type-in-macro.rs +++ b/src/test/ui/issues/issue-69396-const-no-type-in-macro.rs @@ -4,7 +4,7 @@ macro_rules! suite { const A = "A".$fn(); //~^ ERROR the name `A` is defined multiple times //~| ERROR missing type for `const` item - //~| ERROR the type placeholder `_` is not allowed within types + //~| ERROR the type placeholder `_` is not allowed within types on item signatures for constants )* } } diff --git a/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr b/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr index a84c048fab96..34c2073db048 100644 --- a/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr +++ b/src/test/ui/issues/issue-69396-const-no-type-in-macro.stderr @@ -20,7 +20,7 @@ error: missing type for `const` item --> $DIR/issue-69396-const-no-type-in-macro.rs:4:19 | LL | const A = "A".$fn(); - | ^ help: provide a type for the item: `A: usize` + | ^ help: provide a type for the constant: `A: usize` ... LL | / suite! { LL | | len; @@ -30,7 +30,7 @@ LL | | } | = note: this error originates in the macro `suite` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants --> $DIR/issue-69396-const-no-type-in-macro.rs:4:19 | LL | const A = "A".$fn(); diff --git a/src/test/ui/self/self-infer.rs b/src/test/ui/self/self-infer.rs index 0956f2a56918..cc17d8f8e396 100644 --- a/src/test/ui/self/self-infer.rs +++ b/src/test/ui/self/self-infer.rs @@ -1,8 +1,8 @@ struct S; impl S { - fn f(self: _) {} //~ERROR the type placeholder `_` is not allowed within types on item sig - fn g(self: &_) {} //~ERROR the type placeholder `_` is not allowed within types on item sig + fn f(self: _) {} //~ERROR the type placeholder `_` is not allowed within types on item signatures for functions + fn g(self: &_) {} //~ERROR the type placeholder `_` is not allowed within types on item signatures for functions } fn main() {} diff --git a/src/test/ui/self/self-infer.stderr b/src/test/ui/self/self-infer.stderr index 1475b212b56a..8d70c6287e55 100644 --- a/src/test/ui/self/self-infer.stderr +++ b/src/test/ui/self/self-infer.stderr @@ -1,4 +1,4 @@ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/self-infer.rs:4:16 | LL | fn f(self: _) {} @@ -9,7 +9,7 @@ help: use type parameters instead LL | fn f(self: T) {} | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/self-infer.rs:5:17 | LL | fn g(self: &_) {} diff --git a/src/test/ui/suggestions/const-no-type.rs b/src/test/ui/suggestions/const-no-type.rs index 2ffb24c6e6c6..6f46cfdf0246 100644 --- a/src/test/ui/suggestions/const-no-type.rs +++ b/src/test/ui/suggestions/const-no-type.rs @@ -32,20 +32,20 @@ static mut SM2 = "abc"; const C = 42; //~^ ERROR missing type for `const` item -//~| HELP provide a type for the item +//~| HELP provide a type for the constant //~| SUGGESTION C: i32 const D = &&42; //~^ ERROR missing type for `const` item -//~| HELP provide a type for the item +//~| HELP provide a type for the constant //~| SUGGESTION D: &&i32 static S = Vec::::new(); //~^ ERROR missing type for `static` item -//~| HELP provide a type for the item +//~| HELP provide a type for the static variable //~| SUGGESTION S: Vec static mut SM = "abc"; //~^ ERROR missing type for `static mut` item -//~| HELP provide a type for the item +//~| HELP provide a type for the static variable //~| SUGGESTION &str diff --git a/src/test/ui/suggestions/const-no-type.stderr b/src/test/ui/suggestions/const-no-type.stderr index b180a6a9a9b4..3b0fd6337f1f 100644 --- a/src/test/ui/suggestions/const-no-type.stderr +++ b/src/test/ui/suggestions/const-no-type.stderr @@ -2,25 +2,25 @@ error: missing type for `const` item --> $DIR/const-no-type.rs:33:7 | LL | const C = 42; - | ^ help: provide a type for the item: `C: i32` + | ^ help: provide a type for the constant: `C: i32` error: missing type for `const` item --> $DIR/const-no-type.rs:38:7 | LL | const D = &&42; - | ^ help: provide a type for the item: `D: &&i32` + | ^ help: provide a type for the constant: `D: &&i32` error: missing type for `static` item --> $DIR/const-no-type.rs:43:8 | LL | static S = Vec::::new(); - | ^ help: provide a type for the item: `S: Vec` + | ^ help: provide a type for the static variable: `S: Vec` error: missing type for `static mut` item --> $DIR/const-no-type.rs:48:12 | LL | static mut SM = "abc"; - | ^^ help: provide a type for the item: `SM: &str` + | ^^ help: provide a type for the static variable: `SM: &str` error: missing type for `const` item --> $DIR/const-no-type.rs:14:7 diff --git a/src/test/ui/suggestions/unnamable-types.rs b/src/test/ui/suggestions/unnamable-types.rs index 5d0616443e5a..483f9bbb48cc 100644 --- a/src/test/ui/suggestions/unnamable-types.rs +++ b/src/test/ui/suggestions/unnamable-types.rs @@ -5,17 +5,17 @@ const A = 5; //~^ ERROR: missing type for `const` item -//~| HELP: provide a type for the item +//~| HELP: provide a type for the constant static B: _ = "abc"; -//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures for static variables //~| NOTE: not allowed in type signatures //~| HELP: replace with the correct type // FIXME: this should also suggest a function pointer, as the closure is non-capturing const C: _ = || 42; -//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures for constants //~| NOTE: not allowed in type signatures //~| NOTE: however, the inferred type @@ -28,10 +28,10 @@ const D = S { t: { let i = 0; move || -> i32 { i } } }; fn foo() -> i32 { 42 } const E = foo; //~^ ERROR: missing type for `const` item -//~| HELP: provide a type for the item +//~| HELP: provide a type for the constant const F = S { t: foo }; //~^ ERROR: missing type for `const` item -//~| HELP: provide a type for the item +//~| HELP: provide a type for the constant const G = || -> i32 { yield 0; return 1; }; diff --git a/src/test/ui/suggestions/unnamable-types.stderr b/src/test/ui/suggestions/unnamable-types.stderr index 05a7baa68baf..3a489a6e9431 100644 --- a/src/test/ui/suggestions/unnamable-types.stderr +++ b/src/test/ui/suggestions/unnamable-types.stderr @@ -2,9 +2,9 @@ error: missing type for `const` item --> $DIR/unnamable-types.rs:6:7 | LL | const A = 5; - | ^ help: provide a type for the item: `A: i32` + | ^ help: provide a type for the constant: `A: i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/unnamable-types.rs:10:11 | LL | static B: _ = "abc"; @@ -13,7 +13,7 @@ LL | static B: _ = "abc"; | not allowed in type signatures | help: replace with the correct type: `&str` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants --> $DIR/unnamable-types.rs:17:10 | LL | const C: _ = || 42; @@ -41,13 +41,13 @@ error: missing type for `const` item --> $DIR/unnamable-types.rs:29:7 | LL | const E = foo; - | ^ help: provide a type for the item: `E: fn() -> i32` + | ^ help: provide a type for the constant: `E: fn() -> i32` error: missing type for `const` item --> $DIR/unnamable-types.rs:32:7 | LL | const F = S { t: foo }; - | ^ help: provide a type for the item: `F: S i32>` + | ^ help: provide a type for the constant: `F: S i32>` error: missing type for `const` item --> $DIR/unnamable-types.rs:37:7 diff --git a/src/test/ui/typeck/issue-74086.rs b/src/test/ui/typeck/issue-74086.rs index f68a665b2f38..1de9cd8007cf 100644 --- a/src/test/ui/typeck/issue-74086.rs +++ b/src/test/ui/typeck/issue-74086.rs @@ -1,4 +1,4 @@ fn main() { static BUG: fn(_) -> u8 = |_| 8; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures [E0121] + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions [E0121] } diff --git a/src/test/ui/typeck/issue-74086.stderr b/src/test/ui/typeck/issue-74086.stderr index e602425059e1..ac1752e17dfb 100644 --- a/src/test/ui/typeck/issue-74086.stderr +++ b/src/test/ui/typeck/issue-74086.stderr @@ -1,4 +1,4 @@ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/issue-74086.rs:2:20 | LL | static BUG: fn(_) -> u8 = |_| 8; diff --git a/src/test/ui/typeck/issue-75883.rs b/src/test/ui/typeck/issue-75883.rs index 8cd34f48835e..0d1534df091f 100644 --- a/src/test/ui/typeck/issue-75883.rs +++ b/src/test/ui/typeck/issue-75883.rs @@ -5,7 +5,7 @@ pub struct UI {} impl UI { pub fn run() -> Result<_> { //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied - //~| ERROR: the type placeholder `_` is not allowed within types on item signatures + //~| ERROR: the type placeholder `_` is not allowed within types on item signatures for return types let mut ui = UI {}; ui.interact(); @@ -14,7 +14,7 @@ impl UI { pub fn interact(&mut self) -> Result<_> { //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied - //~| ERROR: the type placeholder `_` is not allowed within types on item signatures + //~| ERROR: the type placeholder `_` is not allowed within types on item signatures for return types unimplemented!(); } } diff --git a/src/test/ui/typeck/issue-75883.stderr b/src/test/ui/typeck/issue-75883.stderr index 71f4138c81d5..a722c4b5e3ea 100644 --- a/src/test/ui/typeck/issue-75883.stderr +++ b/src/test/ui/typeck/issue-75883.stderr @@ -34,13 +34,13 @@ help: add missing generic argument LL | pub fn interact(&mut self) -> Result<_, E> { | ^^^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/issue-75883.rs:15:42 | LL | pub fn interact(&mut self) -> Result<_> { | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/issue-75883.rs:6:28 | LL | pub fn run() -> Result<_> { diff --git a/src/test/ui/typeck/issue-80779.rs b/src/test/ui/typeck/issue-80779.rs index 6791976196f3..99a93b1863d6 100644 --- a/src/test/ui/typeck/issue-80779.rs +++ b/src/test/ui/typeck/issue-80779.rs @@ -3,11 +3,11 @@ pub struct T<'a>(&'a str); pub fn f<'a>(val: T<'a>) -> _ { - //~^ ERROR: the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR: the type placeholder `_` is not allowed within types on item signatures for return types g(val) } pub fn g(_: T<'static>) -> _ {} -//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR: the type placeholder `_` is not allowed within types on item signatures for return types fn main() {} diff --git a/src/test/ui/typeck/issue-80779.stderr b/src/test/ui/typeck/issue-80779.stderr index aca494520f8b..5a695fecc29d 100644 --- a/src/test/ui/typeck/issue-80779.stderr +++ b/src/test/ui/typeck/issue-80779.stderr @@ -1,4 +1,4 @@ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/issue-80779.rs:10:28 | LL | pub fn g(_: T<'static>) -> _ {} @@ -7,7 +7,7 @@ LL | pub fn g(_: T<'static>) -> _ {} | not allowed in type signatures | help: replace with the correct return type: `()` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/issue-80779.rs:5:29 | LL | pub fn f<'a>(val: T<'a>) -> _ { diff --git a/src/test/ui/typeck/issue-81885.rs b/src/test/ui/typeck/issue-81885.rs index 86c39d4a48c0..5117f250fe5e 100644 --- a/src/test/ui/typeck/issue-81885.rs +++ b/src/test/ui/typeck/issue-81885.rs @@ -1,10 +1,8 @@ const TEST4: fn() -> _ = 42; - //~^ ERROR the type placeholder `_` is not allowed within types on item - //signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn main() { const TEST5: fn() -> _ = 42; - //~^ ERROR the type placeholder `_` is not allowed within types on item - //signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions } diff --git a/src/test/ui/typeck/issue-81885.stderr b/src/test/ui/typeck/issue-81885.stderr index 955b42838744..8206156a6180 100644 --- a/src/test/ui/typeck/issue-81885.stderr +++ b/src/test/ui/typeck/issue-81885.stderr @@ -1,11 +1,11 @@ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/issue-81885.rs:1:22 | LL | const TEST4: fn() -> _ = 42; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/issue-81885.rs:6:26 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/issue-81885.rs:5:26 | LL | const TEST5: fn() -> _ = 42; | ^ not allowed in type signatures diff --git a/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr b/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr index b1bec4c0827f..7c5cf1082be0 100644 --- a/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr +++ b/src/test/ui/typeck/issue-83621-placeholder-static-in-extern.stderr @@ -1,4 +1,4 @@ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/issue-83621-placeholder-static-in-extern.rs:4:15 | LL | static x: _; diff --git a/src/test/ui/typeck/type-placeholder-fn-in-const.rs b/src/test/ui/typeck/type-placeholder-fn-in-const.rs index c27edc8485b9..f657bea16487 100644 --- a/src/test/ui/typeck/type-placeholder-fn-in-const.rs +++ b/src/test/ui/typeck/type-placeholder-fn-in-const.rs @@ -2,13 +2,13 @@ struct MyStruct; trait Test { const TEST: fn() -> _; - //~^ ERROR: the type placeholder `_` is not allowed within types on item signatures [E0121] - //~| ERROR: the type placeholder `_` is not allowed within types on item signatures [E0121] + //~^ ERROR: the type placeholder `_` is not allowed within types on item signatures for functions [E0121] + //~| ERROR: the type placeholder `_` is not allowed within types on item signatures for constants [E0121] } impl Test for MyStruct { const TEST: fn() -> _ = 42; - //~^ ERROR: the type placeholder `_` is not allowed within types on item signatures [E0121] + //~^ ERROR: the type placeholder `_` is not allowed within types on item signatures for functions [E0121] } fn main() {} diff --git a/src/test/ui/typeck/type-placeholder-fn-in-const.stderr b/src/test/ui/typeck/type-placeholder-fn-in-const.stderr index 662871779a10..62f4db8638f3 100644 --- a/src/test/ui/typeck/type-placeholder-fn-in-const.stderr +++ b/src/test/ui/typeck/type-placeholder-fn-in-const.stderr @@ -1,16 +1,16 @@ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/type-placeholder-fn-in-const.rs:4:25 | LL | const TEST: fn() -> _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants --> $DIR/type-placeholder-fn-in-const.rs:4:25 | LL | const TEST: fn() -> _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/type-placeholder-fn-in-const.rs:10:25 | LL | const TEST: fn() -> _ = 42; diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.full_tait.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.full_tait.stderr index bd7cbd444d70..b6aea9586b87 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.full_tait.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.full_tait.stderr @@ -1,35 +1,35 @@ error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:158:18 + --> $DIR/typeck_type_placeholder_item.rs:157:18 | LL | struct BadStruct<_>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:161:16 + --> $DIR/typeck_type_placeholder_item.rs:160:16 | LL | trait BadTrait<_> {} | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:171:19 + --> $DIR/typeck_type_placeholder_item.rs:170:19 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:171:22 + --> $DIR/typeck_type_placeholder_item.rs:170:22 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:176:19 + --> $DIR/typeck_type_placeholder_item.rs:175:19 | LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error: associated constant in `impl` without body - --> $DIR/typeck_type_placeholder_item.rs:209:5 + --> $DIR/typeck_type_placeholder_item.rs:208:5 | LL | const C: _; | ^^^^^^^^^^- @@ -37,7 +37,7 @@ LL | const C: _; | help: provide a definition for the constant: `= ;` error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters - --> $DIR/typeck_type_placeholder_item.rs:171:22 + --> $DIR/typeck_type_placeholder_item.rs:170:22 | LL | struct BadStruct1<_, _>(_); | - ^ already used @@ -53,7 +53,7 @@ LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))] = note: `#[warn(incomplete_features)]` on by default = note: see issue #63063 for more information -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:10:14 | LL | fn test() -> _ { 5 } @@ -62,7 +62,7 @@ LL | fn test() -> _ { 5 } | not allowed in type signatures | help: replace with the correct return type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:13:16 | LL | fn test2() -> (_, _) { (5, 5) } @@ -72,7 +72,7 @@ LL | fn test2() -> (_, _) { (5, 5) } | |not allowed in type signatures | help: replace with the correct return type: `(i32, i32)` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:16:15 | LL | static TEST3: _ = "test"; @@ -81,7 +81,7 @@ LL | static TEST3: _ = "test"; | not allowed in type signatures | help: replace with the correct type: `&str` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:19:15 | LL | static TEST4: _ = 145; @@ -90,13 +90,13 @@ LL | static TEST4: _ = 145; | not allowed in type signatures | help: replace with the correct type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:22:15 | LL | static TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:25:13 | LL | fn test6(_: _) { } @@ -107,7 +107,7 @@ help: use type parameters instead LL | fn test6(_: T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:28:18 | LL | fn test6_b(_: _, _: T) { } @@ -118,7 +118,7 @@ help: use type parameters instead LL | fn test6_b(_: U, _: T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:31:30 | LL | fn test6_c(_: _, _: (T, K, L, A, B)) { } @@ -129,7 +129,7 @@ help: use type parameters instead LL | fn test6_c(_: U, _: (T, K, L, A, B)) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:34:13 | LL | fn test7(x: _) { let _x: usize = x; } @@ -140,7 +140,7 @@ help: use type parameters instead LL | fn test7(x: T) { let _x: usize = x; } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:37:22 | LL | fn test8(_f: fn() -> _) { } @@ -149,7 +149,7 @@ LL | fn test8(_f: fn() -> _) { } | not allowed in type signatures | help: use type parameters instead: `T` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:37:22 | LL | fn test8(_f: fn() -> _) { } @@ -160,7 +160,7 @@ help: use type parameters instead LL | fn test8(_f: fn() -> T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:51:26 | LL | fn test11(x: &usize) -> &_ { @@ -169,7 +169,7 @@ LL | fn test11(x: &usize) -> &_ { | |not allowed in type signatures | help: replace with the correct return type: `&'static &'static usize` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:56:52 | LL | unsafe fn test12(x: *const usize) -> *const *const _ { @@ -178,7 +178,7 @@ LL | unsafe fn test12(x: *const usize) -> *const *const _ { | | not allowed in type signatures | help: replace with the correct return type: `*const *const usize` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs --> $DIR/typeck_type_placeholder_item.rs:70:8 | LL | a: _, @@ -201,9 +201,9 @@ error: missing type for `static` item --> $DIR/typeck_type_placeholder_item.rs:76:12 | LL | static A = 42; - | ^ help: provide a type for the item: `A: i32` + | ^ help: provide a type for the static variable: `A: i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:78:15 | LL | static B: _ = 42; @@ -212,14 +212,14 @@ LL | static B: _ = 42; | not allowed in type signatures | help: replace with the correct type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:80:15 | LL | static C: Option<_> = Some(42); | ^^^^^^^^^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:83:21 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:82:21 | LL | fn fn_test() -> _ { 5 } | ^ @@ -227,8 +227,8 @@ LL | fn fn_test() -> _ { 5 } | not allowed in type signatures | help: replace with the correct return type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:86:23 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:85:23 | LL | fn fn_test2() -> (_, _) { (5, 5) } | -^--^- @@ -237,8 +237,8 @@ LL | fn fn_test2() -> (_, _) { (5, 5) } | |not allowed in type signatures | help: replace with the correct return type: `(i32, i32)` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:89:22 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:88:22 | LL | static FN_TEST3: _ = "test"; | ^ @@ -246,8 +246,8 @@ LL | static FN_TEST3: _ = "test"; | not allowed in type signatures | help: replace with the correct type: `&str` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:92:22 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:91:22 | LL | static FN_TEST4: _ = 145; | ^ @@ -255,14 +255,14 @@ LL | static FN_TEST4: _ = 145; | not allowed in type signatures | help: replace with the correct type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:95:22 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:94:22 | LL | static FN_TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:98:20 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:97:20 | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures @@ -272,8 +272,8 @@ help: use type parameters instead LL | fn fn_test6(_: T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:101:20 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:100:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -283,8 +283,8 @@ help: use type parameters instead LL | fn fn_test7(x: T) { let _x: usize = x; } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:104:29 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:103:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ @@ -292,8 +292,8 @@ LL | fn fn_test8(_f: fn() -> _) { } | not allowed in type signatures | help: use type parameters instead: `T` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:104:29 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:103:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -303,8 +303,8 @@ help: use type parameters instead LL | fn fn_test8(_f: fn() -> T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:127:12 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:126:12 | LL | a: _, | ^ not allowed in type signatures @@ -323,21 +323,21 @@ LL | b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:132:18 + --> $DIR/typeck_type_placeholder_item.rs:131:18 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ cannot infer type -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:132:28 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:131:28 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ ^ not allowed in type signatures | | | not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:136:30 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:135:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | -^--^- @@ -346,8 +346,8 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | |not allowed in type signatures | help: replace with the correct return type: `(i32, i32)` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:139:33 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:138:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ------^- @@ -355,8 +355,8 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | | not allowed in type signatures | help: replace with the correct return type: `(i32, i32)` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:158:21 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:157:21 | LL | struct BadStruct<_>(_); | ^ not allowed in type signatures @@ -366,8 +366,8 @@ help: use type parameters instead LL | struct BadStruct(T); | ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:163:15 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for implementations + --> $DIR/typeck_type_placeholder_item.rs:162:15 | LL | impl BadTrait<_> for BadStruct<_> {} | ^ ^ not allowed in type signatures @@ -379,14 +379,14 @@ help: use type parameters instead LL | impl BadTrait for BadStruct {} | ^^^ ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:166:34 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/typeck_type_placeholder_item.rs:165:34 | LL | fn impl_trait() -> impl BadTrait<_> { | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:171:25 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:170:25 | LL | struct BadStruct1<_, _>(_); | ^ not allowed in type signatures @@ -396,8 +396,8 @@ help: use type parameters instead LL | struct BadStruct1(T); | ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:176:25 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:175:25 | LL | struct BadStruct2<_, T>(_, T); | ^ not allowed in type signatures @@ -407,20 +407,20 @@ help: use type parameters instead LL | struct BadStruct2(U, T); | ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:180:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for type aliases + --> $DIR/typeck_type_placeholder_item.rs:179:14 | LL | type X = Box<_>; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:186:21 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/typeck_type_placeholder_item.rs:185:21 | LL | type Y = impl Trait<_>; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:220:31 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:219:31 | LL | fn value() -> Option<&'static _> { | ----------------^- @@ -428,8 +428,8 @@ LL | fn value() -> Option<&'static _> { | | not allowed in type signatures | help: replace with the correct return type: `Option<&'static u8>` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:225:10 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:224:10 | LL | const _: Option<_> = map(value); | ^^^^^^^^^ @@ -437,8 +437,8 @@ LL | const _: Option<_> = map(value); | not allowed in type signatures | help: replace with the correct type: `Option` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:144:31 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:143:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures @@ -448,8 +448,8 @@ help: use type parameters instead LL | fn method_test1(&self, x: T); | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:146:31 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:145:31 | LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures @@ -461,8 +461,8 @@ help: use type parameters instead LL | fn method_test2(&self, x: T) -> T; | ^^^ ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:148:31 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:147:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures @@ -472,8 +472,8 @@ help: use type parameters instead LL | fn method_test3(&self) -> T; | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:150:26 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:149:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures @@ -483,8 +483,8 @@ help: use type parameters instead LL | fn assoc_fn_test1(x: T); | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:152:26 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:151:26 | LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures @@ -496,8 +496,8 @@ help: use type parameters instead LL | fn assoc_fn_test2(x: T) -> T; | ^^^ ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:154:28 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:153:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures @@ -507,20 +507,20 @@ help: use type parameters instead LL | fn assoc_fn_test3() -> T; | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:194:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:193:14 | LL | type B = _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:196:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:195:14 | LL | const C: _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:198:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:197:14 | LL | const D: _ = 42; | ^ @@ -528,13 +528,13 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace with the correct type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:201:26 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:200:26 | LL | type F: std::ops::Fn(_); | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:44:24 | LL | fn test9(&self) -> _ { () } @@ -543,7 +543,7 @@ LL | fn test9(&self) -> _ { () } | not allowed in type signatures | help: replace with the correct return type: `()` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:47:27 | LL | fn test10(&self, _x : _) { } @@ -554,7 +554,7 @@ help: use type parameters instead LL | fn test10(&self, _x : T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:62:24 | LL | fn clone(&self) -> _ { Test9 } @@ -563,7 +563,7 @@ LL | fn clone(&self) -> _ { Test9 } | not allowed in type signatures | help: replace with the correct return type: `Test9` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:65:37 | LL | fn clone_from(&mut self, other: _) { *self = Test9; } @@ -574,8 +574,8 @@ help: use type parameters instead LL | fn clone_from(&mut self, other: T) { *self = Test9; } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:111:31 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:110:31 | LL | fn fn_test9(&self) -> _ { () } | ^ @@ -583,8 +583,8 @@ LL | fn fn_test9(&self) -> _ { () } | not allowed in type signatures | help: replace with the correct return type: `()` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:114:34 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:113:34 | LL | fn fn_test10(&self, _x : _) { } | ^ not allowed in type signatures @@ -594,8 +594,8 @@ help: use type parameters instead LL | fn fn_test10(&self, _x : T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:119:28 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:118:28 | LL | fn clone(&self) -> _ { FnTest9 } | ^ @@ -603,8 +603,8 @@ LL | fn clone(&self) -> _ { FnTest9 } | not allowed in type signatures | help: replace with the correct return type: `FnTest9` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:122:41 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:121:41 | LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } | ^ not allowed in type signatures @@ -614,26 +614,26 @@ help: use type parameters instead LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:205:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:204:14 | LL | type A = _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:207:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:206:14 | LL | type B = _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:209:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:208:14 | LL | const C: _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:212:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:211:14 | LL | const D: _ = 42; | ^ diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.min_tait.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.min_tait.stderr index afd6aaf4e55a..88cc3bfc7f8c 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.min_tait.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.min_tait.stderr @@ -1,35 +1,35 @@ error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:158:18 + --> $DIR/typeck_type_placeholder_item.rs:157:18 | LL | struct BadStruct<_>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:161:16 + --> $DIR/typeck_type_placeholder_item.rs:160:16 | LL | trait BadTrait<_> {} | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:171:19 + --> $DIR/typeck_type_placeholder_item.rs:170:19 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:171:22 + --> $DIR/typeck_type_placeholder_item.rs:170:22 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:176:19 + --> $DIR/typeck_type_placeholder_item.rs:175:19 | LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error: associated constant in `impl` without body - --> $DIR/typeck_type_placeholder_item.rs:209:5 + --> $DIR/typeck_type_placeholder_item.rs:208:5 | LL | const C: _; | ^^^^^^^^^^- @@ -37,14 +37,14 @@ LL | const C: _; | help: provide a definition for the constant: `= ;` error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters - --> $DIR/typeck_type_placeholder_item.rs:171:22 + --> $DIR/typeck_type_placeholder_item.rs:170:22 | LL | struct BadStruct1<_, _>(_); | - ^ already used | | | first use of `_` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:10:14 | LL | fn test() -> _ { 5 } @@ -53,7 +53,7 @@ LL | fn test() -> _ { 5 } | not allowed in type signatures | help: replace with the correct return type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:13:16 | LL | fn test2() -> (_, _) { (5, 5) } @@ -63,7 +63,7 @@ LL | fn test2() -> (_, _) { (5, 5) } | |not allowed in type signatures | help: replace with the correct return type: `(i32, i32)` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:16:15 | LL | static TEST3: _ = "test"; @@ -72,7 +72,7 @@ LL | static TEST3: _ = "test"; | not allowed in type signatures | help: replace with the correct type: `&str` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:19:15 | LL | static TEST4: _ = 145; @@ -81,13 +81,13 @@ LL | static TEST4: _ = 145; | not allowed in type signatures | help: replace with the correct type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:22:15 | LL | static TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:25:13 | LL | fn test6(_: _) { } @@ -98,7 +98,7 @@ help: use type parameters instead LL | fn test6(_: T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:28:18 | LL | fn test6_b(_: _, _: T) { } @@ -109,7 +109,7 @@ help: use type parameters instead LL | fn test6_b(_: U, _: T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:31:30 | LL | fn test6_c(_: _, _: (T, K, L, A, B)) { } @@ -120,7 +120,7 @@ help: use type parameters instead LL | fn test6_c(_: U, _: (T, K, L, A, B)) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:34:13 | LL | fn test7(x: _) { let _x: usize = x; } @@ -131,7 +131,7 @@ help: use type parameters instead LL | fn test7(x: T) { let _x: usize = x; } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:37:22 | LL | fn test8(_f: fn() -> _) { } @@ -140,7 +140,7 @@ LL | fn test8(_f: fn() -> _) { } | not allowed in type signatures | help: use type parameters instead: `T` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:37:22 | LL | fn test8(_f: fn() -> _) { } @@ -151,7 +151,7 @@ help: use type parameters instead LL | fn test8(_f: fn() -> T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:51:26 | LL | fn test11(x: &usize) -> &_ { @@ -160,7 +160,7 @@ LL | fn test11(x: &usize) -> &_ { | |not allowed in type signatures | help: replace with the correct return type: `&'static &'static usize` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:56:52 | LL | unsafe fn test12(x: *const usize) -> *const *const _ { @@ -169,7 +169,7 @@ LL | unsafe fn test12(x: *const usize) -> *const *const _ { | | not allowed in type signatures | help: replace with the correct return type: `*const *const usize` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs --> $DIR/typeck_type_placeholder_item.rs:70:8 | LL | a: _, @@ -192,9 +192,9 @@ error: missing type for `static` item --> $DIR/typeck_type_placeholder_item.rs:76:12 | LL | static A = 42; - | ^ help: provide a type for the item: `A: i32` + | ^ help: provide a type for the static variable: `A: i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:78:15 | LL | static B: _ = 42; @@ -203,14 +203,14 @@ LL | static B: _ = 42; | not allowed in type signatures | help: replace with the correct type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:80:15 | LL | static C: Option<_> = Some(42); | ^^^^^^^^^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:83:21 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:82:21 | LL | fn fn_test() -> _ { 5 } | ^ @@ -218,8 +218,8 @@ LL | fn fn_test() -> _ { 5 } | not allowed in type signatures | help: replace with the correct return type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:86:23 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:85:23 | LL | fn fn_test2() -> (_, _) { (5, 5) } | -^--^- @@ -228,8 +228,8 @@ LL | fn fn_test2() -> (_, _) { (5, 5) } | |not allowed in type signatures | help: replace with the correct return type: `(i32, i32)` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:89:22 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:88:22 | LL | static FN_TEST3: _ = "test"; | ^ @@ -237,8 +237,8 @@ LL | static FN_TEST3: _ = "test"; | not allowed in type signatures | help: replace with the correct type: `&str` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:92:22 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:91:22 | LL | static FN_TEST4: _ = 145; | ^ @@ -246,14 +246,14 @@ LL | static FN_TEST4: _ = 145; | not allowed in type signatures | help: replace with the correct type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:95:22 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static variables + --> $DIR/typeck_type_placeholder_item.rs:94:22 | LL | static FN_TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:98:20 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:97:20 | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures @@ -263,8 +263,8 @@ help: use type parameters instead LL | fn fn_test6(_: T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:101:20 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:100:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -274,8 +274,8 @@ help: use type parameters instead LL | fn fn_test7(x: T) { let _x: usize = x; } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:104:29 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:103:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ @@ -283,8 +283,8 @@ LL | fn fn_test8(_f: fn() -> _) { } | not allowed in type signatures | help: use type parameters instead: `T` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:104:29 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:103:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -294,8 +294,8 @@ help: use type parameters instead LL | fn fn_test8(_f: fn() -> T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:127:12 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:126:12 | LL | a: _, | ^ not allowed in type signatures @@ -314,21 +314,21 @@ LL | b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:132:18 + --> $DIR/typeck_type_placeholder_item.rs:131:18 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ cannot infer type -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:132:28 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:131:28 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ ^ not allowed in type signatures | | | not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:136:30 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:135:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | -^--^- @@ -337,8 +337,8 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | |not allowed in type signatures | help: replace with the correct return type: `(i32, i32)` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:139:33 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:138:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ------^- @@ -346,8 +346,8 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | | not allowed in type signatures | help: replace with the correct return type: `(i32, i32)` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:158:21 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:157:21 | LL | struct BadStruct<_>(_); | ^ not allowed in type signatures @@ -357,8 +357,8 @@ help: use type parameters instead LL | struct BadStruct(T); | ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:163:15 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for implementations + --> $DIR/typeck_type_placeholder_item.rs:162:15 | LL | impl BadTrait<_> for BadStruct<_> {} | ^ ^ not allowed in type signatures @@ -370,14 +370,14 @@ help: use type parameters instead LL | impl BadTrait for BadStruct {} | ^^^ ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:166:34 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/typeck_type_placeholder_item.rs:165:34 | LL | fn impl_trait() -> impl BadTrait<_> { | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:171:25 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:170:25 | LL | struct BadStruct1<_, _>(_); | ^ not allowed in type signatures @@ -387,8 +387,8 @@ help: use type parameters instead LL | struct BadStruct1(T); | ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:176:25 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for structs + --> $DIR/typeck_type_placeholder_item.rs:175:25 | LL | struct BadStruct2<_, T>(_, T); | ^ not allowed in type signatures @@ -398,20 +398,20 @@ help: use type parameters instead LL | struct BadStruct2(U, T); | ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:180:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for type aliases + --> $DIR/typeck_type_placeholder_item.rs:179:14 | LL | type X = Box<_>; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:186:21 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for opaque types + --> $DIR/typeck_type_placeholder_item.rs:185:21 | LL | type Y = impl Trait<_>; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:220:31 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:219:31 | LL | fn value() -> Option<&'static _> { | ----------------^- @@ -419,8 +419,8 @@ LL | fn value() -> Option<&'static _> { | | not allowed in type signatures | help: replace with the correct return type: `Option<&'static u8>` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:225:10 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:224:10 | LL | const _: Option<_> = map(value); | ^^^^^^^^^ @@ -428,8 +428,8 @@ LL | const _: Option<_> = map(value); | not allowed in type signatures | help: replace with the correct type: `Option` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:144:31 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:143:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures @@ -439,8 +439,8 @@ help: use type parameters instead LL | fn method_test1(&self, x: T); | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:146:31 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:145:31 | LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures @@ -452,8 +452,8 @@ help: use type parameters instead LL | fn method_test2(&self, x: T) -> T; | ^^^ ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:148:31 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:147:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures @@ -463,8 +463,8 @@ help: use type parameters instead LL | fn method_test3(&self) -> T; | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:150:26 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:149:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures @@ -474,8 +474,8 @@ help: use type parameters instead LL | fn assoc_fn_test1(x: T); | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:152:26 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:151:26 | LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures @@ -487,8 +487,8 @@ help: use type parameters instead LL | fn assoc_fn_test2(x: T) -> T; | ^^^ ^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:154:28 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:153:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures @@ -498,20 +498,20 @@ help: use type parameters instead LL | fn assoc_fn_test3() -> T; | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:194:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:193:14 | LL | type B = _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:196:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:195:14 | LL | const C: _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:198:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:197:14 | LL | const D: _ = 42; | ^ @@ -519,13 +519,13 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace with the correct type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:201:26 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:200:26 | LL | type F: std::ops::Fn(_); | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:44:24 | LL | fn test9(&self) -> _ { () } @@ -534,7 +534,7 @@ LL | fn test9(&self) -> _ { () } | not allowed in type signatures | help: replace with the correct return type: `()` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:47:27 | LL | fn test10(&self, _x : _) { } @@ -545,7 +545,7 @@ help: use type parameters instead LL | fn test10(&self, _x : T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:62:24 | LL | fn clone(&self) -> _ { Test9 } @@ -554,7 +554,7 @@ LL | fn clone(&self) -> _ { Test9 } | not allowed in type signatures | help: replace with the correct return type: `Test9` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:65:37 | LL | fn clone_from(&mut self, other: _) { *self = Test9; } @@ -565,8 +565,8 @@ help: use type parameters instead LL | fn clone_from(&mut self, other: T) { *self = Test9; } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:111:31 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:110:31 | LL | fn fn_test9(&self) -> _ { () } | ^ @@ -574,8 +574,8 @@ LL | fn fn_test9(&self) -> _ { () } | not allowed in type signatures | help: replace with the correct return type: `()` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:114:34 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:113:34 | LL | fn fn_test10(&self, _x : _) { } | ^ not allowed in type signatures @@ -585,8 +585,8 @@ help: use type parameters instead LL | fn fn_test10(&self, _x : T) { } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:119:28 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/typeck_type_placeholder_item.rs:118:28 | LL | fn clone(&self) -> _ { FnTest9 } | ^ @@ -594,8 +594,8 @@ LL | fn clone(&self) -> _ { FnTest9 } | not allowed in type signatures | help: replace with the correct return type: `FnTest9` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:122:41 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/typeck_type_placeholder_item.rs:121:41 | LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } | ^ not allowed in type signatures @@ -605,26 +605,26 @@ help: use type parameters instead LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } | ^^^ ^ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:205:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:204:14 | LL | type A = _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:207:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for associated types + --> $DIR/typeck_type_placeholder_item.rs:206:14 | LL | type B = _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:209:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:208:14 | LL | const C: _; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:212:14 +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:211:14 | LL | const D: _ = 42; | ^ diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index 8a52556ed346..55f5d44d46b3 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -8,67 +8,67 @@ // inference by using the `_` type placeholder. fn test() -> _ { 5 } -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types fn test2() -> (_, _) { (5, 5) } -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types static TEST3: _ = "test"; -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for static variables static TEST4: _ = 145; -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for static variables static TEST5: (_, _) = (1, 2); -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for static variables fn test6(_: _) { } -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn test6_b(_: _, _: T) { } -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn test6_c(_: _, _: (T, K, L, A, B)) { } -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn test7(x: _) { let _x: usize = x; } -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn test8(_f: fn() -> _) { } -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures -//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions +//~^^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions struct Test9; impl Test9 { fn test9(&self) -> _ { () } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types fn test10(&self, _x : _) { } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions } fn test11(x: &usize) -> &_ { -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types &x } unsafe fn test12(x: *const usize) -> *const *const _ { -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types &x } impl Clone for Test9 { fn clone(&self) -> _ { Test9 } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types fn clone_from(&mut self, other: _) { *self = Test9; } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions } struct Test10 { a: _, - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for structs b: (_, _), } @@ -76,95 +76,94 @@ pub fn main() { static A = 42; //~^ ERROR missing type for `static` item static B: _ = 42; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for static variables static C: Option<_> = Some(42); - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures - + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for static variables fn fn_test() -> _ { 5 } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types fn fn_test2() -> (_, _) { (5, 5) } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types static FN_TEST3: _ = "test"; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for static variables static FN_TEST4: _ = 145; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for static variables static FN_TEST5: (_, _) = (1, 2); - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for static variables fn fn_test6(_: _) { } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn fn_test7(x: _) { let _x: usize = x; } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn fn_test8(_f: fn() -> _) { } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures - //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions + //~^^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions struct FnTest9; impl FnTest9 { fn fn_test9(&self) -> _ { () } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types fn fn_test10(&self, _x : _) { } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions } impl Clone for FnTest9 { fn clone(&self) -> _ { FnTest9 } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types fn clone_from(&mut self, other: _) { *self = FnTest9; } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions } struct FnTest10 { a: _, - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for structs b: (_, _), } fn fn_test11(_: _) -> (_, _) { panic!() } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types //~| ERROR type annotations needed fn fn_test12(x: i32) -> (_, _) { (x, x) } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types fn fn_test13(x: _) -> (i32, _) { (x, x) } - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types } trait T { fn method_test1(&self, x: _); - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn method_test2(&self, x: _) -> _; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn method_test3(&self) -> _; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn assoc_fn_test1(x: _); - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn assoc_fn_test2(x: _) -> _; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions fn assoc_fn_test3() -> _; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions } struct BadStruct<_>(_); //~^ ERROR expected identifier, found reserved identifier `_` -//~| ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures for structs trait BadTrait<_> {} //~^ ERROR expected identifier, found reserved identifier `_` impl BadTrait<_> for BadStruct<_> {} -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for implementations fn impl_trait() -> impl BadTrait<_> { -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for opaque types unimplemented!() } @@ -172,19 +171,19 @@ struct BadStruct1<_, _>(_); //~^ ERROR expected identifier, found reserved identifier `_` //~| ERROR expected identifier, found reserved identifier `_` //~| ERROR the name `_` is already used -//~| ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures for structs struct BadStruct2<_, T>(_, T); //~^ ERROR expected identifier, found reserved identifier `_` -//~| ERROR the type placeholder `_` is not allowed within types on item signatures +//~| ERROR the type placeholder `_` is not allowed within types on item signatures for structs type X = Box<_>; -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for type aliases struct Struct; trait Trait {} impl Trait for Struct {} type Y = impl Trait<_>; -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for opaque types fn foo() -> Y { Struct } @@ -192,25 +191,25 @@ fn foo() -> Y { trait Qux { type A; type B = _; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for associated types const C: _; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for constants const D: _ = 42; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for constants // type E: _; // FIXME: make the parser propagate the existence of `B` type F: std::ops::Fn(_); - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for associated types } impl Qux for Struct { type A = _; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for associated types type B = _; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for associated types const C: _; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for constants //~| ERROR associated constant in `impl` without body const D: _ = 42; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for constants } fn map(_: fn() -> Option<&'static T>) -> Option { @@ -218,9 +217,9 @@ fn map(_: fn() -> Option<&'static T>) -> Option { } fn value() -> Option<&'static _> { -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types Option::<&'static u8>::None } const _: Option<_> = map(value); -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for constants diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.rs b/src/test/ui/typeck/typeck_type_placeholder_item_help.rs index 0c890f88c60d..3af5cf926abf 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item_help.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.rs @@ -2,27 +2,27 @@ // using the `_` type placeholder. fn test1() -> _ { Some(42) } -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for return types const TEST2: _ = 42u32; -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for constants const TEST3: _ = Some(42); -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for constants const TEST4: fn() -> _ = 42; -//~^ ERROR the type placeholder `_` is not allowed within types on item signatures +//~^ ERROR the type placeholder `_` is not allowed within types on item signatures for functions trait Test5 { const TEST5: _ = 42; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for constants } struct Test6; impl Test6 { const TEST6: _ = 13; - //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures for constants } pub fn main() { diff --git a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr index 2b64df774b08..1b56b1033a8c 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item_help.stderr @@ -1,4 +1,4 @@ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item_help.rs:4:15 | LL | fn test1() -> _ { Some(42) } @@ -7,7 +7,7 @@ LL | fn test1() -> _ { Some(42) } | not allowed in type signatures | help: replace with the correct return type: `Option` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants --> $DIR/typeck_type_placeholder_item_help.rs:7:14 | LL | const TEST2: _ = 42u32; @@ -16,7 +16,7 @@ LL | const TEST2: _ = 42u32; | not allowed in type signatures | help: replace with the correct type: `u32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants --> $DIR/typeck_type_placeholder_item_help.rs:10:14 | LL | const TEST3: _ = Some(42); @@ -25,13 +25,13 @@ LL | const TEST3: _ = Some(42); | not allowed in type signatures | help: replace with the correct type: `Option` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item_help.rs:13:22 | LL | const TEST4: fn() -> _ = 42; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants --> $DIR/typeck_type_placeholder_item_help.rs:17:18 | LL | const TEST5: _ = 42; @@ -40,7 +40,7 @@ LL | const TEST5: _ = 42; | not allowed in type signatures | help: replace with the correct type: `i32` -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constants --> $DIR/typeck_type_placeholder_item_help.rs:24:18 | LL | const TEST6: _ = 13; From e66f241b80a91133c454cc02306f25269c03ea73 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 22 Jun 2021 01:03:54 +0800 Subject: [PATCH 32/37] Update #83739 with type of the item specified --- compiler/rustc_typeck/src/collect.rs | 10 +++++++++- src/test/ui/typeck/issue-75889.stderr | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index f741606370fb..91e65cffc58c 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -839,7 +839,15 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { if let hir::TyKind::TraitObject(..) = ty.kind { let mut visitor = PlaceholderHirTyCollector::default(); visitor.visit_item(it); - placeholder_type_error(tcx, None, &[], visitor.0, false, None); + placeholder_type_error( + tcx, + None, + &[], + visitor.0, + false, + None, + it.kind.descr(), + ); } } _ => (), diff --git a/src/test/ui/typeck/issue-75889.stderr b/src/test/ui/typeck/issue-75889.stderr index 0a8a3c9e7433..de4bdf4e6d9d 100644 --- a/src/test/ui/typeck/issue-75889.stderr +++ b/src/test/ui/typeck/issue-75889.stderr @@ -1,10 +1,10 @@ -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for constant items --> $DIR/issue-75889.rs:3:24 | LL | const FOO: dyn Fn() -> _ = ""; | ^ not allowed in type signatures -error[E0121]: the type placeholder `_` is not allowed within types on item signatures +error[E0121]: the type placeholder `_` is not allowed within types on item signatures for static items --> $DIR/issue-75889.rs:4:25 | LL | static BOO: dyn Fn() -> _ = ""; From aa3580baa6f5ef69aba41a63297fb659bcd4b793 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 21 Jun 2021 14:36:25 -0400 Subject: [PATCH 33/37] introduce helper function --- .../src/check/method/prelude2021.rs | 54 +++++++++++-------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index 0750567d3dd6..4c925a6f2370 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -137,28 +137,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { segment.ident.name )); - if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span) - { - let derefs = "*".repeat(pick.autoderefs); - - let autoref = match pick.autoref_or_ptr_adjustment { - Some(probe::AutorefOrPtrAdjustment::Autoref { - mutbl: Mutability::Mut, - .. - }) => "&mut ", - Some(probe::AutorefOrPtrAdjustment::Autoref { - mutbl: Mutability::Not, - .. - }) => "&", - Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "", - }; - let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) = - pick.autoref_or_ptr_adjustment - { - format!("{}{} as *const _", derefs, self_expr) - } else { - format!("{}{}{}", autoref, derefs, self_expr) - }; + let (self_adjusted, precise) = self.adjust_expr(pick, self_expr); + if precise { let args = args .iter() .skip(1) @@ -317,4 +297,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } + + /// Creates a string version of the `expr` that includes explicit adjustments. + /// Returns the string and also a bool indicating whther this is a *precise* + /// suggestion. + fn adjust_expr(&self, pick: &Pick<'tcx>, expr: &hir::Expr<'tcx>) -> (String, bool) { + let derefs = "*".repeat(pick.autoderefs); + + let autoref = match pick.autoref_or_ptr_adjustment { + Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl: Mutability::Mut, .. }) => "&mut ", + Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl: Mutability::Not, .. }) => "&", + Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "", + }; + + let (expr_text, precise) = + if let Ok(expr_text) = self.sess().source_map().span_to_snippet(expr.span) { + (expr_text, true) + } else { + (format!("(..)"), false) + }; + + let adjusted_text = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) = + pick.autoref_or_ptr_adjustment + { + format!("{}{} as *const _", derefs, expr_text) + } else { + format!("{}{}{}", autoref, derefs, expr_text) + }; + + (adjusted_text, precise) + } } From b07bb6d698d842f05b1664b8824671080274d53d Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Thu, 29 Apr 2021 20:54:22 -0500 Subject: [PATCH 34/37] Fix unused_unsafe with compiler-generated unsafe --- compiler/rustc_middle/src/mir/mod.rs | 2 ++ compiler/rustc_middle/src/thir.rs | 1 + .../rustc_mir/src/transform/check_unsafety.rs | 1 + compiler/rustc_mir_build/src/build/block.rs | 1 + .../rustc_mir_build/src/check_unsafety.rs | 33 +++++++++++-------- compiler/rustc_mir_build/src/thir/cx/block.rs | 7 +++- ...round-compiler-generated-unsafe.mir.stderr | 8 ++--- ...unsafe-around-compiler-generated-unsafe.rs | 7 ++-- ...ound-compiler-generated-unsafe.thir.stderr | 8 ++--- 9 files changed, 43 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 0daaec272fd9..672686410f9b 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -494,6 +494,8 @@ impl<'tcx> Body<'tcx> { #[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)] pub enum Safety { Safe, + /// Unsafe because of compiler-generated unsafe code, like `await` desugaring + BuiltinUnsafe, /// Unsafe because of an unsafe fn FnUnsafe, /// Unsafe because of an `unsafe` block diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 2f107e7b96c5..6b2e542ee705 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -114,6 +114,7 @@ pub struct Adt<'tcx> { #[derive(Copy, Clone, Debug, HashStable)] pub enum BlockSafety { Safe, + BuiltinUnsafe, ExplicitUnsafe(hir::HirId), } diff --git a/compiler/rustc_mir/src/transform/check_unsafety.rs b/compiler/rustc_mir/src/transform/check_unsafety.rs index 324a5257f5df..103ddda1a1d2 100644 --- a/compiler/rustc_mir/src/transform/check_unsafety.rs +++ b/compiler/rustc_mir/src/transform/check_unsafety.rs @@ -321,6 +321,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { } false } + Safety::BuiltinUnsafe => true, Safety::ExplicitUnsafe(hir_id) => { // mark unsafe block as used if there are any unsafe operations inside if !violations.is_empty() { diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 4e1983aca944..df71379c1d88 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -214,6 +214,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug!("update_source_scope_for({:?}, {:?})", span, safety_mode); let new_unsafety = match safety_mode { BlockSafety::Safe => None, + BlockSafety::BuiltinUnsafe => Some(Safety::BuiltinUnsafe), BlockSafety::ExplicitUnsafe(hir_id) => { match self.in_scope_unsafe { Safety::Safe => {} diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index e4ed5dece862..4e80931ec037 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -29,11 +29,7 @@ struct UnsafetyVisitor<'a, 'tcx> { } impl<'tcx> UnsafetyVisitor<'_, 'tcx> { - fn in_safety_context( - &mut self, - safety_context: SafetyContext, - f: impl FnOnce(&mut Self) -> R, - ) { + fn in_safety_context(&mut self, safety_context: SafetyContext, f: impl FnOnce(&mut Self)) { if let ( SafetyContext::UnsafeBlock { span: enclosing_span, .. }, SafetyContext::UnsafeBlock { span: block_span, hir_id, .. }, @@ -63,7 +59,6 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { ); } self.safety_context = prev_context; - return; } } @@ -71,6 +66,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { let (description, note) = kind.description_and_note(); let unsafe_op_in_unsafe_fn_allowed = self.unsafe_op_in_unsafe_fn_allowed(); match self.safety_context { + SafetyContext::BuiltinUnsafeBlock => {} SafetyContext::UnsafeBlock { ref mut used, .. } => { if !self.body_unsafety.is_unsafe() || !unsafe_op_in_unsafe_fn_allowed { // Mark this block as useful @@ -142,13 +138,23 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } fn visit_block(&mut self, block: &Block) { - if let BlockSafety::ExplicitUnsafe(hir_id) = block.safety_mode { - self.in_safety_context( - SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false }, - |this| visit::walk_block(this, block), - ); - } else { - visit::walk_block(self, block); + match block.safety_mode { + // compiler-generated unsafe code should not count towards the usefulness of + // an outer unsafe block + BlockSafety::BuiltinUnsafe => { + self.in_safety_context(SafetyContext::BuiltinUnsafeBlock, |this| { + visit::walk_block(this, block) + }); + } + BlockSafety::ExplicitUnsafe(hir_id) => { + self.in_safety_context( + SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false }, + |this| visit::walk_block(this, block), + ); + } + BlockSafety::Safe => { + visit::walk_block(self, block); + } } } @@ -250,6 +256,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { #[derive(Clone, Copy)] enum SafetyContext { Safe, + BuiltinUnsafeBlock, UnsafeFn, UnsafeBlock { span: Span, hir_id: hir::HirId, used: bool }, } diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 4fe8cd8541aa..2d9b5c1d98aa 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -26,7 +26,12 @@ impl<'tcx> Cx<'tcx> { expr: block.expr.map(|expr| self.mirror_expr(expr)), safety_mode: match block.rules { hir::BlockCheckMode::DefaultBlock => BlockSafety::Safe, - hir::BlockCheckMode::UnsafeBlock(..) => BlockSafety::ExplicitUnsafe(block.hir_id), + hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::CompilerGenerated) => { + BlockSafety::BuiltinUnsafe + } + hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) => { + BlockSafety::ExplicitUnsafe(block.hir_id) + } }, } } diff --git a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.mir.stderr b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.mir.stderr index 681013268612..29bd84cd0db5 100644 --- a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.mir.stderr +++ b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.mir.stderr @@ -1,11 +1,11 @@ error: unnecessary `unsafe` block - --> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:5 + --> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:9 | -LL | unsafe { println!("foo"); } - | ^^^^^^ unnecessary `unsafe` block +LL | unsafe { async {}.await; } + | ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here - --> $DIR/unsafe-around-compiler-generated-unsafe.rs:6:9 + --> $DIR/unsafe-around-compiler-generated-unsafe.rs:5:9 | LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ diff --git a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs index 08801f9ef59f..e9c7efb9e8b8 100644 --- a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs +++ b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.rs @@ -1,10 +1,11 @@ -// issue #12418 - +// edition:2018 // revisions: mir thir // [thir]compile-flags: -Z thir-unsafeck #![deny(unused_unsafe)] fn main() { - unsafe { println!("foo"); } //~ ERROR unnecessary `unsafe` + let _ = async { + unsafe { async {}.await; } //~ ERROR unnecessary `unsafe` + }; } diff --git a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.thir.stderr b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.thir.stderr index 681013268612..29bd84cd0db5 100644 --- a/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.thir.stderr +++ b/src/test/ui/unsafe/unsafe-around-compiler-generated-unsafe.thir.stderr @@ -1,11 +1,11 @@ error: unnecessary `unsafe` block - --> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:5 + --> $DIR/unsafe-around-compiler-generated-unsafe.rs:9:9 | -LL | unsafe { println!("foo"); } - | ^^^^^^ unnecessary `unsafe` block +LL | unsafe { async {}.await; } + | ^^^^^^ unnecessary `unsafe` block | note: the lint level is defined here - --> $DIR/unsafe-around-compiler-generated-unsafe.rs:6:9 + --> $DIR/unsafe-around-compiler-generated-unsafe.rs:5:9 | LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ From 9224b6fe205e20c6b88570977ad1c27d2c2ecfb3 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 20 Jun 2021 20:22:25 -0400 Subject: [PATCH 35/37] Remove unnecessary call to queries.crate_name() It's much more complicated than just going through the TyCtxt. --- src/librustdoc/doctest.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 88e2f6048e9c..90ec0eb273e7 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -4,6 +4,7 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{ColorConfig, ErrorReported}; use rustc_hir as hir; use rustc_hir::intravisit; +use rustc_hir::def_id::LOCAL_CRATE; use rustc_hir::{HirId, CRATE_HIR_ID}; use rustc_interface::interface; use rustc_middle::hir::map::Map; @@ -111,8 +112,6 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { let res = interface::run_compiler(config, |compiler| { compiler.enter(|queries| { let _lower_to_hir = queries.lower_to_hir()?; - - let crate_name = queries.crate_name()?.peek().to_string(); let mut global_ctxt = queries.global_ctxt()?.take(); let collector = global_ctxt.enter(|tcx| { @@ -123,7 +122,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { opts.display_warnings |= options.display_warnings; let enable_per_target_ignores = options.enable_per_target_ignores; let mut collector = Collector::new( - crate_name, + tcx.crate_name(LOCAL_CRATE).to_string(), options, false, opts, From 1c557dada20ef79f7a46666b3152ac42fe58e6f9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 20 Jun 2021 20:24:59 -0400 Subject: [PATCH 36/37] Rename cratename -> crate_name This makes it consistent with rustc_session::Options. --- src/librustdoc/doctest.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 90ec0eb273e7..d791a995d863 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -292,7 +292,7 @@ struct UnusedExterns { fn run_test( test: &str, - cratename: &str, + crate_name: &str, line: usize, options: Options, should_panic: bool, @@ -311,7 +311,7 @@ fn run_test( report_unused_externs: impl Fn(UnusedExterns), ) -> Result<(), TestFailure> { let (test, line_offset, supports_color) = - make_test(test, Some(cratename), as_test_harness, opts, edition, Some(test_id)); + make_test(test, Some(crate_name), as_test_harness, opts, edition, Some(test_id)); let output_file = outdir.path().join("rust_out"); @@ -478,7 +478,7 @@ fn run_test( /// lines before the test code begins as well as if the output stream supports colors or not. crate fn make_test( s: &str, - cratename: Option<&str>, + crate_name: Option<&str>, dont_insert_main: bool, opts: &TestOptions, edition: Edition, @@ -539,7 +539,7 @@ crate fn make_test( let sess = ParseSess::with_span_handler(handler, sm); let mut found_main = false; - let mut found_extern_crate = cratename.is_none(); + let mut found_extern_crate = crate_name.is_none(); let mut found_macro = false; let mut parser = match maybe_new_parser_from_source_str(&sess, filename, source) { @@ -566,13 +566,13 @@ crate fn make_test( if !found_extern_crate { if let ast::ItemKind::ExternCrate(original) = item.kind { - // This code will never be reached if `cratename` is none because + // This code will never be reached if `crate_name` is none because // `found_extern_crate` is initialized to `true` if it is none. - let cratename = cratename.unwrap(); + let crate_name = crate_name.unwrap(); match original { - Some(name) => found_extern_crate = name.as_str() == cratename, - None => found_extern_crate = item.ident.as_str() == cratename, + Some(name) => found_extern_crate = name.as_str() == crate_name, + None => found_extern_crate = item.ident.as_str() == crate_name, } } } @@ -630,14 +630,14 @@ crate fn make_test( // Don't inject `extern crate std` because it's already injected by the // compiler. - if !already_has_extern_crate && !opts.no_crate_inject && cratename != Some("std") { - if let Some(cratename) = cratename { + if !already_has_extern_crate && !opts.no_crate_inject && crate_name != Some("std") { + if let Some(crate_name) = crate_name { // Don't inject `extern crate` if the crate is never used. // NOTE: this is terribly inaccurate because it doesn't actually // parse the source, but only has false positives, not false // negatives. - if s.contains(cratename) { - prog.push_str(&format!("extern crate r#{};\n", cratename)); + if s.contains(crate_name) { + prog.push_str(&format!("extern crate r#{};\n", crate_name)); line_offset += 1; } } @@ -796,7 +796,7 @@ crate struct Collector { options: Options, use_headers: bool, enable_per_target_ignores: bool, - cratename: String, + crate_name: String, opts: TestOptions, position: Span, source_map: Option>, @@ -808,7 +808,7 @@ crate struct Collector { impl Collector { crate fn new( - cratename: String, + crate_name: String, options: Options, use_headers: bool, opts: TestOptions, @@ -822,7 +822,7 @@ impl Collector { options, use_headers, enable_per_target_ignores, - cratename, + crate_name, opts, position: DUMMY_SP, source_map, @@ -870,7 +870,7 @@ impl Tester for Collector { fn add_test(&mut self, test: String, config: LangString, line: usize) { let filename = self.get_filename(); let name = self.generate_name(line, &filename); - let cratename = self.cratename.to_string(); + let crate_name = self.crate_name.to_string(); let opts = self.opts.clone(); let edition = config.edition.unwrap_or(self.options.edition); let options = self.options.clone(); @@ -953,7 +953,7 @@ impl Tester for Collector { }; let res = run_test( &test, - &cratename, + &crate_name, line, options, config.should_panic, From ff0e0466abc364f90bd5930b9e48cce41aa08137 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 20 Jun 2021 20:34:38 -0400 Subject: [PATCH 37/37] Don't reallocate the crate name when running doctests --- src/librustdoc/doctest.rs | 9 +++++---- src/librustdoc/markdown.rs | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index d791a995d863..1750f05b4dcf 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -3,8 +3,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_errors::{ColorConfig, ErrorReported}; use rustc_hir as hir; -use rustc_hir::intravisit; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_hir::intravisit; use rustc_hir::{HirId, CRATE_HIR_ID}; use rustc_interface::interface; use rustc_middle::hir::map::Map; @@ -14,6 +14,7 @@ use rustc_session::{lint, DiagnosticOutput, Session}; use rustc_span::edition::Edition; use rustc_span::source_map::SourceMap; use rustc_span::symbol::sym; +use rustc_span::Symbol; use rustc_span::{BytePos, FileName, Pos, Span, DUMMY_SP}; use rustc_target::spec::TargetTriple; use tempfile::Builder as TempFileBuilder; @@ -122,7 +123,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> { opts.display_warnings |= options.display_warnings; let enable_per_target_ignores = options.enable_per_target_ignores; let mut collector = Collector::new( - tcx.crate_name(LOCAL_CRATE).to_string(), + tcx.crate_name(LOCAL_CRATE), options, false, opts, @@ -796,7 +797,7 @@ crate struct Collector { options: Options, use_headers: bool, enable_per_target_ignores: bool, - crate_name: String, + crate_name: Symbol, opts: TestOptions, position: Span, source_map: Option>, @@ -808,7 +809,7 @@ crate struct Collector { impl Collector { crate fn new( - crate_name: String, + crate_name: Symbol, options: Options, use_headers: bool, opts: TestOptions, diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 963f2cf71f38..5da3a75e8763 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -4,6 +4,7 @@ use std::path::Path; use rustc_span::edition::Edition; use rustc_span::source_map::DUMMY_SP; +use rustc_span::Symbol; use crate::config::{Options, RenderOptions}; use crate::doctest::{Collector, TestOptions}; @@ -121,7 +122,7 @@ crate fn test(mut options: Options) -> Result<(), String> { opts.no_crate_inject = true; opts.display_warnings = options.display_warnings; let mut collector = Collector::new( - options.input.display().to_string(), + Symbol::intern(&options.input.display().to_string()), options.clone(), true, opts,