Skip to content

Commit 4ce3749

Browse files
committed
Auto merge of rust-lang#94453 - matthiaskrgr:rollup-xv9y98j, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#92399 (fix typo in btree/vec doc: Self -> self) - rust-lang#92823 (Tweak diagnostics) - rust-lang#94248 (Fix ICE when passing block to while-loop condition) - rust-lang#94414 (Fix ICE when using Box<T, A> with large A) - rust-lang#94445 (4 - Make more use of `let_chains`) - rust-lang#94449 (Add long explanation for E0726) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 97cde9f + 34657cc commit 4ce3749

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+591
-321
lines changed

compiler/rustc_codegen_ssa/src/mir/place.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
453453
};
454454
for elem in place_ref.projection[base..].iter() {
455455
cg_base = match elem.clone() {
456-
mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
456+
mir::ProjectionElem::Deref => {
457+
// custom allocators can change box's abi, making it unable to be derefed directly
458+
if cg_base.layout.ty.is_box()
459+
&& matches!(cg_base.layout.abi, Abi::Aggregate { .. } | Abi::Uninhabited)
460+
{
461+
let ptr = cg_base.project_field(bx, 0).project_field(bx, 0);
462+
463+
bx.load_operand(ptr).deref(bx.cx())
464+
} else {
465+
bx.load_operand(cg_base).deref(bx.cx())
466+
}
467+
}
457468
mir::ProjectionElem::Field(ref field, _) => {
458469
cg_base.project_field(bx, field.index())
459470
}

compiler/rustc_error_codes/src/error_codes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ E0720: include_str!("./error_codes/E0720.md"),
429429
E0722: include_str!("./error_codes/E0722.md"),
430430
E0724: include_str!("./error_codes/E0724.md"),
431431
E0725: include_str!("./error_codes/E0725.md"),
432+
E0726: include_str!("./error_codes/E0726.md"),
432433
E0727: include_str!("./error_codes/E0727.md"),
433434
E0728: include_str!("./error_codes/E0728.md"),
434435
E0729: include_str!("./error_codes/E0729.md"),
@@ -641,6 +642,5 @@ E0787: include_str!("./error_codes/E0787.md"),
641642
E0717, // rustc_promotable without stability attribute
642643
// E0721, // `await` keyword
643644
// E0723, // unstable feature in `const` context
644-
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
645645
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
646646
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
An argument lifetime was elided in an async function.
2+
3+
Erroneous code example:
4+
5+
When a struct or a type is bound/declared with a lifetime it is important for
6+
the Rust compiler to know, on usage, the lifespan of the type. When the
7+
lifetime is not explicitly mentioned and the Rust Compiler cannot determine
8+
the lifetime of your type, the following error occurs.
9+
10+
```compile_fail,E0726
11+
use futures::executor::block_on;
12+
struct Content<'a> {
13+
title: &'a str,
14+
body: &'a str,
15+
}
16+
async fn create(content: Content) { // error: implicit elided
17+
// lifetime not allowed here
18+
println!("title: {}", content.title);
19+
println!("body: {}", content.body);
20+
}
21+
let content = Content { title: "Rust", body: "is great!" };
22+
let future = create(content);
23+
block_on(future);
24+
```
25+
26+
Specify desired lifetime of parameter `content` or indicate the anonymous
27+
lifetime like `content: Content<'_>`. The anonymous lifetime tells the Rust
28+
compiler that `content` is only needed until create function is done with
29+
it's execution.
30+
31+
The `implicit elision` meaning the omission of suggested lifetime that is
32+
`pub async fn create<'a>(content: Content<'a>) {}` is not allowed here as
33+
lifetime of the `content` can differ from current context:
34+
35+
```ignore (needs futures dependency)
36+
async fn create(content: Content<'_>) { // ok!
37+
println!("title: {}", content.title);
38+
println!("body: {}", content.body);
39+
}
40+
```
41+
42+
Know more about lifetime elision in this [chapter][lifetime-elision] and a
43+
chapter on lifetimes can be found [here][lifetimes].
44+
45+
[lifetime-elision]: https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-elision
46+
[lifetimes]: https://doc.rust-lang.org/rust-by-example/scope/lifetime.html

compiler/rustc_expand/src/expand.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_data_structures::sync::Lrc;
2020
use rustc_errors::{Applicability, PResult};
2121
use rustc_feature::Features;
2222
use rustc_parse::parser::{
23-
AttemptLocalParseRecovery, ForceCollect, Parser, RecoverColon, RecoverComma,
23+
AttemptLocalParseRecovery, CommaRecoveryMode, ForceCollect, Parser, RecoverColon, RecoverComma,
2424
};
2525
use rustc_parse::validate_attr;
2626
use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
@@ -911,6 +911,7 @@ pub fn parse_ast_fragment<'a>(
911911
None,
912912
RecoverComma::No,
913913
RecoverColon::Yes,
914+
CommaRecoveryMode::LikelyTuple,
914915
)?),
915916
AstFragmentKind::Crate => AstFragment::Crate(this.parse_crate_mod()?),
916917
AstFragmentKind::Arms

compiler/rustc_parse/src/lexer/tokentrees.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -282,14 +282,13 @@ struct TokenStreamBuilder {
282282

283283
impl TokenStreamBuilder {
284284
fn push(&mut self, (tree, joint): TreeAndSpacing) {
285-
if let Some((TokenTree::Token(prev_token), Joint)) = self.buf.last() {
286-
if let TokenTree::Token(token) = &tree {
287-
if let Some(glued) = prev_token.glue(token) {
288-
self.buf.pop();
289-
self.buf.push((TokenTree::Token(glued), joint));
290-
return;
291-
}
292-
}
285+
if let Some((TokenTree::Token(prev_token), Joint)) = self.buf.last()
286+
&& let TokenTree::Token(token) = &tree
287+
&& let Some(glued) = prev_token.glue(token)
288+
{
289+
self.buf.pop();
290+
self.buf.push((TokenTree::Token(glued), joint));
291+
return;
293292
}
294293
self.buf.push((tree, joint))
295294
}

compiler/rustc_parse/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//! The main parser interface.
22
33
#![feature(array_windows)]
4+
#![feature(box_patterns)]
45
#![feature(crate_visibility_modifier)]
56
#![feature(if_let_guard)]
6-
#![feature(box_patterns)]
7+
#![feature(let_chains)]
78
#![feature(let_else)]
89
#![recursion_limit = "256"]
910

compiler/rustc_parse/src/parser/diagnostics.rs

+78-53
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use super::pat::Expected;
22
use super::ty::{AllowPlus, IsAsCast};
33
use super::{
4-
BlockMode, Parser, PathStyle, RecoverColon, RecoverComma, Restrictions, SemiColonMode, SeqSep,
5-
TokenExpectType, TokenType,
4+
BlockMode, CommaRecoveryMode, Parser, PathStyle, RecoverColon, RecoverComma, Restrictions,
5+
SemiColonMode, SeqSep, TokenExpectType, TokenType,
66
};
77

88
use rustc_ast as ast;
@@ -732,43 +732,42 @@ impl<'a> Parser<'a> {
732732
mut e: DiagnosticBuilder<'a, ErrorReported>,
733733
expr: &mut P<Expr>,
734734
) -> PResult<'a, ()> {
735-
if let ExprKind::Binary(binop, _, _) = &expr.kind {
736-
if let ast::BinOpKind::Lt = binop.node {
737-
if self.eat(&token::Comma) {
738-
let x = self.parse_seq_to_before_end(
739-
&token::Gt,
740-
SeqSep::trailing_allowed(token::Comma),
741-
|p| p.parse_generic_arg(None),
742-
);
743-
match x {
744-
Ok((_, _, false)) => {
745-
if self.eat(&token::Gt) {
746-
e.span_suggestion_verbose(
747-
binop.span.shrink_to_lo(),
748-
TURBOFISH_SUGGESTION_STR,
749-
"::".to_string(),
750-
Applicability::MaybeIncorrect,
751-
)
752-
.emit();
753-
match self.parse_expr() {
754-
Ok(_) => {
755-
*expr =
756-
self.mk_expr_err(expr.span.to(self.prev_token.span));
757-
return Ok(());
758-
}
759-
Err(err) => {
760-
*expr = self.mk_expr_err(expr.span);
761-
err.cancel();
762-
}
763-
}
735+
if let ExprKind::Binary(binop, _, _) = &expr.kind
736+
&& let ast::BinOpKind::Lt = binop.node
737+
&& self.eat(&token::Comma)
738+
{
739+
let x = self.parse_seq_to_before_end(
740+
&token::Gt,
741+
SeqSep::trailing_allowed(token::Comma),
742+
|p| p.parse_generic_arg(None),
743+
);
744+
match x {
745+
Ok((_, _, false)) => {
746+
if self.eat(&token::Gt) {
747+
e.span_suggestion_verbose(
748+
binop.span.shrink_to_lo(),
749+
TURBOFISH_SUGGESTION_STR,
750+
"::".to_string(),
751+
Applicability::MaybeIncorrect,
752+
)
753+
.emit();
754+
match self.parse_expr() {
755+
Ok(_) => {
756+
*expr =
757+
self.mk_expr_err(expr.span.to(self.prev_token.span));
758+
return Ok(());
759+
}
760+
Err(err) => {
761+
*expr = self.mk_expr_err(expr.span);
762+
err.cancel();
764763
}
765764
}
766-
Err(err) => {
767-
err.cancel();
768-
}
769-
_ => {}
770765
}
771766
}
767+
Err(err) => {
768+
err.cancel();
769+
}
770+
_ => {}
772771
}
773772
}
774773
Err(e)
@@ -784,12 +783,13 @@ impl<'a> Parser<'a> {
784783
outer_op: &Spanned<AssocOp>,
785784
) -> bool /* advanced the cursor */ {
786785
if let ExprKind::Binary(op, ref l1, ref r1) = inner_op.kind {
787-
if let ExprKind::Field(_, ident) = l1.kind {
788-
if ident.as_str().parse::<i32>().is_err() && !matches!(r1.kind, ExprKind::Lit(_)) {
789-
// The parser has encountered `foo.bar<baz`, the likelihood of the turbofish
790-
// suggestion being the only one to apply is high.
791-
return false;
792-
}
786+
if let ExprKind::Field(_, ident) = l1.kind
787+
&& ident.as_str().parse::<i32>().is_err()
788+
&& !matches!(r1.kind, ExprKind::Lit(_))
789+
{
790+
// The parser has encountered `foo.bar<baz`, the likelihood of the turbofish
791+
// suggestion being the only one to apply is high.
792+
return false;
793793
}
794794
let mut enclose = |left: Span, right: Span| {
795795
err.multipart_suggestion(
@@ -2245,12 +2245,32 @@ impl<'a> Parser<'a> {
22452245
first_pat
22462246
}
22472247

2248+
crate fn maybe_recover_unexpected_block_label(&mut self) -> bool {
2249+
let Some(label) = self.eat_label().filter(|_| {
2250+
self.eat(&token::Colon) && self.token.kind == token::OpenDelim(token::Brace)
2251+
}) else {
2252+
return false;
2253+
};
2254+
let span = label.ident.span.to(self.prev_token.span);
2255+
let mut err = self.struct_span_err(span, "block label not supported here");
2256+
err.span_label(span, "not supported here");
2257+
err.tool_only_span_suggestion(
2258+
label.ident.span.until(self.token.span),
2259+
"remove this block label",
2260+
String::new(),
2261+
Applicability::MachineApplicable,
2262+
);
2263+
err.emit();
2264+
true
2265+
}
2266+
22482267
/// Some special error handling for the "top-level" patterns in a match arm,
22492268
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
22502269
crate fn maybe_recover_unexpected_comma(
22512270
&mut self,
22522271
lo: Span,
22532272
rc: RecoverComma,
2273+
rt: CommaRecoveryMode,
22542274
) -> PResult<'a, ()> {
22552275
if rc == RecoverComma::No || self.token != token::Comma {
22562276
return Ok(());
@@ -2270,20 +2290,25 @@ impl<'a> Parser<'a> {
22702290
let seq_span = lo.to(self.prev_token.span);
22712291
let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
22722292
if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
2273-
const MSG: &str = "try adding parentheses to match on a tuple...";
2274-
2275-
err.span_suggestion(
2276-
seq_span,
2277-
MSG,
2278-
format!("({})", seq_snippet),
2279-
Applicability::MachineApplicable,
2280-
);
2281-
err.span_suggestion(
2282-
seq_span,
2283-
"...or a vertical bar to match on multiple alternatives",
2284-
seq_snippet.replace(',', " |"),
2293+
err.multipart_suggestion(
2294+
&format!(
2295+
"try adding parentheses to match on a tuple{}",
2296+
if let CommaRecoveryMode::LikelyTuple = rt { "" } else { "..." },
2297+
),
2298+
vec![
2299+
(seq_span.shrink_to_lo(), "(".to_string()),
2300+
(seq_span.shrink_to_hi(), ")".to_string()),
2301+
],
22852302
Applicability::MachineApplicable,
22862303
);
2304+
if let CommaRecoveryMode::EitherTupleOrPipe = rt {
2305+
err.span_suggestion(
2306+
seq_span,
2307+
"...or a vertical bar to match on multiple alternatives",
2308+
seq_snippet.replace(',', " |"),
2309+
Applicability::MachineApplicable,
2310+
);
2311+
}
22872312
}
22882313
Err(err)
22892314
}

0 commit comments

Comments
 (0)