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`.