diff --git a/Cargo.lock b/Cargo.lock index 26b1570995407..ebf4229839076 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2282,9 +2282,9 @@ checksum = "803ec87c9cfb29b9d2633f20cba1f488db3fd53f2158b1024cbefb47ba05d413" [[package]] name = "libc" -version = "0.2.189" +version = "0.2.191" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" [[package]] name = "libffi" diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 871b974d28eea..1d1c9c0baef51 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -170,7 +170,7 @@ impl RegionName { RegionNameHighlight::CannotMatchHirTy(span, type_name), mir_description, ) => { - diag.span_label(*span, format!("return type{mir_description} is {type_name}")); + diag.span_label(*span, format!("return type{mir_description} is `{type_name}`")); } RegionNameSource::AnonRegionFromYieldTy(span, type_name) => { diag.span_label(*span, format!("yield type is {type_name}")); diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 880d387e7d72e..37e9c99d1acae 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -713,7 +713,7 @@ impl<'a> TraitDef<'a> { if self.is_const && cx.ecfg.features.staged_api() { let rustc_const_unstable = cx.path_name(self.span, sym::rustc_const_unstable); - // #[rustc_const_unstable(feature = "derive_const", issue = "118304")] + // #[rustc_const_unstable(feature = "derive_const", issue = "143874")] attrs.push( cx.attr_nested( rustc_ast::AttrItem { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 9541becfe324d..f6f1a5815a436 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -270,6 +270,8 @@ declare_features! ( (internal, profiler_runtime, "1.18.0", None), /// Allows using `rustc_*` attributes (RFC 572). (internal, rustc_attrs, "1.0.0", None), + /// Allows using internal rustdoc features like `doc(keyword)`. + (internal, rustdoc_internals, "1.58.0", None), /// Allows using the `#[stable]` and `#[unstable]` attributes. (internal, staged_api, "1.0.0", None), /// Perma-unstable, only used in the test suite for binders (`for<'a>`). @@ -322,8 +324,6 @@ declare_features! ( (internal, repr_simd, "1.4.0", Some(27731)), /// Allows using compiler's own crates. (unstable, rustc_private, "1.0.0", Some(27812)), - /// Allows using internal rustdoc features like `doc(keyword)`. - (internal, rustdoc_internals, "1.58.0", Some(90418)), /// Allows using the `rustdoc::missing_doc_code_examples` lint (unstable, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730)), /// Introduces a hierarchy of `Sized` traits (RFC 3729). @@ -666,7 +666,7 @@ declare_features! ( /// Allows providing names to parameters of `impl Fn` etc (unstable, named_fn_trait_parameters, "1.99.0", Some(158499)), /// Allows specifying the as-needed link modifier - (unstable, native_link_modifiers_as_needed, "1.53.0", Some(81490)), + (unstable, native_link_modifiers_as_needed, "1.53.0", Some(99424)), /// Allow negative trait implementations. (unstable, negative_impls, "1.44.0", Some(68318)), /// Allows the `!` pattern. @@ -725,7 +725,7 @@ declare_features! ( /// Allows the use of the `sanitize` attribute. (unstable, sanitize, "1.91.0", Some(39699)), /// Allows the use of SIMD types in functions declared in `extern` blocks. - (unstable, simd_ffi, "1.0.0", Some(27731)), + (unstable, simd_ffi, "1.0.0", Some(63068)), /// Target features on sparc. (unstable, sparc_target_feature, "1.84.0", Some(132783)), /// Allows specialization of implementations (RFC 1210). diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index f28a99744aa56..2443641efe615 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -924,6 +924,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut err = fn_call_diag_ctxt.initial_final_diagnostic(); fn_call_diag_ctxt.suggest_confusable(&mut err); + fn_call_diag_ctxt.detect_missing_turbofish(&mut err); // As we encounter issues, keep track of what we want to provide for the suggestion. @@ -3227,6 +3228,45 @@ impl<'a, 'tcx> ArgMatchingCtxt<'a, 'tcx> { self.annotate_alternative_method_deref(err, self.call_expr, None); } + fn detect_missing_turbofish(&self, err: &mut Diag<'_>) { + if self.tcx.dcx().has_errors().is_none() { + return; + } + let mut iter = self.provided_args.iter().peekable(); + while let Some(arg) = iter.next() { + let hir::ExprKind::Binary(lt, lt_left, lt_right) = arg.kind else { + continue; + }; + let hir::BinOpKind::Lt = lt.node else { continue }; + let hir::ExprKind::Path(_) = lt_left.kind else { continue }; + let hir::ExprKind::Path(_) = lt_right.kind else { continue }; + + let Some(mut next) = iter.next() else { break }; + loop { + match next.kind { + hir::ExprKind::Binary(gt, gt_left, gt_right) + if let hir::BinOpKind::Gt = gt.node + && let hir::ExprKind::Path(_) = gt_left.kind + && let hir::ExprKind::Call(..) = gt_right.kind => + { + // We've encountered a likely missing turbofish error, for which we've already + // emitted a more targeted diagnostic during name resolution making this one + // redundant (`LateResolutionVisitor::detect_missing_turbofish`). + err.downgrade_to_delayed_bug(); + } + hir::ExprKind::Path(_) => { + if let Some(n) = iter.next() { + next = n; + continue; + } + } + _ => {} + } + break; + } + } + } + /// A "softer" version of the `demand_compatible`, which checks types without persisting them, /// and treats error types differently /// This will allow us to "probe" for other argument orders that would likely have been correct diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 315ace9c0d4cf..bffcf60a920ff 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2964,9 +2964,14 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let mut mod_inner_attrs_start = None; match item.kind { ItemKind::Mod(..) => { - // We only handle outer doc comments for modules here. + // We only handle outer attributes which can contain intra-doc links (doc comments + // and `deprecated`) for modules here. let attrs = if let Some(pos) = item.attrs.iter().position(|a| { a.doc_resolution_scope().is_some_and(|style| style == AttrStyle::Inner) + || matches!( + a.kind, + AttrKind::Normal(ref n) + if n.item.name() == Some(sym::deprecated) && a.style == AttrStyle::Inner) }) { mod_inner_attrs_start = Some(pos); &item.attrs[..pos] @@ -5166,6 +5171,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } /// Handles paths that may refer to associated items. + #[tracing::instrument(skip(self, source), level = "debug")] fn resolve_qpath( &mut self, qself: &Option>, @@ -5174,11 +5180,6 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { finalize: Finalize, source: PathSource<'_, 'ast, 'ra>, ) -> Result, Spanned>> { - debug!( - "resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})", - qself, path, ns, finalize, - ); - if let Some(qself) = qself { if qself.position == 0 { // This is a case like `::B`, where there is no @@ -5578,6 +5579,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.resolve_expr(arg, None); } self.visit_path_segment(seg); + self.detect_missing_turbofish(&args); } ExprKind::Call(ref callee, ref arguments) => { @@ -5599,6 +5601,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.resolve_expr(argument, None); } } + self.detect_missing_turbofish(&arguments); } ExprKind::FormatArgs(ref args) => { for arg in args.arguments.all_args() { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 83e5fbef9bcb9..df1155bd3208c 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1768,6 +1768,170 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { } } + /// When encountering `Ty < Ty, Ty > call()` in function and method call arguments, suggest + /// using the turbofish and silence redundant resolve errors. + pub(in crate::late) fn detect_missing_turbofish(&mut self, arguments: &'ast [Box]) { + if self.use_injections.is_empty() { + // Avoid doing unnecessary work, we would have had resolve errors by now if this mistake + // had happened. + return; + } + let mut iter = arguments.iter().peekable(); + // Look through every call argument expression, when encountering `a < b`, try to find a + // closing `c > ::d()` that would make the whole thing be syntactically valid as a + // fully-qualified path `a::::d()`. + while let Some(arg) = iter.next() { + // foo(left < right, bar, baz>::qux()) + // ^^^^ ^^^^^ + let ExprKind::Binary(lt, left, right) = &arg.kind else { continue }; + // foo(left < right, bar, baz>::qux()) + // ^ + let ast::BinOpKind::Lt = lt.node else { + continue; + }; + // foo(left < right, bar, baz>::qux()) + // ^^^^ is a path + let ExprKind::Path(_, lt_left) = &left.kind else { continue }; + // foo(a::B < right, bar, baz>::qux()) + // ^ ^ lt_left_segments + let lt_left_segments: Vec<_> = lt_left.segments.iter().map(|seg| seg.into()).collect(); + // `a::B` is a type-like. + let lt_res = if let PathResult::NonModule(res) = + self.resolve_path(<_left_segments, Some(TypeNS), None, PathSource::Expr(None)) + && let Some(lt_res) = res.full_res() + { + lt_res + } else { + continue; + }; + + // Same thing we do for `left`, for `right`: + // foo(left < right, bar, baz>::qux()) + // ^^^^^ is a path + let ExprKind::Path(_, lt_right) = &right.kind else { continue }; + let lt_right_segments: Vec<_> = + lt_right.segments.iter().map(|seg| seg.into()).collect(); + if let PathResult::NonModule(res) = + self.resolve_path(<_right_segments, Some(TypeNS), None, PathSource::Expr(None)) + && let Some(_res) = res.full_res() + { + } else { + continue; + } + + // foo(left < right, bar, baz>::qux()) + // next is ^^^ or ^^^^^^^^^^^ + let Some(mut next) = iter.next() else { + break; + }; + let mut other_path_spans = vec![]; + loop { + match &next.kind { + // foo(left < right, bar, baz>::qux()) + // ^^^^^^^^^ + ExprKind::Binary(gt, gt_left, gt_right) + // foo(left < right, bar, baz>::qux()) + // ^ + if let ast::BinOpKind::Gt = gt.node + // foo(left < right, bar, baz>::qux()) + // ^^^ + && let ExprKind::Path(_, gt_left) = >_left.kind + // foo(left < right, bar, baz>::qux()) + // ^^^^^^^ + && let ExprKind::Call(call_expr, _) = >_right.kind + && let ExprKind::Path(_, call_path) = &call_expr.kind + && let gt_left_segments = gt_left + .segments + .iter() + .map(|seg| seg.into()) + .collect::>() + && let PathResult::NonModule(res) = self.resolve_path( + >_left_segments, + Some(TypeNS), + None, + PathSource::Expr(None), + ) + && let Some(_res) = res.full_res() => + { + // We've encountered an expression where we have `Ty < Ty, Ty > call(...)`. + // A binop between two types is non-sensical in (current?) Rust, and the + // presence of two binops separated by a comma of less-than followed by + // greater-than heavily implies a missing turbofish in an expression. + let mut any = false; + let spans: Vec = lt_left_segments + .iter() + .map(|s| s.ident.span) + .chain(lt_right_segments.iter().map(|s| s.ident.span)) + .chain(gt_left_segments.iter().map(|s| s.ident.span)) + .chain(gt_left_segments.iter().map(|s| s.ident.span)) + .chain(call_path.segments.iter().map(|seg| seg.span())) + .chain(other_path_spans.iter().cloned()) + .collect(); + for injection in self.use_injections.iter_mut() { + // Silence all already constructed resolution errors that are contained + // by the likely missing turbofish. + if injection.path.iter().any(|s| spans.contains(&s.ident.span)) { + any = true; + injection.err.downgrade_to_delayed_bug(); + } + } + if any { + let sp = MultiSpan::from(vec![lt.span, gt.span]); + let mut err = + self.r.tcx.dcx().struct_span_err(sp, "can't compare two types"); + err.span_label( + gt.span, + "these are parsed as \"less than\" and \"greater than\"", + ); + let name = if let Some(def_id) = lt_res.opt_def_id() + && let Some(name) = self.r.tcx.opt_item_name(def_id) + { + name.to_string() + } else { + lt_right_segments + .iter() + .map(|s| s.ident.name.to_string()) + .collect::>() + .join("::") + }; + err.span_suggestion_verbose( + lt.span.shrink_to_lo(), + format!( + "you likely intended to write type `{name}` with type parameters, but \ + type parameters in expression contexts require the use of the \ + \"turbofish\" `::<>`", + ), + "::".to_string(), + Applicability::MachineApplicable, + ); + err.emit(); + } + } + + // foo(left < right, bat, bar, baz>::qux()) + // ^^^ + ExprKind::Path(_, path) => { + // foo(left < right, bat, bar, baz>::qux()) + // ^^^ or ^^^^^^^^^^^ + if let Some(n) = iter.next() { + next = n; + other_path_spans.extend(path.segments.iter().map(|seg| seg.ident.span)); + // Only case where we don't break from the `loop` advancing the parsed + // call arguments , we've encountered a path that is likely one of the + // type parameters for the missing turbofish. + continue; + } + } + + _ => {} + } + // This doesn't look like a turbofish, look for more missing turbofishes on the + // following arguments. + break; + } + } + } + fn suggest_at_operator_in_slice_pat_with_range(&self, err: &mut Diag<'_>, path: &[Segment]) { let Some(pat) = self.diag_metadata.current_pat else { return }; let (bound, side, range) = match &pat.kind { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9f9e5fd6cba3d..cc340af0cdff1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -839,7 +839,7 @@ symbols! { deref_target, derive, derive_const, - derive_const_issue: "118304", + derive_const_issue: "143874", derive_default_enum, derive_from, derive_smart_pointer, diff --git a/library/alloc/src/collections/vec_deque/iter.rs b/library/alloc/src/collections/vec_deque/iter.rs index 7794fb450d776..9e6a72e595a1e 100644 --- a/library/alloc/src/collections/vec_deque/iter.rs +++ b/library/alloc/src/collections/vec_deque/iter.rs @@ -49,7 +49,7 @@ impl<'a, T> Iter<'a, T> { /// /// assert_eq!(iter.as_slices(), (&[9, 10][..], &[0, 1][..])); /// ``` - #[unstable(feature = "vec_deque_iter_as_slices", issue = "123947")] + #[unstable(feature = "vec_deque_iter_as_slices", issue = "133253")] pub fn as_slices(&self) -> (&'a [T], &'a [T]) { (self.i1.as_slice(), self.i2.as_slice()) } diff --git a/library/alloc/src/collections/vec_deque/iter_mut.rs b/library/alloc/src/collections/vec_deque/iter_mut.rs index 9d7b99d765fac..cf3f96122b90f 100644 --- a/library/alloc/src/collections/vec_deque/iter_mut.rs +++ b/library/alloc/src/collections/vec_deque/iter_mut.rs @@ -52,7 +52,7 @@ impl<'a, T> IterMut<'a, T> { /// slices.1[0] = 24; /// assert_eq!(deque.as_slices(), (&[8, 42, 10][..], &[24, 1, 2][..])); /// ``` - #[unstable(feature = "vec_deque_iter_as_slices", issue = "123947")] + #[unstable(feature = "vec_deque_iter_as_slices", issue = "133253")] pub fn into_slices(self) -> (&'a mut [T], &'a mut [T]) { (self.i1.into_slice(), self.i2.into_slice()) } @@ -86,7 +86,7 @@ impl<'a, T> IterMut<'a, T> { /// /// assert_eq!(iter.as_slices(), (&[9, 10][..], &[0, 1][..])); /// ``` - #[unstable(feature = "vec_deque_iter_as_slices", issue = "123947")] + #[unstable(feature = "vec_deque_iter_as_slices", issue = "133253")] pub fn as_slices(&self) -> (&[T], &[T]) { (self.i1.as_slice(), self.i2.as_slice()) } @@ -122,7 +122,7 @@ impl<'a, T> IterMut<'a, T> { /// iter.as_mut_slices().1[0] = 24; /// assert_eq!(deque.as_slices(), (&[8, 42, 10][..], &[24, 1, 2][..])); /// ``` - #[unstable(feature = "vec_deque_iter_as_slices", issue = "123947")] + #[unstable(feature = "vec_deque_iter_as_slices", issue = "133253")] pub fn as_mut_slices(&mut self) -> (&mut [T], &mut [T]) { (self.i1.as_mut_slice(), self.i2.as_mut_slice()) } diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 438549160a1c6..5583fce0b944d 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -713,31 +713,31 @@ impl [u8] { /// fn borrow(&self) -> &[String] { &self.1 } /// } /// ``` -#[unstable(feature = "slice_concat_trait", issue = "27747")] +#[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] pub trait Concat { - #[unstable(feature = "slice_concat_trait", issue = "27747")] + #[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] /// The resulting type after concatenation type Output; /// Implementation of [`[T]::concat`](slice::concat) - #[unstable(feature = "slice_concat_trait", issue = "27747")] + #[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] fn concat(slice: &Self) -> Self::Output; } /// Helper trait for [`[T]::join`](slice::join) -#[unstable(feature = "slice_concat_trait", issue = "27747")] +#[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] pub trait Join { - #[unstable(feature = "slice_concat_trait", issue = "27747")] + #[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] /// The resulting type after concatenation type Output; /// Implementation of [`[T]::join`](slice::join) - #[unstable(feature = "slice_concat_trait", issue = "27747")] + #[unstable(feature = "slice_concat_trait", issue = "none", reason = "implementation detail")] fn join(slice: &Self, sep: Separator) -> Self::Output; } #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> Concat for [V] { type Output = Vec; @@ -752,7 +752,7 @@ impl> Concat for [V] { } #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> Join<&T> for [V] { type Output = Vec; @@ -775,7 +775,7 @@ impl> Join<&T> for [V] { } #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> Join<&[T]> for [V] { type Output = Vec; diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index a736a25ccdeb8..7997e0c053dc9 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -58,7 +58,7 @@ use crate::vec::Vec; /// Note: `str` in `Concat` is not meaningful here. /// This type parameter of the trait only exists to enable another impl. #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> Concat for [S] { type Output = String; @@ -68,7 +68,7 @@ impl> Concat for [S] { } #[cfg(not(no_global_oom_handling))] -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> Join<&str> for [S] { type Output = String; diff --git a/library/core/src/intrinsics/gpu.rs b/library/core/src/intrinsics/gpu.rs index 8ea894b3955d4..b5e993342b843 100644 --- a/library/core/src/intrinsics/gpu.rs +++ b/library/core/src/intrinsics/gpu.rs @@ -46,7 +46,7 @@ #[must_use = "returns a pointer that does nothing unless used"] #[rustc_intrinsic] #[rustc_nounwind] -#[unstable(feature = "gpu_launch_sized_workgroup_mem", issue = "135513")] +#[unstable(feature = "gpu_launch_sized_workgroup_mem", issue = "131513")] #[cfg(any(doc, target_arch = "amdgpu", target_arch = "nvptx64"))] pub fn gpu_launch_sized_workgroup_mem() -> *mut T; diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 550e52480301c..e4eb66f4f97c8 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -2218,7 +2218,7 @@ pub const fn mul_with_overflow(x: T, y: T) -> (T, bool); /// This currently supports unsigned integers *only*, no signed ones. /// The stabilized versions of this intrinsic are available on integers. #[unstable(feature = "core_intrinsics", issue = "none")] -#[rustc_const_unstable(feature = "const_carrying_mul_add", issue = "85532")] +#[rustc_const_unstable(feature = "const_carrying_mul_add", issue = "152015")] #[rustc_nounwind] #[rustc_intrinsic] #[miri::intrinsic_fallback_is_spec] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index ab8fc47009186..384213bbbe56d 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1784,7 +1784,7 @@ pub(crate) mod builtin { /// See [the reference] for more info. /// /// [the reference]: ../../../reference/attributes/derive.html - #[unstable(feature = "derive_const", issue = "118304")] + #[unstable(feature = "derive_const", issue = "143874")] #[rustc_builtin_macro] pub macro derive_const($item:item) { /* compiler built-in */ @@ -1910,7 +1910,7 @@ pub(crate) mod builtin { #[allow_internal_unstable(builtin_syntax)] #[unstable( feature = "type_ascription", - issue = "23416", + issue = "101728", reason = "placeholder syntax for type ascription" )] #[diagnostic::opaque] diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 6122ab12ec351..f68d3e614c53f 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -127,7 +127,7 @@ pub use crate::macros::builtin::{ #[doc(no_inline)] pub use crate::macros::builtin::derive; -#[unstable(feature = "derive_const", issue = "118304")] +#[unstable(feature = "derive_const", issue = "143874")] pub use crate::macros::builtin::derive_const; #[unstable( @@ -146,7 +146,7 @@ pub use crate::macros::builtin::cfg_eval; #[unstable( feature = "type_ascription", - issue = "23416", + issue = "101728", reason = "placeholder syntax for type ascription" )] pub use crate::macros::builtin::type_ascribe; diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 35af6488895a1..0677bb8f5871a 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -5660,7 +5660,7 @@ const impl Default for &mut [T] { } } -#[unstable(feature = "slice_pattern", reason = "stopgap trait for slice patterns", issue = "56345")] +#[unstable(feature = "slice_pattern", issue = "none", reason = "stopgap trait for slice patterns")] /// Patterns in slices - currently, only used by `strip_prefix` and `strip_suffix`. At a future /// point, we hope to generalise `core::str::Pattern` (which at the time of writing is limited to /// `str`) to slices, and then this trait will be replaced or abolished. diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index b9d344284734b..770cc5f834a11 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -1711,7 +1711,7 @@ impl fmt::Display for Display<'_> { } } -#[unstable(feature = "slice_concat_ext", issue = "27747")] +#[unstable(feature = "slice_concat_ext", issue = "none", reason = "implementation detail")] impl> alloc::slice::Join<&OsStr> for [S] { type Output = OsString; diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index aeefec8b9e084..8f0a02119e007 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -122,7 +122,7 @@ pub use core::prelude::v1::{ #[doc(no_inline)] pub use core::prelude::v1::derive; -#[unstable(feature = "derive_const", issue = "118304")] +#[unstable(feature = "derive_const", issue = "143874")] pub use core::prelude::v1::derive_const; // Do not `doc(no_inline)` either. @@ -144,7 +144,7 @@ pub use core::prelude::v1::cfg_eval; // Do not `doc(no_inline)` either. #[unstable( feature = "type_ascription", - issue = "23416", + issue = "101728", reason = "placeholder syntax for type ascription" )] pub use core::prelude::v1::type_ascribe; diff --git a/library/std/src/sys/sync/futex/unix.rs b/library/std/src/sys/sync/futex/unix.rs index 004d8323060e5..82861c35e4c43 100644 --- a/library/std/src/sys/sync/futex/unix.rs +++ b/library/std/src/sys/sync/futex/unix.rs @@ -11,6 +11,18 @@ pub type SmallFutex = Atomic; /// Must be the underlying type of SmallFutex pub type SmallPrimitive = u32; +#[cfg(any(target_os = "linux", target_os = "android"))] +cfg_select! { + // riscv32 only exposes the `SYS_futex_time64` syscall, + // whereas other 32-bit targets also expose `SYS_futex`, which uses 32-bit time. + target_arch = "riscv32" => { + use libc::SYS_futex_time64 as SYS_futex; + } + _ => { + use libc::SYS_futex; + } +} + /// Waits for a `futex_wake` operation to wake us. /// /// Returns directly if the futex doesn't hold the expected value. @@ -61,7 +73,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option) // Use FUTEX_WAIT_BITSET rather than FUTEX_WAIT to be able to give an // absolute time rather than a relative time. libc::syscall( - libc::SYS_futex, + SYS_futex, futex as *const Atomic as *const u32, libc::FUTEX_WAIT_BITSET | libc::FUTEX_PRIVATE_FLAG, expected, @@ -94,7 +106,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option) pub fn futex_wake(futex: &Atomic) -> bool { let ptr = futex as *const Atomic as *const u32; let op = libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG; - unsafe { libc::syscall(libc::SYS_futex, ptr, op, 1) > 0 } + unsafe { libc::syscall(SYS_futex, ptr, op, 1) > 0 } } /// Wakes up all threads that are waiting on `futex_wait` on this futex. @@ -103,7 +115,7 @@ pub fn futex_wake_all(futex: &Atomic) { let ptr = futex as *const Atomic as *const u32; let op = libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG; unsafe { - libc::syscall(libc::SYS_futex, ptr, op, i32::MAX); + libc::syscall(SYS_futex, ptr, op, i32::MAX); } } diff --git a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md b/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md deleted file mode 100644 index e7414aa9119de..0000000000000 --- a/src/doc/unstable-book/src/compiler-flags/control-flow-guard.md +++ /dev/null @@ -1,59 +0,0 @@ -# `control-flow-guard` - -The tracking issue for this feature is: [#68793](https://github.com/rust-lang/rust/issues/68793). - ------------------------- - -The rustc flag `-Z control-flow-guard` enables the Windows [Control Flow Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard) (CFG) platform security feature. - -CFG is an exploit mitigation designed to enforce control-flow integrity for software running on supported [Windows platforms (Windows 8.1 onwards)](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard). Specifically, CFG uses runtime checks to validate the target address of every indirect call/jump before allowing the call to complete. - -During compilation, the compiler identifies all indirect calls/jumps and adds CFG checks. It also emits metadata containing the relative addresses of all address-taken functions. At runtime, if the binary is run on a CFG-aware operating system, the loader uses the CFG metadata to generate a bitmap of the address space and marks those addresses that contain valid targets. On each indirect call, the inserted check determines whether the target address is marked in this bitmap. If the target is not valid, the process is terminated. - -In terms of interoperability: -- Code compiled with CFG enabled can be linked with libraries and object files that are not compiled with CFG. In this case, a CFG-aware linker can identify address-taken functions in the non-CFG libraries. -- Libraries compiled with CFG can linked into non-CFG programs. In this case, the CFG runtime checks in the libraries are not used (i.e. the mitigation is completely disabled). - -CFG functionality is completely implemented in the LLVM backend and is supported for X86 (32-bit and 64-bit), ARM, and Aarch64 targets. The rustc flag adds the relevant LLVM module flags to enable the feature. This flag will be ignored for all non-Windows targets. - - -## When to use Control Flow Guard - -The primary motivation for enabling CFG in Rust is to enhance security when linking against non-Rust code, especially C/C++ code. To achieve full CFG protection, all indirect calls (including any from Rust code) must have the appropriate CFG checks, as added by this flag. CFG can also improve security for Rust code that uses the `unsafe` keyword. - -Another motivation behind CFG is to harden programs against [return-oriented programming (ROP)](https://en.wikipedia.org/wiki/Return-oriented_programming) attacks. CFG disallows an attacker from taking advantage of the program's own instructions while redirecting control flow in unexpected ways. - -## Overhead of Control Flow Guard - -The CFG checks and metadata can potentially increase binary size and runtime overhead. The magnitude of any increase depends on the number and frequency of indirect calls. For example, enabling CFG for the Rust standard library increases binary size by approximately 0.14%. Enabling CFG in the SPEC CPU 2017 Integer Speed benchmark suite (compiled with Clang/LLVM) incurs approximate runtime overheads of between 0% and 8%, with a geometric mean of 2.9%. - - -## Testing Control Flow Guard - -The rustc flag `-Z control-flow-guard=nochecks` instructs LLVM to emit the list of valid call targets without inserting runtime checks. This flag should only be used for testing purposes as it does not provide security enforcement. - - -## Control Flow Guard in libraries - -It is strongly recommended to also enable CFG checks for all linked libraries, including the standard library. - -To enable CFG in the standard library, use the [cargo `-Z build-std` functionality][build-std] to recompile the standard library with the same configuration options as the main program. - -[build-std]: ../../cargo/reference/unstable.html#build-std - -For example: -```cmd -rustup toolchain install --force nightly -rustup component add rust-src -SET RUSTFLAGS=-Z control-flow-guard -cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc -``` - -```PowerShell -rustup toolchain install --force nightly -rustup component add rust-src -$Env:RUSTFLAGS = "-Z control-flow-guard" -cargo +nightly build -Z build-std --target x86_64-pc-windows-msvc -``` - -Alternatively, if you are building the standard library from source, you can set `control-flow-guard = true` in the bootstrap.toml file. diff --git a/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md b/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md index c72df43796038..dd6345bb55055 100644 --- a/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md +++ b/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md @@ -1,6 +1,6 @@ # `direct_access_external_data` -The tracking issue for this feature is: https://github.com/rust-lang/compiler-team/issues/707 +The tracking issue for this feature is: [#127488](https://github.com/rust-lang/rust/issues/127488). ------------------------ diff --git a/src/doc/unstable-book/src/compiler-flags/location-detail.md b/src/doc/unstable-book/src/compiler-flags/location-detail.md index db07061996964..64c5ac0dbb8be 100644 --- a/src/doc/unstable-book/src/compiler-flags/location-detail.md +++ b/src/doc/unstable-book/src/compiler-flags/location-detail.md @@ -1,6 +1,6 @@ # `location-detail` -The tracking issue for this feature is: [#70580](https://github.com/rust-lang/rust/issues/70580). +The tracking issue for this feature is: [cargo#14511](https://github.com/rust-lang/cargo/issues/14511). ------------------------ diff --git a/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md b/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md index bcf526694ad94..45aca930f60df 100644 --- a/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md +++ b/src/doc/unstable-book/src/compiler-flags/remap-cwd-prefix.md @@ -1,6 +1,6 @@ # `remap-cwd-prefix` -The tracking issue for this feature is: [#87325](https://github.com/rust-lang/rust/issues/87325). +The tracking issue for this feature is: [#89434](https://github.com/rust-lang/rust/issues/89434). ------------------------ diff --git a/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md b/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md index 93e9bc32ff064..e1384e22456d6 100644 --- a/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md +++ b/src/doc/unstable-book/src/language-features/half-open-range-patterns-in-slices.md @@ -1,11 +1,8 @@ # `half_open_range_patterns_in_slices` -The tracking issue for this feature is: [#67264] -It is a future part of the `exclusive_range_pattern` feature, -tracked at [#37854]. +The tracking issue for this feature is: [#67264]. [#67264]: https://github.com/rust-lang/rust/issues/67264 -[#37854]: https://github.com/rust-lang/rust/issues/37854 ----- This feature allow using top-level half-open range patterns in slices. diff --git a/src/doc/unstable-book/src/language-features/native-link-modifiers-as-needed.md b/src/doc/unstable-book/src/language-features/native-link-modifiers-as-needed.md index 1757673612c48..ba995c7d47848 100644 --- a/src/doc/unstable-book/src/language-features/native-link-modifiers-as-needed.md +++ b/src/doc/unstable-book/src/language-features/native-link-modifiers-as-needed.md @@ -1,8 +1,8 @@ # `native_link_modifiers_as_needed` -The tracking issue for this feature is: [#81490] +The tracking issue for this feature is: [#99424] -[#81490]: https://github.com/rust-lang/rust/issues/81490 +[#99424]: https://github.com/rust-lang/rust/issues/99424 ------------------------ diff --git a/src/doc/unstable-book/src/language-features/profiler-runtime.md b/src/doc/unstable-book/src/language-features/profiler-runtime.md deleted file mode 100644 index aee86f63952a5..0000000000000 --- a/src/doc/unstable-book/src/language-features/profiler-runtime.md +++ /dev/null @@ -1,5 +0,0 @@ -# `profiler_runtime` - -The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524). - ------------------------- diff --git a/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs new file mode 100644 index 0000000000000..e993b988b3fea --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.rs @@ -0,0 +1,15 @@ +// Because inner and outer attributes don't have the same scope for a module, we need +// to also apply the logic to the other module attributes which can contain intra-doc +// links. +// Regression test for . + +#![deny(rustdoc::broken_intra_doc_links)] + +pub mod a { + #![deprecated = "[](TypeAlias::x)"] + //~^ ERROR broken_intra_doc_links +} + +#[deprecated = "[](TypeAlias::x)"] +//~^ ERROR broken_intra_doc_links +pub mod b {} diff --git a/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr new file mode 100644 index 0000000000000..36c6ce48dd42a --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/link-in-deprecation-note-2.stderr @@ -0,0 +1,31 @@ +error: unresolved link to `TypeAlias::x` + --> $DIR/link-in-deprecation-note-2.rs:9:21 + | +LL | #![deprecated = "[](TypeAlias::x)"] + | ^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [](TypeAlias::x) + ^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope +note: the lint level is defined here + --> $DIR/link-in-deprecation-note-2.rs:6:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unresolved link to `TypeAlias::x` + --> $DIR/link-in-deprecation-note-2.rs:13:16 + | +LL | #[deprecated = "[](TypeAlias::x)"] + | ^^^^^^^^^^^^^^^^^^ + | + = note: the link appears in this line: + + [](TypeAlias::x) + ^^^^^^^^^^^^ + = note: no item named `TypeAlias` in scope + +error: aborting due to 2 previous errors + diff --git a/tests/ui/async-await/async-closures/not-lending.stderr b/tests/ui/async-await/async-closures/not-lending.stderr index 989b9ccb88a76..2b19516e99415 100644 --- a/tests/ui/async-await/async-closures/not-lending.stderr +++ b/tests/ui/async-await/async-closures/not-lending.stderr @@ -15,7 +15,7 @@ error: lifetime may not live long enough LL | let x = async move || { &s }; | ------------- ^^^^^^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of async closure is &'2 String + | | return type of async closure is `&'2 String` | lifetime `'1` represents this closure's body | = note: closure implements `AsyncFn`, so references to captured variables can't escape the closure diff --git a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr index b7f9a9ed24ecf..a76670f472225 100644 --- a/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr +++ b/tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr @@ -34,7 +34,7 @@ error: lifetime may not live long enough LL | (async move || { | ______-------------_^ | | | | - | | | return type of async closure is &'2 i32 + | | | return type of async closure is `&'2 i32` | | lifetime `'1` represents this closure's body LL | | LL | | @@ -50,7 +50,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-74072-lifetime-name-annotations.rs:17:9 | LL | (async move || { - | - return type of async closure is &'1 i32 + | - return type of async closure is `&'1 i32` ... LL | let y = &*x; | --- `*x` is borrowed here @@ -99,7 +99,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-74072-lifetime-name-annotations.rs:27:9 | LL | (async move || -> &i32 { - | - return type of async closure is &'1 i32 + | - return type of async closure is `&'1 i32` ... LL | let y = &*x; | --- `*x` is borrowed here @@ -112,7 +112,7 @@ error[E0506]: cannot assign to `*x` because it is borrowed --> $DIR/issue-74072-lifetime-name-annotations.rs:35:9 | LL | async move { - | - return type of async block is &'1 i32 + | - return type of async block is `&'1 i32` LL | let y = &*x; | --- `*x` is borrowed here LL | *x += 1; diff --git a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr index f1a561ef88049..1b441ba13bef2 100644 --- a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr +++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr @@ -15,7 +15,7 @@ error[E0597]: `not_static` does not live long enough --> $DIR/implementation-not-general-enough-ice-133252.rs:9:31 | LL | async { - | - return type of async block is &(dyn Owned + '1) + | - return type of async block is `&(dyn Owned + '1)` LL | let not_static = 0; | ---------- binding `not_static` declared here LL | force_send(async_load(¬_static)); diff --git a/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr b/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr index a18c4e7271949..dc19178732ba2 100644 --- a/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr +++ b/tests/ui/borrowck/unmatched-arg-and-hir-arg-issue-126385.stderr @@ -24,7 +24,7 @@ error: lifetime may not live long enough --> $DIR/unmatched-arg-and-hir-arg-issue-126385.rs:10:9 | LL | pub fn f(field: &[u32]) -> Self { - | - --------- return type is MyStruct<'2> + | - --------- return type is `MyStruct<'2>` | | | let's call the lifetime of this reference `'1` LL | Self { field } diff --git a/tests/ui/closures/return-value-lifetime-error.stderr b/tests/ui/closures/return-value-lifetime-error.stderr index a0ad127db2891..54d6be4cd16e2 100644 --- a/tests/ui/closures/return-value-lifetime-error.stderr +++ b/tests/ui/closures/return-value-lifetime-error.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | let _ = counts.iter().max_by_key(|(_, v)| v); | ------- ^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of closure is &'2 &i32 + | | return type of closure is `&'2 &i32` | has type `&'1 (&i32, &i32)` | help: dereference the return value diff --git a/tests/ui/error-codes/E0621-does-not-trigger-for-closures.stderr b/tests/ui/error-codes/E0621-does-not-trigger-for-closures.stderr index 2d96926a230ff..d8a59850b3a19 100644 --- a/tests/ui/error-codes/E0621-does-not-trigger-for-closures.stderr +++ b/tests/ui/error-codes/E0621-does-not-trigger-for-closures.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | invoke(&x, |a, b| if a > b { a } else { b }); | -- ^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 i32 + | |return type of closure is `&'2 i32` | has type `&'1 i32` error: aborting due to 1 previous error diff --git a/tests/ui/feature-gates/doc-rust-logo.stderr b/tests/ui/feature-gates/doc-rust-logo.stderr index f31837be284d1..802187e6a598c 100644 --- a/tests/ui/feature-gates/doc-rust-logo.stderr +++ b/tests/ui/feature-gates/doc-rust-logo.stderr @@ -4,7 +4,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #![doc(rust_logo)] | ^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: the `#[doc(rust_logo)]` attribute is used for Rust branding diff --git a/tests/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.in_attr.stderr b/tests/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.in_attr.stderr index 11b7abc883e15..bbe1a0dc9ae5e 100644 --- a/tests/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.in_attr.stderr +++ b/tests/ui/feature-gates/feature-gate-native_link_modifiers_as_needed.in_attr.stderr @@ -4,7 +4,7 @@ error[E0658]: linking modifier `as-needed` is unstable LL | #[link(name = "foo", kind = "dylib", modifiers = "+as-needed")] | ^^^^^^^^^^^^ | - = note: see issue #81490 for more information + = note: see issue #99424 for more information = help: add `#![feature(native_link_modifiers_as_needed)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr b/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr index ab542eb85bacf..268c854285607 100644 --- a/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr +++ b/tests/ui/feature-gates/feature-gate-rustdoc_internals.stderr @@ -4,7 +4,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(search_unbox)] | ^^^^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -14,7 +13,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(fake_variadic)] | ^^^^^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -24,7 +22,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(attribute = "repr")] | ^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -34,7 +31,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(keyword = "match")] | ^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -44,7 +40,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(attribute = "repr")] | ^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -54,7 +49,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(fake_variadic)] | ^^^^^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date @@ -64,7 +58,6 @@ error[E0658]: this subset of the `doc` attribute is meant for internal use only LL | #[doc(search_unbox)] | ^^^^^^^^^^^^ | - = note: see issue #90418 for more information = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/feature-gates/feature-gate-type_ascription.stderr b/tests/ui/feature-gates/feature-gate-type_ascription.stderr index f59e6435c8e89..1ed7604ebb448 100644 --- a/tests/ui/feature-gates/feature-gate-type_ascription.stderr +++ b/tests/ui/feature-gates/feature-gate-type_ascription.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature `type_ascription`: placeholder syn LL | let a = type_ascribe!(10, u8); | ^^^^^^^^^^^^ | - = note: see issue #23416 for more information + = note: see issue #101728 for more information = help: add `#![feature(type_ascription)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/tests/ui/lifetimes/issue-79187-2.stderr b/tests/ui/lifetimes/issue-79187-2.stderr index adc64984a05e9..67bb7e8ba0e27 100644 --- a/tests/ui/lifetimes/issue-79187-2.stderr +++ b/tests/ui/lifetimes/issue-79187-2.stderr @@ -52,7 +52,7 @@ error: lifetime may not live long enough LL | take_foo(|a: &i32| a); | - - ^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of closure is &'2 i32 + | | return type of closure is `&'2 i32` | let's call the lifetime of this reference `'1` error[E0308]: mismatched types diff --git a/tests/ui/nll/issue-48238.stderr b/tests/ui/nll/issue-48238.stderr index e15fbbdcdf21f..5c8505751bfad 100644 --- a/tests/ui/nll/issue-48238.stderr +++ b/tests/ui/nll/issue-48238.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | move || use_val(&orig); | ------- ^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of closure is &'2 u8 + | | return type of closure is `&'2 u8` | lifetime `'1` represents this closure's body | = note: closure implements `Fn`, so references to captured variables can't escape the closure diff --git a/tests/ui/nll/issue-55394.stderr b/tests/ui/nll/issue-55394.stderr index 69df901026436..03382b668aa53 100644 --- a/tests/ui/nll/issue-55394.stderr +++ b/tests/ui/nll/issue-55394.stderr @@ -2,7 +2,7 @@ error: lifetime may not live long enough --> $DIR/issue-55394.rs:9:9 | LL | fn new(bar: &mut Bar) -> Self { - | - ---- return type is Foo<'2> + | - ---- return type is `Foo<'2>` | | | let's call the lifetime of this reference `'1` LL | Foo { bar } diff --git a/tests/ui/nll/issue-58053.stderr b/tests/ui/nll/issue-58053.stderr index bf7416e1ab085..820da14c96dc7 100644 --- a/tests/ui/nll/issue-58053.stderr +++ b/tests/ui/nll/issue-58053.stderr @@ -13,7 +13,7 @@ error: lifetime may not live long enough LL | let g = |x: &i32| { x }; | - - ^ returning this value requires that `'1` must outlive `'2` | | | - | | return type of closure is &'2 i32 + | | return type of closure is `&'2 i32` | let's call the lifetime of this reference `'1` error: aborting due to 2 previous errors diff --git a/tests/ui/regions/regions-escape-method.stderr b/tests/ui/regions/regions-escape-method.stderr index 687b91bb7b47b..b3a51c2f09268 100644 --- a/tests/ui/regions/regions-escape-method.stderr +++ b/tests/ui/regions/regions-escape-method.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | s.f(|p| p) | -- ^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 i32 + | |return type of closure is `&'2 i32` | has type `&'1 i32` | help: dereference the return value diff --git a/tests/ui/regions/regions-escape-via-trait-or-not.stderr b/tests/ui/regions/regions-escape-via-trait-or-not.stderr index 4d185e52d01be..668a27d3fdaef 100644 --- a/tests/ui/regions/regions-escape-via-trait-or-not.stderr +++ b/tests/ui/regions/regions-escape-via-trait-or-not.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | with(|o| o) | -- ^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 isize + | |return type of closure is `&'2 isize` | has type `&'1 isize` error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-infer-call-3.stderr b/tests/ui/regions/regions-infer-call-3.stderr index 14d1ce7ae8b38..688bcce7bf30b 100644 --- a/tests/ui/regions/regions-infer-call-3.stderr +++ b/tests/ui/regions/regions-infer-call-3.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | let z = with(|y| { select(x, y) }); | -- ^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 isize + | |return type of closure is `&'2 isize` | has type `&'1 isize` error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-ret-borrowed-1.stderr b/tests/ui/regions/regions-ret-borrowed-1.stderr index 4ad526602df6b..dd48a761c2184 100644 --- a/tests/ui/regions/regions-ret-borrowed-1.stderr +++ b/tests/ui/regions/regions-ret-borrowed-1.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | with(|o| o) | -- ^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 isize + | |return type of closure is `&'2 isize` | has type `&'1 isize` error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-ret-borrowed.stderr b/tests/ui/regions/regions-ret-borrowed.stderr index f16a4a2e8c154..7119eff0141f9 100644 --- a/tests/ui/regions/regions-ret-borrowed.stderr +++ b/tests/ui/regions/regions-ret-borrowed.stderr @@ -4,7 +4,7 @@ error: lifetime may not live long enough LL | with(|o| o) | -- ^ returning this value requires that `'1` must outlive `'2` | || - | |return type of closure is &'2 isize + | |return type of closure is `&'2 isize` | has type `&'1 isize` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons-2.rs b/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons-2.rs new file mode 100644 index 0000000000000..4c2e5e59d3340 --- /dev/null +++ b/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons-2.rs @@ -0,0 +1,11 @@ +fn set_alert(_: bool) {} +fn current_limit() -> i32 { + 100 +} + +fn main() { + let used = 120; + let warning = 90; + set_alert(used < warning, used > current_limit()); + //~^ ERROR: this function takes 1 argument but 2 arguments were supplied +} diff --git a/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons-2.stderr b/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons-2.stderr new file mode 100644 index 0000000000000..c0666a75cefcb --- /dev/null +++ b/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons-2.stderr @@ -0,0 +1,20 @@ +error[E0061]: this function takes 1 argument but 2 arguments were supplied + --> $DIR/suggest-turbofish-parsed-as-comparisons-2.rs:9:5 + | +LL | set_alert(used < warning, used > current_limit()); + | ^^^^^^^^^ ---------------------- unexpected argument #2 of type `bool` + | +note: function defined here + --> $DIR/suggest-turbofish-parsed-as-comparisons-2.rs:1:4 + | +LL | fn set_alert(_: bool) {} + | ^^^^^^^^^ +help: remove the extra argument + | +LL - set_alert(used < warning, used > current_limit()); +LL + set_alert(used < warning); + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons.rs b/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons.rs new file mode 100644 index 0000000000000..28b8fd8ca1d51 --- /dev/null +++ b/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons.rs @@ -0,0 +1,54 @@ +// Issue #81816. +use std::sync::Arc; +use std::sync::RwLock; +use std::collections::HashMap; + +struct S; +impl S { + fn foo(&self, _: HashMap) {} + fn bar(&self, _: Many) {} +} +fn bar(_: Many) {} +struct Many { + a: A, + b: B, + c: C, + d: D, +} + +impl Many { + fn new() -> Self { todo!() } +} + +fn main() { + let _ = Arc::new(RwLock::new(HashMap::default())); + //~^ ERROR can't compare two types + let _ = S.foo(HashMap::default()); + //~^ ERROR can't compare two types + let _ = bar(Many::new()); + //~^ ERROR can't compare two types + let _ = S.bar(Many::new()); + //~^ ERROR can't compare two types + let _ = bar(Many::new(), Many::new()); + //~^ ERROR can't compare two types + //~| ERROR can't compare two types + let _ = S.bar(Many::new(), Many::new()); + //~^ ERROR can't compare two types + //~| ERROR can't compare two types + let _ = bar(1, 2, Many::new()); + //~^ ERROR can't compare two types + let _ = S.bar(1, 2, Many::new()); + //~^ ERROR can't compare two types + let _ = bar(a, b, Many::new(), c, d); + //~^ ERROR can't compare two types + //~| ERROR cannot find value `a` in this scope + //~| ERROR cannot find value `b` in this scope + //~| ERROR cannot find value `c` in this scope + //~| ERROR cannot find value `d` in this scope + let _ = S.bar(a, b, Many::new(), c, d); + //~^ ERROR can't compare two types + //~| ERROR cannot find value `a` in this scope + //~| ERROR cannot find value `b` in this scope + //~| ERROR cannot find value `c` in this scope + //~| ERROR cannot find value `d` in this scope +} diff --git a/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons.stderr b/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons.stderr new file mode 100644 index 0000000000000..5ffbc96a02ac2 --- /dev/null +++ b/tests/ui/suggestions/suggest-turbofish-parsed-as-comparisons.stderr @@ -0,0 +1,271 @@ +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:24:41 + | +LL | let _ = Arc::new(RwLock::new(HashMap::default())); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `HashMap` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = Arc::new(RwLock::new(HashMap::::default())); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:26:26 + | +LL | let _ = S.foo(HashMap::default()); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `HashMap` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = S.foo(HashMap::::default()); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:28:21 + | +LL | let _ = bar(Many::new()); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `Many` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = bar(Many::::new()); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:30:23 + | +LL | let _ = S.bar(Many::new()); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `Many` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = S.bar(Many::::new()); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:32:21 + | +LL | let _ = bar(Many::new(), Many::new()); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `Many` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = bar(Many::::new(), Many::new()); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:32:54 + | +LL | let _ = bar(Many::new(), Many::new()); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `Many` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = bar(Many::new(), Many::::new()); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:35:23 + | +LL | let _ = S.bar(Many::new(), Many::new()); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `Many` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = S.bar(Many::::new(), Many::new()); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:35:56 + | +LL | let _ = S.bar(Many::new(), Many::new()); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `Many` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = S.bar(Many::new(), Many::::new()); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:38:27 + | +LL | let _ = bar(1, 2, Many::new()); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `Many` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = bar(1, 2, Many::::new()); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:40:29 + | +LL | let _ = S.bar(1, 2, Many::new()); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `Many` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = S.bar(1, 2, Many::::new()); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:42:27 + | +LL | let _ = bar(a, b, Many::new(), c, d); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `Many` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = bar(a, b, Many::::new(), c, d); + | ++ + +error: can't compare two types + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:48:29 + | +LL | let _ = S.bar(a, b, Many::new(), c, d); + | ^ ^ these are parsed as "less than" and "greater than" + | +help: you likely intended to write type `Many` with type parameters, but type parameters in expression contexts require the use of the "turbofish" `::<>` + | +LL | let _ = S.bar(a, b, Many::::new(), c, d); + | ++ + +error[E0425]: cannot find value `a` in this scope + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:42:17 + | +LL | let _ = bar(a, b, Many::new(), c, d); + | ^ not found in this scope + | +note: similarly named unit struct `S` defined here + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:6:1 + | +LL | struct S; + | ^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL - let _ = bar(a, b, Many::new(), c, d); +LL + let _ = bar(S, b, Many::new(), c, d); + | + +error[E0425]: cannot find value `b` in this scope + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:42:20 + | +LL | let _ = bar(a, b, Many::new(), c, d); + | ^ not found in this scope + | +note: similarly named unit struct `S` defined here + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:6:1 + | +LL | struct S; + | ^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL - let _ = bar(a, b, Many::new(), c, d); +LL + let _ = bar(a, S, Many::new(), c, d); + | + +error[E0425]: cannot find value `c` in this scope + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:42:56 + | +LL | let _ = bar(a, b, Many::new(), c, d); + | ^ not found in this scope + | +note: similarly named unit struct `S` defined here + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:6:1 + | +LL | struct S; + | ^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL - let _ = bar(a, b, Many::new(), c, d); +LL + let _ = bar(a, b, Many::new(), S, d); + | + +error[E0425]: cannot find value `d` in this scope + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:42:59 + | +LL | let _ = bar(a, b, Many::new(), c, d); + | ^ not found in this scope + | +note: similarly named unit struct `S` defined here + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:6:1 + | +LL | struct S; + | ^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL - let _ = bar(a, b, Many::new(), c, d); +LL + let _ = bar(a, b, Many::new(), c, S); + | + +error[E0425]: cannot find value `a` in this scope + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:48:19 + | +LL | let _ = S.bar(a, b, Many::new(), c, d); + | ^ not found in this scope + | +note: similarly named unit struct `S` defined here + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:6:1 + | +LL | struct S; + | ^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL - let _ = S.bar(a, b, Many::new(), c, d); +LL + let _ = S.bar(S, b, Many::new(), c, d); + | + +error[E0425]: cannot find value `b` in this scope + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:48:22 + | +LL | let _ = S.bar(a, b, Many::new(), c, d); + | ^ not found in this scope + | +note: similarly named unit struct `S` defined here + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:6:1 + | +LL | struct S; + | ^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL - let _ = S.bar(a, b, Many::new(), c, d); +LL + let _ = S.bar(a, S, Many::new(), c, d); + | + +error[E0425]: cannot find value `c` in this scope + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:48:58 + | +LL | let _ = S.bar(a, b, Many::new(), c, d); + | ^ not found in this scope + | +note: similarly named unit struct `S` defined here + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:6:1 + | +LL | struct S; + | ^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL - let _ = S.bar(a, b, Many::new(), c, d); +LL + let _ = S.bar(a, b, Many::new(), S, d); + | + +error[E0425]: cannot find value `d` in this scope + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:48:61 + | +LL | let _ = S.bar(a, b, Many::new(), c, d); + | ^ not found in this scope + | +note: similarly named unit struct `S` defined here + --> $DIR/suggest-turbofish-parsed-as-comparisons.rs:6:1 + | +LL | struct S; + | ^^^^^^^^^ +help: a unit struct with a similar name exists + | +LL - let _ = S.bar(a, b, Many::new(), c, d); +LL + let _ = S.bar(a, b, Many::new(), c, S); + | + +error: aborting due to 20 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr index cbc62d602a473..5820d1f353ef1 100644 --- a/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr +++ b/tests/ui/traits/const-traits/const_derives/derive-const-gate.stderr @@ -4,7 +4,7 @@ error[E0658]: use of unstable library feature `derive_const` LL | #[derive_const(Debug)] | ^^^^^^^^^^^^ | - = note: see issue #118304 for more information + = note: see issue #143874 for more information = help: add `#![feature(derive_const)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date diff --git a/triagebot.toml b/triagebot.toml index 676ab4df6448a..dbb39058daac6 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -614,7 +614,6 @@ trigger_files = [ "src/doc/rustc/src/exploit-mitigations.md", "src/doc/unstable-book/src/compiler-flags/branch-protection.md", "src/doc/unstable-book/src/compiler-flags/cf-protection.md", - "src/doc/unstable-book/src/compiler-flags/control-flow-guard.md", "src/doc/unstable-book/src/compiler-flags/sanitizer.md", "src/doc/unstable-book/src/language-features/cfg-sanitize.md", "src/doc/unstable-book/src/language-features/cfi-encoding.md", @@ -1429,9 +1428,6 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] [mentions."src/doc/unstable-book/src/compiler-flags/cf-protection.md"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] -[mentions."src/doc/unstable-book/src/compiler-flags/control-flow-guard.md"] -cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] - [mentions."src/doc/unstable-book/src/compiler-flags/sanitizer.md"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"]