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:
commit
e9b0d99259
@ -835,11 +835,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
new_temp
|
||||
}
|
||||
|
||||
fn promote_candidate(
|
||||
mut self,
|
||||
candidate: Candidate,
|
||||
next_promoted_id: usize,
|
||||
) -> Option<Body<'tcx>> {
|
||||
fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Body<'tcx> {
|
||||
let def = self.source.source.with_opt_param();
|
||||
let mut rvalue = {
|
||||
let promoted = &mut self.promoted;
|
||||
@ -938,7 +934,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
|
||||
|
||||
let span = self.promoted.span;
|
||||
self.assign(RETURN_PLACE, rvalue, span);
|
||||
Some(self.promoted)
|
||||
self.promoted
|
||||
}
|
||||
}
|
||||
|
||||
@ -1011,11 +1007,9 @@ pub fn promote_candidates<'tcx>(
|
||||
keep_original: false,
|
||||
};
|
||||
|
||||
//FIXME(oli-obk): having a `maybe_push()` method on `IndexVec` might be nice
|
||||
if let Some(mut promoted) = promoter.promote_candidate(candidate, promotions.len()) {
|
||||
promoted.source.promoted = Some(promotions.next_index());
|
||||
promotions.push(promoted);
|
||||
}
|
||||
let mut promoted = promoter.promote_candidate(candidate, promotions.len());
|
||||
promoted.source.promoted = Some(promotions.next_index());
|
||||
promotions.push(promoted);
|
||||
}
|
||||
|
||||
// Insert each of `extra_statements` before its indicated location, which
|
||||
|
@ -1,5 +1,4 @@
|
||||
use crate::def_id::{LocalDefId, CRATE_DEF_INDEX};
|
||||
use rustc_index::vec::IndexVec;
|
||||
use std::fmt;
|
||||
|
||||
/// 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 },
|
||||
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]
|
||||
}
|
||||
}
|
||||
|
@ -303,7 +303,6 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
|
||||
UNUSED_LABELS,
|
||||
UNUSED_PARENS,
|
||||
UNUSED_BRACES,
|
||||
MUST_NOT_SUSPEND,
|
||||
REDUNDANT_SEMICOLONS
|
||||
);
|
||||
|
||||
|
@ -323,6 +323,7 @@ declare_lint! {
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(must_not_suspend)]
|
||||
/// #![warn(must_not_suspend)]
|
||||
///
|
||||
/// #[must_not_suspend]
|
||||
/// struct SyncThing {}
|
||||
@ -349,8 +350,9 @@ declare_lint! {
|
||||
/// `MutexGuard`'s)
|
||||
///
|
||||
pub MUST_NOT_SUSPEND,
|
||||
Warn,
|
||||
Allow,
|
||||
"use of a `#[must_not_suspend]` value across a yield point",
|
||||
@feature_gate = rustc_span::symbol::sym::must_not_suspend;
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
|
@ -1026,7 +1026,15 @@ class RustBuild(object):
|
||||
if self.git_version >= distutils.version.LooseVersion("2.11.0"):
|
||||
update_args.append("--progress")
|
||||
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"],
|
||||
cwd=module_path, verbose=self.verbose)
|
||||
|
@ -134,9 +134,27 @@ Book][unstable-masked] and [its tracking issue][issue-masked].
|
||||
|
||||
## 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
|
||||
attributes. The `#[doc(primitive)]` attribute is used by the standard library to provide a way to generate
|
||||
documentation for primitive types, and requires `#![feature(doc_primitive)]` to enable.
|
||||
attributes. The `#[doc(primitive)]` attribute is used by the standard library to provide a way
|
||||
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
|
||||
|
||||
|
@ -13,3 +13,12 @@ rules.
|
||||
/* It requires JS to work so no need to display it in this case. */
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sub {
|
||||
/* The search bar and related controls don't work without JS */
|
||||
display: none;
|
||||
}
|
||||
|
||||
#theme-picker {
|
||||
display: none;
|
||||
}
|
||||
|
@ -255,10 +255,6 @@ details.undocumented > summary::before {
|
||||
box-shadow: 0 0 0 1px #148099,0 0 0 2px transparent;
|
||||
}
|
||||
|
||||
.search-input:disabled {
|
||||
background-color: #3e3e3e;
|
||||
}
|
||||
|
||||
.module-item .stab,
|
||||
.import-item .stab {
|
||||
color: #000;
|
||||
|
@ -219,10 +219,6 @@ details.undocumented > summary::before {
|
||||
border-color: #008dfd;
|
||||
}
|
||||
|
||||
.search-input:disabled {
|
||||
background-color: #c5c4c4;
|
||||
}
|
||||
|
||||
#crate-search + .search-input:focus {
|
||||
box-shadow: 0 0 8px 4px #078dd8;
|
||||
}
|
||||
|
@ -209,10 +209,6 @@ details.undocumented > summary::before {
|
||||
border-color: #66afe9;
|
||||
}
|
||||
|
||||
.search-input:disabled {
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
|
||||
#crate-search + .search-input:focus {
|
||||
box-shadow: 0 0 8px #078dd8;
|
||||
}
|
||||
|
@ -263,7 +263,9 @@ function hideThemeButtonState() {
|
||||
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
|
||||
// safely.
|
||||
|
@ -85,7 +85,6 @@
|
||||
<input {# -#}
|
||||
class="search-input" {# -#}
|
||||
name="search" {# -#}
|
||||
disabled {# -#}
|
||||
autocomplete="off" {# -#}
|
||||
spellcheck="false" {# -#}
|
||||
placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
|
||||
|
@ -132,12 +132,28 @@ where
|
||||
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
|
||||
intravisit::walk_expr(self, ex);
|
||||
|
||||
// Get type of function if expression is a function call
|
||||
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 {
|
||||
hir::ExprKind::Call(f, _) => {
|
||||
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) => {
|
||||
let types = tcx.typeck(ex.hir_id.owner);
|
||||
|
@ -0,0 +1,5 @@
|
||||
deps := ex
|
||||
|
||||
-include ../rustdoc-scrape-examples-multiple/scrape.mk
|
||||
|
||||
all: scrape
|
@ -0,0 +1,2 @@
|
||||
pub struct Foo([usize; foobar::f()]);
|
||||
fn main() {}
|
@ -0,0 +1 @@
|
||||
pub const fn f() -> usize { 5 }
|
@ -1,4 +1,6 @@
|
||||
// @has foobar/fn.ok.html '//*[@class="docblock scraped-example-list"]//*[@class="prev"]' ''
|
||||
// @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() {}
|
||||
|
6
src/test/rustdoc-gui/javascript-disabled.goml
Normal file
6
src/test/rustdoc-gui/javascript-disabled.goml
Normal 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"})
|
@ -1,4 +1,6 @@
|
||||
// edition:2018
|
||||
#![feature(must_not_suspend)]
|
||||
#![allow(must_not_suspend)]
|
||||
|
||||
// This tests the basic example case for the async-await-specific error.
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
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());
|
||||
| ^^^^^ future returned by `foo` is not `Send`
|
||||
|
|
||||
= 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
|
||||
--> $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();
|
||||
| - has type `MutexGuard<'_, u32>` which is not `Send`
|
||||
@ -15,7 +15,7 @@ LL | baz().await;
|
||||
LL | }
|
||||
| - `g` is later dropped here
|
||||
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) { }
|
||||
| ^^^^ required by this bound in `is_send`
|
||||
|
@ -1,4 +1,6 @@
|
||||
// edition:2018
|
||||
#![feature(must_not_suspend)]
|
||||
#![allow(must_not_suspend)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::sync::Mutex;
|
||||
|
@ -1,12 +1,12 @@
|
||||
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());
|
||||
| ^^^^^^^^^^^^^ future returned by `wrong_mutex` is not `Send`
|
||||
|
|
||||
= 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
|
||||
--> $DIR/issue-71137.rs:12:5
|
||||
--> $DIR/issue-71137.rs:14:5
|
||||
|
|
||||
LL | let mut guard = m.lock().unwrap();
|
||||
| --------- has type `MutexGuard<'_, i32>` which is not `Send`
|
||||
@ -16,7 +16,7 @@ LL | *guard += 1;
|
||||
LL | }
|
||||
| - `mut guard` is later dropped here
|
||||
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) { }
|
||||
| ^^^^ required by this bound in `fake_spawn`
|
||||
|
@ -39,6 +39,8 @@ const TEST_INTERIOR_MUT: () = {
|
||||
let _val: &'static _ = &(Cell::new(1), 2).1; //~ ERROR temporary value dropped while borrowed
|
||||
};
|
||||
|
||||
const TEST_DROP: String = String::new();
|
||||
|
||||
fn main() {
|
||||
// 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
|
||||
@ -50,4 +52,17 @@ fn main() {
|
||||
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,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
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ LL | };
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
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;
|
||||
| ---------- ^^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
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;
|
||||
| ---------- ^^^^^^^^^^^^^^^^^ 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
|
||||
|
||||
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);
|
||||
| ---------- ^^^^^ 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
|
||||
|
||||
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));
|
||||
| ---------- ^^^^^^^^^ 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
|
||||
|
||||
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);
|
||||
| ---------- ^^^^^ 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
|
||||
|
||||
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));
|
||||
| ---------- ^^^^^^^^^ creates a temporary which is freed while still in use
|
||||
| |
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
LL | let _val: &'static _ = &([1,2,3][4]+1);
|
||||
...
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
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);
|
||||
| ---------- ^^^^^^^^^^^^^^ 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: 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`.
|
||||
|
14
src/test/ui/lint/must_not_suspend/gated.rs
Normal file
14
src/test/ui/lint/must_not_suspend/gated.rs
Normal 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() {
|
||||
}
|
54
src/test/ui/lint/must_not_suspend/gated.stderr
Normal file
54
src/test/ui/lint/must_not_suspend/gated.stderr
Normal 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`.
|
19
src/test/ui/lint/must_not_suspend/issue-89562.rs
Normal file
19
src/test/ui/lint/must_not_suspend/issue-89562.rs
Normal 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() {}
|
@ -1,4 +1,5 @@
|
||||
// edition:2018
|
||||
#![feature(must_not_suspend)]
|
||||
#![deny(must_not_suspend)]
|
||||
|
||||
async fn other() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
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();
|
||||
| ^^^^^^
|
||||
@ -7,17 +7,17 @@ LL | other().await;
|
||||
| ------------- the value is held across this suspend point
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/mutex.rs:2:9
|
||||
--> $DIR/mutex.rs:3: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/mutex.rs:7:9
|
||||
--> $DIR/mutex.rs:8:9
|
||||
|
|
||||
LL | let _guard = m.lock().unwrap();
|
||||
| ^^^^^^
|
||||
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();
|
||||
| ^^^^^^
|
||||
|
@ -1,6 +1,7 @@
|
||||
// edition:2018
|
||||
// run-pass
|
||||
#![feature(must_not_suspend)]
|
||||
#![warn(must_not_suspend)]
|
||||
|
||||
#[must_not_suspend = "You gotta use Umm's, ya know?"]
|
||||
struct Umm {
|
||||
|
@ -1,19 +1,23 @@
|
||||
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 | other().await;
|
||||
| ------------- 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?
|
||||
--> $DIR/warn.rs:20:9
|
||||
--> $DIR/warn.rs:21:9
|
||||
|
|
||||
LL | let _guard = bar();
|
||||
| ^^^^^^
|
||||
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();
|
||||
| ^^^^^^
|
||||
|
Loading…
x
Reference in New Issue
Block a user