diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index d533e267fd702..d9a1193aac4ba 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -287,6 +287,7 @@ pub struct InferenceDiagnosticsData {
pub struct InferenceDiagnosticsParentData {
pub prefix: &'static str,
pub name: String,
+ pub def_id: DefId,
}
pub enum UnderspecifiedArgKind {
@@ -328,6 +329,7 @@ impl InferenceDiagnosticsParentData {
Some(InferenceDiagnosticsParentData {
prefix: tcx.def_kind(parent_def_id).descr(parent_def_id),
name: parent_name,
+ def_id: parent_def_id,
})
}
}
@@ -754,12 +756,30 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
if let (UnderspecifiedArgKind::Const { .. }, Some(parent_data)) =
(&arg_data.kind, &arg_data.parent)
{
- err.span_suggestion_verbose(
- span,
- "consider specifying the const argument",
- format!("{}::<{}>", parent_data.name, arg_data.name),
- Applicability::MaybeIncorrect,
- );
+ let has_impl_trait =
+ self.tcx.generics_of(parent_data.def_id).params.iter().any(|param| {
+ matches!(
+ param.kind,
+ ty::GenericParamDefKind::Type {
+ synthetic: Some(
+ hir::SyntheticTyParamKind::ImplTrait
+ | hir::SyntheticTyParamKind::FromAttr,
+ ),
+ ..
+ }
+ )
+ });
+
+ // (#83606): Do not emit a suggestion if the parent has an `impl Trait`
+ // as an argument otherwise it will cause the E0282 error.
+ if !has_impl_trait {
+ err.span_suggestion_verbose(
+ span,
+ "consider specifying the const argument",
+ format!("{}::<{}>", parent_data.name, arg_data.name),
+ Applicability::MaybeIncorrect,
+ );
+ }
}
err.span_label(
diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs
index e64cbc18bf71b..2a3d44fb17d9f 100644
--- a/library/std/src/keyword_docs.rs
+++ b/library/std/src/keyword_docs.rs
@@ -547,15 +547,18 @@ mod fn_keyword {}
/// # fn code() { }
/// # let iterator = 0..2;
/// {
-/// let mut _iter = std::iter::IntoIterator::into_iter(iterator);
-/// loop {
-/// match _iter.next() {
-/// Some(loop_variable) => {
-/// code()
-/// },
-/// None => break,
-/// }
-/// }
+/// let result = match IntoIterator::into_iter(iterator) {
+/// mut iter => loop {
+/// let next;
+/// match iter.next() {
+/// Some(val) => next = val,
+/// None => break,
+/// };
+/// let loop_variable = next;
+/// let () = { code(); };
+/// },
+/// };
+/// result
/// }
/// ```
///
@@ -1310,7 +1313,11 @@ mod return_keyword {}
/// [Reference]: ../reference/items/associated-items.html#methods
mod self_keyword {}
-#[doc(keyword = "Self")]
+// FIXME: Once rustdoc can handle URL conflicts on case insensitive file systems, we can remove the
+// three next lines and put back: `#[doc(keyword = "Self")]`.
+#[doc(alias = "Self")]
+#[allow(rustc::existing_doc_keyword)]
+#[doc(keyword = "SelfTy")]
//
/// The implementing type within a [`trait`] or [`impl`] block, or the current type within a type
/// definition.
diff --git a/library/std/src/prelude/mod.rs b/library/std/src/prelude/mod.rs
index 505b5f3013b35..1b4facdd049bb 100644
--- a/library/std/src/prelude/mod.rs
+++ b/library/std/src/prelude/mod.rs
@@ -28,53 +28,53 @@
//! The current version of the prelude (version 1) lives in
//! [`std::prelude::v1`], and re-exports the following:
//!
-//! * [`std::marker`]::{[`Copy`], [`Send`], [`Sized`], [`Sync`], [`Unpin`]}:
+//! * [std::marker]::{[Copy], [Send], [Sized], [Sync], [Unpin]}
,
//! marker traits that indicate fundamental properties of types.
-//! * [`std::ops`]::{[`Drop`], [`Fn`], [`FnMut`], [`FnOnce`]}: various
+//! * [std::ops]::{[Drop], [Fn], [FnMut], [FnOnce]}
, various
//! operations for both destructors and overloading `()`.
-//! * [`std::mem`]::[`drop`][`mem::drop`]: a convenience function for explicitly
+//! * [std::mem]::[drop][mem::drop]
, a convenience function for explicitly
//! dropping a value.
-//! * [`std::boxed`]::[`Box`]: a way to allocate values on the heap.
-//! * [`std::borrow`]::[`ToOwned`]: the conversion trait that defines
+//! * [std::boxed]::[Box]
, a way to allocate values on the heap.
+//! * [std::borrow]::[ToOwned]
, the conversion trait that defines
//! [`to_owned`], the generic method for creating an owned type from a
//! borrowed type.
-//! * [`std::clone`]::[`Clone`]: the ubiquitous trait that defines
-//! [`clone`][`Clone::clone`], the method for producing a copy of a value.
-//! * [`std::cmp`]::{[`PartialEq`], [`PartialOrd`], [`Eq`], [`Ord`]}: the
+//! * [std::clone]::[Clone]
, the ubiquitous trait that defines
+//! [`clone`][Clone::clone], the method for producing a copy of a value.
+//! * [std::cmp]::{[PartialEq], [PartialOrd], [Eq], [Ord]}
, the
//! comparison traits, which implement the comparison operators and are often
//! seen in trait bounds.
-//! * [`std::convert`]::{[`AsRef`], [`AsMut`], [`Into`], [`From`]}: generic
+//! * [std::convert]::{[AsRef], [AsMut], [Into], [From]}
, generic
//! conversions, used by savvy API authors to create overloaded methods.
-//! * [`std::default`]::[`Default`], types that have default values.
-//! * [`std::iter`]::{[`Iterator`], [`Extend`], [`IntoIterator`],
-//! [`DoubleEndedIterator`], [`ExactSizeIterator`]}: iterators of various
+//! * [std::default]::[Default]
, types that have default values.
+//! * [std::iter]::{[Iterator], [Extend], [IntoIterator], [DoubleEndedIterator], [ExactSizeIterator]}
,
+//! iterators of various
//! kinds.
-//! * [`std::option`]::[`Option`]::{[`self`][`Option`], [`Some`], [`None`]}, a
+//! * [std::option]::[Option]::{[self][Option], [Some], [None]}
, a
//! type which expresses the presence or absence of a value. This type is so
//! commonly used, its variants are also exported.
-//! * [`std::result`]::[`Result`]::{[`self`][`Result`], [`Ok`], [`Err`]}: a type
+//! * [std::result]::[Result]::{[self][Result], [Ok], [Err]}
, a type
//! for functions that may succeed or fail. Like [`Option`], its variants are
//! exported as well.
-//! * [`std::string`]::{[`String`], [`ToString`]}: heap-allocated strings.
-//! * [`std::vec`]::[`Vec`]: a growable, heap-allocated vector.
+//! * [std::string]::{[String], [ToString]}
, heap-allocated strings.
+//! * [std::vec]::[Vec]
, a growable, heap-allocated vector.
//!
-//! [`mem::drop`]: crate::mem::drop
-//! [`std::borrow`]: crate::borrow
-//! [`std::boxed`]: crate::boxed
-//! [`std::clone`]: crate::clone
-//! [`std::cmp`]: crate::cmp
-//! [`std::convert`]: crate::convert
-//! [`std::default`]: crate::default
-//! [`std::iter`]: crate::iter
-//! [`std::marker`]: crate::marker
-//! [`std::mem`]: crate::mem
-//! [`std::ops`]: crate::ops
-//! [`std::option`]: crate::option
+//! [mem::drop]: crate::mem::drop
+//! [std::borrow]: crate::borrow
+//! [std::boxed]: crate::boxed
+//! [std::clone]: crate::clone
+//! [std::cmp]: crate::cmp
+//! [std::convert]: crate::convert
+//! [std::default]: crate::default
+//! [std::iter]: crate::iter
+//! [std::marker]: crate::marker
+//! [std::mem]: crate::mem
+//! [std::ops]: crate::ops
+//! [std::option]: crate::option
//! [`std::prelude::v1`]: v1
-//! [`std::result`]: crate::result
-//! [`std::slice`]: crate::slice
-//! [`std::string`]: crate::string
-//! [`std::vec`]: mod@crate::vec
+//! [std::result]: crate::result
+//! [std::slice]: crate::slice
+//! [std::string]: crate::string
+//! [std::vec]: mod@crate::vec
//! [`to_owned`]: crate::borrow::ToOwned::to_owned
//! [book-closures]: ../../book/ch13-01-closures.html
//! [book-dtor]: ../../book/ch15-03-drop.html
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index f4976f2f436fc..adb0a372c64dd 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -108,6 +108,19 @@ impl Step for Linkcheck {
/// documentation to ensure we don't have a bunch of dead ones.
fn run(self, builder: &Builder<'_>) {
let host = self.host;
+ let hosts = &builder.hosts;
+ let targets = &builder.targets;
+
+ // if we have different hosts and targets, some things may be built for
+ // the host (e.g. rustc) and others for the target (e.g. std). The
+ // documentation built for each will contain broken links to
+ // docs built for the other platform (e.g. rustc linking to cargo)
+ if (hosts != targets) && !hosts.is_empty() && !targets.is_empty() {
+ panic!(
+ "Linkcheck currently does not support builds with different hosts and targets.
+You can skip linkcheck with --exclude src/tools/linkchecker"
+ );
+ }
builder.info(&format!("Linkcheck ({})", host));
@@ -123,19 +136,6 @@ impl Step for Linkcheck {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let builder = run.builder;
let run = run.path("src/tools/linkchecker");
- let hosts = &builder.hosts;
- let targets = &builder.targets;
-
- // if we have different hosts and targets, some things may be built for
- // the host (e.g. rustc) and others for the target (e.g. std). The
- // documentation built for each will contain broken links to
- // docs built for the other platform (e.g. rustc linking to cargo)
- if (hosts != targets) && !hosts.is_empty() && !targets.is_empty() {
- panic!(
- "Linkcheck currently does not support builds with different hosts and targets.
-You can skip linkcheck with --exclude src/tools/linkchecker"
- );
- }
run.default_condition(builder.config.docs)
}
diff --git a/src/test/ui/inference/issue-83606.rs b/src/test/ui/inference/issue-83606.rs
new file mode 100644
index 0000000000000..be56a3020cc33
--- /dev/null
+++ b/src/test/ui/inference/issue-83606.rs
@@ -0,0 +1,10 @@
+// Regression test for #83606.
+
+fn foo(_: impl std::fmt::Display) -> [usize; N] {
+ [0; N]
+}
+
+fn main() {
+ let _ = foo("foo"); //<- Do not suggest `foo::("foo");`!
+ //~^ ERROR: type annotations needed for `[usize; _]`
+}
diff --git a/src/test/ui/inference/issue-83606.stderr b/src/test/ui/inference/issue-83606.stderr
new file mode 100644
index 0000000000000..65f3336b9358a
--- /dev/null
+++ b/src/test/ui/inference/issue-83606.stderr
@@ -0,0 +1,11 @@
+error[E0282]: type annotations needed for `[usize; _]`
+ --> $DIR/issue-83606.rs:8:13
+ |
+LL | let _ = foo("foo"); //<- Do not suggest `foo::("foo");`!
+ | - ^^^ cannot infer the value of const parameter `N` declared on the function `foo`
+ | |
+ | consider giving this pattern the explicit type `[usize; _]`, where the type parameter `N` is specified
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/proc-macro/auxiliary/issue-75801.rs b/src/test/ui/proc-macro/auxiliary/issue-75801.rs
new file mode 100644
index 0000000000000..d6c031d7d4f7e
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/issue-75801.rs
@@ -0,0 +1,13 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn foo(_args: TokenStream, item: TokenStream) -> TokenStream {
+ item
+}
diff --git a/src/test/ui/proc-macro/issue-75801.rs b/src/test/ui/proc-macro/issue-75801.rs
new file mode 100644
index 0000000000000..b07cde0fabd74
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-75801.rs
@@ -0,0 +1,19 @@
+// aux-build: issue-75801.rs
+
+// Regression test for #75801.
+
+#[macro_use]
+extern crate issue_75801;
+
+macro_rules! foo {
+ ($arg:expr) => {
+ #[foo]
+ fn bar() {
+ let _bar: u32 = $arg;
+ }
+ };
+}
+
+foo!("baz"); //~ ERROR: mismatched types [E0308]
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/issue-75801.stderr b/src/test/ui/proc-macro/issue-75801.stderr
new file mode 100644
index 0000000000000..ee0a9bd7783e6
--- /dev/null
+++ b/src/test/ui/proc-macro/issue-75801.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-75801.rs:17:6
+ |
+LL | let _bar: u32 = $arg;
+ | --- expected due to this
+...
+LL | foo!("baz");
+ | ^^^^^ expected `u32`, found `&str`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.