Skip to content

Commit 7637fd5

Browse files
committed
Auto merge of rust-lang#83503 - Dylan-DPC:rollup-mqvjfav, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - rust-lang#83055 ([rustdoc] Don't document stripped items in JSON renderer.) - rust-lang#83437 (Refactor rust-lang#82270 as lint instead of an error) - rust-lang#83444 (Fix bootstrap tests on beta) - rust-lang#83456 (Add docs for Vec::from functions) - rust-lang#83463 (ExitStatusExt: Fix missing word in two docs messages) - rust-lang#83470 (Fix patch note about rust-lang#80653 not mentioning nested nor recursive) - rust-lang#83485 (Mark asm tests as requiring LLVM 10.0.1) - rust-lang#83486 (Don't ICE when using `#[global_alloc]` on a non-item statement) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0ced530 + b0bec95 commit 7637fd5

39 files changed

+393
-159
lines changed

Cargo.lock

+7
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,12 @@ dependencies = [
12191219
"rustc-std-workspace-core",
12201220
]
12211221

1222+
[[package]]
1223+
name = "fs-err"
1224+
version = "2.5.0"
1225+
source = "registry+https://github.com/rust-lang/crates.io-index"
1226+
checksum = "bcd1163ae48bda72a20ae26d66a04d3094135cadab911cff418ae5e33f253431"
1227+
12221228
[[package]]
12231229
name = "fs_extra"
12241230
version = "1.1.0"
@@ -1748,6 +1754,7 @@ checksum = "92c245af8786f6ac35f95ca14feca9119e71339aaab41e878e7cdd655c97e9e5"
17481754
name = "jsondocck"
17491755
version = "0.1.0"
17501756
dependencies = [
1757+
"fs-err",
17511758
"getopts",
17521759
"jsonpath_lib",
17531760
"lazy_static",

RELEASES.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Cargo
8787
Rustdoc
8888
-------
8989

90-
- [Rustdoc will now include documentation for methods available from `Deref` traits.][80653]
90+
- [Rustdoc will now include documentation for methods available from _nested_ `Deref` traits.][80653]
9191
- [You can now provide a `--default-theme` flag which sets the default theme to use for
9292
documentation.][79642]
9393

compiler/rustc_builtin_macros/src/asm.rs

+30-65
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
77
use rustc_expand::base::{self, *};
88
use rustc_parse::parser::Parser;
99
use rustc_parse_format as parse;
10-
use rustc_span::{
11-
symbol::{kw, sym, Symbol},
12-
BytePos,
13-
};
10+
use rustc_session::lint;
11+
use rustc_span::symbol::{kw, sym, Symbol};
1412
use rustc_span::{InnerSpan, Span};
13+
use rustc_target::asm::InlineAsmArch;
1514

1615
struct AsmArgs {
1716
templates: Vec<P<ast::Expr>>,
@@ -402,8 +401,6 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
402401
let mut line_spans = Vec::with_capacity(args.templates.len());
403402
let mut curarg = 0;
404403

405-
let default_dialect = ecx.sess.inline_asm_dialect();
406-
407404
for template_expr in args.templates.into_iter() {
408405
if !template.is_empty() {
409406
template.push(ast::InlineAsmTemplatePiece::String("\n".to_string()));
@@ -430,56 +427,36 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
430427
let template_str = &template_str.as_str();
431428
let template_snippet = ecx.source_map().span_to_snippet(template_sp).ok();
432429

433-
if let Some(snippet) = &template_snippet {
434-
let snippet = snippet.trim_matches('"');
435-
match default_dialect {
436-
ast::LlvmAsmDialect::Intel => {
437-
if let Some(span) = check_syntax_directive(snippet, ".intel_syntax") {
438-
let span = template_span.from_inner(span);
439-
let mut err = ecx.struct_span_err(span, "intel syntax is the default syntax on this target, and trying to use this directive may cause issues");
440-
err.span_suggestion(
441-
span,
442-
"remove this assembler directive",
443-
"".to_string(),
444-
Applicability::MachineApplicable,
445-
);
446-
err.emit();
447-
}
448-
449-
if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
450-
let span = template_span.from_inner(span);
451-
let mut err = ecx.struct_span_err(span, "using the .att_syntax directive may cause issues, use the att_syntax option instead");
452-
let asm_end = sp.hi() - BytePos(2);
453-
let suggestions = vec![
454-
(span, "".to_string()),
455-
(
456-
Span::new(asm_end, asm_end, sp.ctxt()),
457-
", options(att_syntax)".to_string(),
458-
),
459-
];
460-
err.multipart_suggestion(
461-
"remove the assembler directive and replace it with options(att_syntax)",
462-
suggestions,
463-
Applicability::MachineApplicable,
464-
);
465-
err.emit();
430+
if let Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) = ecx.sess.asm_arch {
431+
let find_span = |needle: &str| -> Span {
432+
if let Some(snippet) = &template_snippet {
433+
if let Some(pos) = snippet.find(needle) {
434+
let end = pos
435+
+ &snippet[pos..]
436+
.find(|c| matches!(c, '\n' | ';' | '\\' | '"'))
437+
.unwrap_or(snippet[pos..].len() - 1);
438+
let inner = InnerSpan::new(pos, end);
439+
return template_sp.from_inner(inner);
466440
}
467441
}
468-
ast::LlvmAsmDialect::Att => {
469-
if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
470-
let span = template_span.from_inner(span);
471-
let mut err = ecx.struct_span_err(span, "att syntax is the default syntax on this target, and trying to use this directive may cause issues");
472-
err.span_suggestion(
473-
span,
474-
"remove this assembler directive",
475-
"".to_string(),
476-
Applicability::MachineApplicable,
477-
);
478-
err.emit();
479-
}
442+
template_sp
443+
};
480444

481-
// Use of .intel_syntax is ignored
482-
}
445+
if template_str.contains(".intel_syntax") {
446+
ecx.parse_sess().buffer_lint(
447+
lint::builtin::BAD_ASM_STYLE,
448+
find_span(".intel_syntax"),
449+
ecx.resolver.lint_node_id(ecx.current_expansion.id),
450+
"avoid using `.intel_syntax`, Intel syntax is the default",
451+
);
452+
}
453+
if template_str.contains(".att_syntax") {
454+
ecx.parse_sess().buffer_lint(
455+
lint::builtin::BAD_ASM_STYLE,
456+
find_span(".att_syntax"),
457+
ecx.resolver.lint_node_id(ecx.current_expansion.id),
458+
"avoid using `.att_syntax`, prefer using `options(att_syntax)` instead",
459+
);
483460
}
484461
}
485462

@@ -690,15 +667,3 @@ pub fn expand_asm<'cx>(
690667
}
691668
}
692669
}
693-
694-
fn check_syntax_directive<S: AsRef<str>>(piece: S, syntax: &str) -> Option<InnerSpan> {
695-
let piece = piece.as_ref();
696-
if let Some(idx) = piece.find(syntax) {
697-
let end =
698-
idx + &piece[idx..].find(|c| matches!(c, '\n' | ';')).unwrap_or(piece[idx..].len());
699-
// Offset by one because these represent the span with the " removed
700-
Some(InnerSpan::new(idx + 1, end + 1))
701-
} else {
702-
None
703-
}
704-
}

compiler/rustc_builtin_macros/src/global_allocator.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,31 @@ pub fn expand(
1414
ecx: &mut ExtCtxt<'_>,
1515
_span: Span,
1616
meta_item: &ast::MetaItem,
17-
mut item: Annotatable,
17+
item: Annotatable,
1818
) -> Vec<Annotatable> {
1919
check_builtin_macro_attribute(ecx, meta_item, sym::global_allocator);
2020

21-
let not_static = |item: Annotatable| {
21+
let orig_item = item.clone();
22+
let not_static = || {
2223
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics");
23-
vec![item]
24+
vec![orig_item.clone()]
2425
};
25-
let orig_item = item.clone();
26-
let mut is_stmt = false;
2726

2827
// Allow using `#[global_allocator]` on an item statement
29-
if let Annotatable::Stmt(stmt) = &item {
30-
if let StmtKind::Item(item_) = &stmt.kind {
31-
item = Annotatable::Item(item_.clone());
32-
is_stmt = true;
33-
}
34-
}
35-
36-
let item = match item {
28+
// FIXME - if we get deref patterns, use them to reduce duplication here
29+
let (item, is_stmt) = match &item {
3730
Annotatable::Item(item) => match item.kind {
38-
ItemKind::Static(..) => item,
39-
_ => return not_static(Annotatable::Item(item)),
31+
ItemKind::Static(..) => (item, false),
32+
_ => return not_static(),
33+
},
34+
Annotatable::Stmt(stmt) => match &stmt.kind {
35+
StmtKind::Item(item_) => match item_.kind {
36+
ItemKind::Static(..) => (item_, true),
37+
_ => return not_static(),
38+
},
39+
_ => return not_static(),
4040
},
41-
_ => return not_static(item),
41+
_ => return not_static(),
4242
};
4343

4444
// Generate a bunch of new items using the AllocFnFactory

compiler/rustc_lint_defs/src/builtin.rs

+46
Original file line numberDiff line numberDiff line change
@@ -2486,6 +2486,52 @@ declare_lint! {
24862486
"using only a subset of a register for inline asm inputs",
24872487
}
24882488

2489+
declare_lint! {
2490+
/// The `bad_asm_style` lint detects the use of the `.intel_syntax` and
2491+
/// `.att_syntax` directives.
2492+
///
2493+
/// ### Example
2494+
///
2495+
/// ```rust,ignore (fails on system llvm)
2496+
/// #![feature(asm)]
2497+
///
2498+
/// fn main() {
2499+
/// #[cfg(target_arch="x86_64")]
2500+
/// unsafe {
2501+
/// asm!(
2502+
/// ".att_syntax",
2503+
/// "movl {0}, {0}", in(reg) 0usize
2504+
/// );
2505+
/// }
2506+
/// }
2507+
/// ```
2508+
///
2509+
/// This will produce:
2510+
///
2511+
/// ```text
2512+
/// warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
2513+
/// --> test.rs:7:14
2514+
/// |
2515+
/// 7 | ".att_syntax",
2516+
/// | ^^^^^^^^^^^
2517+
/// 8 | "movq {0}, {0}", out(reg) _,
2518+
/// 9 | );
2519+
/// | - help: add option: `, options(att_syntax)`
2520+
/// |
2521+
/// = note: `#[warn(bad_asm_style)]` on by default
2522+
/// ```
2523+
///
2524+
/// ### Explanation
2525+
///
2526+
/// On x86, `asm!` uses the intel assembly syntax by default. While this
2527+
/// can be switched using assembler directives like `.att_syntax`, using the
2528+
/// `att_syntax` option is recomended instead because it will also properly
2529+
/// prefix register placeholders with `%` as required by AT&T syntax.
2530+
pub BAD_ASM_STYLE,
2531+
Warn,
2532+
"incorrect use of inline assembly",
2533+
}
2534+
24892535
declare_lint! {
24902536
/// The `unsafe_op_in_unsafe_fn` lint detects unsafe operations in unsafe
24912537
/// functions without an explicit unsafe block.

compiler/rustc_session/src/session.rs

-7
Original file line numberDiff line numberDiff line change
@@ -793,13 +793,6 @@ impl Session {
793793
}
794794
}
795795

796-
pub fn inline_asm_dialect(&self) -> rustc_ast::LlvmAsmDialect {
797-
match self.asm_arch {
798-
Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) => rustc_ast::LlvmAsmDialect::Intel,
799-
_ => rustc_ast::LlvmAsmDialect::Att,
800-
}
801-
}
802-
803796
pub fn relocation_model(&self) -> RelocModel {
804797
self.opts.cg.relocation_model.unwrap_or(self.target.relocation_model)
805798
}

library/alloc/src/vec/mod.rs

+61
Original file line numberDiff line numberDiff line change
@@ -2712,6 +2712,13 @@ impl<T, A: Allocator> AsMut<[T]> for Vec<T, A> {
27122712

27132713
#[stable(feature = "rust1", since = "1.0.0")]
27142714
impl<T: Clone> From<&[T]> for Vec<T> {
2715+
/// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
2716+
///
2717+
/// # Examples
2718+
///
2719+
/// ```
2720+
/// assert_eq!(Vec::from(&[1, 2, 3][..]), vec![1, 2, 3]);
2721+
/// ```
27152722
#[cfg(not(test))]
27162723
fn from(s: &[T]) -> Vec<T> {
27172724
s.to_vec()
@@ -2724,6 +2731,13 @@ impl<T: Clone> From<&[T]> for Vec<T> {
27242731

27252732
#[stable(feature = "vec_from_mut", since = "1.19.0")]
27262733
impl<T: Clone> From<&mut [T]> for Vec<T> {
2734+
/// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
2735+
///
2736+
/// # Examples
2737+
///
2738+
/// ```
2739+
/// assert_eq!(Vec::from(&mut [1, 2, 3][..]), vec![1, 2, 3]);
2740+
/// ```
27272741
#[cfg(not(test))]
27282742
fn from(s: &mut [T]) -> Vec<T> {
27292743
s.to_vec()
@@ -2740,6 +2754,13 @@ impl<T, const N: usize> From<[T; N]> for Vec<T> {
27402754
fn from(s: [T; N]) -> Vec<T> {
27412755
<[T]>::into_vec(box s)
27422756
}
2757+
/// Allocate a `Vec<T>` and move `s`'s items into it.
2758+
///
2759+
/// # Examples
2760+
///
2761+
/// ```
2762+
/// assert_eq!(Vec::from([1, 2, 3]), vec![1, 2, 3]);
2763+
/// ```
27432764
#[cfg(test)]
27442765
fn from(s: [T; N]) -> Vec<T> {
27452766
crate::slice::into_vec(box s)
@@ -2751,6 +2772,20 @@ impl<'a, T> From<Cow<'a, [T]>> for Vec<T>
27512772
where
27522773
[T]: ToOwned<Owned = Vec<T>>,
27532774
{
2775+
/// Convert a clone-on-write slice into a vector.
2776+
///
2777+
/// If `s` already owns a `Vec<T>`, it will be returned directly.
2778+
/// If `s` is borrowing a slice, a new `Vec<T>` will be allocated and
2779+
/// filled by cloning `s`'s items into it.
2780+
///
2781+
/// # Examples
2782+
///
2783+
/// ```
2784+
/// # use std::borrow::Cow;
2785+
/// let o: Cow<[i32]> = Cow::Owned(vec![1, 2, 3]);
2786+
/// let b: Cow<[i32]> = Cow::Borrowed(&[1, 2, 3]);
2787+
/// assert_eq!(Vec::from(o), Vec::from(b));
2788+
/// ```
27542789
fn from(s: Cow<'a, [T]>) -> Vec<T> {
27552790
s.into_owned()
27562791
}
@@ -2760,6 +2795,15 @@ where
27602795
#[cfg(not(test))]
27612796
#[stable(feature = "vec_from_box", since = "1.18.0")]
27622797
impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A> {
2798+
/// Convert a boxed slice into a vector by transferring ownership of
2799+
/// the existing heap allocation.
2800+
///
2801+
/// # Examples
2802+
///
2803+
/// ```
2804+
/// let b: Box<[i32]> = vec![1, 2, 3].into_boxed_slice();
2805+
/// assert_eq!(Vec::from(b), vec![1, 2, 3]);
2806+
/// ```
27632807
fn from(s: Box<[T], A>) -> Self {
27642808
let len = s.len();
27652809
Self { buf: RawVec::from_box(s), len }
@@ -2770,13 +2814,30 @@ impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A> {
27702814
#[cfg(not(test))]
27712815
#[stable(feature = "box_from_vec", since = "1.20.0")]
27722816
impl<T, A: Allocator> From<Vec<T, A>> for Box<[T], A> {
2817+
/// Convert a vector into a boxed slice.
2818+
///
2819+
/// If `v` has excess capacity, its items will be moved into a
2820+
/// newly-allocated buffer with exactly the right capacity.
2821+
///
2822+
/// # Examples
2823+
///
2824+
/// ```
2825+
/// assert_eq!(Box::from(vec![1, 2, 3]), vec![1, 2, 3].into_boxed_slice());
2826+
/// ```
27732827
fn from(v: Vec<T, A>) -> Self {
27742828
v.into_boxed_slice()
27752829
}
27762830
}
27772831

27782832
#[stable(feature = "rust1", since = "1.0.0")]
27792833
impl From<&str> for Vec<u8> {
2834+
/// Allocate a `Vec<u8>` and fill it with a UTF-8 string.
2835+
///
2836+
/// # Examples
2837+
///
2838+
/// ```
2839+
/// assert_eq!(Vec::from("123"), vec![b'1', b'2', b'3']);
2840+
/// ```
27802841
fn from(s: &str) -> Vec<u8> {
27812842
From::from(s.as_bytes())
27822843
}

library/std/src/sys/unix/ext/process.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,14 @@ pub trait ExitStatusExt: Sealed {
227227
/// If the process was stopped by a signal, returns that signal.
228228
///
229229
/// In other words, if `WIFSTOPPED`, this returns `WSTOPSIG`. This is only possible if the status came from
230-
/// a `wait` system call which was passed `WUNTRACED`, was then converted into an `ExitStatus`.
230+
/// a `wait` system call which was passed `WUNTRACED`, and was then converted into an `ExitStatus`.
231231
#[unstable(feature = "unix_process_wait_more", issue = "80695")]
232232
fn stopped_signal(&self) -> Option<i32>;
233233

234234
/// Whether the process was continued from a stopped status.
235235
///
236236
/// Ie, `WIFCONTINUED`. This is only possible if the status came from a `wait` system call
237-
/// which was passed `WCONTINUED`, was then converted into an `ExitStatus`.
237+
/// which was passed `WCONTINUED`, and was then converted into an `ExitStatus`.
238238
#[unstable(feature = "unix_process_wait_more", issue = "80695")]
239239
fn continued(&self) -> bool;
240240

0 commit comments

Comments
 (0)