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 6 pull requests #73437

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
10 changes: 10 additions & 0 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,16 @@ pub fn std_cargo(builder: &Builder<'_>, target: Interned<String>, stage: u32, ca
if stage >= 1 {
cargo.rustflag("-Cembed-bitcode=yes");
}

// By default, rustc does not include unwind tables unless they are required
// for a particular target. They are not required by RISC-V targets, but
// compiling the standard library with them means that users can get
// backtraces without having to recompile the standard library themselves.
//
// This choice was discussed in https://github.com/rust-lang/rust/pull/69890
if target.contains("riscv") {
cargo.rustflag("-Cforce-unwind-tables=yes");
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
Expand Down
67 changes: 67 additions & 0 deletions src/libcore/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1399,3 +1399,70 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I }
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J }
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K }
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }

/// Create a `const` raw pointer to a place, without creating an intermediate reference.
///
/// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
/// and points to initialized data. For cases where those requirements do not hold,
/// raw pointers should be used instead. However, `&expr as *const _` creates a reference
/// before casting it to a raw pointer, and that reference is subject to the same rules
/// as all other references. This macro can create a raw pointer *without* creating
/// a reference first.
///
/// # Example
///
/// ```
/// #![feature(raw_ref_macros)]
/// use std::ptr;
///
/// #[repr(packed)]
/// struct Packed {
/// f1: u8,
/// f2: u16,
/// }
///
/// let packed = Packed { f1: 1, f2: 2 };
/// // `&packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
/// let raw_f2 = ptr::raw_const!(packed.f2);
/// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
/// ```
#[unstable(feature = "raw_ref_macros", issue = "73394")]
#[rustc_macro_transparency = "semitransparent"]
#[allow_internal_unstable(raw_ref_op)]
pub macro raw_const($e:expr) {
&raw const $e
}

/// Create a `mut` raw pointer to a place, without creating an intermediate reference.
///
/// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
/// and points to initialized data. For cases where those requirements do not hold,
/// raw pointers should be used instead. However, `&mut expr as *mut _` creates a reference
/// before casting it to a raw pointer, and that reference is subject to the same rules
/// as all other references. This macro can create a raw pointer *without* creating
/// a reference first.
///
/// # Example
///
/// ```
/// #![feature(raw_ref_macros)]
/// use std::ptr;
///
/// #[repr(packed)]
/// struct Packed {
/// f1: u8,
/// f2: u16,
/// }
///
/// let mut packed = Packed { f1: 1, f2: 2 };
/// // `&mut packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
/// let raw_f2 = ptr::raw_mut!(packed.f2);
/// unsafe { raw_f2.write_unaligned(42); }
/// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
/// ```
#[unstable(feature = "raw_ref_macros", issue = "73394")]
#[rustc_macro_transparency = "semitransparent"]
#[allow_internal_unstable(raw_ref_op)]
pub macro raw_mut($e:expr) {
&raw mut $e
}
2 changes: 1 addition & 1 deletion src/librustc_ast/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! additional metadata), and [`ItemKind`] (which represents a concrete type and contains
//! information specific to the type of the item).
//!
//! Other module items that worth mentioning:
//! Other module items worth mentioning:
//! - [`Ty`] and [`TyKind`]: A parsed Rust type.
//! - [`Expr`] and [`ExprKind`]: A parsed Rust expression.
//! - [`Pat`] and [`PatKind`]: A parsed Rust pattern. Patterns are often dual to expressions.
Expand Down
24 changes: 22 additions & 2 deletions src/librustc_parse/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,28 @@ impl<'a> Parser<'a> {
}

/// Parses the RHS of a local variable declaration (e.g., '= 14;').
fn parse_initializer(&mut self, skip_eq: bool) -> PResult<'a, Option<P<Expr>>> {
if self.eat(&token::Eq) || skip_eq { Ok(Some(self.parse_expr()?)) } else { Ok(None) }
fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option<P<Expr>>> {
let eq_consumed = match self.token.kind {
token::BinOpEq(..) => {
// Recover `let x <op>= 1` as `let x = 1`
self.struct_span_err(
self.token.span,
"can't reassign to an uninitialized variable",
)
.span_suggestion_short(
self.token.span,
"initialize the variable",
"=".to_string(),
Applicability::MaybeIncorrect,
)
.emit();
self.bump();
true
}
_ => self.eat(&token::Eq),
};

Ok(if eq_consumed || eq_optional { Some(self.parse_expr()?) } else { None })
}

/// Parses a block. No inner attributes are allowed.
Expand Down
1 change: 0 additions & 1 deletion src/librustc_target/spec/riscv32i_unknown_none_elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ pub fn target() -> TargetResult {
relocation_model: RelocModel::Static,
emit_debug_gdb_scripts: false,
abi_blacklist: super::riscv_base::abi_blacklist(),
eliminate_frame_pointer: false,
..Default::default()
},
})
Expand Down
1 change: 0 additions & 1 deletion src/librustc_target/spec/riscv32imac_unknown_none_elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ pub fn target() -> TargetResult {
relocation_model: RelocModel::Static,
emit_debug_gdb_scripts: false,
abi_blacklist: super::riscv_base::abi_blacklist(),
eliminate_frame_pointer: false,
..Default::default()
},
})
Expand Down
1 change: 0 additions & 1 deletion src/librustc_target/spec/riscv32imc_unknown_none_elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ pub fn target() -> TargetResult {
relocation_model: RelocModel::Static,
emit_debug_gdb_scripts: false,
abi_blacklist: super::riscv_base::abi_blacklist(),
eliminate_frame_pointer: false,
..Default::default()
},
})
Expand Down
1 change: 0 additions & 1 deletion src/librustc_target/spec/riscv64gc_unknown_none_elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ pub fn target() -> TargetResult {
code_model: Some(CodeModel::Medium),
emit_debug_gdb_scripts: false,
abi_blacklist: super::riscv_base::abi_blacklist(),
eliminate_frame_pointer: false,
..Default::default()
},
})
Expand Down
1 change: 0 additions & 1 deletion src/librustc_target/spec/riscv64imac_unknown_none_elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ pub fn target() -> TargetResult {
code_model: Some(CodeModel::Medium),
emit_debug_gdb_scripts: false,
abi_blacklist: super::riscv_base::abi_blacklist(),
eliminate_frame_pointer: false,
..Default::default()
},
})
Expand Down
16 changes: 7 additions & 9 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,8 @@ fn opts() -> Vec<RustcOptGroup> {
o.optmulti(
"",
"passes",
"list of passes to also run, you might want \
to pass it multiple times; a value of `list` \
will print available passes",
"list of passes to also run, you might want to pass it multiple times; a value of \
`list` will print available passes",
"PASSES",
)
}),
Expand Down Expand Up @@ -248,8 +247,8 @@ fn opts() -> Vec<RustcOptGroup> {
"e",
"extend-css",
"To add some CSS rules with a given file to generate doc with your \
own theme. However, your theme might break if the rustdoc's generated HTML \
changes, so be careful!",
own theme. However, your theme might break if the rustdoc's generated HTML \
changes, so be careful!",
"PATH",
)
}),
Expand All @@ -262,7 +261,7 @@ fn opts() -> Vec<RustcOptGroup> {
"",
"playground-url",
"URL to send code snippets to, may be reset by --markdown-playground-url \
or `#![doc(html_playground_url=...)]`",
or `#![doc(html_playground_url=...)]`",
"URL",
)
}),
Expand All @@ -276,8 +275,7 @@ fn opts() -> Vec<RustcOptGroup> {
o.optflag(
"",
"sort-modules-by-appearance",
"sort modules by where they appear in the \
program, rather than alphabetically",
"sort modules by where they appear in the program, rather than alphabetically",
)
}),
stable("theme", |o| {
Expand Down Expand Up @@ -358,7 +356,7 @@ fn opts() -> Vec<RustcOptGroup> {
"",
"static-root-path",
"Path string to force loading static files from in output pages. \
If not set, uses combinations of '../' to reach the documentation root.",
If not set, uses combinations of '../' to reach the documentation root.",
"PATH",
)
}),
Expand Down
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@
#![feature(prelude_import)]
#![feature(ptr_internals)]
#![feature(raw)]
#![feature(raw_ref_macros)]
#![feature(renamed_spin_loop)]
#![feature(rustc_attrs)]
#![feature(rustc_private)]
Expand Down
43 changes: 43 additions & 0 deletions src/test/codegen/issue-69101-bounds-check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// no-system-llvm
// compile-flags: -O
#![crate_type = "lib"]

// Make sure no bounds checks are emitted in the loop when upfront slicing
// ensures that the slices are big enough.
// In particular, bounds checks were not always optimized out if the upfront
// check was for a greater len than the loop requires.
// (i.e. `already_sliced_no_bounds_check` was not always optimized even when
// `already_sliced_no_bounds_check_exact` was)
// CHECK-LABEL: @already_sliced_no_bounds_check
#[no_mangle]
pub fn already_sliced_no_bounds_check(a: &[u8], b: &[u8], c: &mut [u8]) {
// CHECK: slice_index_len_fail
// CHECK-NOT: panic_bounds_check
let _ = (&a[..2048], &b[..2048], &mut c[..2048]);
for i in 0..1024 {
c[i] = a[i] ^ b[i];
}
}

// CHECK-LABEL: @already_sliced_no_bounds_check_exact
#[no_mangle]
pub fn already_sliced_no_bounds_check_exact(a: &[u8], b: &[u8], c: &mut [u8]) {
// CHECK: slice_index_len_fail
// CHECK-NOT: panic_bounds_check
let _ = (&a[..1024], &b[..1024], &mut c[..1024]);
for i in 0..1024 {
c[i] = a[i] ^ b[i];
}
}

// Make sure we're checking for the right thing: there can be a panic if the slice is too small.
// CHECK-LABEL: @already_sliced_bounds_check
#[no_mangle]
pub fn already_sliced_bounds_check(a: &[u8], b: &[u8], c: &mut [u8]) {
// CHECK: slice_index_len_fail
// CHECK: panic_bounds_check
let _ = (&a[..1023], &b[..2048], &mut c[..2048]);
for i in 0..1024 {
c[i] = a[i] ^ b[i];
}
}
8 changes: 8 additions & 0 deletions src/test/ui/parser/let-binop.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn main() {
let a: i8 *= 1; //~ ERROR can't reassign to an uninitialized variable
let _ = a;
let b += 1; //~ ERROR can't reassign to an uninitialized variable
let _ = b;
let c *= 1; //~ ERROR can't reassign to an uninitialized variable
let _ = c;
}
20 changes: 20 additions & 0 deletions src/test/ui/parser/let-binop.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:2:15
|
LL | let a: i8 *= 1;
| ^^ help: initialize the variable

error: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:4:11
|
LL | let b += 1;
| ^^ help: initialize the variable

error: can't reassign to an uninitialized variable
--> $DIR/let-binop.rs:6:11
|
LL | let c *= 1;
| ^^ help: initialize the variable

error: aborting due to 3 previous errors