Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #71966

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,15 @@ def format_build_time(duration):
def default_build_triple():
"""Build triple as in LLVM"""
default_encoding = sys.getdefaultencoding()
required = not sys.platform == 'win32'
ostype = require(["uname", "-s"], exit=required).decode(default_encoding)
cputype = require(['uname', '-m'], exit=required).decode(default_encoding)
required = sys.platform != 'win32'
ostype = require(["uname", "-s"], exit=required)
cputype = require(['uname', '-m'], exit=required)

if ostype is None or cputype is None:
return 'x86_64-pc-windows-msvc'

ostype = ostype.decode(default_encoding)
cputype = cputype.decode(default_encoding)

# The goal here is to come up with the same triple as LLVM would,
# at least for the subset of platforms we're willing to target.
Expand Down
22 changes: 11 additions & 11 deletions src/liballoc/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
//! The internal iterator over the argument has not been advanced by the time
//! the first `{}` is seen, so it prints the first argument. Then upon reaching
//! the second `{}`, the iterator has advanced forward to the second argument.
//! Essentially, parameters which explicitly name their argument do not affect
//! parameters which do not name an argument in terms of positional specifiers.
//! Essentially, parameters that explicitly name their argument do not affect
//! parameters that do not name an argument in terms of positional specifiers.
//!
//! A format string is required to use all of its arguments, otherwise it is a
//! compile-time error. You may refer to the same argument more than once in the
Expand All @@ -60,7 +60,7 @@
//! ## Named parameters
//!
//! Rust itself does not have a Python-like equivalent of named parameters to a
//! function, but the [`format!`] macro is a syntax extension which allows it to
//! function, but the [`format!`] macro is a syntax extension that allows it to
//! leverage named parameters. Named parameters are listed at the end of the
//! argument list and have the syntax:
//!
Expand All @@ -77,7 +77,7 @@
//! ```
//!
//! It is not valid to put positional parameters (those without names) after
//! arguments which have names. Like with positional parameters, it is not
//! arguments that have names. Like with positional parameters, it is not
//! valid to provide named parameters that are unused by the format string.
//!
//! # Formatting Parameters
Expand Down Expand Up @@ -130,7 +130,7 @@
//!
//! The default [fill/alignment](#fillalignment) for non-numerics is a space and
//! left-aligned. The
//! defaults for numeric formatters is also a space but with right-alignment. If
//! default for numeric formatters is also a space character but with right-alignment. If
//! the `0` flag (see below) is specified for numerics, then the implicit fill character is
//! `0`.
//!
Expand Down Expand Up @@ -161,7 +161,7 @@
//! `Signed` trait. This flag indicates that the correct sign (`+` or `-`)
//! should always be printed.
//! * `-` - Currently not used
//! * `#` - This flag is indicates that the "alternate" form of printing should
//! * `#` - This flag indicates that the "alternate" form of printing should
//! be used. The alternate forms are:
//! * `#?` - pretty-print the [`Debug`] formatting
//! * `#x` - precedes the argument with a `0x`
Expand All @@ -173,9 +173,9 @@
//! like `{:08}` would yield `00000001` for the integer `1`, while the
//! same format would yield `-0000001` for the integer `-1`. Notice that
//! the negative version has one fewer zero than the positive version.
//! Note that padding zeroes are always placed after the sign (if any)
//! Note that padding zeros are always placed after the sign (if any)
//! and before the digits. When used together with the `#` flag, a similar
//! rule applies: padding zeroes are inserted after the prefix but before
//! rule applies: padding zeros are inserted after the prefix but before
//! the digits. The prefix is included in the total width.
//!
//! ## Precision
Expand Down Expand Up @@ -251,7 +251,7 @@
//!
//! In some programming languages, the behavior of string formatting functions
//! depends on the operating system's locale setting. The format functions
//! provided by Rust's standard library do not have any concept of locale, and
//! provided by Rust's standard library do not have any concept of locale and
//! will produce the same results on all systems regardless of user
//! configuration.
//!
Expand Down Expand Up @@ -470,7 +470,7 @@
//!
//! ### `format_args!`
//!
//! This is a curious macro which is used to safely pass around
//! This is a curious macro used to safely pass around
//! an opaque object describing the format string. This object
//! does not require any heap allocations to create, and it only
//! references information on the stack. Under the hood, all of
Expand All @@ -495,7 +495,7 @@
//! This structure can then be passed to the [`write`] and [`format`] functions
//! inside this module in order to process the format string.
//! The goal of this macro is to even further prevent intermediate allocations
//! when dealing formatting strings.
//! when dealing with formatting strings.
//!
//! For example, a logging library could use the standard formatting syntax, but
//! it would internally pass around this structure until it has been determined
Expand Down
54 changes: 34 additions & 20 deletions src/librustc_parse/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc_ast::util::classify;
use rustc_ast::util::literal::LitError;
use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
use rustc_ast_pretty::pprust;
use rustc_errors::{Applicability, PResult};
use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
use rustc_span::source_map::{self, Span, Spanned};
use rustc_span::symbol::{kw, sym, Symbol};
use std::mem;
Expand Down Expand Up @@ -1068,8 +1068,8 @@ impl<'a> Parser<'a> {
}

fn parse_path_start_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
let lo = self.token.span;
let path = self.parse_path(PathStyle::Expr)?;
let lo = path.span;

// `!`, as an operator, is prefix, so we know this isn't that.
let (hi, kind) = if self.eat(&token::Not) {
Expand All @@ -1081,7 +1081,7 @@ impl<'a> Parser<'a> {
};
(self.prev_token.span, ExprKind::MacCall(mac))
} else if self.check(&token::OpenDelim(token::Brace)) {
if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
if let Some(expr) = self.maybe_parse_struct_expr(&path, &attrs) {
return expr;
} else {
(path.span, ExprKind::Path(None, path))
Expand Down Expand Up @@ -1895,16 +1895,15 @@ impl<'a> Parser<'a> {

fn maybe_parse_struct_expr(
&mut self,
lo: Span,
path: &ast::Path,
attrs: &AttrVec,
) -> Option<PResult<'a, P<Expr>>> {
let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
if struct_allowed || self.is_certainly_not_a_block() {
// This is a struct literal, but we don't can't accept them here.
let expr = self.parse_struct_expr(lo, path.clone(), attrs.clone());
let expr = self.parse_struct_expr(path.clone(), attrs.clone());
if let (Ok(expr), false) = (&expr, struct_allowed) {
self.error_struct_lit_not_allowed_here(lo, expr.span);
self.error_struct_lit_not_allowed_here(path.span, expr.span);
}
return Some(expr);
}
Expand All @@ -1923,17 +1922,23 @@ impl<'a> Parser<'a> {

pub(super) fn parse_struct_expr(
&mut self,
lo: Span,
pth: ast::Path,
mut attrs: AttrVec,
) -> PResult<'a, P<Expr>> {
let struct_sp = lo.to(self.prev_token.span);
self.bump();
let mut fields = Vec::new();
let mut base = None;
let mut recover_async = false;

attrs.extend(self.parse_inner_attributes()?);

let mut async_block_err = |e: &mut DiagnosticBuilder<'_>, span: Span| {
recover_async = true;
e.span_label(span, "`async` blocks are only allowed in the 2018 edition");
e.help("set `edition = \"2018\"` in `Cargo.toml`");
e.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
};

while self.token != token::CloseDelim(token::Brace) {
if self.eat(&token::DotDot) {
let exp_span = self.prev_token.span;
Expand All @@ -1952,7 +1957,11 @@ impl<'a> Parser<'a> {
let parsed_field = match self.parse_field() {
Ok(f) => Some(f),
Err(mut e) => {
e.span_label(struct_sp, "while parsing this struct");
if pth == kw::Async {
async_block_err(&mut e, pth.span);
} else {
e.span_label(pth.span, "while parsing this struct");
}
e.emit();

// If the next token is a comma, then try to parse
Expand All @@ -1976,15 +1985,19 @@ impl<'a> Parser<'a> {
}
}
Err(mut e) => {
e.span_label(struct_sp, "while parsing this struct");
if let Some(f) = recovery_field {
fields.push(f);
e.span_suggestion(
self.prev_token.span.shrink_to_hi(),
"try adding a comma",
",".into(),
Applicability::MachineApplicable,
);
if pth == kw::Async {
async_block_err(&mut e, pth.span);
} else {
e.span_label(pth.span, "while parsing this struct");
if let Some(f) = recovery_field {
fields.push(f);
e.span_suggestion(
self.prev_token.span.shrink_to_hi(),
"try adding a comma",
",".into(),
Applicability::MachineApplicable,
);
}
}
e.emit();
self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
Expand All @@ -1993,9 +2006,10 @@ impl<'a> Parser<'a> {
}
}

let span = lo.to(self.token.span);
let span = pth.span.to(self.token.span);
self.expect(&token::CloseDelim(token::Brace))?;
Ok(self.mk_expr(span, ExprKind::Struct(pth, fields, base), attrs))
let expr = if recover_async { ExprKind::Err } else { ExprKind::Struct(pth, fields, base) };
Ok(self.mk_expr(span, expr, attrs))
}

/// Use in case of error after field-looking code: `S { foo: () with a }`.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_parse/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1550,7 +1550,7 @@ impl<'a> Parser<'a> {
if span.rust_2015() {
let diag = self.diagnostic();
struct_span_err!(diag, span, E0670, "`async fn` is not permitted in the 2015 edition")
.note("to use `async fn`, switch to Rust 2018")
.span_label(span, "to use `async fn`, switch to Rust 2018")
.help("set `edition = \"2018\"` in `Cargo.toml`")
.note("for more on editions, read https://doc.rust-lang.org/edition-guide")
.emit();
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_parse/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl<'a> Parser<'a> {
}

let expr = if self.check(&token::OpenDelim(token::Brace)) {
self.parse_struct_expr(lo, path, AttrVec::new())?
self.parse_struct_expr(path, AttrVec::new())?
} else {
let hi = self.prev_token.span;
self.mk_expr(lo.to(hi), ExprKind::Path(None, path), AttrVec::new())
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_resolve/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,11 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
};
(
format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
format!("not found in {}", mod_str),
if path_str == "async" && expected.starts_with("struct") {
"`async` blocks are only allowed in the 2018 edition".to_string()
} else {
format!("not found in {}", mod_str)
},
item_span,
false,
)
Expand Down
2 changes: 2 additions & 0 deletions src/test/auxiliary/rust_test_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ rust_dbg_unpack_option_u64(struct U8TaggedEnumOptionU64 o, uint64_t *into) {
return 0;
default:
assert(0 && "unexpected tag");
return 0;
}
}

Expand Down Expand Up @@ -411,5 +412,6 @@ rust_dbg_unpack_option_u64u64(struct U8TaggedEnumOptionU64U64 o, uint64_t *a, ui
return 0;
default:
assert(0 && "unexpected tag");
return 0;
}
}
22 changes: 22 additions & 0 deletions src/test/codegen/ffi-out-of-bounds-loads.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// compile-flags: -C no-prepopulate-passes
// Regression test for #29988

#[repr(C)]
struct S {
f1: i32,
f2: i32,
f3: i32,
}

extern {
fn foo(s: S);
}

fn main() {
let s = S { f1: 1, f2: 2, f3: 3 };
unsafe {
// CHECK: load { i64, i32 }, { i64, i32 }* {{.*}}, align 4
// CHECK: call void @foo({ i64, i32 } {{.*}})
foo(s);
}
}
Loading