1
Fork 0

Auto merge of #90463 - matthiaskrgr:rollup-eljk9vo, r=matthiaskrgr

Rollup of 8 pull requests

Successful merges:

 - #89826 (Feature gate + make must_not_suspend allow-by-default)
 - #89929 (Handling submodule update failures more gracefully from x.py)
 - #90333 (rustdoc: remove flicker during page load)
 - #90349 (Fix rare ICE during typeck in rustdoc scrape_examples)
 - #90398 (Document `doc(keyword)` unstable attribute)
 - #90441 (Test that promotion follows references when looking for drop)
 - #90450 (Remove `rustc_hir::hir_id::HirIdVec`)
 - #90452 (Remove unnecessary `Option` from `promote_candidate` return type)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-11-01 14:00:08 +00:00
commit e9b0d99259
31 changed files with 294 additions and 123 deletions

View file

@ -835,11 +835,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
new_temp new_temp
} }
fn promote_candidate( fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Body<'tcx> {
mut self,
candidate: Candidate,
next_promoted_id: usize,
) -> Option<Body<'tcx>> {
let def = self.source.source.with_opt_param(); let def = self.source.source.with_opt_param();
let mut rvalue = { let mut rvalue = {
let promoted = &mut self.promoted; let promoted = &mut self.promoted;
@ -938,7 +934,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
let span = self.promoted.span; let span = self.promoted.span;
self.assign(RETURN_PLACE, rvalue, span); self.assign(RETURN_PLACE, rvalue, span);
Some(self.promoted) self.promoted
} }
} }
@ -1011,11 +1007,9 @@ pub fn promote_candidates<'tcx>(
keep_original: false, keep_original: false,
}; };
//FIXME(oli-obk): having a `maybe_push()` method on `IndexVec` might be nice let mut promoted = promoter.promote_candidate(candidate, promotions.len());
if let Some(mut promoted) = promoter.promote_candidate(candidate, promotions.len()) { promoted.source.promoted = Some(promotions.next_index());
promoted.source.promoted = Some(promotions.next_index()); promotions.push(promoted);
promotions.push(promoted);
}
} }
// Insert each of `extra_statements` before its indicated location, which // Insert each of `extra_statements` before its indicated location, which

View file

@ -1,5 +1,4 @@
use crate::def_id::{LocalDefId, CRATE_DEF_INDEX}; use crate::def_id::{LocalDefId, CRATE_DEF_INDEX};
use rustc_index::vec::IndexVec;
use std::fmt; use std::fmt;
/// Uniquely identifies a node in the HIR of the current crate. It is /// Uniquely identifies a node in the HIR of the current crate. It is
@ -66,70 +65,3 @@ pub const CRATE_HIR_ID: HirId = HirId {
owner: LocalDefId { local_def_index: CRATE_DEF_INDEX }, owner: LocalDefId { local_def_index: CRATE_DEF_INDEX },
local_id: ItemLocalId::from_u32(0), local_id: ItemLocalId::from_u32(0),
}; };
/// N.B. This collection is currently unused, but will be used by #72015 and future PRs.
#[derive(Clone, Default, Debug, Encodable, Decodable)]
pub struct HirIdVec<T> {
map: IndexVec<LocalDefId, IndexVec<ItemLocalId, T>>,
}
impl<T> HirIdVec<T> {
pub fn push_owner(&mut self, id: LocalDefId) {
self.map.ensure_contains_elem(id, IndexVec::new);
}
pub fn push(&mut self, id: HirId, value: T) {
if id.local_id == ItemLocalId::from_u32(0) {
self.push_owner(id.owner);
}
let submap = &mut self.map[id.owner];
let _ret_id = submap.push(value);
debug_assert_eq!(_ret_id, id.local_id);
}
pub fn push_sparse(&mut self, id: HirId, value: T)
where
T: Default,
{
self.map.ensure_contains_elem(id.owner, IndexVec::new);
let submap = &mut self.map[id.owner];
let i = id.local_id.index();
let len = submap.len();
if i >= len {
submap.extend(std::iter::repeat_with(T::default).take(i - len + 1));
}
submap[id.local_id] = value;
}
pub fn get(&self, id: HirId) -> Option<&T> {
self.map.get(id.owner)?.get(id.local_id)
}
pub fn get_owner(&self, id: LocalDefId) -> &IndexVec<ItemLocalId, T> {
&self.map[id]
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.map.iter().flat_map(|la| la.iter())
}
pub fn iter_enumerated(&self) -> impl Iterator<Item = (HirId, &T)> {
self.map.iter_enumerated().flat_map(|(owner, la)| {
la.iter_enumerated().map(move |(local_id, attr)| (HirId { owner, local_id }, attr))
})
}
}
impl<T> std::ops::Index<HirId> for HirIdVec<T> {
type Output = T;
fn index(&self, id: HirId) -> &T {
&self.map[id.owner][id.local_id]
}
}
impl<T> std::ops::IndexMut<HirId> for HirIdVec<T> {
fn index_mut(&mut self, id: HirId) -> &mut T {
&mut self.map[id.owner][id.local_id]
}
}

View file

@ -303,7 +303,6 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
UNUSED_LABELS, UNUSED_LABELS,
UNUSED_PARENS, UNUSED_PARENS,
UNUSED_BRACES, UNUSED_BRACES,
MUST_NOT_SUSPEND,
REDUNDANT_SEMICOLONS REDUNDANT_SEMICOLONS
); );

View file

@ -323,6 +323,7 @@ declare_lint! {
/// ///
/// ```rust /// ```rust
/// #![feature(must_not_suspend)] /// #![feature(must_not_suspend)]
/// #![warn(must_not_suspend)]
/// ///
/// #[must_not_suspend] /// #[must_not_suspend]
/// struct SyncThing {} /// struct SyncThing {}
@ -349,8 +350,9 @@ declare_lint! {
/// `MutexGuard`'s) /// `MutexGuard`'s)
/// ///
pub MUST_NOT_SUSPEND, pub MUST_NOT_SUSPEND,
Warn, Allow,
"use of a `#[must_not_suspend]` value across a yield point", "use of a `#[must_not_suspend]` value across a yield point",
@feature_gate = rustc_span::symbol::sym::must_not_suspend;
} }
declare_lint! { declare_lint! {

View file

@ -1026,7 +1026,15 @@ class RustBuild(object):
if self.git_version >= distutils.version.LooseVersion("2.11.0"): if self.git_version >= distutils.version.LooseVersion("2.11.0"):
update_args.append("--progress") update_args.append("--progress")
update_args.append(module) update_args.append(module)
run(update_args, cwd=self.rust_root, verbose=self.verbose, exception=True) try:
run(update_args, cwd=self.rust_root, verbose=self.verbose, exception=True)
except RuntimeError:
print("Failed updating submodule. This is probably due to uncommitted local changes.")
print('Either stash the changes by running "git stash" within the submodule\'s')
print('directory, reset them by running "git reset --hard", or commit them.')
print("To reset all submodules' changes run", end=" ")
print('"git submodule foreach --recursive git reset --hard".')
raise SystemExit(1)
run(["git", "reset", "-q", "--hard"], run(["git", "reset", "-q", "--hard"],
cwd=module_path, verbose=self.verbose) cwd=module_path, verbose=self.verbose)

View file

@ -134,9 +134,27 @@ Book][unstable-masked] and [its tracking issue][issue-masked].
## Document primitives ## Document primitives
This is for Rust compiler internal use only.
Since primitive types are defined in the compiler, there's no place to attach documentation Since primitive types are defined in the compiler, there's no place to attach documentation
attributes. The `#[doc(primitive)]` attribute is used by the standard library to provide a way to generate attributes. The `#[doc(primitive)]` attribute is used by the standard library to provide a way
documentation for primitive types, and requires `#![feature(doc_primitive)]` to enable. to generate documentation for primitive types, and requires `#![feature(doc_primitive)]` to enable.
## Document keywords
This is for Rust compiler internal use only.
Rust keywords are documented in the standard library (look for `match` for example).
To do so, the `#[doc(keyword = "...")]` attribute is used. Example:
```rust
#![feature(doc_keyword)]
/// Some documentation about the keyword.
#[doc(keyword = "keyword")]
mod empty_mod {}
```
## Unstable command-line arguments ## Unstable command-line arguments

View file

@ -13,3 +13,12 @@ rules.
/* It requires JS to work so no need to display it in this case. */ /* It requires JS to work so no need to display it in this case. */
display: none; display: none;
} }
.sub {
/* The search bar and related controls don't work without JS */
display: none;
}
#theme-picker {
display: none;
}

View file

@ -255,10 +255,6 @@ details.undocumented > summary::before {
box-shadow: 0 0 0 1px #148099,0 0 0 2px transparent; box-shadow: 0 0 0 1px #148099,0 0 0 2px transparent;
} }
.search-input:disabled {
background-color: #3e3e3e;
}
.module-item .stab, .module-item .stab,
.import-item .stab { .import-item .stab {
color: #000; color: #000;

View file

@ -219,10 +219,6 @@ details.undocumented > summary::before {
border-color: #008dfd; border-color: #008dfd;
} }
.search-input:disabled {
background-color: #c5c4c4;
}
#crate-search + .search-input:focus { #crate-search + .search-input:focus {
box-shadow: 0 0 8px 4px #078dd8; box-shadow: 0 0 8px 4px #078dd8;
} }

View file

@ -209,10 +209,6 @@ details.undocumented > summary::before {
border-color: #66afe9; border-color: #66afe9;
} }
.search-input:disabled {
background-color: #e6e6e6;
}
#crate-search + .search-input:focus { #crate-search + .search-input:focus {
box-shadow: 0 0 8px #078dd8; box-shadow: 0 0 8px #078dd8;
} }

View file

@ -263,7 +263,9 @@ function hideThemeButtonState() {
search_input.placeholder = searchState.input.origPlaceholder; search_input.placeholder = searchState.input.origPlaceholder;
}); });
search_input.removeAttribute('disabled'); if (search_input.value != '') {
loadSearch();
}
// `crates{version}.js` should always be loaded before this script, so we can use it // `crates{version}.js` should always be loaded before this script, so we can use it
// safely. // safely.

View file

@ -85,7 +85,6 @@
<input {# -#} <input {# -#}
class="search-input" {# -#} class="search-input" {# -#}
name="search" {# -#} name="search" {# -#}
disabled {# -#}
autocomplete="off" {# -#} autocomplete="off" {# -#}
spellcheck="false" {# -#} spellcheck="false" {# -#}
placeholder="Click or press S to search, ? for more options…" {# -#} placeholder="Click or press S to search, ? for more options…" {# -#}

View file

@ -132,12 +132,28 @@ where
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
intravisit::walk_expr(self, ex); intravisit::walk_expr(self, ex);
// Get type of function if expression is a function call
let tcx = self.tcx; let tcx = self.tcx;
// If we visit an item that contains an expression outside a function body,
// then we need to exit before calling typeck (which will panic). See
// test/run-make/rustdoc-scrape-examples-invalid-expr for an example.
let hir = tcx.hir();
let owner = hir.local_def_id_to_hir_id(ex.hir_id.owner);
if hir.maybe_body_owned_by(owner).is_none() {
return;
}
// Get type of function if expression is a function call
let (ty, span) = match ex.kind { let (ty, span) = match ex.kind {
hir::ExprKind::Call(f, _) => { hir::ExprKind::Call(f, _) => {
let types = tcx.typeck(ex.hir_id.owner); let types = tcx.typeck(ex.hir_id.owner);
(types.node_type(f.hir_id), ex.span)
match types.node_type_opt(f.hir_id) {
Some(ty) => (ty, ex.span),
None => {
return;
}
}
} }
hir::ExprKind::MethodCall(_, _, _, span) => { hir::ExprKind::MethodCall(_, _, _, span) => {
let types = tcx.typeck(ex.hir_id.owner); let types = tcx.typeck(ex.hir_id.owner);

View file

@ -0,0 +1,5 @@
deps := ex
-include ../rustdoc-scrape-examples-multiple/scrape.mk
all: scrape

View file

@ -0,0 +1,2 @@
pub struct Foo([usize; foobar::f()]);
fn main() {}

View file

@ -0,0 +1 @@
pub const fn f() -> usize { 5 }

View file

@ -1,4 +1,6 @@
// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]//*[@class="prev"]' '' // @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]//*[@class="prev"]' ''
// @has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' '' // @has foobar/fn.ok.html '//*[@class="more-scraped-examples"]' ''
// @has src/ex/ex.rs.html
// @has foobar/fn.ok.html '//a[@href="../src/ex/ex.rs.html#2"]' ''
pub fn ok() {} pub fn ok() {}

View file

@ -0,0 +1,6 @@
// When JavaScript is disabled, we hide the search bar, because it
// can't be used without JS.
javascript: false
goto: file://|DOC_PATH|/test_docs/struct.Foo.html
assert-css: (".sub", {"display": "none"})

View file

@ -1,4 +1,6 @@
// edition:2018 // edition:2018
#![feature(must_not_suspend)]
#![allow(must_not_suspend)]
// This tests the basic example case for the async-await-specific error. // This tests the basic example case for the async-await-specific error.

View file

@ -1,12 +1,12 @@
error: future cannot be sent between threads safely error: future cannot be sent between threads safely
--> $DIR/issue-64130-non-send-future-diags.rs:21:13 --> $DIR/issue-64130-non-send-future-diags.rs:23:13
| |
LL | is_send(foo()); LL | is_send(foo());
| ^^^^^ future returned by `foo` is not `Send` | ^^^^^ future returned by `foo` is not `Send`
| |
= help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, u32>` = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, u32>`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-64130-non-send-future-diags.rs:15:5 --> $DIR/issue-64130-non-send-future-diags.rs:17:5
| |
LL | let g = x.lock().unwrap(); LL | let g = x.lock().unwrap();
| - has type `MutexGuard<'_, u32>` which is not `Send` | - has type `MutexGuard<'_, u32>` which is not `Send`
@ -15,7 +15,7 @@ LL | baz().await;
LL | } LL | }
| - `g` is later dropped here | - `g` is later dropped here
note: required by a bound in `is_send` note: required by a bound in `is_send`
--> $DIR/issue-64130-non-send-future-diags.rs:7:15 --> $DIR/issue-64130-non-send-future-diags.rs:9:15
| |
LL | fn is_send<T: Send>(t: T) { } LL | fn is_send<T: Send>(t: T) { }
| ^^^^ required by this bound in `is_send` | ^^^^ required by this bound in `is_send`

View file

@ -1,4 +1,6 @@
// edition:2018 // edition:2018
#![feature(must_not_suspend)]
#![allow(must_not_suspend)]
use std::future::Future; use std::future::Future;
use std::sync::Mutex; use std::sync::Mutex;

View file

@ -1,12 +1,12 @@
error: future cannot be sent between threads safely error: future cannot be sent between threads safely
--> $DIR/issue-71137.rs:20:14 --> $DIR/issue-71137.rs:22:14
| |
LL | fake_spawn(wrong_mutex()); LL | fake_spawn(wrong_mutex());
| ^^^^^^^^^^^^^ future returned by `wrong_mutex` is not `Send` | ^^^^^^^^^^^^^ future returned by `wrong_mutex` is not `Send`
| |
= help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, i32>` = help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, i32>`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-71137.rs:12:5 --> $DIR/issue-71137.rs:14:5
| |
LL | let mut guard = m.lock().unwrap(); LL | let mut guard = m.lock().unwrap();
| --------- has type `MutexGuard<'_, i32>` which is not `Send` | --------- has type `MutexGuard<'_, i32>` which is not `Send`
@ -16,7 +16,7 @@ LL | *guard += 1;
LL | } LL | }
| - `mut guard` is later dropped here | - `mut guard` is later dropped here
note: required by a bound in `fake_spawn` note: required by a bound in `fake_spawn`
--> $DIR/issue-71137.rs:6:27 --> $DIR/issue-71137.rs:8:27
| |
LL | fn fake_spawn<F: Future + Send + 'static>(f: F) { } LL | fn fake_spawn<F: Future + Send + 'static>(f: F) { }
| ^^^^ required by this bound in `fake_spawn` | ^^^^ required by this bound in `fake_spawn`

View file

@ -39,6 +39,8 @@ const TEST_INTERIOR_MUT: () = {
let _val: &'static _ = &(Cell::new(1), 2).1; //~ ERROR temporary value dropped while borrowed let _val: &'static _ = &(Cell::new(1), 2).1; //~ ERROR temporary value dropped while borrowed
}; };
const TEST_DROP: String = String::new();
fn main() { fn main() {
// We must not promote things with interior mutability. Not even if we "project it away". // We must not promote things with interior mutability. Not even if we "project it away".
let _val: &'static _ = &(Cell::new(1), 2).0; //~ ERROR temporary value dropped while borrowed let _val: &'static _ = &(Cell::new(1), 2).0; //~ ERROR temporary value dropped while borrowed
@ -50,4 +52,17 @@ fn main() {
let _val: &'static _ = &(1%0); //~ ERROR temporary value dropped while borrowed let _val: &'static _ = &(1%0); //~ ERROR temporary value dropped while borrowed
let _val: &'static _ = &(1%(1-1)); //~ ERROR temporary value dropped while borrowed let _val: &'static _ = &(1%(1-1)); //~ ERROR temporary value dropped while borrowed
let _val: &'static _ = &([1,2,3][4]+1); //~ ERROR temporary value dropped while borrowed let _val: &'static _ = &([1,2,3][4]+1); //~ ERROR temporary value dropped while borrowed
// No promotion of temporaries that need to be dropped.
let _val: &'static _ = &TEST_DROP;
//~^ ERROR temporary value dropped while borrowed
let _val: &'static _ = &&TEST_DROP;
//~^ ERROR temporary value dropped while borrowed
//~| ERROR temporary value dropped while borrowed
let _val: &'static _ = &(&TEST_DROP,);
//~^ ERROR temporary value dropped while borrowed
//~| ERROR temporary value dropped while borrowed
let _val: &'static _ = &[&TEST_DROP; 1];
//~^ ERROR temporary value dropped while borrowed
//~| ERROR temporary value dropped while borrowed
} }

View file

@ -59,7 +59,7 @@ LL | };
| - temporary value is freed at the end of this statement | - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:44:29 --> $DIR/promote-not.rs:46:29
| |
LL | let _val: &'static _ = &(Cell::new(1), 2).0; LL | let _val: &'static _ = &(Cell::new(1), 2).0;
| ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
@ -70,7 +70,7 @@ LL | }
| - temporary value is freed at the end of this statement | - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:45:29 --> $DIR/promote-not.rs:47:29
| |
LL | let _val: &'static _ = &(Cell::new(1), 2).1; LL | let _val: &'static _ = &(Cell::new(1), 2).1;
| ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
@ -81,7 +81,7 @@ LL | }
| - temporary value is freed at the end of this statement | - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:48:29 --> $DIR/promote-not.rs:50:29
| |
LL | let _val: &'static _ = &(1/0); LL | let _val: &'static _ = &(1/0);
| ---------- ^^^^^ creates a temporary which is freed while still in use | ---------- ^^^^^ creates a temporary which is freed while still in use
@ -92,7 +92,7 @@ LL | }
| - temporary value is freed at the end of this statement | - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:49:29 --> $DIR/promote-not.rs:51:29
| |
LL | let _val: &'static _ = &(1/(1-1)); LL | let _val: &'static _ = &(1/(1-1));
| ---------- ^^^^^^^^^ creates a temporary which is freed while still in use | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
@ -103,7 +103,7 @@ LL | }
| - temporary value is freed at the end of this statement | - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:50:29 --> $DIR/promote-not.rs:52:29
| |
LL | let _val: &'static _ = &(1%0); LL | let _val: &'static _ = &(1%0);
| ---------- ^^^^^ creates a temporary which is freed while still in use | ---------- ^^^^^ creates a temporary which is freed while still in use
@ -114,26 +114,102 @@ LL | }
| - temporary value is freed at the end of this statement | - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:51:29 --> $DIR/promote-not.rs:53:29
| |
LL | let _val: &'static _ = &(1%(1-1)); LL | let _val: &'static _ = &(1%(1-1));
| ---------- ^^^^^^^^^ creates a temporary which is freed while still in use | ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
| | | |
| type annotation requires that borrow lasts for `'static` | type annotation requires that borrow lasts for `'static`
LL | let _val: &'static _ = &([1,2,3][4]+1); ...
LL | } LL | }
| - temporary value is freed at the end of this statement | - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:52:29 --> $DIR/promote-not.rs:54:29
| |
LL | let _val: &'static _ = &([1,2,3][4]+1); LL | let _val: &'static _ = &([1,2,3][4]+1);
| ---------- ^^^^^^^^^^^^^^ creates a temporary which is freed while still in use | ---------- ^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
| | | |
| type annotation requires that borrow lasts for `'static` | type annotation requires that borrow lasts for `'static`
...
LL | } LL | }
| - temporary value is freed at the end of this statement | - temporary value is freed at the end of this statement
error: aborting due to 13 previous errors error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:57:29
|
LL | let _val: &'static _ = &TEST_DROP;
| ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
LL | }
| - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:59:29
|
LL | let _val: &'static _ = &&TEST_DROP;
| ---------- ^^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
LL | }
| - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:59:30
|
LL | let _val: &'static _ = &&TEST_DROP;
| ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
LL | }
| - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:62:29
|
LL | let _val: &'static _ = &(&TEST_DROP,);
| ---------- ^^^^^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
LL | }
| - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:62:31
|
LL | let _val: &'static _ = &(&TEST_DROP,);
| ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
LL | }
| - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:65:29
|
LL | let _val: &'static _ = &[&TEST_DROP; 1];
| ---------- ^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'static`
...
LL | }
| - temporary value is freed at the end of this statement
error[E0716]: temporary value dropped while borrowed
--> $DIR/promote-not.rs:65:31
|
LL | let _val: &'static _ = &[&TEST_DROP; 1];
| ---------- ^^^^^^^^^ - temporary value is freed at the end of this statement
| | |
| | creates a temporary which is freed while still in use
| type annotation requires that borrow lasts for `'static`
error: aborting due to 20 previous errors
For more information about this error, try `rustc --explain E0716`. For more information about this error, try `rustc --explain E0716`.

View file

@ -0,0 +1,14 @@
// edition:2018
#![deny(must_not_suspend)] //~ ERROR the `must_not_suspend`
//~| ERROR the `must_not_suspend`
//~| ERROR the `must_not_suspend`
async fn other() {}
pub async fn uhoh(m: std::sync::Mutex<()>) {
let _guard = m.lock().unwrap(); //~ ERROR `MutexGuard` held across
other().await;
}
fn main() {
}

View file

@ -0,0 +1,54 @@
error[E0658]: the `must_not_suspend` lint is unstable
--> $DIR/gated.rs:2:1
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
= help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
error[E0658]: the `must_not_suspend` lint is unstable
--> $DIR/gated.rs:2:1
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
= help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
error[E0658]: the `must_not_suspend` lint is unstable
--> $DIR/gated.rs:2:1
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information
= help: add `#![feature(must_not_suspend)]` to the crate attributes to enable
error: `MutexGuard` held across a suspend point, but should not be
--> $DIR/gated.rs:9:9
|
LL | let _guard = m.lock().unwrap();
| ^^^^^^
LL | other().await;
| ------------- the value is held across this suspend point
|
note: the lint level is defined here
--> $DIR/gated.rs:2:9
|
LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^
note: holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send`
--> $DIR/gated.rs:9:9
|
LL | let _guard = m.lock().unwrap();
| ^^^^^^
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
--> $DIR/gated.rs:9:9
|
LL | let _guard = m.lock().unwrap();
| ^^^^^^
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0658`.

View file

@ -0,0 +1,19 @@
// edition:2018
// run-pass
use std::sync::Mutex;
// Copied from the issue. Allow-by-default for now, so run-pass
pub async fn foo() {
let foo = Mutex::new(1);
let lock = foo.lock().unwrap();
// Prevent mutex lock being held across `.await` point.
drop(lock);
bar().await;
}
async fn bar() {}
fn main() {}

View file

@ -1,4 +1,5 @@
// edition:2018 // edition:2018
#![feature(must_not_suspend)]
#![deny(must_not_suspend)] #![deny(must_not_suspend)]
async fn other() {} async fn other() {}

View file

@ -1,5 +1,5 @@
error: `MutexGuard` held across a suspend point, but should not be error: `MutexGuard` held across a suspend point, but should not be
--> $DIR/mutex.rs:7:9 --> $DIR/mutex.rs:8:9
| |
LL | let _guard = m.lock().unwrap(); LL | let _guard = m.lock().unwrap();
| ^^^^^^ | ^^^^^^
@ -7,17 +7,17 @@ LL | other().await;
| ------------- the value is held across this suspend point | ------------- the value is held across this suspend point
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/mutex.rs:2:9 --> $DIR/mutex.rs:3:9
| |
LL | #![deny(must_not_suspend)] LL | #![deny(must_not_suspend)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
note: holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send` note: holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send`
--> $DIR/mutex.rs:7:9 --> $DIR/mutex.rs:8:9
| |
LL | let _guard = m.lock().unwrap(); LL | let _guard = m.lock().unwrap();
| ^^^^^^ | ^^^^^^
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
--> $DIR/mutex.rs:7:9 --> $DIR/mutex.rs:8:9
| |
LL | let _guard = m.lock().unwrap(); LL | let _guard = m.lock().unwrap();
| ^^^^^^ | ^^^^^^

View file

@ -1,6 +1,7 @@
// edition:2018 // edition:2018
// run-pass // run-pass
#![feature(must_not_suspend)] #![feature(must_not_suspend)]
#![warn(must_not_suspend)]
#[must_not_suspend = "You gotta use Umm's, ya know?"] #[must_not_suspend = "You gotta use Umm's, ya know?"]
struct Umm { struct Umm {

View file

@ -1,19 +1,23 @@
warning: `Umm` held across a suspend point, but should not be warning: `Umm` held across a suspend point, but should not be
--> $DIR/warn.rs:20:9 --> $DIR/warn.rs:21:9
| |
LL | let _guard = bar(); LL | let _guard = bar();
| ^^^^^^ | ^^^^^^
LL | other().await; LL | other().await;
| ------------- the value is held across this suspend point | ------------- the value is held across this suspend point
| |
= note: `#[warn(must_not_suspend)]` on by default note: the lint level is defined here
--> $DIR/warn.rs:4:9
|
LL | #![warn(must_not_suspend)]
| ^^^^^^^^^^^^^^^^
note: You gotta use Umm's, ya know? note: You gotta use Umm's, ya know?
--> $DIR/warn.rs:20:9 --> $DIR/warn.rs:21:9
| |
LL | let _guard = bar(); LL | let _guard = bar();
| ^^^^^^ | ^^^^^^
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
--> $DIR/warn.rs:20:9 --> $DIR/warn.rs:21:9
| |
LL | let _guard = bar(); LL | let _guard = bar();
| ^^^^^^ | ^^^^^^