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 #69230

Closed
wants to merge 18 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: 5 additions & 4 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1423,13 +1423,14 @@ pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
}

/// Checks whether the regions of memory starting at `src` and `dst` of size
/// `count * size_of::<T>()` overlap.
fn overlaps<T>(src: *const T, dst: *const T, count: usize) -> bool {
/// `count * size_of::<T>()` do *not* overlap.
pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -> bool {
let src_usize = src as usize;
let dst_usize = dst as usize;
let size = mem::size_of::<T>().checked_mul(count).unwrap();
let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize };
size > diff
let overlaps = size > diff;
!overlaps
}

/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
Expand Down Expand Up @@ -1524,7 +1525,7 @@ pub unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {

debug_assert!(is_aligned_and_not_null(src), "attempt to copy from unaligned or null pointer");
debug_assert!(is_aligned_and_not_null(dst), "attempt to copy to unaligned or null pointer");
debug_assert!(!overlaps(src, dst, count), "attempt to copy to overlapping memory");
debug_assert!(is_nonoverlapping(src, dst, count), "attempt to copy to overlapping memory");
copy_nonoverlapping(src, dst, count)
}

Expand Down
12 changes: 11 additions & 1 deletion src/libcore/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
use crate::cmp::Ordering;
use crate::fmt;
use crate::hash;
use crate::intrinsics;
use crate::intrinsics::{self, is_aligned_and_not_null, is_nonoverlapping};
use crate::mem::{self, MaybeUninit};

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -392,6 +392,10 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
#[inline]
#[stable(feature = "swap_nonoverlapping", since = "1.27.0")]
pub unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
debug_assert!(is_aligned_and_not_null(x), "attempt to swap unaligned or null pointer");
debug_assert!(is_aligned_and_not_null(y), "attempt to swap unaligned or null pointer");
debug_assert!(is_nonoverlapping(x, y, count), "attempt to swap overlapping memory");

let x = x as *mut u8;
let y = y as *mut u8;
let len = mem::size_of::<T>() * count;
Expand Down Expand Up @@ -619,6 +623,7 @@ pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn read<T>(src: *const T) -> T {
// `copy_nonoverlapping` takes care of debug_assert.
let mut tmp = MaybeUninit::<T>::uninit();
copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
tmp.assume_init()
Expand Down Expand Up @@ -712,6 +717,7 @@ pub unsafe fn read<T>(src: *const T) -> T {
#[inline]
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
pub unsafe fn read_unaligned<T>(src: *const T) -> T {
// `copy_nonoverlapping` takes care of debug_assert.
let mut tmp = MaybeUninit::<T>::uninit();
copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::<T>());
tmp.assume_init()
Expand Down Expand Up @@ -804,6 +810,7 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn write<T>(dst: *mut T, src: T) {
debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
intrinsics::move_val_init(&mut *dst, src)
}

Expand Down Expand Up @@ -896,6 +903,7 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
#[inline]
#[stable(feature = "ptr_unaligned", since = "1.17.0")]
pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
// `copy_nonoverlapping` takes care of debug_assert.
copy_nonoverlapping(&src as *const T as *const u8, dst as *mut u8, mem::size_of::<T>());
mem::forget(src);
}
Expand Down Expand Up @@ -967,6 +975,7 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
#[inline]
#[stable(feature = "volatile", since = "1.9.0")]
pub unsafe fn read_volatile<T>(src: *const T) -> T {
debug_assert!(is_aligned_and_not_null(src), "attempt to read from unaligned or null pointer");
intrinsics::volatile_load(src)
}

Expand Down Expand Up @@ -1035,6 +1044,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
#[inline]
#[stable(feature = "volatile", since = "1.9.0")]
pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
debug_assert!(is_aligned_and_not_null(dst), "attempt to write to unaligned or null pointer");
intrinsics::volatile_store(dst, src);
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/hir/map/hir_id_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_hir::intravisit;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::{HirId, ItemLocalId};

pub fn check_crate(hir_map: &Map<'_>) {
pub fn check_crate(hir_map: &Map<'_>, sess: &rustc_session::Session) {
hir_map.dep_graph.assert_ignored();

let errors = Lock::new(Vec::new());
Expand All @@ -24,7 +24,7 @@ pub fn check_crate(hir_map: &Map<'_>) {

if !errors.is_empty() {
let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2);
bug!("{}", message);
sess.delay_span_bug(rustc_span::DUMMY_SP, &message);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1235,7 +1235,7 @@ pub fn map_crate<'hir>(
let map = Map { krate, dep_graph, crate_hash, map, hir_to_node_id, definitions };

sess.time("validate_HIR_map", || {
hir_id_validator::check_crate(&map);
hir_id_validator::check_crate(&map, sess);
});

map
Expand Down
16 changes: 8 additions & 8 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1468,21 +1468,21 @@ impl<'tcx> TerminatorKind<'tcx> {
/// successors, which may be rendered differently between the text and the graphviz format.
pub fn fmt_head<W: Write>(&self, fmt: &mut W) -> fmt::Result {
use self::TerminatorKind::*;
match *self {
match self {
Goto { .. } => write!(fmt, "goto"),
SwitchInt { discr: ref place, .. } => write!(fmt, "switchInt({:?})", place),
SwitchInt { discr, .. } => write!(fmt, "switchInt({:?})", discr),
Return => write!(fmt, "return"),
GeneratorDrop => write!(fmt, "generator_drop"),
Resume => write!(fmt, "resume"),
Abort => write!(fmt, "abort"),
Yield { ref value, .. } => write!(fmt, "_1 = suspend({:?})", value),
Yield { value, resume_arg, .. } => write!(fmt, "{:?} = yield({:?})", resume_arg, value),
Unreachable => write!(fmt, "unreachable"),
Drop { ref location, .. } => write!(fmt, "drop({:?})", location),
DropAndReplace { ref location, ref value, .. } => {
Drop { location, .. } => write!(fmt, "drop({:?})", location),
DropAndReplace { location, value, .. } => {
write!(fmt, "replace({:?} <- {:?})", location, value)
}
Call { ref func, ref args, ref destination, .. } => {
if let Some((ref destination, _)) = *destination {
Call { func, args, destination, .. } => {
if let Some((destination, _)) = destination {
write!(fmt, "{:?} = ", destination)?;
}
write!(fmt, "{:?}(", func)?;
Expand All @@ -1494,7 +1494,7 @@ impl<'tcx> TerminatorKind<'tcx> {
}
write!(fmt, ")")
}
Assert { ref cond, expected, ref msg, .. } => {
Assert { cond, expected, msg, .. } => {
write!(fmt, "assert(")?;
if !expected {
write!(fmt, "!")?;
Expand Down
11 changes: 4 additions & 7 deletions src/librustc_expand/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
span: Span,
) -> AstFragment {
let mut parser = self.cx.new_parser_from_tts(toks);
match parse_ast_fragment(&mut parser, kind, false) {
match parse_ast_fragment(&mut parser, kind) {
Ok(fragment) => {
ensure_complete_parse(&mut parser, path, kind.name(), span);
fragment
Expand All @@ -851,7 +851,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
pub fn parse_ast_fragment<'a>(
this: &mut Parser<'a>,
kind: AstFragmentKind,
macro_legacy_warnings: bool,
) -> PResult<'a, AstFragment> {
Ok(match kind {
AstFragmentKind::Items => {
Expand Down Expand Up @@ -884,11 +883,9 @@ pub fn parse_ast_fragment<'a>(
}
AstFragmentKind::Stmts => {
let mut stmts = SmallVec::new();
while this.token != token::Eof &&
// won't make progress on a `}`
this.token != token::CloseDelim(token::Brace)
{
if let Some(stmt) = this.parse_full_stmt(macro_legacy_warnings)? {
// Won't make progress on a `}`.
while this.token != token::Eof && this.token != token::CloseDelim(token::Brace) {
if let Some(stmt) = this.parse_full_stmt()? {
stmts.push(stmt);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_expand/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Pa
impl<'a> ParserAnyMacro<'a> {
crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
let fragment = panictry!(parse_ast_fragment(parser, kind, true).map_err(|mut e| {
let fragment = panictry!(parse_ast_fragment(parser, kind).map_err(|mut e| {
if parser.token == token::Eof && e.message().ends_with(", found `<eof>`") {
if !e.span.is_dummy() {
// early end of macro arm (#52866)
Expand Down
62 changes: 9 additions & 53 deletions src/librustc_parse/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,14 @@ impl<'a> Parser<'a> {
/// Parses a statement. This stops just before trailing semicolons on everything but items.
/// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
Ok(self.parse_stmt_without_recovery(true).unwrap_or_else(|mut e| {
Ok(self.parse_stmt_without_recovery().unwrap_or_else(|mut e| {
e.emit();
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
None
}))
}

fn parse_stmt_without_recovery(
&mut self,
macro_legacy_warnings: bool,
) -> PResult<'a, Option<Stmt>> {
fn parse_stmt_without_recovery(&mut self) -> PResult<'a, Option<Stmt>> {
maybe_whole!(self, NtStmt, |x| Some(x));

let attrs = self.parse_outer_attributes()?;
Expand Down Expand Up @@ -64,7 +61,7 @@ impl<'a> Parser<'a> {
let path = self.parse_path(PathStyle::Expr)?;

if self.eat(&token::Not) {
return self.parse_stmt_mac(lo, attrs.into(), path, macro_legacy_warnings);
return self.parse_stmt_mac(lo, attrs.into(), path);
}

let expr = if self.check(&token::OpenDelim(token::Brace)) {
Expand Down Expand Up @@ -127,7 +124,6 @@ impl<'a> Parser<'a> {
lo: Span,
attrs: AttrVec,
path: ast::Path,
legacy_warnings: bool,
) -> PResult<'a, Option<Stmt>> {
let args = self.parse_mac_args()?;
let delim = args.delim();
Expand All @@ -140,30 +136,6 @@ impl<'a> Parser<'a> {

let kind = if delim == token::Brace || self.token == token::Semi || self.token == token::Eof
{
StmtKind::Mac(P((mac, style, attrs.into())))
}
// We used to incorrectly stop parsing macro-expanded statements here.
// If the next token will be an error anyway but could have parsed with the
// earlier behavior, stop parsing here and emit a warning to avoid breakage.
else if legacy_warnings
&& self.token.can_begin_expr()
&& match self.token.kind {
// These can continue an expression, so we can't stop parsing and warn.
token::OpenDelim(token::Paren)
| token::OpenDelim(token::Bracket)
| token::BinOp(token::Minus)
| token::BinOp(token::Star)
| token::BinOp(token::And)
| token::BinOp(token::Or)
| token::AndAnd
| token::OrOr
| token::DotDot
| token::DotDotDot
| token::DotDotEq => false,
_ => true,
}
{
self.warn_missing_semicolon();
StmtKind::Mac(P((mac, style, attrs)))
} else {
// Since none of the above applied, this is an expression statement macro.
Expand Down Expand Up @@ -310,7 +282,7 @@ impl<'a> Parser<'a> {
// bar;
//
// which is valid in other languages, but not Rust.
match self.parse_stmt_without_recovery(false) {
match self.parse_stmt_without_recovery() {
Ok(Some(stmt)) => {
if self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace))
|| do_not_suggest_help
Expand Down Expand Up @@ -369,7 +341,7 @@ impl<'a> Parser<'a> {
if self.token == token::Eof {
break;
}
let stmt = match self.parse_full_stmt(false) {
let stmt = match self.parse_full_stmt() {
Err(mut err) => {
self.maybe_annotate_with_ascription(&mut err, false);
err.emit();
Expand All @@ -389,11 +361,11 @@ impl<'a> Parser<'a> {
}

/// Parses a statement, including the trailing semicolon.
pub fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
pub fn parse_full_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
// Skip looking for a trailing semicolon when we have an interpolated statement.
maybe_whole!(self, NtStmt, |x| Some(x));

let mut stmt = match self.parse_stmt_without_recovery(macro_legacy_warnings)? {
let mut stmt = match self.parse_stmt_without_recovery()? {
Some(stmt) => stmt,
None => return Ok(None),
};
Expand Down Expand Up @@ -433,13 +405,8 @@ impl<'a> Parser<'a> {
}
}
StmtKind::Local(..) => {
// We used to incorrectly allow a macro-expanded let statement to lack a semicolon.
if macro_legacy_warnings && self.token != token::Semi {
self.warn_missing_semicolon();
} else {
self.expect_semi()?;
eat_semi = false;
}
self.expect_semi()?;
eat_semi = false;
}
_ => {}
}
Expand All @@ -451,17 +418,6 @@ impl<'a> Parser<'a> {
Ok(Some(stmt))
}

fn warn_missing_semicolon(&self) {
self.diagnostic()
.struct_span_warn(self.token.span, {
&format!("expected `;`, found {}", super::token_descr(&self.token))
})
.note({
"this was erroneously allowed and will become a hard error in a future release"
})
.emit();
}

pub(super) fn mk_block(&self, stmts: Vec<Stmt>, rules: BlockCheckMode, span: Span) -> P<Block> {
P(Block { stmts, id: DUMMY_NODE_ID, rules, span })
}
Expand Down
Loading