diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 71932f02017ca..30c54ef2d3c41 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3184,38 +3184,6 @@ pub struct StaticItem { pub expr: Option>, } -/// A static item in `extern` block. -// This struct is identical to StaticItem for now but it's going to have a safety attribute. -#[derive(Clone, Encodable, Decodable, Debug)] -pub struct StaticForeignItem { - pub ty: P, - pub safety: Safety, - pub mutability: Mutability, - pub expr: Option>, -} - -impl From for StaticForeignItem { - fn from(static_item: StaticItem) -> StaticForeignItem { - StaticForeignItem { - ty: static_item.ty, - safety: static_item.safety, - mutability: static_item.mutability, - expr: static_item.expr, - } - } -} - -impl From for StaticItem { - fn from(static_item: StaticForeignItem) -> StaticItem { - StaticItem { - ty: static_item.ty, - safety: static_item.safety, - mutability: static_item.mutability, - expr: static_item.expr, - } - } -} - #[derive(Clone, Encodable, Decodable, Debug)] pub struct ConstItem { pub defaultness: Defaultness, @@ -3430,7 +3398,7 @@ impl TryFrom for AssocItemKind { #[derive(Clone, Encodable, Decodable, Debug)] pub enum ForeignItemKind { /// A foreign static item (`static FOO: u8`). - Static(Box), + Static(Box), /// An foreign function. Fn(Box), /// An foreign type. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 35aa53e978c15..c9d2f5c779bb6 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1310,12 +1310,7 @@ pub fn noop_flat_map_item( impl NoopVisitItemKind for ForeignItemKind { fn noop_visit(&mut self, visitor: &mut impl MutVisitor) { match self { - ForeignItemKind::Static(box StaticForeignItem { - ty, - mutability: _, - expr, - safety: _, - }) => { + ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { visitor.visit_ty(ty); visit_opt(expr, |expr| visitor.visit_expr(expr)); } diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 4dc41a02cb853..cc66cc87652d0 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -900,7 +900,11 @@ pub enum NonterminalKind { PatWithOr, Expr, /// Matches an expression using the rules from edition 2021 and earlier. - Expr2021, + Expr2021 { + /// Keep track of whether the user used `:expr` or `:expr_2021` and we inferred it from the + /// edition of the span. This is used for diagnostics AND feature gating. + inferred: bool, + }, Ty, Ident, Lifetime, @@ -929,8 +933,13 @@ impl NonterminalKind { Edition::Edition2021 | Edition::Edition2024 => NonterminalKind::PatWithOr, }, sym::pat_param => NonterminalKind::PatParam { inferred: false }, - sym::expr => NonterminalKind::Expr, - sym::expr_2021 if edition().at_least_rust_2021() => NonterminalKind::Expr2021, + sym::expr => match edition() { + Edition::Edition2015 | Edition::Edition2018 | Edition::Edition2021 => { + NonterminalKind::Expr2021 { inferred: true } + } + Edition::Edition2024 => NonterminalKind::Expr, + }, + sym::expr_2021 => NonterminalKind::Expr2021 { inferred: false }, sym::ty => NonterminalKind::Ty, sym::ident => NonterminalKind::Ident, sym::lifetime => NonterminalKind::Lifetime, @@ -949,8 +958,8 @@ impl NonterminalKind { NonterminalKind::Stmt => sym::stmt, NonterminalKind::PatParam { inferred: false } => sym::pat_param, NonterminalKind::PatParam { inferred: true } | NonterminalKind::PatWithOr => sym::pat, - NonterminalKind::Expr => sym::expr, - NonterminalKind::Expr2021 => sym::expr_2021, + NonterminalKind::Expr | NonterminalKind::Expr2021 { inferred: true } => sym::expr, + NonterminalKind::Expr2021 { inferred: false } => sym::expr_2021, NonterminalKind::Ty => sym::ty, NonterminalKind::Ident => sym::ident, NonterminalKind::Lifetime => sym::lifetime, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ed34a44db677f..ce38a67ea69ab 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -672,12 +672,7 @@ impl WalkItemKind for ForeignItemKind { ) -> V::Result { let &Item { id, span, ident, ref vis, .. } = item; match self { - ForeignItemKind::Static(box StaticForeignItem { - ty, - mutability: _, - expr, - safety: _, - }) => { + ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_expr, expr); } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index c6c0d9a2e608e..4c7e8c24d32a9 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -664,12 +664,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ForeignItemKind::Fn(fn_dec, fn_args, generics, safety) } - ForeignItemKind::Static(box StaticForeignItem { - ty, - mutability, - expr: _, - safety, - }) => { + ForeignItemKind::Static(box StaticItem { ty, mutability, expr: _, safety }) => { let ty = self .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy)); let safety = self.lower_safety(*safety, hir::Safety::Unsafe); diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index b274a9b9114ac..cad1fc79d7f4f 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1232,7 +1232,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_foreign_ty_genericless(generics, where_clauses); self.check_foreign_item_ascii_only(fi.ident); } - ForeignItemKind::Static(box StaticForeignItem { expr, safety, .. }) => { + ForeignItemKind::Static(box StaticItem { expr, safety, .. }) => { self.check_foreign_item_safety(fi.span, *safety); self.check_foreign_kind_bodyless(fi.ident, "static", expr.as_ref().map(|b| b.span)); self.check_foreign_item_ascii_only(fi.ident); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 49ac5ece337f0..d8382057d3f64 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -37,12 +37,7 @@ impl<'a> State<'a> { ast::ForeignItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => { self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs); } - ast::ForeignItemKind::Static(box ast::StaticForeignItem { - ty, - mutability, - expr, - safety, - }) => { + ast::ForeignItemKind::Static(box ast::StaticItem { ty, mutability, expr, safety }) => { self.print_safety(*safety); self.print_item_const( ident, diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 49b1f5ce0e3ea..0050ff10539a8 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -1292,7 +1292,9 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow { // maintain IsInFollow::Yes } - NonterminalKind::Stmt | NonterminalKind::Expr | NonterminalKind::Expr2021 => { + NonterminalKind::Stmt + | NonterminalKind::Expr + | NonterminalKind::Expr2021 { inferred: _ } => { const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"]; match tok { TokenTree::Token(token) => match token.kind { diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs index 74f78c0ef7857..fdf187438d3d7 100644 --- a/compiler/rustc_expand/src/mbe/quoted.rs +++ b/compiler/rustc_expand/src/mbe/quoted.rs @@ -113,7 +113,8 @@ pub(super) fn parse( ); token::NonterminalKind::Ident }); - if kind == token::NonterminalKind::Expr2021 + if kind + == (token::NonterminalKind::Expr2021 { inferred: false }) && !features.expr_fragment_specifier_2024 { rustc_session::parse::feature_err( diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index c2b91488a117a..81d5f0fca0ec9 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2965,9 +2965,10 @@ impl<'a> Parser<'a> { /// This checks if this is a conflict marker, depending of the parameter passed. /// - /// * `>>>>>` - /// * `=====` - /// * `<<<<<` + /// * `<<<<<<<` + /// * `|||||||` + /// * `=======` + /// * `>>>>>>>` /// pub(super) fn is_vcs_conflict_marker( &mut self, @@ -2997,14 +2998,18 @@ impl<'a> Parser<'a> { } pub(crate) fn err_vcs_conflict_marker(&mut self) -> PResult<'a, ()> { + // <<<<<<< let Some(start) = self.conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) else { return Ok(()); }; let mut spans = Vec::with_capacity(3); spans.push(start); + // ||||||| let mut middlediff3 = None; + // ======= let mut middle = None; + // >>>>>>> let mut end = None; loop { if self.token.kind == TokenKind::Eof { @@ -3025,29 +3030,50 @@ impl<'a> Parser<'a> { } self.bump(); } + let mut err = self.dcx().struct_span_err(spans, "encountered diff marker"); - err.span_label(start, "after this is the code before the merge"); - if let Some(middle) = middlediff3 { - err.span_label(middle, ""); - } + match middlediff3 { + // We're using diff3 + Some(middlediff3) => { + err.span_label( + start, + "between this marker and `|||||||` is the code that we're merging into", + ); + err.span_label(middlediff3, "between this marker and `=======` is the base code (what the two refs diverged from)"); + } + None => { + err.span_label( + start, + "between this marker and `=======` is the code that we're merging into", + ); + } + }; + if let Some(middle) = middle { - err.span_label(middle, ""); + err.span_label(middle, "between this marker and `>>>>>>>` is the incoming code"); } if let Some(end) = end { - err.span_label(end, "above this are the incoming code changes"); + err.span_label(end, "this marker concludes the conflict region"); } - err.help( - "if you're having merge conflicts after pulling new code, the top section is the code \ - you already had and the bottom section is the remote code", + err.note( + "conflict markers indicate that a merge was started but could not be completed due \ + to merge conflicts\n\ + to resolve a conflict, keep only the code you want and then delete the lines \ + containing conflict markers", ); err.help( - "if you're in the middle of a rebase, the top section is the code being rebased onto \ - and the bottom section is the code coming from the current commit being rebased", + "if you're having merge conflicts after pulling new code:\n\ + the top section is the code you already had and the bottom section is the remote code\n\ + if you're in the middle of a rebase:\n\ + the top section is the code being rebased onto and the bottom section is the code \ + coming from the current commit being rebased", ); + err.note( - "for an explanation on these markers from the `git` documentation, visit \ - ", + "for an explanation on these markers from the `git` documentation:\n\ + visit ", ); + Err(err) } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 3e1ea7b129de0..abb6b51cebd68 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1228,7 +1228,7 @@ impl<'a> Parser<'a> { ident_span: ident.span, const_span, }); - ForeignItemKind::Static(Box::new(StaticForeignItem { + ForeignItemKind::Static(Box::new(StaticItem { ty, mutability: Mutability::Not, expr, diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index a0b704aeea5fb..59f6eff07b320 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -36,7 +36,7 @@ impl<'a> Parser<'a> { } match kind { - NonterminalKind::Expr2021 => { + NonterminalKind::Expr2021 { inferred: _ } => { token.can_begin_expr() // This exception is here for backwards compatibility. && !token.is_keyword(kw::Let) @@ -47,7 +47,6 @@ impl<'a> Parser<'a> { token.can_begin_expr() // This exception is here for backwards compatibility. && !token.is_keyword(kw::Let) - && (!token.is_keyword(kw::Const) || token.span.edition().at_least_rust_2024()) } NonterminalKind::Ty => token.can_begin_type(), NonterminalKind::Ident => get_macro_ident(token).is_some(), @@ -149,7 +148,7 @@ impl<'a> Parser<'a> { })?) } - NonterminalKind::Expr | NonterminalKind::Expr2021 => { + NonterminalKind::Expr | NonterminalKind::Expr2021 { inferred: _ } => { NtExpr(self.parse_expr_force_collect()?) } NonterminalKind::Literal => { diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 60789c083133f..1bca5602a4eaa 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -217,12 +217,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> { fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { let def_kind = match fi.kind { - ForeignItemKind::Static(box StaticForeignItem { - ty: _, - mutability, - expr: _, - safety, - }) => { + ForeignItemKind::Static(box StaticItem { ty: _, mutability, expr: _, safety }) => { let safety = match safety { ast::Safety::Unsafe(_) | ast::Safety::Default => hir::Safety::Unsafe, ast::Safety::Safe(_) => hir::Safety::Safe, diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index d9812540e497d..017fd3072fdb7 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -208,6 +208,11 @@ const X86_ALLOWED_FEATURES: &[(&str, Stability)] = &[ ("avx512vnni", Unstable(sym::avx512_target_feature)), ("avx512vp2intersect", Unstable(sym::avx512_target_feature)), ("avx512vpopcntdq", Unstable(sym::avx512_target_feature)), + ("avxifma", Unstable(sym::avx512_target_feature)), + ("avxneconvert", Unstable(sym::avx512_target_feature)), + ("avxvnni", Unstable(sym::avx512_target_feature)), + ("avxvnniint16", Unstable(sym::avx512_target_feature)), + ("avxvnniint8", Unstable(sym::avx512_target_feature)), ("bmi1", Stable), ("bmi2", Stable), ("cmpxchg16b", Stable), diff --git a/library/core/tests/num/int_log.rs b/library/core/tests/num/int_log.rs index a1edb1a518632..2320a7acc35ac 100644 --- a/library/core/tests/num/int_log.rs +++ b/library/core/tests/num/int_log.rs @@ -24,15 +24,15 @@ fn checked_ilog() { #[cfg(not(miri))] // Miri is too slow for i in i16::MIN..=0 { - assert_eq!(i.checked_ilog(4), None); + assert_eq!(i.checked_ilog(4), None, "checking {i}"); } #[cfg(not(miri))] // Miri is too slow for i in 1..=i16::MAX { - assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32)); + assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32), "checking {i}"); } #[cfg(not(miri))] // Miri is too slow for i in 1..=u16::MAX { - assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32)); + assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32), "checking {i}"); } } @@ -49,30 +49,30 @@ fn checked_ilog2() { assert_eq!(0i16.checked_ilog2(), None); for i in 1..=u8::MAX { - assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32)); + assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32), "checking {i}"); } #[cfg(not(miri))] // Miri is too slow for i in 1..=u16::MAX { // Guard against Android's imprecise f32::ilog2 implementation. if i != 8192 && i != 32768 { - assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32)); + assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32), "checking {i}"); } } for i in i8::MIN..=0 { - assert_eq!(i.checked_ilog2(), None); + assert_eq!(i.checked_ilog2(), None, "checking {i}"); } for i in 1..=i8::MAX { - assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32)); + assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32), "checking {i}"); } #[cfg(not(miri))] // Miri is too slow for i in i16::MIN..=0 { - assert_eq!(i.checked_ilog2(), None); + assert_eq!(i.checked_ilog2(), None, "checking {i}"); } #[cfg(not(miri))] // Miri is too slow for i in 1..=i16::MAX { // Guard against Android's imprecise f32::ilog2 implementation. if i != 8192 { - assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32)); + assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32), "checking {i}"); } } } @@ -95,19 +95,19 @@ fn checked_ilog10() { #[cfg(not(miri))] // Miri is too slow for i in i16::MIN..=0 { - assert_eq!(i.checked_ilog10(), None); + assert_eq!(i.checked_ilog10(), None, "checking {i}"); } #[cfg(not(miri))] // Miri is too slow for i in 1..=i16::MAX { - assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32)); + assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32), "checking {i}"); } #[cfg(not(miri))] // Miri is too slow for i in 1..=u16::MAX { - assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32)); + assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32), "checking {i}"); } #[cfg(not(miri))] // Miri is too slow for i in 1..=100_000u32 { - assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32)); + assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32), "checking {i}"); } } diff --git a/library/std/src/os/linux/process.rs b/library/std/src/os/linux/process.rs index 2ba67a6dd1aa9..e9d436bc355cd 100644 --- a/library/std/src/os/linux/process.rs +++ b/library/std/src/os/linux/process.rs @@ -6,20 +6,21 @@ use crate::io::Result; use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; -use crate::process; +use crate::process::{self, ExitStatus}; use crate::sealed::Sealed; -#[cfg(not(doc))] use crate::sys::fd::FileDesc; +#[cfg(not(doc))] +use crate::sys::linux::pidfd::PidFd as InnerPidFd; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; #[cfg(doc)] -struct FileDesc; +struct InnerPidFd; /// This type represents a file descriptor that refers to a process. /// /// A `PidFd` can be obtained by setting the corresponding option on [`Command`] /// with [`create_pidfd`]. Subsequently, the created pidfd can be retrieved -/// from the [`Child`] by calling [`pidfd`] or [`take_pidfd`]. +/// from the [`Child`] by calling [`pidfd`] or [`into_pidfd`]. /// /// Example: /// ```no_run @@ -33,7 +34,7 @@ struct FileDesc; /// .expect("Failed to spawn child"); /// /// let pidfd = child -/// .take_pidfd() +/// .into_pidfd() /// .expect("Failed to retrieve pidfd"); /// /// // The file descriptor will be closed when `pidfd` is dropped. @@ -44,28 +45,63 @@ struct FileDesc; /// [`create_pidfd`]: CommandExt::create_pidfd /// [`Child`]: process::Child /// [`pidfd`]: fn@ChildExt::pidfd -/// [`take_pidfd`]: ChildExt::take_pidfd +/// [`into_pidfd`]: ChildExt::into_pidfd /// [`pidfd_open(2)`]: https://man7.org/linux/man-pages/man2/pidfd_open.2.html #[derive(Debug)] +#[repr(transparent)] pub struct PidFd { - inner: FileDesc, + inner: InnerPidFd, +} + +impl PidFd { + /// Forces the child process to exit. + /// + /// Unlike [`Child::kill`] it is possible to attempt to kill + /// reaped children since PidFd does not suffer from pid recycling + /// races. But doing so will return an Error. + /// + /// [`Child::kill`]: process::Child::kill + pub fn kill(&self) -> Result<()> { + self.inner.kill() + } + + /// Waits for the child to exit completely, returning the status that it exited with. + /// + /// Unlike [`Child::wait`] it does not ensure that the stdin handle is closed. + /// Additionally it will not return an `ExitStatus` if the child + /// has already been reaped. Instead an error will be returned. + /// + /// [`Child::wait`]: process::Child::wait + pub fn wait(&self) -> Result { + self.inner.wait().map(FromInner::from_inner) + } + + /// Attempts to collect the exit status of the child if it has already exited. + /// + /// Unlike [`Child::try_wait`] this method will return an Error + /// if the child has already been reaped. + /// + /// [`Child::try_wait`]: process::Child::try_wait + pub fn try_wait(&self) -> Result> { + Ok(self.inner.try_wait()?.map(FromInner::from_inner)) + } } -impl AsInner for PidFd { +impl AsInner for PidFd { #[inline] - fn as_inner(&self) -> &FileDesc { + fn as_inner(&self) -> &InnerPidFd { &self.inner } } -impl FromInner for PidFd { - fn from_inner(inner: FileDesc) -> PidFd { +impl FromInner for PidFd { + fn from_inner(inner: InnerPidFd) -> PidFd { PidFd { inner } } } -impl IntoInner for PidFd { - fn into_inner(self) -> FileDesc { +impl IntoInner for PidFd { + fn into_inner(self) -> InnerPidFd { self.inner } } @@ -73,37 +109,37 @@ impl IntoInner for PidFd { impl AsRawFd for PidFd { #[inline] fn as_raw_fd(&self) -> RawFd { - self.as_inner().as_raw_fd() + self.as_inner().as_inner().as_raw_fd() } } impl FromRawFd for PidFd { unsafe fn from_raw_fd(fd: RawFd) -> Self { - Self::from_inner(FileDesc::from_raw_fd(fd)) + Self::from_inner(InnerPidFd::from_raw_fd(fd)) } } impl IntoRawFd for PidFd { fn into_raw_fd(self) -> RawFd { - self.into_inner().into_raw_fd() + self.into_inner().into_inner().into_raw_fd() } } impl AsFd for PidFd { fn as_fd(&self) -> BorrowedFd<'_> { - self.as_inner().as_fd() + self.as_inner().as_inner().as_fd() } } impl From for PidFd { fn from(fd: OwnedFd) -> Self { - Self::from_inner(FileDesc::from_inner(fd)) + Self::from_inner(InnerPidFd::from_inner(FileDesc::from_inner(fd))) } } impl From for OwnedFd { fn from(pid_fd: PidFd) -> Self { - pid_fd.into_inner().into_inner() + pid_fd.into_inner().into_inner().into_inner() } } @@ -124,18 +160,26 @@ pub trait ChildExt: Sealed { /// [`Child`]: process::Child fn pidfd(&self) -> Result<&PidFd>; - /// Takes ownership of the [`PidFd`] created for this [`Child`], if available. + /// Returns the [`PidFd`] created for this [`Child`], if available. + /// Otherwise self is returned. /// /// A pidfd will only be available if its creation was requested with /// [`create_pidfd`] when the corresponding [`Command`] was created. /// + /// Taking ownership of the PidFd consumes the Child to avoid pid reuse + /// races. Use [`pidfd`] and [`BorrowedFd::try_clone_to_owned`] if + /// you don't want to disassemble the Child yet. + /// /// Even if requested, a pidfd may not be available due to an older /// version of Linux being in use, or if some other error occurred. /// /// [`Command`]: process::Command /// [`create_pidfd`]: CommandExt::create_pidfd + /// [`pidfd`]: ChildExt::pidfd /// [`Child`]: process::Child - fn take_pidfd(&mut self) -> Result; + fn into_pidfd(self) -> crate::result::Result + where + Self: Sized; } /// Os-specific extensions for [`Command`] @@ -146,7 +190,7 @@ pub trait CommandExt: Sealed { /// spawned by this [`Command`]. /// By default, no pidfd will be created. /// - /// The pidfd can be retrieved from the child with [`pidfd`] or [`take_pidfd`]. + /// The pidfd can be retrieved from the child with [`pidfd`] or [`into_pidfd`]. /// /// A pidfd will only be created if it is possible to do so /// in a guaranteed race-free manner. Otherwise, [`pidfd`] will return an error. @@ -160,7 +204,7 @@ pub trait CommandExt: Sealed { /// [`Command`]: process::Command /// [`Child`]: process::Child /// [`pidfd`]: fn@ChildExt::pidfd - /// [`take_pidfd`]: ChildExt::take_pidfd + /// [`into_pidfd`]: ChildExt::into_pidfd fn create_pidfd(&mut self, val: bool) -> &mut process::Command; } diff --git a/library/std/src/sys/pal/unix/linux/mod.rs b/library/std/src/sys/pal/unix/linux/mod.rs new file mode 100644 index 0000000000000..88aa1e3deccf8 --- /dev/null +++ b/library/std/src/sys/pal/unix/linux/mod.rs @@ -0,0 +1 @@ +pub mod pidfd; diff --git a/library/std/src/sys/pal/unix/linux/pidfd.rs b/library/std/src/sys/pal/unix/linux/pidfd.rs new file mode 100644 index 0000000000000..7474f80e94f9d --- /dev/null +++ b/library/std/src/sys/pal/unix/linux/pidfd.rs @@ -0,0 +1,76 @@ +use crate::io; +use crate::os::fd::{AsRawFd, FromRawFd, RawFd}; +use crate::sys::cvt; +use crate::sys::pal::unix::fd::FileDesc; +use crate::sys::process::ExitStatus; +use crate::sys_common::{AsInner, FromInner, IntoInner}; + +#[cfg(test)] +mod tests; + +#[derive(Debug)] +pub(crate) struct PidFd(FileDesc); + +impl PidFd { + pub fn kill(&self) -> io::Result<()> { + return cvt(unsafe { + libc::syscall( + libc::SYS_pidfd_send_signal, + self.0.as_raw_fd(), + libc::SIGKILL, + crate::ptr::null::<()>(), + 0, + ) + }) + .map(drop); + } + + pub fn wait(&self) -> io::Result { + let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() }; + cvt(unsafe { + libc::waitid(libc::P_PIDFD, self.0.as_raw_fd() as u32, &mut siginfo, libc::WEXITED) + })?; + return Ok(ExitStatus::from_waitid_siginfo(siginfo)); + } + + pub fn try_wait(&self) -> io::Result> { + let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() }; + + cvt(unsafe { + libc::waitid( + libc::P_PIDFD, + self.0.as_raw_fd() as u32, + &mut siginfo, + libc::WEXITED | libc::WNOHANG, + ) + })?; + if unsafe { siginfo.si_pid() } == 0 { + return Ok(None); + } + return Ok(Some(ExitStatus::from_waitid_siginfo(siginfo))); + } +} + +impl AsInner for PidFd { + fn as_inner(&self) -> &FileDesc { + &self.0 + } +} + +impl IntoInner for PidFd { + fn into_inner(self) -> FileDesc { + self.0 + } +} + +impl FromInner for PidFd { + fn from_inner(inner: FileDesc) -> Self { + Self(inner) + } +} + +impl FromRawFd for PidFd { + unsafe fn from_raw_fd(fd: RawFd) -> Self { + Self(FileDesc::from_raw_fd(fd)) + } +} diff --git a/library/std/src/sys/pal/unix/linux/pidfd/tests.rs b/library/std/src/sys/pal/unix/linux/pidfd/tests.rs new file mode 100644 index 0000000000000..6d9532f2ef1ff --- /dev/null +++ b/library/std/src/sys/pal/unix/linux/pidfd/tests.rs @@ -0,0 +1,87 @@ +use crate::assert_matches::assert_matches; +use crate::os::fd::{AsRawFd, RawFd}; +use crate::os::linux::process::{ChildExt, CommandExt}; +use crate::os::unix::process::ExitStatusExt; +use crate::process::Command; + +#[test] +fn test_command_pidfd() { + let pidfd_open_available = probe_pidfd_support(); + + // always exercise creation attempts + let mut child = Command::new("false").create_pidfd(true).spawn().unwrap(); + + // but only check if we know that the kernel supports pidfds. + // We don't assert the precise value, since the standard library + // might have opened other file descriptors before our code runs. + if pidfd_open_available { + assert!(child.pidfd().is_ok()); + } + if let Ok(pidfd) = child.pidfd() { + let flags = super::cvt(unsafe { libc::fcntl(pidfd.as_raw_fd(), libc::F_GETFD) }).unwrap(); + assert!(flags & libc::FD_CLOEXEC != 0); + } + let status = child.wait().expect("error waiting on pidfd"); + assert_eq!(status.code(), Some(1)); + + let mut child = Command::new("sleep").arg("1000").create_pidfd(true).spawn().unwrap(); + assert_matches!(child.try_wait(), Ok(None)); + child.kill().expect("failed to kill child"); + let status = child.wait().expect("error waiting on pidfd"); + assert_eq!(status.signal(), Some(libc::SIGKILL)); + + let _ = Command::new("echo") + .create_pidfd(false) + .spawn() + .unwrap() + .pidfd() + .expect_err("pidfd should not have been created when create_pid(false) is set"); + + let _ = Command::new("echo") + .spawn() + .unwrap() + .pidfd() + .expect_err("pidfd should not have been created"); +} + +#[test] +fn test_pidfd() { + if !probe_pidfd_support() { + return; + } + + let child = Command::new("sleep") + .arg("1000") + .create_pidfd(true) + .spawn() + .expect("executing 'sleep' failed"); + + let fd = child.into_pidfd().unwrap(); + + assert_matches!(fd.try_wait(), Ok(None)); + fd.kill().expect("kill failed"); + fd.kill().expect("sending kill twice failed"); + let status = fd.wait().expect("1st wait failed"); + assert_eq!(status.signal(), Some(libc::SIGKILL)); + + // Trying to wait again for a reaped child is safe since there's no pid-recycling race. + // But doing so will return an error. + let res = fd.wait(); + assert_matches!(res, Err(e) if e.raw_os_error() == Some(libc::ECHILD)); + + // Ditto for additional attempts to kill an already-dead child. + let res = fd.kill(); + assert_matches!(res, Err(e) if e.raw_os_error() == Some(libc::ESRCH)); +} + +fn probe_pidfd_support() -> bool { + // pidfds require the pidfd_open syscall + let our_pid = crate::process::id(); + let pidfd = unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) }; + if pidfd >= 0 { + unsafe { libc::close(pidfd as RawFd) }; + true + } else { + false + } +} diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 735ed96bc7b16..b370f06e92baf 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -20,6 +20,8 @@ pub mod io; pub mod kernel_copy; #[cfg(target_os = "l4re")] mod l4re; +#[cfg(target_os = "linux")] +pub mod linux; #[cfg(not(target_os = "l4re"))] pub mod net; #[cfg(target_os = "l4re")] diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 72bda90a9ba71..32382d9a50cf4 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -7,9 +7,7 @@ use crate::sys::cvt; use crate::sys::process::process_common::*; #[cfg(target_os = "linux")] -use crate::os::linux::process::PidFd; -#[cfg(target_os = "linux")] -use crate::os::unix::io::AsRawFd; +use crate::sys::pal::unix::linux::pidfd::PidFd; #[cfg(target_os = "vxworks")] use libc::RTP_ID as pid_t; @@ -815,16 +813,7 @@ impl Process { #[cfg(target_os = "linux")] if let Some(pid_fd) = self.pidfd.as_ref() { // pidfd_send_signal predates pidfd_open. so if we were able to get an fd then sending signals will work too - return cvt(unsafe { - libc::syscall( - libc::SYS_pidfd_send_signal, - pid_fd.as_raw_fd(), - libc::SIGKILL, - crate::ptr::null::<()>(), - 0, - ) - }) - .map(drop); + return pid_fd.kill(); } cvt(unsafe { libc::kill(self.pid, libc::SIGKILL) }).map(drop) } @@ -836,12 +825,7 @@ impl Process { } #[cfg(target_os = "linux")] if let Some(pid_fd) = self.pidfd.as_ref() { - let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() }; - - cvt_r(|| unsafe { - libc::waitid(libc::P_PIDFD, pid_fd.as_raw_fd() as u32, &mut siginfo, libc::WEXITED) - })?; - let status = ExitStatus::from_waitid_siginfo(siginfo); + let status = pid_fd.wait()?; self.status = Some(status); return Ok(status); } @@ -857,22 +841,11 @@ impl Process { } #[cfg(target_os = "linux")] if let Some(pid_fd) = self.pidfd.as_ref() { - let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() }; - - cvt(unsafe { - libc::waitid( - libc::P_PIDFD, - pid_fd.as_raw_fd() as u32, - &mut siginfo, - libc::WEXITED | libc::WNOHANG, - ) - })?; - if unsafe { siginfo.si_pid() } == 0 { - return Ok(None); + let status = pid_fd.try_wait()?; + if let Some(status) = status { + self.status = Some(status) } - let status = ExitStatus::from_waitid_siginfo(siginfo); - self.status = Some(status); - return Ok(Some(status)); + return Ok(status); } let mut status = 0 as c_int; let pid = cvt(unsafe { libc::waitpid(self.pid, &mut status, libc::WNOHANG) })?; @@ -1105,20 +1078,33 @@ impl ExitStatusError { } #[cfg(target_os = "linux")] -#[unstable(feature = "linux_pidfd", issue = "82971")] -impl crate::os::linux::process::ChildExt for crate::process::Child { - fn pidfd(&self) -> io::Result<&PidFd> { - self.handle - .pidfd - .as_ref() - .ok_or_else(|| Error::new(ErrorKind::Uncategorized, "No pidfd was created.")) - } +mod linux_child_ext { + + use crate::io; + use crate::mem; + use crate::os::linux::process as os; + use crate::sys::pal::unix::linux::pidfd as imp; + use crate::sys::pal::unix::ErrorKind; + use crate::sys_common::FromInner; + + #[unstable(feature = "linux_pidfd", issue = "82971")] + impl crate::os::linux::process::ChildExt for crate::process::Child { + fn pidfd(&self) -> io::Result<&os::PidFd> { + self.handle + .pidfd + .as_ref() + // SAFETY: The os type is a transparent wrapper, therefore we can transmute references + .map(|fd| unsafe { mem::transmute::<&imp::PidFd, &os::PidFd>(fd) }) + .ok_or_else(|| io::Error::new(ErrorKind::Uncategorized, "No pidfd was created.")) + } - fn take_pidfd(&mut self) -> io::Result { - self.handle - .pidfd - .take() - .ok_or_else(|| Error::new(ErrorKind::Uncategorized, "No pidfd was created.")) + fn into_pidfd(mut self) -> Result { + self.handle + .pidfd + .take() + .map(|fd| >::from_inner(fd)) + .ok_or_else(|| self) + } } } diff --git a/library/std/src/sys/pal/unix/process/process_unix/tests.rs b/library/std/src/sys/pal/unix/process/process_unix/tests.rs index 0a6c6ec19fc7e..e5e1f956bc351 100644 --- a/library/std/src/sys/pal/unix/process/process_unix/tests.rs +++ b/library/std/src/sys/pal/unix/process/process_unix/tests.rs @@ -60,57 +60,3 @@ fn test_command_fork_no_unwind() { || signal == libc::SIGSEGV ); } - -#[test] -#[cfg(target_os = "linux")] // pidfds are a linux-specific concept -fn test_command_pidfd() { - use crate::assert_matches::assert_matches; - use crate::os::fd::{AsRawFd, RawFd}; - use crate::os::linux::process::{ChildExt, CommandExt}; - use crate::process::Command; - - // pidfds require the pidfd_open syscall - let our_pid = crate::process::id(); - let pidfd = unsafe { libc::syscall(libc::SYS_pidfd_open, our_pid, 0) }; - let pidfd_open_available = if pidfd >= 0 { - unsafe { libc::close(pidfd as RawFd) }; - true - } else { - false - }; - - // always exercise creation attempts - let mut child = Command::new("false").create_pidfd(true).spawn().unwrap(); - - // but only check if we know that the kernel supports pidfds. - // We don't assert the precise value, since the standard library - // might have opened other file descriptors before our code runs. - if pidfd_open_available { - assert!(child.pidfd().is_ok()); - } - if let Ok(pidfd) = child.pidfd() { - let flags = super::cvt(unsafe { libc::fcntl(pidfd.as_raw_fd(), libc::F_GETFD) }).unwrap(); - assert!(flags & libc::FD_CLOEXEC != 0); - } - let status = child.wait().expect("error waiting on pidfd"); - assert_eq!(status.code(), Some(1)); - - let mut child = Command::new("sleep").arg("1000").create_pidfd(true).spawn().unwrap(); - assert_matches!(child.try_wait(), Ok(None)); - child.kill().expect("failed to kill child"); - let status = child.wait().expect("error waiting on pidfd"); - assert_eq!(status.signal(), Some(libc::SIGKILL)); - - let _ = Command::new("echo") - .create_pidfd(false) - .spawn() - .unwrap() - .pidfd() - .expect_err("pidfd should not have been created when create_pid(false) is set"); - - let _ = Command::new("echo") - .spawn() - .unwrap() - .pidfd() - .expect_err("pidfd should not have been created"); -} diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 6dbf4f242d71e..1a8ff931f0177 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -60,6 +60,7 @@ - [mipsel-sony-psx](platform-support/mipsel-sony-psx.md) - [mipsisa\*r6\*-unknown-linux-gnu\*](platform-support/mips-release-6.md) - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md) + - [powerpc-unknown-openbsd](platform-support/powerpc-unknown-openbsd.md) - [powerpc64-ibm-aix](platform-support/aix.md) - [riscv32im-risc0-zkvm-elf](platform-support/riscv32im-risc0-zkvm-elf.md) - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c821c0f5726a3..537c88cd22b2e 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -330,7 +330,7 @@ target | std | host | notes `powerpc-unknown-linux-gnuspe` | ✓ | | PowerPC SPE Linux `powerpc-unknown-linux-musl` | ? | | PowerPC Linux with musl 1.2.3 [`powerpc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD 32-bit powerpc systems -`powerpc-unknown-openbsd` | ? | | +[`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * | | `powerpc-wrs-vxworks-spe` | ? | | `powerpc-wrs-vxworks` | ? | | `powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2) diff --git a/src/doc/rustc/src/platform-support/powerpc-unknown-openbsd.md b/src/doc/rustc/src/platform-support/powerpc-unknown-openbsd.md new file mode 100644 index 0000000000000..b1600c71f1f3c --- /dev/null +++ b/src/doc/rustc/src/platform-support/powerpc-unknown-openbsd.md @@ -0,0 +1,3 @@ +## Designated maintainers + +`powerpc-unknown-openbsd` is not maintained by OpenBSD developers and there are currently no active rustc maintainers. diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index fb43f7d80afff..785d5ed5dbeba 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -449,13 +449,13 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool { use ForeignItemKind::*; match (l, r) { ( - Static(box StaticForeignItem { + Static(box StaticItem { ty: lt, mutability: lm, expr: le, safety: ls, }), - Static(box StaticForeignItem { + Static(box StaticItem { ty: rt, mutability: rm, expr: re, diff --git a/tests/run-make/inaccessible-temp-dir/rmake.rs b/tests/run-make/inaccessible-temp-dir/rmake.rs index be24e47b6decc..c6bfae4cc01db 100644 --- a/tests/run-make/inaccessible-temp-dir/rmake.rs +++ b/tests/run-make/inaccessible-temp-dir/rmake.rs @@ -19,7 +19,7 @@ // Reason: `set_readonly` has no effect on directories // and does not prevent modification. -use run_make_support::{fs_wrapper, rustc, test_while_readonly}; +use run_make_support::{fs_wrapper, rustc, target, test_while_readonly}; fn main() { // Create an inaccessible directory. @@ -28,6 +28,7 @@ fn main() { // Run rustc with `-Z temps-dir` set to a directory *inside* the inaccessible one, // so that it can't create `tmp`. rustc() + .target(&target()) .input("program.rs") .arg("-Ztemps-dir=inaccessible/tmp") .run_fail() diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index b3d0046fc1788..cc63466585a6a 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra` LL | cfg!(target_feature = "zebra"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, and `bulk-memory` and 186 more + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, and `avxvnniint8` and 191 more = note: see for more information about checking conditional configuration warning: 27 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index d2026a68450eb..8a99ace75d852 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -165,7 +165,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` + = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` diff --git a/tests/ui/macros/auxiliary/expr_2021_implicit.rs b/tests/ui/macros/auxiliary/expr_2021_implicit.rs new file mode 100644 index 0000000000000..61762e41dee0c --- /dev/null +++ b/tests/ui/macros/auxiliary/expr_2021_implicit.rs @@ -0,0 +1,9 @@ +//@ edition:2021 + +#[macro_export] +macro_rules! m { + ($expr:expr) => { + compile_error!("did not expect an expression to be parsed"); + }; + (const { }) => {}; +} diff --git a/tests/ui/macros/expr_2021_implicit_in_2024.rs b/tests/ui/macros/expr_2021_implicit_in_2024.rs new file mode 100644 index 0000000000000..b3f7a31a802dd --- /dev/null +++ b/tests/ui/macros/expr_2021_implicit_in_2024.rs @@ -0,0 +1,12 @@ +//@ compile-flags: --edition=2024 -Zunstable-options +//@ aux-build:expr_2021_implicit.rs + +//@ check-pass + +extern crate expr_2021_implicit; + +// Makes sure that a `:expr` fragment matcher defined in a edition 2021 crate +// still parses like an `expr_2021` fragment matcher in a 2024 user crate. +expr_2021_implicit::m!(const {}); + +fn main() {} diff --git a/tests/ui/macros/expr_2021_old_edition.rs b/tests/ui/macros/expr_2021_old_edition.rs deleted file mode 100644 index a771126610686..0000000000000 --- a/tests/ui/macros/expr_2021_old_edition.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ compile-flags: --edition=2018 - -// This test ensures that expr_2021 is not allowed on pre-2021 editions - -macro_rules! m { - ($e:expr_2021) => { //~ ERROR: invalid fragment specifier `expr_2021` - $e - }; -} - -fn main() { - m!(()); //~ ERROR: no rules expected the token `(` -} diff --git a/tests/ui/macros/expr_2021_old_edition.stderr b/tests/ui/macros/expr_2021_old_edition.stderr deleted file mode 100644 index bffa8a1ca1759..0000000000000 --- a/tests/ui/macros/expr_2021_old_edition.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: invalid fragment specifier `expr_2021` - --> $DIR/expr_2021_old_edition.rs:6:6 - | -LL | ($e:expr_2021) => { - | ^^^^^^^^^^^^ - | - = help: fragment specifier `expr_2021` requires Rust 2021 or later - valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` - -error: no rules expected the token `(` - --> $DIR/expr_2021_old_edition.rs:12:8 - | -LL | macro_rules! m { - | -------------- when calling this macro -... -LL | m!(()); - | ^ no rules expected this token in macro call - | -note: while trying to match meta-variable `$e:ident` - --> $DIR/expr_2021_old_edition.rs:6:6 - | -LL | ($e:expr_2021) => { - | ^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/parser/diff-markers/enum-2.stderr b/tests/ui/parser/diff-markers/enum-2.stderr index 20e551c2f959a..b76cf5d5a01ee 100644 --- a/tests/ui/parser/diff-markers/enum-2.stderr +++ b/tests/ui/parser/diff-markers/enum-2.stderr @@ -2,20 +2,25 @@ error: encountered diff marker --> $DIR/enum-2.rs:3:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `|||||||` is the code that we're merging into LL | x: u8, LL | ||||||| - | ------- + | ------- between this marker and `=======` is the base code (what the two refs diverged from) LL | z: (), LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | y: i8, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/enum.stderr b/tests/ui/parser/diff-markers/enum.stderr index be94331dce528..0ce473bc70232 100644 --- a/tests/ui/parser/diff-markers/enum.stderr +++ b/tests/ui/parser/diff-markers/enum.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/enum.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | Foo(u8), LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | Bar(i8), LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/fn-arg.stderr b/tests/ui/parser/diff-markers/fn-arg.stderr index aabcb826c1283..24521ffa62623 100644 --- a/tests/ui/parser/diff-markers/fn-arg.stderr +++ b/tests/ui/parser/diff-markers/fn-arg.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/fn-arg.rs:3:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | x: u8, LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | x: i8, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/item-with-attr.stderr b/tests/ui/parser/diff-markers/item-with-attr.stderr index eefb2792e90bc..432673cd5518b 100644 --- a/tests/ui/parser/diff-markers/item-with-attr.stderr +++ b/tests/ui/parser/diff-markers/item-with-attr.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/item-with-attr.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | fn foo() {} LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | fn bar() {} LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/item.stderr b/tests/ui/parser/diff-markers/item.stderr index a3092ebfcfd36..180c74e5d6967 100644 --- a/tests/ui/parser/diff-markers/item.stderr +++ b/tests/ui/parser/diff-markers/item.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/item.rs:1:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | fn foo() {} LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | fn bar() {} LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/statement.stderr b/tests/ui/parser/diff-markers/statement.stderr index c6c6cae876594..6dccce4a48eee 100644 --- a/tests/ui/parser/diff-markers/statement.stderr +++ b/tests/ui/parser/diff-markers/statement.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/statement.rs:10:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | S::foo(); LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | S::bar(); LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/struct-expr.stderr b/tests/ui/parser/diff-markers/struct-expr.stderr index bdea8c841c638..3733cdd349644 100644 --- a/tests/ui/parser/diff-markers/struct-expr.stderr +++ b/tests/ui/parser/diff-markers/struct-expr.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/struct-expr.rs:6:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | x: 42, LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | x: 0, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/struct.stderr b/tests/ui/parser/diff-markers/struct.stderr index 749941290cb82..44f8346613e68 100644 --- a/tests/ui/parser/diff-markers/struct.stderr +++ b/tests/ui/parser/diff-markers/struct.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/struct.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | x: u8, LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | x: i8, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/trait-item.stderr b/tests/ui/parser/diff-markers/trait-item.stderr index f01bbe8ba0340..4361542c7743b 100644 --- a/tests/ui/parser/diff-markers/trait-item.stderr +++ b/tests/ui/parser/diff-markers/trait-item.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/trait-item.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | fn foo() {} LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | fn bar() {} LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/tuple-struct.stderr b/tests/ui/parser/diff-markers/tuple-struct.stderr index 8dae123c96dca..7fda24ba48532 100644 --- a/tests/ui/parser/diff-markers/tuple-struct.stderr +++ b/tests/ui/parser/diff-markers/tuple-struct.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/tuple-struct.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | u8, LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | i8, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr b/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr index 6995b8e6f2370..927821ddfaedb 100644 --- a/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr +++ b/tests/ui/parser/diff-markers/unclosed-delims-in-macro.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/unclosed-delims-in-macro.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into ... LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | () { // LL | >>>>>>> 7a4f13c blah blah blah - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/unclosed-delims.rs b/tests/ui/parser/diff-markers/unclosed-delims.rs index 653a605c28c60..7d400c3827bb6 100644 --- a/tests/ui/parser/diff-markers/unclosed-delims.rs +++ b/tests/ui/parser/diff-markers/unclosed-delims.rs @@ -2,13 +2,17 @@ mod tests { #[test] <<<<<<< HEAD //~^ ERROR encountered diff marker -//~| NOTE after this is the code before the merge +//~| NOTE between this marker and `=======` + +//~| NOTE conflict markers indicate that +//~| HELP if you're having merge conflicts //~| NOTE for an explanation on these markers + fn test1() { ======= -//~^ NOTE +//~^ NOTE between this marker and `>>>>>>>` fn test2() { >>>>>>> 7a4f13c blah blah blah -//~^ NOTE above this are the incoming code changes +//~^ NOTE this marker concludes the conflict region } } diff --git a/tests/ui/parser/diff-markers/unclosed-delims.stderr b/tests/ui/parser/diff-markers/unclosed-delims.stderr index d4636150e66b7..1eab96442b4f2 100644 --- a/tests/ui/parser/diff-markers/unclosed-delims.stderr +++ b/tests/ui/parser/diff-markers/unclosed-delims.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/unclosed-delims.rs:3:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into ... LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code ... LL | >>>>>>> 7a4f13c blah blah blah - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error diff --git a/tests/ui/parser/diff-markers/use-statement.stderr b/tests/ui/parser/diff-markers/use-statement.stderr index 6d376166a7f7a..3eac7bebb5af1 100644 --- a/tests/ui/parser/diff-markers/use-statement.stderr +++ b/tests/ui/parser/diff-markers/use-statement.stderr @@ -2,17 +2,22 @@ error: encountered diff marker --> $DIR/use-statement.rs:2:1 | LL | <<<<<<< HEAD - | ^^^^^^^ after this is the code before the merge + | ^^^^^^^ between this marker and `=======` is the code that we're merging into LL | bar, LL | ======= - | ------- + | ------- between this marker and `>>>>>>>` is the incoming code LL | baz, LL | >>>>>>> branch - | ^^^^^^^ above this are the incoming code changes + | ^^^^^^^ this marker concludes the conflict region | - = help: if you're having merge conflicts after pulling new code, the top section is the code you already had and the bottom section is the remote code - = help: if you're in the middle of a rebase, the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased - = note: for an explanation on these markers from the `git` documentation, visit + = note: conflict markers indicate that a merge was started but could not be completed due to merge conflicts + to resolve a conflict, keep only the code you want and then delete the lines containing conflict markers + = help: if you're having merge conflicts after pulling new code: + the top section is the code you already had and the bottom section is the remote code + if you're in the middle of a rebase: + the top section is the code being rebased onto and the bottom section is the code coming from the current commit being rebased + = note: for an explanation on these markers from the `git` documentation: + visit error: aborting due to 1 previous error