Skip to content

Commit

Permalink
Auto merge of rust-lang#83503 - Dylan-DPC:rollup-mqvjfav, r=Dylan-DPC
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Mar 26, 2021
2 parents 0ced530 + b0bec95 commit 7637fd5
Show file tree
Hide file tree
Showing 39 changed files with 393 additions and 159 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,12 @@ dependencies = [
"rustc-std-workspace-core",
]

[[package]]
name = "fs-err"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcd1163ae48bda72a20ae26d66a04d3094135cadab911cff418ae5e33f253431"

[[package]]
name = "fs_extra"
version = "1.1.0"
Expand Down Expand Up @@ -1748,6 +1754,7 @@ checksum = "92c245af8786f6ac35f95ca14feca9119e71339aaab41e878e7cdd655c97e9e5"
name = "jsondocck"
version = "0.1.0"
dependencies = [
"fs-err",
"getopts",
"jsonpath_lib",
"lazy_static",
Expand Down
2 changes: 1 addition & 1 deletion RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Cargo
Rustdoc
-------

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

Expand Down
95 changes: 30 additions & 65 deletions compiler/rustc_builtin_macros/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_expand::base::{self, *};
use rustc_parse::parser::Parser;
use rustc_parse_format as parse;
use rustc_span::{
symbol::{kw, sym, Symbol},
BytePos,
};
use rustc_session::lint;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{InnerSpan, Span};
use rustc_target::asm::InlineAsmArch;

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

let default_dialect = ecx.sess.inline_asm_dialect();

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

if let Some(snippet) = &template_snippet {
let snippet = snippet.trim_matches('"');
match default_dialect {
ast::LlvmAsmDialect::Intel => {
if let Some(span) = check_syntax_directive(snippet, ".intel_syntax") {
let span = template_span.from_inner(span);
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");
err.span_suggestion(
span,
"remove this assembler directive",
"".to_string(),
Applicability::MachineApplicable,
);
err.emit();
}

if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
let span = template_span.from_inner(span);
let mut err = ecx.struct_span_err(span, "using the .att_syntax directive may cause issues, use the att_syntax option instead");
let asm_end = sp.hi() - BytePos(2);
let suggestions = vec![
(span, "".to_string()),
(
Span::new(asm_end, asm_end, sp.ctxt()),
", options(att_syntax)".to_string(),
),
];
err.multipart_suggestion(
"remove the assembler directive and replace it with options(att_syntax)",
suggestions,
Applicability::MachineApplicable,
);
err.emit();
if let Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) = ecx.sess.asm_arch {
let find_span = |needle: &str| -> Span {
if let Some(snippet) = &template_snippet {
if let Some(pos) = snippet.find(needle) {
let end = pos
+ &snippet[pos..]
.find(|c| matches!(c, '\n' | ';' | '\\' | '"'))
.unwrap_or(snippet[pos..].len() - 1);
let inner = InnerSpan::new(pos, end);
return template_sp.from_inner(inner);
}
}
ast::LlvmAsmDialect::Att => {
if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
let span = template_span.from_inner(span);
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");
err.span_suggestion(
span,
"remove this assembler directive",
"".to_string(),
Applicability::MachineApplicable,
);
err.emit();
}
template_sp
};

// Use of .intel_syntax is ignored
}
if template_str.contains(".intel_syntax") {
ecx.parse_sess().buffer_lint(
lint::builtin::BAD_ASM_STYLE,
find_span(".intel_syntax"),
ecx.resolver.lint_node_id(ecx.current_expansion.id),
"avoid using `.intel_syntax`, Intel syntax is the default",
);
}
if template_str.contains(".att_syntax") {
ecx.parse_sess().buffer_lint(
lint::builtin::BAD_ASM_STYLE,
find_span(".att_syntax"),
ecx.resolver.lint_node_id(ecx.current_expansion.id),
"avoid using `.att_syntax`, prefer using `options(att_syntax)` instead",
);
}
}

Expand Down Expand Up @@ -690,15 +667,3 @@ pub fn expand_asm<'cx>(
}
}
}

fn check_syntax_directive<S: AsRef<str>>(piece: S, syntax: &str) -> Option<InnerSpan> {
let piece = piece.as_ref();
if let Some(idx) = piece.find(syntax) {
let end =
idx + &piece[idx..].find(|c| matches!(c, '\n' | ';')).unwrap_or(piece[idx..].len());
// Offset by one because these represent the span with the " removed
Some(InnerSpan::new(idx + 1, end + 1))
} else {
None
}
}
32 changes: 16 additions & 16 deletions compiler/rustc_builtin_macros/src/global_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,31 @@ pub fn expand(
ecx: &mut ExtCtxt<'_>,
_span: Span,
meta_item: &ast::MetaItem,
mut item: Annotatable,
item: Annotatable,
) -> Vec<Annotatable> {
check_builtin_macro_attribute(ecx, meta_item, sym::global_allocator);

let not_static = |item: Annotatable| {
let orig_item = item.clone();
let not_static = || {
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics");
vec![item]
vec![orig_item.clone()]
};
let orig_item = item.clone();
let mut is_stmt = false;

// Allow using `#[global_allocator]` on an item statement
if let Annotatable::Stmt(stmt) = &item {
if let StmtKind::Item(item_) = &stmt.kind {
item = Annotatable::Item(item_.clone());
is_stmt = true;
}
}

let item = match item {
// FIXME - if we get deref patterns, use them to reduce duplication here
let (item, is_stmt) = match &item {
Annotatable::Item(item) => match item.kind {
ItemKind::Static(..) => item,
_ => return not_static(Annotatable::Item(item)),
ItemKind::Static(..) => (item, false),
_ => return not_static(),
},
Annotatable::Stmt(stmt) => match &stmt.kind {
StmtKind::Item(item_) => match item_.kind {
ItemKind::Static(..) => (item_, true),
_ => return not_static(),
},
_ => return not_static(),
},
_ => return not_static(item),
_ => return not_static(),
};

// Generate a bunch of new items using the AllocFnFactory
Expand Down
46 changes: 46 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2486,6 +2486,52 @@ declare_lint! {
"using only a subset of a register for inline asm inputs",
}

declare_lint! {
/// The `bad_asm_style` lint detects the use of the `.intel_syntax` and
/// `.att_syntax` directives.
///
/// ### Example
///
/// ```rust,ignore (fails on system llvm)
/// #![feature(asm)]
///
/// fn main() {
/// #[cfg(target_arch="x86_64")]
/// unsafe {
/// asm!(
/// ".att_syntax",
/// "movl {0}, {0}", in(reg) 0usize
/// );
/// }
/// }
/// ```
///
/// This will produce:
///
/// ```text
/// warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
/// --> test.rs:7:14
/// |
/// 7 | ".att_syntax",
/// | ^^^^^^^^^^^
/// 8 | "movq {0}, {0}", out(reg) _,
/// 9 | );
/// | - help: add option: `, options(att_syntax)`
/// |
/// = note: `#[warn(bad_asm_style)]` on by default
/// ```
///
/// ### Explanation
///
/// On x86, `asm!` uses the intel assembly syntax by default. While this
/// can be switched using assembler directives like `.att_syntax`, using the
/// `att_syntax` option is recomended instead because it will also properly
/// prefix register placeholders with `%` as required by AT&T syntax.
pub BAD_ASM_STYLE,
Warn,
"incorrect use of inline assembly",
}

declare_lint! {
/// The `unsafe_op_in_unsafe_fn` lint detects unsafe operations in unsafe
/// functions without an explicit unsafe block.
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,13 +793,6 @@ impl Session {
}
}

pub fn inline_asm_dialect(&self) -> rustc_ast::LlvmAsmDialect {
match self.asm_arch {
Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) => rustc_ast::LlvmAsmDialect::Intel,
_ => rustc_ast::LlvmAsmDialect::Att,
}
}

pub fn relocation_model(&self) -> RelocModel {
self.opts.cg.relocation_model.unwrap_or(self.target.relocation_model)
}
Expand Down
61 changes: 61 additions & 0 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2712,6 +2712,13 @@ impl<T, A: Allocator> AsMut<[T]> for Vec<T, A> {

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone> From<&[T]> for Vec<T> {
/// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
///
/// # Examples
///
/// ```
/// assert_eq!(Vec::from(&[1, 2, 3][..]), vec![1, 2, 3]);
/// ```
#[cfg(not(test))]
fn from(s: &[T]) -> Vec<T> {
s.to_vec()
Expand All @@ -2724,6 +2731,13 @@ impl<T: Clone> From<&[T]> for Vec<T> {

#[stable(feature = "vec_from_mut", since = "1.19.0")]
impl<T: Clone> From<&mut [T]> for Vec<T> {
/// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
///
/// # Examples
///
/// ```
/// assert_eq!(Vec::from(&mut [1, 2, 3][..]), vec![1, 2, 3]);
/// ```
#[cfg(not(test))]
fn from(s: &mut [T]) -> Vec<T> {
s.to_vec()
Expand All @@ -2740,6 +2754,13 @@ impl<T, const N: usize> From<[T; N]> for Vec<T> {
fn from(s: [T; N]) -> Vec<T> {
<[T]>::into_vec(box s)
}
/// Allocate a `Vec<T>` and move `s`'s items into it.
///
/// # Examples
///
/// ```
/// assert_eq!(Vec::from([1, 2, 3]), vec![1, 2, 3]);
/// ```
#[cfg(test)]
fn from(s: [T; N]) -> Vec<T> {
crate::slice::into_vec(box s)
Expand All @@ -2751,6 +2772,20 @@ impl<'a, T> From<Cow<'a, [T]>> for Vec<T>
where
[T]: ToOwned<Owned = Vec<T>>,
{
/// Convert a clone-on-write slice into a vector.
///
/// If `s` already owns a `Vec<T>`, it will be returned directly.
/// If `s` is borrowing a slice, a new `Vec<T>` will be allocated and
/// filled by cloning `s`'s items into it.
///
/// # Examples
///
/// ```
/// # use std::borrow::Cow;
/// let o: Cow<[i32]> = Cow::Owned(vec![1, 2, 3]);
/// let b: Cow<[i32]> = Cow::Borrowed(&[1, 2, 3]);
/// assert_eq!(Vec::from(o), Vec::from(b));
/// ```
fn from(s: Cow<'a, [T]>) -> Vec<T> {
s.into_owned()
}
Expand All @@ -2760,6 +2795,15 @@ where
#[cfg(not(test))]
#[stable(feature = "vec_from_box", since = "1.18.0")]
impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A> {
/// Convert a boxed slice into a vector by transferring ownership of
/// the existing heap allocation.
///
/// # Examples
///
/// ```
/// let b: Box<[i32]> = vec![1, 2, 3].into_boxed_slice();
/// assert_eq!(Vec::from(b), vec![1, 2, 3]);
/// ```
fn from(s: Box<[T], A>) -> Self {
let len = s.len();
Self { buf: RawVec::from_box(s), len }
Expand All @@ -2770,13 +2814,30 @@ impl<T, A: Allocator> From<Box<[T], A>> for Vec<T, A> {
#[cfg(not(test))]
#[stable(feature = "box_from_vec", since = "1.20.0")]
impl<T, A: Allocator> From<Vec<T, A>> for Box<[T], A> {
/// Convert a vector into a boxed slice.
///
/// If `v` has excess capacity, its items will be moved into a
/// newly-allocated buffer with exactly the right capacity.
///
/// # Examples
///
/// ```
/// assert_eq!(Box::from(vec![1, 2, 3]), vec![1, 2, 3].into_boxed_slice());
/// ```
fn from(v: Vec<T, A>) -> Self {
v.into_boxed_slice()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl From<&str> for Vec<u8> {
/// Allocate a `Vec<u8>` and fill it with a UTF-8 string.
///
/// # Examples
///
/// ```
/// assert_eq!(Vec::from("123"), vec![b'1', b'2', b'3']);
/// ```
fn from(s: &str) -> Vec<u8> {
From::from(s.as_bytes())
}
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/unix/ext/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,14 @@ pub trait ExitStatusExt: Sealed {
/// If the process was stopped by a signal, returns that signal.
///
/// In other words, if `WIFSTOPPED`, this returns `WSTOPSIG`. This is only possible if the status came from
/// a `wait` system call which was passed `WUNTRACED`, was then converted into an `ExitStatus`.
/// a `wait` system call which was passed `WUNTRACED`, and was then converted into an `ExitStatus`.
#[unstable(feature = "unix_process_wait_more", issue = "80695")]
fn stopped_signal(&self) -> Option<i32>;

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

Expand Down
Loading

0 comments on commit 7637fd5

Please sign in to comment.