Skip to content

Commit

Permalink
Auto merge of rust-lang#2817 - saethlin:rustup, r=saethlin
Browse files Browse the repository at this point in the history
rustup

Doing a sync just before I do a rustc-push
  • Loading branch information
bors committed Mar 16, 2023
2 parents b024de1 + ba1c094 commit 3831a25
Show file tree
Hide file tree
Showing 318 changed files with 3,713 additions and 2,039 deletions.
16 changes: 13 additions & 3 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ dependencies = [

[[package]]
name = "cargo"
version = "0.70.0"
version = "0.71.0"
dependencies = [
"anyhow",
"base64",
Expand Down Expand Up @@ -1001,7 +1001,7 @@ dependencies = [

[[package]]
name = "crates-io"
version = "0.35.1"
version = "0.36.0"
dependencies = [
"anyhow",
"curl",
Expand Down Expand Up @@ -5139,6 +5139,7 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"tracing",
]

Expand Down Expand Up @@ -5457,13 +5458,13 @@ dependencies = [
"itertools",
"minifier",
"once_cell",
"rayon",
"regex",
"rustdoc-json-types",
"serde",
"serde_json",
"smallvec",
"tempfile",
"threadpool",
"tracing",
"tracing-subscriber",
"tracing-tree",
Expand Down Expand Up @@ -6208,6 +6209,15 @@ dependencies = [
"once_cell",
]

[[package]]
name = "threadpool"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
dependencies = [
"num_cpus",
]

[[package]]
name = "tidy"
version = "0.1.0"
Expand Down
3 changes: 2 additions & 1 deletion RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,13 @@ Compiler
- [Optimize field ordering by grouping m\*2^n-sized fields with equivalently aligned ones.](https://github.com/rust-lang/rust/pull/102750/)
- [Stabilize native library modifier `verbatim`.](https://github.com/rust-lang/rust/pull/104360/)

Added and removed targets:
Added, updated, and removed targets:

- [Add a tier 3 target for PowerPC on AIX](https://github.com/rust-lang/rust/pull/102293/), `powerpc64-ibm-aix`.
- [Add a tier 3 target for the Sony PlayStation 1](https://github.com/rust-lang/rust/pull/102689/), `mipsel-sony-psx`.
- [Add tier 3 `no_std` targets for the QNX Neutrino RTOS](https://github.com/rust-lang/rust/pull/102701/),
`aarch64-unknown-nto-qnx710` and `x86_64-pc-nto-qnx710`.
- [Promote UEFI targets to tier 2](https://github.com/rust-lang/rust/pull/103933/), `aarch64-unknown-uefi`, `i686-unknown-uefi`, and `x86_64-unknown-uefi`.
- [Remove tier 3 `linuxkernel` targets](https://github.com/rust-lang/rust/pull/104015/) (not used by the actual kernel).

Refer to Rust's [platform support page][platform-support-doc]
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,15 @@ impl Expr {
expr
}

pub fn peel_parens_and_refs(&self) -> &Expr {
let mut expr = self;
while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
{
expr = inner;
}
expr
}

/// Attempts to reparse as `Ty` (for diagnostic purposes).
pub fn to_ty(&self) -> Option<P<Ty>> {
let kind = match &self.kind {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ impl FormatArguments {
&self.arguments[..]
}

pub fn all_args_mut(&mut self) -> &mut [FormatArgument] {
&mut self.arguments[..]
pub fn all_args_mut(&mut self) -> &mut Vec<FormatArgument> {
&mut self.arguments
}
}

Expand Down
238 changes: 216 additions & 22 deletions compiler/rustc_ast_lowering/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,172 @@ use rustc_hir as hir;
use rustc_span::{
sym,
symbol::{kw, Ident},
Span,
Span, Symbol,
};
use std::borrow::Cow;

impl<'hir> LoweringContext<'_, 'hir> {
pub(crate) fn lower_format_args(&mut self, sp: Span, fmt: &FormatArgs) -> hir::ExprKind<'hir> {
expand_format_args(self, sp, fmt)
// Never call the const constructor of `fmt::Arguments` if the
// format_args!() had any arguments _before_ flattening/inlining.
let allow_const = fmt.arguments.all_args().is_empty();
let mut fmt = Cow::Borrowed(fmt);
if self.tcx.sess.opts.unstable_opts.flatten_format_args {
fmt = flatten_format_args(fmt);
fmt = inline_literals(fmt);
}
expand_format_args(self, sp, &fmt, allow_const)
}
}

/// Flattens nested `format_args!()` into one.
///
/// Turns
///
/// `format_args!("a {} {} {}.", 1, format_args!("b{}!", 2), 3)`
///
/// into
///
/// `format_args!("a {} b{}! {}.", 1, 2, 3)`.
fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
let mut i = 0;
while i < fmt.template.len() {
if let FormatArgsPiece::Placeholder(placeholder) = &fmt.template[i]
&& let FormatTrait::Display | FormatTrait::Debug = &placeholder.format_trait
&& let Ok(arg_index) = placeholder.argument.index
&& let arg = fmt.arguments.all_args()[arg_index].expr.peel_parens_and_refs()
&& let ExprKind::FormatArgs(_) = &arg.kind
// Check that this argument is not used by any other placeholders.
&& fmt.template.iter().enumerate().all(|(j, p)|
i == j ||
!matches!(p, FormatArgsPiece::Placeholder(placeholder)
if placeholder.argument.index == Ok(arg_index))
)
{
// Now we need to mutate the outer FormatArgs.
// If this is the first time, this clones the outer FormatArgs.
let fmt = fmt.to_mut();

// Take the inner FormatArgs out of the outer arguments, and
// replace it by the inner arguments. (We can't just put those at
// the end, because we need to preserve the order of evaluation.)

let args = fmt.arguments.all_args_mut();
let remaining_args = args.split_off(arg_index + 1);
let old_arg_offset = args.len();
let mut fmt2 = &mut args.pop().unwrap().expr; // The inner FormatArgs.
let fmt2 = loop { // Unwrap the Expr to get to the FormatArgs.
match &mut fmt2.kind {
ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) => fmt2 = inner,
ExprKind::FormatArgs(fmt2) => break fmt2,
_ => unreachable!(),
}
};

args.append(fmt2.arguments.all_args_mut());
let new_arg_offset = args.len();
args.extend(remaining_args);

// Correct the indexes that refer to the arguments after the newly inserted arguments.
for_all_argument_indexes(&mut fmt.template, |index| {
if *index >= old_arg_offset {
*index -= old_arg_offset;
*index += new_arg_offset;
}
});

// Now merge the placeholders:

let rest = fmt.template.split_off(i + 1);
fmt.template.pop(); // remove the placeholder for the nested fmt args.
// Insert the pieces from the nested format args, but correct any
// placeholders to point to the correct argument index.
for_all_argument_indexes(&mut fmt2.template, |index| *index += arg_index);
fmt.template.append(&mut fmt2.template);
fmt.template.extend(rest);

// Don't increment `i` here, so we recurse into the newly added pieces.
} else {
i += 1;
}
}
fmt
}

/// Inline literals into the format string.
///
/// Turns
///
/// `format_args!("Hello, {}! {} {}", "World", 123, x)`
///
/// into
///
/// `format_args!("Hello, World! 123 {}", x)`.
fn inline_literals(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
let mut was_inlined = vec![false; fmt.arguments.all_args().len()];
let mut inlined_anything = false;

for i in 0..fmt.template.len() {
let FormatArgsPiece::Placeholder(placeholder) = &fmt.template[i] else { continue };
let Ok(arg_index) = placeholder.argument.index else { continue };

let mut literal = None;

if let FormatTrait::Display = placeholder.format_trait
&& placeholder.format_options == Default::default()
&& let arg = fmt.arguments.all_args()[arg_index].expr.peel_parens_and_refs()
&& let ExprKind::Lit(lit) = arg.kind
{
if let token::LitKind::Str | token::LitKind::StrRaw(_) = lit.kind
&& let Ok(LitKind::Str(s, _)) = LitKind::from_token_lit(lit)
{
literal = Some(s);
} else if let token::LitKind::Integer = lit.kind
&& let Ok(LitKind::Int(n, _)) = LitKind::from_token_lit(lit)
{
literal = Some(Symbol::intern(&n.to_string()));
}
}

if let Some(literal) = literal {
// Now we need to mutate the outer FormatArgs.
// If this is the first time, this clones the outer FormatArgs.
let fmt = fmt.to_mut();
// Replace the placeholder with the literal.
fmt.template[i] = FormatArgsPiece::Literal(literal);
was_inlined[arg_index] = true;
inlined_anything = true;
}
}

// Remove the arguments that were inlined.
if inlined_anything {
let fmt = fmt.to_mut();

let mut remove = was_inlined;

// Don't remove anything that's still used.
for_all_argument_indexes(&mut fmt.template, |index| remove[*index] = false);

// Drop all the arguments that are marked for removal.
let mut remove_it = remove.iter();
fmt.arguments.all_args_mut().retain(|_| remove_it.next() != Some(&true));

// Calculate the mapping of old to new indexes for the remaining arguments.
let index_map: Vec<usize> = remove
.into_iter()
.scan(0, |i, remove| {
let mapped = *i;
*i += !remove as usize;
Some(mapped)
})
.collect();

// Correct the indexes that refer to arguments that have shifted position.
for_all_argument_indexes(&mut fmt.template, |index| *index = index_map[*index]);
}

fmt
}

#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
Expand Down Expand Up @@ -189,11 +348,26 @@ fn expand_format_args<'hir>(
ctx: &mut LoweringContext<'_, 'hir>,
macsp: Span,
fmt: &FormatArgs,
allow_const: bool,
) -> hir::ExprKind<'hir> {
let mut incomplete_lit = String::new();
let lit_pieces =
ctx.arena.alloc_from_iter(fmt.template.iter().enumerate().filter_map(|(i, piece)| {
match piece {
&FormatArgsPiece::Literal(s) => Some(ctx.expr_str(fmt.span, s)),
&FormatArgsPiece::Literal(s) => {
// Coalesce adjacent literal pieces.
if let Some(FormatArgsPiece::Literal(_)) = fmt.template.get(i + 1) {
incomplete_lit.push_str(s.as_str());
None
} else if !incomplete_lit.is_empty() {
incomplete_lit.push_str(s.as_str());
let s = Symbol::intern(&incomplete_lit);
incomplete_lit.clear();
Some(ctx.expr_str(fmt.span, s))
} else {
Some(ctx.expr_str(fmt.span, s))
}
}
&FormatArgsPiece::Placeholder(_) => {
// Inject empty string before placeholders when not already preceded by a literal piece.
if i == 0 || matches!(fmt.template[i - 1], FormatArgsPiece::Placeholder(_)) {
Expand Down Expand Up @@ -244,6 +418,18 @@ fn expand_format_args<'hir>(

let arguments = fmt.arguments.all_args();

if allow_const && arguments.is_empty() && argmap.is_empty() {
// Generate:
// <core::fmt::Arguments>::new_const(lit_pieces)
let new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
macsp,
hir::LangItem::FormatArguments,
sym::new_const,
));
let new_args = ctx.arena.alloc_from_iter([lit_pieces]);
return hir::ExprKind::Call(new, new_args);
}

// If the args array contains exactly all the original arguments once,
// in order, we can use a simple array instead of a `match` construction.
// However, if there's a yield point in any argument except the first one,
Expand Down Expand Up @@ -290,25 +476,14 @@ fn expand_format_args<'hir>(
let args_ident = Ident::new(sym::args, macsp);
let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident);
let args = ctx.arena.alloc_from_iter(argmap.iter().map(|&(arg_index, ty)| {
if let Some(arg) = arguments.get(arg_index) {
let sp = arg.expr.span.with_ctxt(macsp.ctxt());
let args_ident_expr = ctx.expr_ident(macsp, args_ident, args_hir_id);
let arg = ctx.arena.alloc(ctx.expr(
sp,
hir::ExprKind::Field(
args_ident_expr,
Ident::new(sym::integer(arg_index), macsp),
),
));
make_argument(ctx, sp, arg, ty)
} else {
ctx.expr(
macsp,
hir::ExprKind::Err(
ctx.tcx.sess.delay_span_bug(macsp, format!("no arg at {arg_index}")),
),
)
}
let arg = &arguments[arg_index];
let sp = arg.expr.span.with_ctxt(macsp.ctxt());
let args_ident_expr = ctx.expr_ident(macsp, args_ident, args_hir_id);
let arg = ctx.arena.alloc(ctx.expr(
sp,
hir::ExprKind::Field(args_ident_expr, Ident::new(sym::integer(arg_index), macsp)),
));
make_argument(ctx, sp, arg, ty)
}));
let elements: Vec<_> = arguments
.iter()
Expand Down Expand Up @@ -409,3 +584,22 @@ fn may_contain_yield_point(e: &ast::Expr) -> bool {
visitor.visit_expr(e);
visitor.0
}

fn for_all_argument_indexes(template: &mut [FormatArgsPiece], mut f: impl FnMut(&mut usize)) {
for piece in template {
let FormatArgsPiece::Placeholder(placeholder) = piece else { continue };
if let Ok(index) = &mut placeholder.argument.index {
f(index);
}
if let Some(FormatCount::Argument(FormatArgPosition { index: Ok(index), .. })) =
&mut placeholder.format_options.width
{
f(index);
}
if let Some(FormatCount::Argument(FormatArgPosition { index: Ok(index), .. })) =
&mut placeholder.format_options.precision
{
f(index);
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
}

// By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given
// pair of array indices are unequal, so that when `places_conflict` returns true, we
// pair of array indices are not equal, so that when `places_conflict` returns true, we
// will be assured that two places being compared definitely denotes the same sets of
// locations.
let definitely_conflicting_borrows = other_borrows_of_local.filter(|&i| {
Expand Down
Loading

0 comments on commit 3831a25

Please sign in to comment.