Skip to content

Commit e91aebc

Browse files
committed
Auto merge of rust-lang#71664 - Dylan-DPC:rollup-eng60x9, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - rust-lang#71217 (Suggest `;` or assignment to drop borrows in tail exprs) - rust-lang#71286 (Add regression test for rust-lang#69654) - rust-lang#71296 (Change wording on read_vectored docs) - rust-lang#71654 (Update link to unstable book for llvm_asm macro) - rust-lang#71657 (Add rust-lang#24949 assoc constant static recursion test) Failed merges: r? @ghost
2 parents d9312a8 + 878e928 commit e91aebc

22 files changed

+332
-39
lines changed

src/libcore/macros/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,7 @@ pub(crate) mod builtin {
13161316
///
13171317
/// Read the [unstable book] for the usage.
13181318
///
1319-
/// [unstable book]: ../unstable-book/library-features/asm.html
1319+
/// [unstable book]: ../unstable-book/library-features/llvm-asm.html
13201320
#[unstable(
13211321
feature = "llvm_asm",
13221322
issue = "70173",

src/librustc_middle/mir/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,9 @@ pub struct BlockTailInfo {
672672
/// Examples include `{ ...; tail };` and `let _ = { ...; tail };`
673673
/// but not e.g., `let _x = { ...; tail };`
674674
pub tail_result_is_ignored: bool,
675+
676+
/// `Span` of the tail expression.
677+
pub span: Span,
675678
}
676679

677680
/// A MIR local.

src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs

+24-15
Original file line numberDiff line numberDiff line change
@@ -156,23 +156,32 @@ impl BorrowExplanation {
156156
err.span_label(body.source_info(drop_loc).span, message);
157157

158158
if let Some(info) = &local_decl.is_block_tail {
159-
// FIXME: use span_suggestion instead, highlighting the
160-
// whole block tail expression.
161-
let msg = if info.tail_result_is_ignored {
162-
"The temporary is part of an expression at the end of a block. \
163-
Consider adding semicolon after the expression so its temporaries \
164-
are dropped sooner, before the local variables declared by the \
165-
block are dropped."
159+
if info.tail_result_is_ignored {
160+
err.span_suggestion_verbose(
161+
info.span.shrink_to_hi(),
162+
"consider adding semicolon after the expression so its \
163+
temporaries are dropped sooner, before the local variables \
164+
declared by the block are dropped",
165+
";".to_string(),
166+
Applicability::MaybeIncorrect,
167+
);
166168
} else {
167-
"The temporary is part of an expression at the end of a block. \
168-
Consider forcing this temporary to be dropped sooner, before \
169-
the block's local variables are dropped. \
170-
For example, you could save the expression's value in a new \
171-
local variable `x` and then make `x` be the expression \
172-
at the end of the block."
169+
err.note(
170+
"the temporary is part of an expression at the end of a \
171+
block;\nconsider forcing this temporary to be dropped sooner, \
172+
before the block's local variables are dropped",
173+
);
174+
err.multipart_suggestion(
175+
"for example, you could save the expression's value in a new \
176+
local variable `x` and then make `x` be the expression at the \
177+
end of the block",
178+
vec![
179+
(info.span.shrink_to_lo(), "let x = ".to_string()),
180+
(info.span.shrink_to_hi(), "; x".to_string()),
181+
],
182+
Applicability::MaybeIncorrect,
183+
);
173184
};
174-
175-
err.note(msg);
176185
}
177186
}
178187
}

src/librustc_mir_build/build/block.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
173173
if let Some(expr) = expr {
174174
let tail_result_is_ignored =
175175
destination_ty.is_unit() || this.block_context.currently_ignores_tail_results();
176-
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored });
176+
let span = match expr {
177+
ExprRef::Hair(expr) => expr.span,
178+
ExprRef::Mirror(ref expr) => expr.span,
179+
};
180+
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored, span });
177181

178182
unpack!(block = this.into(destination, block, expr));
179183
let popped = this.block_context.pop();

src/librustc_mir_build/build/expr/stmt.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
151151
}
152152
}
153153
this.block_context
154-
.push(BlockFrame::TailExpr { tail_result_is_ignored: true });
154+
.push(BlockFrame::TailExpr { tail_result_is_ignored: true, span: expr.span });
155155
return Some(expr.span);
156156
}
157157
}

src/librustc_mir_build/build/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ enum BlockFrame {
242242
///
243243
/// Example: `let _ = { STMT_1; EXPR };`
244244
tail_result_is_ignored: bool,
245+
246+
/// `Span` of the tail expression.
247+
span: Span,
245248
},
246249

247250
/// Generic mark meaning that the block occurred as a subexpression
@@ -369,8 +372,8 @@ impl BlockContext {
369372
match bf {
370373
BlockFrame::SubExpr => continue,
371374
BlockFrame::Statement { .. } => break,
372-
&BlockFrame::TailExpr { tail_result_is_ignored } => {
373-
return Some(BlockTailInfo { tail_result_is_ignored });
375+
&BlockFrame::TailExpr { tail_result_is_ignored, span } => {
376+
return Some(BlockTailInfo { tail_result_is_ignored, span });
374377
}
375378
}
376379
}
@@ -394,7 +397,7 @@ impl BlockContext {
394397

395398
// otherwise: use accumulated is_ignored state.
396399
Some(
397-
BlockFrame::TailExpr { tail_result_is_ignored: ignored }
400+
BlockFrame::TailExpr { tail_result_is_ignored: ignored, .. }
398401
| BlockFrame::Statement { ignores_expr_result: ignored },
399402
) => *ignored,
400403
}

src/libstd/io/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,9 @@ pub trait Read {
571571
/// Like `read`, except that it reads into a slice of buffers.
572572
///
573573
/// Data is copied to fill each buffer in order, with the final buffer
574-
/// written to possibly being only partially filled. This method must behave
575-
/// as a single call to `read` with the buffers concatenated would.
574+
/// written to possibly being only partially filled. This method must
575+
/// behave equivalently to a single call to `read` with concatenated
576+
/// buffers.
576577
///
577578
/// The default implementation calls `read` with either the first nonempty
578579
/// buffer provided, or an empty one if none exists.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Check for recursion involving references to impl-associated const.
2+
3+
trait Foo {
4+
const BAR: u32;
5+
}
6+
7+
const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; //~ ERROR E0391
8+
9+
struct GlobalImplRef;
10+
11+
impl GlobalImplRef {
12+
const BAR: u32 = IMPL_REF_BAR;
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
error[E0391]: cycle detected when const-evaluating + checking `IMPL_REF_BAR`
2+
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
3+
|
4+
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: ...which requires const-evaluating + checking `IMPL_REF_BAR`...
8+
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
9+
|
10+
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
note: ...which requires const-evaluating `IMPL_REF_BAR`...
13+
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
14+
|
15+
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
= note: ...which requires normalizing `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
18+
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
19+
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
20+
|
21+
LL | const BAR: u32 = IMPL_REF_BAR;
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23+
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
24+
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
25+
|
26+
LL | const BAR: u32 = IMPL_REF_BAR;
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
28+
note: ...which requires const-evaluating `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
29+
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
30+
|
31+
LL | const BAR: u32 = IMPL_REF_BAR;
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
33+
note: ...which requires processing `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
34+
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
35+
|
36+
LL | const BAR: u32 = IMPL_REF_BAR;
37+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38+
= note: ...which requires normalizing `IMPL_REF_BAR`...
39+
= note: ...which again requires const-evaluating + checking `IMPL_REF_BAR`, completing the cycle
40+
= note: cycle used when running analysis passes on this crate
41+
42+
error: aborting due to previous error
43+
44+
For more information about this error, try `rustc --explain E0391`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Check for recursion involving references to trait-associated const default.
2+
3+
trait Foo {
4+
const BAR: u32;
5+
}
6+
7+
trait FooDefault {
8+
const BAR: u32 = DEFAULT_REF_BAR;
9+
}
10+
11+
const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR; //~ ERROR E0391
12+
13+
struct GlobalDefaultRef;
14+
15+
impl FooDefault for GlobalDefaultRef {}
16+
17+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
error[E0391]: cycle detected when const-evaluating + checking `DEFAULT_REF_BAR`
2+
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
3+
|
4+
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`...
8+
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
9+
|
10+
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
note: ...which requires const-evaluating `DEFAULT_REF_BAR`...
13+
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
14+
|
15+
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
= note: ...which requires normalizing `<GlobalDefaultRef as FooDefault>::BAR`...
18+
note: ...which requires const-evaluating + checking `FooDefault::BAR`...
19+
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
20+
|
21+
LL | const BAR: u32 = DEFAULT_REF_BAR;
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23+
note: ...which requires const-evaluating + checking `FooDefault::BAR`...
24+
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
25+
|
26+
LL | const BAR: u32 = DEFAULT_REF_BAR;
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
28+
note: ...which requires const-evaluating `FooDefault::BAR`...
29+
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
30+
|
31+
LL | const BAR: u32 = DEFAULT_REF_BAR;
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
33+
note: ...which requires processing `FooDefault::BAR`...
34+
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
35+
|
36+
LL | const BAR: u32 = DEFAULT_REF_BAR;
37+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38+
= note: ...which requires normalizing `DEFAULT_REF_BAR`...
39+
= note: ...which again requires const-evaluating + checking `DEFAULT_REF_BAR`, completing the cycle
40+
= note: cycle used when running analysis passes on this crate
41+
42+
error: aborting due to previous error
43+
44+
For more information about this error, try `rustc --explain E0391`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Check for recursion involving references to trait-associated const.
2+
3+
trait Foo {
4+
const BAR: u32;
5+
}
6+
7+
const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR; //~ ERROR E0391
8+
9+
struct GlobalTraitRef;
10+
11+
impl Foo for GlobalTraitRef {
12+
const BAR: u32 = TRAIT_REF_BAR;
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
error[E0391]: cycle detected when const-evaluating + checking `TRAIT_REF_BAR`
2+
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
3+
|
4+
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`...
8+
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
9+
|
10+
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
note: ...which requires const-evaluating `TRAIT_REF_BAR`...
13+
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
14+
|
15+
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
= note: ...which requires normalizing `<GlobalTraitRef as Foo>::BAR`...
18+
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 13:2>::BAR`...
19+
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
20+
|
21+
LL | const BAR: u32 = TRAIT_REF_BAR;
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23+
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 13:2>::BAR`...
24+
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
25+
|
26+
LL | const BAR: u32 = TRAIT_REF_BAR;
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
28+
note: ...which requires const-evaluating `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 13:2>::BAR`...
29+
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
30+
|
31+
LL | const BAR: u32 = TRAIT_REF_BAR;
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
33+
note: ...which requires processing `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 13:2>::BAR`...
34+
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
35+
|
36+
LL | const BAR: u32 = TRAIT_REF_BAR;
37+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38+
= note: ...which requires normalizing `TRAIT_REF_BAR`...
39+
= note: ...which again requires const-evaluating + checking `TRAIT_REF_BAR`, completing the cycle
40+
= note: cycle used when running analysis passes on this crate
41+
42+
error: aborting due to previous error
43+
44+
For more information about this error, try `rustc --explain E0391`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![feature(const_generics)]
2+
#![allow(incomplete_features)]
3+
4+
trait Bar<O> {}
5+
impl<O> Bar<O> for [u8; O] {}
6+
//~^ ERROR expected value, found type parameter `O`
7+
8+
struct Foo<const O: usize> {}
9+
impl<const O: usize> Foo<O>
10+
where
11+
[u8; O]: Bar<[(); O]>,
12+
{
13+
fn foo() {}
14+
}
15+
16+
fn main() {
17+
Foo::foo();
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0423]: expected value, found type parameter `O`
2+
--> $DIR/issue-69654.rs:5:25
3+
|
4+
LL | impl<O> Bar<O> for [u8; O] {}
5+
| ^ help: a tuple variant with a similar name exists: `Ok`
6+
|
7+
::: $SRC_DIR/libcore/result.rs:LL:COL
8+
|
9+
LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
10+
| --------------------------------------------------- similarly named tuple variant `Ok` defined here
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0423`.

src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ LL |
1313
LL | ;
1414
| - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
1515
|
16-
= note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.
16+
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
17+
|
18+
LL | D("other").next(&_thing1);
19+
| ^
1720

1821
error: aborting due to previous error
1922

src/test/ui/nll/issue-54556-niconii.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ LL | }
1313
| `counter` dropped here while still borrowed
1414
| ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `std::result::Result<MutexGuard<'_>, ()>`
1515
|
16-
= note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.
16+
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
17+
|
18+
LL | if let Ok(_) = counter.lock() { };
19+
| ^
1720

1821
error: aborting due to previous error
1922

src/test/ui/nll/issue-54556-stephaneyfx.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ LL | }
1212
| `stmt` dropped here while still borrowed
1313
| ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `std::iter::Map<Rows<'_>, [closure@$DIR/issue-54556-stephaneyfx.rs:28:14: 28:23]>`
1414
|
15-
= note: The temporary is part of an expression at the end of a block. Consider forcing this temporary to be dropped sooner, before the block's local variables are dropped. For example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block.
15+
= note: the temporary is part of an expression at the end of a block;
16+
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
17+
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
18+
|
19+
LL | let x = rows.map(|row| row).next(); x
20+
| ^^^^^^^ ^^^
1621

1722
error: aborting due to previous error
1823

src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ LL |
1212
LL | ;
1313
| - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
1414
|
15-
= note: The temporary is part of an expression at the end of a block. Consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped.
15+
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
16+
|
17+
LL | D(&_thing1).end();
18+
| ^
1619

1720
error: aborting due to previous error
1821

0 commit comments

Comments
 (0)