Skip to content

Rollup of 5 pull requests #71664

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

Merged
merged 10 commits into from
Apr 29, 2020
2 changes: 1 addition & 1 deletion src/libcore/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,7 @@ pub(crate) mod builtin {
///
/// Read the [unstable book] for the usage.
///
/// [unstable book]: ../unstable-book/library-features/asm.html
/// [unstable book]: ../unstable-book/library-features/llvm-asm.html
#[unstable(
feature = "llvm_asm",
issue = "70173",
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_middle/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,9 @@ pub struct BlockTailInfo {
/// Examples include `{ ...; tail };` and `let _ = { ...; tail };`
/// but not e.g., `let _x = { ...; tail };`
pub tail_result_is_ignored: bool,

/// `Span` of the tail expression.
pub span: Span,
}

/// A MIR local.
Expand Down
39 changes: 24 additions & 15 deletions src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,23 +156,32 @@ impl BorrowExplanation {
err.span_label(body.source_info(drop_loc).span, message);

if let Some(info) = &local_decl.is_block_tail {
// FIXME: use span_suggestion instead, highlighting the
// whole block tail expression.
let msg = if info.tail_result_is_ignored {
"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."
if info.tail_result_is_ignored {
err.span_suggestion_verbose(
info.span.shrink_to_hi(),
"consider adding semicolon after the expression so its \
temporaries are dropped sooner, before the local variables \
declared by the block are dropped",
";".to_string(),
Applicability::MaybeIncorrect,
);
} else {
"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."
err.note(
"the temporary is part of an expression at the end of a \
block;\nconsider forcing this temporary to be dropped sooner, \
before the block's local variables are dropped",
);
err.multipart_suggestion(
"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",
vec![
(info.span.shrink_to_lo(), "let x = ".to_string()),
(info.span.shrink_to_hi(), "; x".to_string()),
],
Applicability::MaybeIncorrect,
);
};

err.note(msg);
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_mir_build/build/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
if let Some(expr) = expr {
let tail_result_is_ignored =
destination_ty.is_unit() || this.block_context.currently_ignores_tail_results();
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored });
let span = match expr {
ExprRef::Hair(expr) => expr.span,
ExprRef::Mirror(ref expr) => expr.span,
};
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored, span });

unpack!(block = this.into(destination, block, expr));
let popped = this.block_context.pop();
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir_build/build/expr/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}
this.block_context
.push(BlockFrame::TailExpr { tail_result_is_ignored: true });
.push(BlockFrame::TailExpr { tail_result_is_ignored: true, span: expr.span });
return Some(expr.span);
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/librustc_mir_build/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ enum BlockFrame {
///
/// Example: `let _ = { STMT_1; EXPR };`
tail_result_is_ignored: bool,

/// `Span` of the tail expression.
span: Span,
},

/// Generic mark meaning that the block occurred as a subexpression
Expand Down Expand Up @@ -369,8 +372,8 @@ impl BlockContext {
match bf {
BlockFrame::SubExpr => continue,
BlockFrame::Statement { .. } => break,
&BlockFrame::TailExpr { tail_result_is_ignored } => {
return Some(BlockTailInfo { tail_result_is_ignored });
&BlockFrame::TailExpr { tail_result_is_ignored, span } => {
return Some(BlockTailInfo { tail_result_is_ignored, span });
}
}
}
Expand All @@ -394,7 +397,7 @@ impl BlockContext {

// otherwise: use accumulated is_ignored state.
Some(
BlockFrame::TailExpr { tail_result_is_ignored: ignored }
BlockFrame::TailExpr { tail_result_is_ignored: ignored, .. }
| BlockFrame::Statement { ignores_expr_result: ignored },
) => *ignored,
}
Expand Down
5 changes: 3 additions & 2 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,8 +571,9 @@ pub trait Read {
/// Like `read`, except that it reads into a slice of buffers.
///
/// Data is copied to fill each buffer in order, with the final buffer
/// written to possibly being only partially filled. This method must behave
/// as a single call to `read` with the buffers concatenated would.
/// written to possibly being only partially filled. This method must
/// behave equivalently to a single call to `read` with concatenated
/// buffers.
///
/// The default implementation calls `read` with either the first nonempty
/// buffer provided, or an empty one if none exists.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Check for recursion involving references to impl-associated const.

trait Foo {
const BAR: u32;
}

const IMPL_REF_BAR: u32 = GlobalImplRef::BAR; //~ ERROR E0391

struct GlobalImplRef;

impl GlobalImplRef {
const BAR: u32 = IMPL_REF_BAR;
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
error[E0391]: cycle detected when const-evaluating + checking `IMPL_REF_BAR`
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
|
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `IMPL_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
|
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating `IMPL_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:7:1
|
LL | const IMPL_REF_BAR: u32 = GlobalImplRef::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires normalizing `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
LL | const BAR: u32 = IMPL_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
LL | const BAR: u32 = IMPL_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
LL | const BAR: u32 = IMPL_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `<impl at $DIR/issue-24949-assoc-const-static-recursion-impl.rs:11:1: 13:2>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-impl.rs:12:5
|
LL | const BAR: u32 = IMPL_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires normalizing `IMPL_REF_BAR`...
= note: ...which again requires const-evaluating + checking `IMPL_REF_BAR`, completing the cycle
= note: cycle used when running analysis passes on this crate

error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Check for recursion involving references to trait-associated const default.

trait Foo {
const BAR: u32;
}

trait FooDefault {
const BAR: u32 = DEFAULT_REF_BAR;
}

const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR; //~ ERROR E0391

struct GlobalDefaultRef;

impl FooDefault for GlobalDefaultRef {}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
error[E0391]: cycle detected when const-evaluating + checking `DEFAULT_REF_BAR`
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
|
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `DEFAULT_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
|
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating `DEFAULT_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:11:1
|
LL | const DEFAULT_REF_BAR: u32 = <GlobalDefaultRef>::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires normalizing `<GlobalDefaultRef as FooDefault>::BAR`...
note: ...which requires const-evaluating + checking `FooDefault::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
|
LL | const BAR: u32 = DEFAULT_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `FooDefault::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
|
LL | const BAR: u32 = DEFAULT_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating `FooDefault::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
|
LL | const BAR: u32 = DEFAULT_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `FooDefault::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait-default.rs:8:5
|
LL | const BAR: u32 = DEFAULT_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires normalizing `DEFAULT_REF_BAR`...
= note: ...which again requires const-evaluating + checking `DEFAULT_REF_BAR`, completing the cycle
= note: cycle used when running analysis passes on this crate

error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Check for recursion involving references to trait-associated const.

trait Foo {
const BAR: u32;
}

const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR; //~ ERROR E0391

struct GlobalTraitRef;

impl Foo for GlobalTraitRef {
const BAR: u32 = TRAIT_REF_BAR;
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
error[E0391]: cycle detected when const-evaluating + checking `TRAIT_REF_BAR`
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
|
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires const-evaluating + checking `TRAIT_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
|
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating `TRAIT_REF_BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:7:1
|
LL | const TRAIT_REF_BAR: u32 = <GlobalTraitRef>::BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires normalizing `<GlobalTraitRef as Foo>::BAR`...
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 13:2>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
|
LL | const BAR: u32 = TRAIT_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating + checking `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 13:2>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
|
LL | const BAR: u32 = TRAIT_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires const-evaluating `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 13:2>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
|
LL | const BAR: u32 = TRAIT_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires processing `<impl at $DIR/issue-24949-assoc-const-static-recursion-trait.rs:11:1: 13:2>::BAR`...
--> $DIR/issue-24949-assoc-const-static-recursion-trait.rs:12:5
|
LL | const BAR: u32 = TRAIT_REF_BAR;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires normalizing `TRAIT_REF_BAR`...
= note: ...which again requires const-evaluating + checking `TRAIT_REF_BAR`, completing the cycle
= note: cycle used when running analysis passes on this crate

error: aborting due to previous error

For more information about this error, try `rustc --explain E0391`.
18 changes: 18 additions & 0 deletions src/test/ui/const-generics/issues/issue-69654.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#![feature(const_generics)]
#![allow(incomplete_features)]

trait Bar<O> {}
impl<O> Bar<O> for [u8; O] {}
//~^ ERROR expected value, found type parameter `O`

struct Foo<const O: usize> {}
impl<const O: usize> Foo<O>
where
[u8; O]: Bar<[(); O]>,
{
fn foo() {}
}

fn main() {
Foo::foo();
}
14 changes: 14 additions & 0 deletions src/test/ui/const-generics/issues/issue-69654.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0423]: expected value, found type parameter `O`
--> $DIR/issue-69654.rs:5:25
|
LL | impl<O> Bar<O> for [u8; O] {}
| ^ help: a tuple variant with a similar name exists: `Ok`
|
::: $SRC_DIR/libcore/result.rs:LL:COL
|
LL | Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
| --------------------------------------------------- similarly named tuple variant `Ok` defined here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0423`.
5 changes: 4 additions & 1 deletion src/test/ui/nll/issue-54382-use-span-of-tail-of-block.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ LL |
LL | ;
| - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
|
= 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.
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
|
LL | D("other").next(&_thing1);
| ^

error: aborting due to previous error

Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/nll/issue-54556-niconii.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ LL | }
| `counter` dropped here while still borrowed
| ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `std::result::Result<MutexGuard<'_>, ()>`
|
= 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.
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
|
LL | if let Ok(_) = counter.lock() { };
| ^

error: aborting due to previous error

Expand Down
7 changes: 6 additions & 1 deletion src/test/ui/nll/issue-54556-stephaneyfx.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ LL | }
| `stmt` dropped here while still borrowed
| ... 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]>`
|
= 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.
= 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
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
|
LL | let x = rows.map(|row| row).next(); x
| ^^^^^^^ ^^^

error: aborting due to previous error

Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/nll/issue-54556-temps-in-tail-diagnostic.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ LL |
LL | ;
| - ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
|
= 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.
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
|
LL | D(&_thing1).end();
| ^

error: aborting due to previous error

Expand Down
Loading