mirror of https://github.com/rust-lang/rust.git
Auto merge of #87480 - GuillaumeGomez:rollup-3ly8t5d, r=GuillaumeGomez
Rollup of 8 pull requests Successful merges: - #87436 (Suggest `;` on parse error where applicable) - #87444 (Flatten nested `format!` calls) - #87447 (Miri: santiy check that null pointer can never have an AllocId) - #87457 (freebsd remove compiler workaround.) - #87458 (Fix help message for modification to &T created by &{t}) - #87464 (Remove unnecessary `structhead` parameter from `render_union`) - #87473 (Notify the Rust 2021 edition working group in zulip of edition bugs) - #87474 (Add missing whitespace after attribute in HTML template) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
8bebfe5cc2
|
@ -905,6 +905,8 @@ fn suggest_ampmut<'tcx>(
|
|||
Some(c) if c.is_whitespace() => true,
|
||||
// e.g. `&mut(x)`
|
||||
Some('(') => true,
|
||||
// e.g. `&mut{x}`
|
||||
Some('{') => true,
|
||||
// e.g. `&mutablevar`
|
||||
_ => false,
|
||||
}
|
||||
|
@ -912,9 +914,7 @@ fn suggest_ampmut<'tcx>(
|
|||
false
|
||||
}
|
||||
};
|
||||
if let (true, Some(ws_pos)) =
|
||||
(src.starts_with("&'"), src.find(|c: char| -> bool { c.is_whitespace() }))
|
||||
{
|
||||
if let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace)) {
|
||||
let lt_name = &src[1..ws_pos];
|
||||
let ty = src[ws_pos..].trim_start();
|
||||
if !is_mutbl(ty) {
|
||||
|
@ -940,9 +940,7 @@ fn suggest_ampmut<'tcx>(
|
|||
};
|
||||
|
||||
if let Ok(src) = tcx.sess.source_map().span_to_snippet(highlight_span) {
|
||||
if let (true, Some(ws_pos)) =
|
||||
(src.starts_with("&'"), src.find(|c: char| -> bool { c.is_whitespace() }))
|
||||
{
|
||||
if let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace)) {
|
||||
let lt_name = &src[1..ws_pos];
|
||||
let ty = &src[ws_pos..];
|
||||
return (highlight_span, format!("&{} mut{}", lt_name, ty));
|
||||
|
|
|
@ -1142,7 +1142,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
Err(ptr) => ptr.into(),
|
||||
Ok(bits) => {
|
||||
let addr = u64::try_from(bits).unwrap();
|
||||
M::ptr_from_addr(&self, addr)
|
||||
let ptr = M::ptr_from_addr(&self, addr);
|
||||
if addr == 0 {
|
||||
assert!(ptr.provenance.is_none(), "null pointer can never have an AllocId");
|
||||
}
|
||||
ptr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,6 +242,63 @@ impl<'a> Parser<'a> {
|
|||
expected.sort_by_cached_key(|x| x.to_string());
|
||||
expected.dedup();
|
||||
|
||||
let sm = self.sess.source_map();
|
||||
let msg = format!("expected `;`, found {}", super::token_descr(&self.token));
|
||||
let appl = Applicability::MachineApplicable;
|
||||
if expected.contains(&TokenType::Token(token::Semi)) {
|
||||
if self.token.span == DUMMY_SP || self.prev_token.span == DUMMY_SP {
|
||||
// Likely inside a macro, can't provide meaningful suggestions.
|
||||
} else if !sm.is_multiline(self.prev_token.span.until(self.token.span)) {
|
||||
// The current token is in the same line as the prior token, not recoverable.
|
||||
} else if [token::Comma, token::Colon].contains(&self.token.kind)
|
||||
&& self.prev_token.kind == token::CloseDelim(token::Paren)
|
||||
{
|
||||
// Likely typo: The current token is on a new line and is expected to be
|
||||
// `.`, `;`, `?`, or an operator after a close delimiter token.
|
||||
//
|
||||
// let a = std::process::Command::new("echo")
|
||||
// .arg("1")
|
||||
// ,arg("2")
|
||||
// ^
|
||||
// https://github.com/rust-lang/rust/issues/72253
|
||||
} else if self.look_ahead(1, |t| {
|
||||
t == &token::CloseDelim(token::Brace)
|
||||
|| t.can_begin_expr() && t.kind != token::Colon
|
||||
}) && [token::Comma, token::Colon].contains(&self.token.kind)
|
||||
{
|
||||
// Likely typo: `,` → `;` or `:` → `;`. This is triggered if the current token is
|
||||
// either `,` or `:`, and the next token could either start a new statement or is a
|
||||
// block close. For example:
|
||||
//
|
||||
// let x = 32:
|
||||
// let y = 42;
|
||||
self.bump();
|
||||
let sp = self.prev_token.span;
|
||||
self.struct_span_err(sp, &msg)
|
||||
.span_suggestion_short(sp, "change this to `;`", ";".to_string(), appl)
|
||||
.emit();
|
||||
return Ok(false);
|
||||
} else if self.look_ahead(0, |t| {
|
||||
t == &token::CloseDelim(token::Brace)
|
||||
|| (
|
||||
t.can_begin_expr() && t != &token::Semi && t != &token::Pound
|
||||
// Avoid triggering with too many trailing `#` in raw string.
|
||||
)
|
||||
}) {
|
||||
// Missing semicolon typo. This is triggered if the next token could either start a
|
||||
// new statement or is a block close. For example:
|
||||
//
|
||||
// let x = 32
|
||||
// let y = 42;
|
||||
let sp = self.prev_token.span.shrink_to_hi();
|
||||
self.struct_span_err(sp, &msg)
|
||||
.span_label(self.token.span, "unexpected token")
|
||||
.span_suggestion_short(sp, "add `;` here", ";".to_string(), appl)
|
||||
.emit();
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
let expect = tokens_to_string(&expected[..]);
|
||||
let actual = super::token_descr(&self.token);
|
||||
let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
|
||||
|
@ -303,7 +360,6 @@ impl<'a> Parser<'a> {
|
|||
return Err(err);
|
||||
}
|
||||
|
||||
let sm = self.sess.source_map();
|
||||
if self.prev_token.span == DUMMY_SP {
|
||||
// Account for macro context where the previous span might not be
|
||||
// available to avoid incorrect output (#54841).
|
||||
|
@ -1144,62 +1200,6 @@ impl<'a> Parser<'a> {
|
|||
if self.eat(&token::Semi) {
|
||||
return Ok(());
|
||||
}
|
||||
let sm = self.sess.source_map();
|
||||
let msg = format!("expected `;`, found {}", super::token_descr(&self.token));
|
||||
let appl = Applicability::MachineApplicable;
|
||||
if self.token.span == DUMMY_SP || self.prev_token.span == DUMMY_SP {
|
||||
// Likely inside a macro, can't provide meaningful suggestions.
|
||||
return self.expect(&token::Semi).map(drop);
|
||||
} else if !sm.is_multiline(self.prev_token.span.until(self.token.span)) {
|
||||
// The current token is in the same line as the prior token, not recoverable.
|
||||
} else if [token::Comma, token::Colon].contains(&self.token.kind)
|
||||
&& self.prev_token.kind == token::CloseDelim(token::Paren)
|
||||
{
|
||||
// Likely typo: The current token is on a new line and is expected to be
|
||||
// `.`, `;`, `?`, or an operator after a close delimiter token.
|
||||
//
|
||||
// let a = std::process::Command::new("echo")
|
||||
// .arg("1")
|
||||
// ,arg("2")
|
||||
// ^
|
||||
// https://github.com/rust-lang/rust/issues/72253
|
||||
self.expect(&token::Semi)?;
|
||||
return Ok(());
|
||||
} else if self.look_ahead(1, |t| {
|
||||
t == &token::CloseDelim(token::Brace) || t.can_begin_expr() && t.kind != token::Colon
|
||||
}) && [token::Comma, token::Colon].contains(&self.token.kind)
|
||||
{
|
||||
// Likely typo: `,` → `;` or `:` → `;`. This is triggered if the current token is
|
||||
// either `,` or `:`, and the next token could either start a new statement or is a
|
||||
// block close. For example:
|
||||
//
|
||||
// let x = 32:
|
||||
// let y = 42;
|
||||
self.bump();
|
||||
let sp = self.prev_token.span;
|
||||
self.struct_span_err(sp, &msg)
|
||||
.span_suggestion_short(sp, "change this to `;`", ";".to_string(), appl)
|
||||
.emit();
|
||||
return Ok(());
|
||||
} else if self.look_ahead(0, |t| {
|
||||
t == &token::CloseDelim(token::Brace)
|
||||
|| (
|
||||
t.can_begin_expr() && t != &token::Semi && t != &token::Pound
|
||||
// Avoid triggering with too many trailing `#` in raw string.
|
||||
)
|
||||
}) {
|
||||
// Missing semicolon typo. This is triggered if the next token could either start a
|
||||
// new statement or is a block close. For example:
|
||||
//
|
||||
// let x = 32
|
||||
// let y = 42;
|
||||
let sp = self.prev_token.span.shrink_to_hi();
|
||||
self.struct_span_err(sp, &msg)
|
||||
.span_label(self.token.span, "unexpected token")
|
||||
.span_suggestion_short(sp, "add `;` here", ";".to_string(), appl)
|
||||
.emit();
|
||||
return Ok(());
|
||||
}
|
||||
self.expect(&token::Semi).map(drop) // Error unconditionally
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::spec::{FramePointer, RelroLevel, TargetOptions};
|
||||
use crate::spec::{RelroLevel, TargetOptions};
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
TargetOptions {
|
||||
|
@ -8,7 +8,6 @@ pub fn opts() -> TargetOptions {
|
|||
families: vec!["unix".to_string()],
|
||||
has_rpath: true,
|
||||
position_independent_executables: true,
|
||||
frame_pointer: FramePointer::Always, // FIXME 43575: should be MayOmit...
|
||||
relro_level: RelroLevel::Full,
|
||||
abi_return_struct_as_int: true,
|
||||
dwarf_version: Some(2),
|
||||
|
|
|
@ -234,9 +234,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
|||
return Some(Event::Html(
|
||||
format!(
|
||||
"<div class=\"example-wrap\">\
|
||||
<pre{}>{}</pre>\
|
||||
<pre class=\"language-{}\">{}</pre>\
|
||||
</div>",
|
||||
format!(" class=\"language-{}\"", lang),
|
||||
lang,
|
||||
Escape(&text),
|
||||
)
|
||||
.into(),
|
||||
|
|
|
@ -888,7 +888,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni
|
|||
wrap_into_docblock(w, |w| {
|
||||
w.write_str("<pre class=\"rust union\">");
|
||||
render_attributes_in_pre(w, it, "");
|
||||
render_union(w, it, Some(&s.generics), &s.fields, "", true, cx);
|
||||
render_union(w, it, Some(&s.generics), &s.fields, "", cx);
|
||||
w.write_str("</pre>")
|
||||
});
|
||||
|
||||
|
@ -1380,14 +1380,12 @@ fn render_union(
|
|||
g: Option<&clean::Generics>,
|
||||
fields: &[clean::Item],
|
||||
tab: &str,
|
||||
structhead: bool,
|
||||
cx: &Context<'_>,
|
||||
) {
|
||||
write!(
|
||||
w,
|
||||
"{}{}{}",
|
||||
"{}union {}",
|
||||
it.visibility.print_with_space(it.def_id, cx),
|
||||
if structhead { "union " } else { "" },
|
||||
it.name.as_ref().unwrap()
|
||||
);
|
||||
if let Some(g) = g {
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
</select> {#- -#}
|
||||
{%- endif -%}
|
||||
<input {# -#}
|
||||
class="search-input"{# -#}
|
||||
class="search-input" {# -#}
|
||||
name="search" {# -#}
|
||||
disabled {# -#}
|
||||
autocomplete="off" {# -#}
|
||||
|
|
|
@ -12,4 +12,18 @@ fn main() {
|
|||
*r = 0;
|
||||
//~^ ERROR cannot assign to `*r`, which is behind a `&` reference
|
||||
//~| NOTE `r` is a `&` reference, so the data it refers to cannot be written
|
||||
|
||||
#[rustfmt::skip]
|
||||
let x: &usize = &mut{0};
|
||||
//~^ HELP consider changing this to be a mutable reference
|
||||
*x = 1;
|
||||
//~^ ERROR cannot assign to `*x`, which is behind a `&` reference
|
||||
//~| NOTE `x` is a `&` reference, so the data it refers to cannot be written
|
||||
|
||||
#[rustfmt::skip]
|
||||
let y: &usize = &mut(0);
|
||||
//~^ HELP consider changing this to be a mutable reference
|
||||
*y = 1;
|
||||
//~^ ERROR cannot assign to `*y`, which is behind a `&` reference
|
||||
//~| NOTE `y` is a `&` reference, so the data it refers to cannot be written
|
||||
}
|
||||
|
|
|
@ -16,7 +16,25 @@ LL |
|
|||
LL | *r = 0;
|
||||
| ^^^^^^ `r` is a `&` reference, so the data it refers to cannot be written
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0594]: cannot assign to `*x`, which is behind a `&` reference
|
||||
--> $DIR/issue-85765.rs:19:5
|
||||
|
|
||||
LL | let x: &usize = &mut{0};
|
||||
| - help: consider changing this to be a mutable reference: `&mut usize`
|
||||
LL |
|
||||
LL | *x = 1;
|
||||
| ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
|
||||
|
||||
error[E0594]: cannot assign to `*y`, which is behind a `&` reference
|
||||
--> $DIR/issue-85765.rs:26:5
|
||||
|
|
||||
LL | let y: &usize = &mut(0);
|
||||
| - help: consider changing this to be a mutable reference: `&mut usize`
|
||||
LL |
|
||||
LL | *y = 1;
|
||||
| ^^^^^^ `y` is a `&` reference, so the data it refers to cannot be written
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0594, E0596.
|
||||
For more information about an error, try `rustc --explain E0594`.
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
// run-rustfix
|
||||
// Parser should know when a semicolon is missing.
|
||||
// https://github.com/rust-lang/rust/issues/87197
|
||||
|
||||
fn main() {
|
||||
let x = 100; //~ ERROR: expected `;`
|
||||
println!("{}", x); //~ ERROR: expected `;`
|
||||
let y = 200; //~ ERROR: expected `;`
|
||||
println!("{}", y);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// run-rustfix
|
||||
// Parser should know when a semicolon is missing.
|
||||
// https://github.com/rust-lang/rust/issues/87197
|
||||
|
||||
fn main() {
|
||||
let x = 100 //~ ERROR: expected `;`
|
||||
println!("{}", x) //~ ERROR: expected `;`
|
||||
let y = 200 //~ ERROR: expected `;`
|
||||
println!("{}", y);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
error: expected `;`, found `println`
|
||||
--> $DIR/issue-87197-missing-semicolon.rs:6:16
|
||||
|
|
||||
LL | let x = 100
|
||||
| ^ help: add `;` here
|
||||
LL | println!("{}", x)
|
||||
| ------- unexpected token
|
||||
|
||||
error: expected `;`, found keyword `let`
|
||||
--> $DIR/issue-87197-missing-semicolon.rs:7:22
|
||||
|
|
||||
LL | println!("{}", x)
|
||||
| ^ help: add `;` here
|
||||
LL | let y = 200
|
||||
| --- unexpected token
|
||||
|
||||
error: expected `;`, found `println`
|
||||
--> $DIR/issue-87197-missing-semicolon.rs:8:16
|
||||
|
|
||||
LL | let y = 200
|
||||
| ^ help: add `;` here
|
||||
LL | println!("{}", y);
|
||||
| ------- unexpected token
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
fn main() {
|
||||
assert_eq!(1, 2)
|
||||
assert_eq!(3, 4) //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `assert_eq`
|
||||
assert_eq!(1, 2) //~ ERROR: expected `;`
|
||||
assert_eq!(3, 4) //~ ERROR: expected `;`
|
||||
println!("hello");
|
||||
}
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `assert_eq`
|
||||
--> $DIR/macros-no-semicolon.rs:3:5
|
||||
error: expected `;`, found `assert_eq`
|
||||
--> $DIR/macros-no-semicolon.rs:2:21
|
||||
|
|
||||
LL | assert_eq!(1, 2)
|
||||
| - expected one of `.`, `;`, `?`, `}`, or an operator
|
||||
| ^ help: add `;` here
|
||||
LL | assert_eq!(3, 4)
|
||||
| ^^^^^^^^^ unexpected token
|
||||
| --------- unexpected token
|
||||
|
||||
error: aborting due to previous error
|
||||
error: expected `;`, found `println`
|
||||
--> $DIR/macros-no-semicolon.rs:3:21
|
||||
|
|
||||
LL | assert_eq!(3, 4)
|
||||
| ^ help: add `;` here
|
||||
LL | println!("hello");
|
||||
| ------- unexpected token
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -112,6 +112,14 @@ message_on_add = """\
|
|||
"""
|
||||
message_on_remove = "Issue #{number}'s nomination request has been removed."
|
||||
|
||||
[notify-zulip."A-edition-2021"]
|
||||
required_labels = ["C-bug"]
|
||||
zulip_stream = 268952 # #edition 2021
|
||||
topic = "Edition Bugs"
|
||||
message_on_add = """\
|
||||
Issue #{number} "{title}" has been added.
|
||||
"""
|
||||
|
||||
[github-releases]
|
||||
format = "rustc"
|
||||
project-name = "Rust"
|
||||
|
|
Loading…
Reference in New Issue