Auto merge of #118433 - matthiaskrgr:rollup-fi9lrwg, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #116839 (Implement thread parking for xous) - #118265 (remove the memcpy-on-equal-ptrs assumption) - #118269 (Unify `TraitRefs` and `PolyTraitRefs` in `ValuePairs`) - #118394 (Remove HIR opkinds) - #118398 (Add proper cfgs in std) - #118419 (Eagerly return `ExprKind::Err` on `yield`/`await` in wrong coroutine context) - #118422 (Fix coroutine validation for mixed panic strategy) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
ec1f21cb04
@ -817,7 +817,7 @@ pub enum BorrowKind {
|
|||||||
Raw,
|
Raw,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
|
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
||||||
pub enum BinOpKind {
|
pub enum BinOpKind {
|
||||||
/// The `+` operator (addition)
|
/// The `+` operator (addition)
|
||||||
Add,
|
Add,
|
||||||
@ -858,9 +858,9 @@ pub enum BinOpKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BinOpKind {
|
impl BinOpKind {
|
||||||
pub fn to_string(&self) -> &'static str {
|
pub fn as_str(&self) -> &'static str {
|
||||||
use BinOpKind::*;
|
use BinOpKind::*;
|
||||||
match *self {
|
match self {
|
||||||
Add => "+",
|
Add => "+",
|
||||||
Sub => "-",
|
Sub => "-",
|
||||||
Mul => "*",
|
Mul => "*",
|
||||||
@ -881,19 +881,25 @@ pub fn to_string(&self) -> &'static str {
|
|||||||
Gt => ">",
|
Gt => ">",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn lazy(&self) -> bool {
|
|
||||||
|
pub fn is_lazy(&self) -> bool {
|
||||||
matches!(self, BinOpKind::And | BinOpKind::Or)
|
matches!(self, BinOpKind::And | BinOpKind::Or)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_comparison(&self) -> bool {
|
pub fn is_comparison(&self) -> bool {
|
||||||
use BinOpKind::*;
|
use BinOpKind::*;
|
||||||
// Note for developers: please keep this as is;
|
// Note for developers: please keep this match exhaustive;
|
||||||
// we want compilation to fail if another variant is added.
|
// we want compilation to fail if another variant is added.
|
||||||
match *self {
|
match *self {
|
||||||
Eq | Lt | Le | Ne | Gt | Ge => true,
|
Eq | Lt | Le | Ne | Gt | Ge => true,
|
||||||
And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
|
And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the binary operator takes its arguments by value.
|
||||||
|
pub fn is_by_value(self) -> bool {
|
||||||
|
!self.is_comparison()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BinOp = Spanned<BinOpKind>;
|
pub type BinOp = Spanned<BinOpKind>;
|
||||||
@ -901,7 +907,7 @@ pub fn is_comparison(&self) -> bool {
|
|||||||
/// Unary operator.
|
/// Unary operator.
|
||||||
///
|
///
|
||||||
/// Note that `&data` is not an operator, it's an `AddrOf` expression.
|
/// Note that `&data` is not an operator, it's an `AddrOf` expression.
|
||||||
#[derive(Clone, Encodable, Decodable, Debug, Copy)]
|
#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
|
||||||
pub enum UnOp {
|
pub enum UnOp {
|
||||||
/// The `*` operator for dereferencing
|
/// The `*` operator for dereferencing
|
||||||
Deref,
|
Deref,
|
||||||
@ -912,13 +918,18 @@ pub enum UnOp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UnOp {
|
impl UnOp {
|
||||||
pub fn to_string(op: UnOp) -> &'static str {
|
pub fn as_str(&self) -> &'static str {
|
||||||
match op {
|
match self {
|
||||||
UnOp::Deref => "*",
|
UnOp::Deref => "*",
|
||||||
UnOp::Not => "!",
|
UnOp::Not => "!",
|
||||||
UnOp::Neg => "-",
|
UnOp::Neg => "-",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the unary operator takes its argument by value.
|
||||||
|
pub fn is_by_value(self) -> bool {
|
||||||
|
matches!(self, Self::Neg | Self::Not)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A statement
|
/// A statement
|
||||||
|
@ -72,7 +72,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
|||||||
let kind = match &e.kind {
|
let kind = match &e.kind {
|
||||||
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
|
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
|
||||||
ExprKind::ConstBlock(c) => {
|
ExprKind::ConstBlock(c) => {
|
||||||
let c = self.with_new_scopes(|this| hir::ConstBlock {
|
let c = self.with_new_scopes(c.value.span, |this| hir::ConstBlock {
|
||||||
def_id: this.local_def_id(c.id),
|
def_id: this.local_def_id(c.id),
|
||||||
hir_id: this.lower_node_id(c.id),
|
hir_id: this.lower_node_id(c.id),
|
||||||
body: this.lower_const_body(c.value.span, Some(&c.value)),
|
body: this.lower_const_body(c.value.span, Some(&c.value)),
|
||||||
@ -189,7 +189,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
|||||||
None,
|
None,
|
||||||
e.span,
|
e.span,
|
||||||
hir::CoroutineSource::Block,
|
hir::CoroutineSource::Block,
|
||||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
|this| this.with_new_scopes(e.span, |this| this.lower_block_expr(block)),
|
||||||
),
|
),
|
||||||
ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr),
|
ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr),
|
||||||
ExprKind::Closure(box Closure {
|
ExprKind::Closure(box Closure {
|
||||||
@ -323,7 +323,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
|
|||||||
None,
|
None,
|
||||||
e.span,
|
e.span,
|
||||||
hir::CoroutineSource::Block,
|
hir::CoroutineSource::Block,
|
||||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
|this| this.with_new_scopes(e.span, |this| this.lower_block_expr(block)),
|
||||||
),
|
),
|
||||||
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
|
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
|
||||||
ExprKind::Err => hir::ExprKind::Err(
|
ExprKind::Err => hir::ExprKind::Err(
|
||||||
@ -350,30 +350,8 @@ fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
|
fn lower_binop(&mut self, b: BinOp) -> BinOp {
|
||||||
Spanned {
|
Spanned { node: b.node, span: self.lower_span(b.span) }
|
||||||
node: match b.node {
|
|
||||||
BinOpKind::Add => hir::BinOpKind::Add,
|
|
||||||
BinOpKind::Sub => hir::BinOpKind::Sub,
|
|
||||||
BinOpKind::Mul => hir::BinOpKind::Mul,
|
|
||||||
BinOpKind::Div => hir::BinOpKind::Div,
|
|
||||||
BinOpKind::Rem => hir::BinOpKind::Rem,
|
|
||||||
BinOpKind::And => hir::BinOpKind::And,
|
|
||||||
BinOpKind::Or => hir::BinOpKind::Or,
|
|
||||||
BinOpKind::BitXor => hir::BinOpKind::BitXor,
|
|
||||||
BinOpKind::BitAnd => hir::BinOpKind::BitAnd,
|
|
||||||
BinOpKind::BitOr => hir::BinOpKind::BitOr,
|
|
||||||
BinOpKind::Shl => hir::BinOpKind::Shl,
|
|
||||||
BinOpKind::Shr => hir::BinOpKind::Shr,
|
|
||||||
BinOpKind::Eq => hir::BinOpKind::Eq,
|
|
||||||
BinOpKind::Lt => hir::BinOpKind::Lt,
|
|
||||||
BinOpKind::Le => hir::BinOpKind::Le,
|
|
||||||
BinOpKind::Ne => hir::BinOpKind::Ne,
|
|
||||||
BinOpKind::Ge => hir::BinOpKind::Ge,
|
|
||||||
BinOpKind::Gt => hir::BinOpKind::Gt,
|
|
||||||
},
|
|
||||||
span: self.lower_span(b.span),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_legacy_const_generics(
|
fn lower_legacy_const_generics(
|
||||||
@ -781,10 +759,10 @@ fn lower_expr_await(&mut self, await_kw_span: Span, expr: &Expr) -> hir::ExprKin
|
|||||||
match self.coroutine_kind {
|
match self.coroutine_kind {
|
||||||
Some(hir::CoroutineKind::Async(_)) => {}
|
Some(hir::CoroutineKind::Async(_)) => {}
|
||||||
Some(hir::CoroutineKind::Coroutine) | Some(hir::CoroutineKind::Gen(_)) | None => {
|
Some(hir::CoroutineKind::Coroutine) | Some(hir::CoroutineKind::Gen(_)) | None => {
|
||||||
self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
|
return hir::ExprKind::Err(self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
|
||||||
await_kw_span,
|
await_kw_span,
|
||||||
item_span: self.current_item,
|
item_span: self.current_item,
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, None);
|
let span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, None);
|
||||||
@ -944,9 +922,7 @@ fn lower_expr_closure(
|
|||||||
) -> hir::ExprKind<'hir> {
|
) -> hir::ExprKind<'hir> {
|
||||||
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
|
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
|
||||||
|
|
||||||
let (body_id, coroutine_option) = self.with_new_scopes(move |this| {
|
let (body_id, coroutine_option) = self.with_new_scopes(fn_decl_span, move |this| {
|
||||||
let prev = this.current_item;
|
|
||||||
this.current_item = Some(fn_decl_span);
|
|
||||||
let mut coroutine_kind = None;
|
let mut coroutine_kind = None;
|
||||||
let body_id = this.lower_fn_body(decl, |this| {
|
let body_id = this.lower_fn_body(decl, |this| {
|
||||||
let e = this.lower_expr_mut(body);
|
let e = this.lower_expr_mut(body);
|
||||||
@ -955,7 +931,6 @@ fn lower_expr_closure(
|
|||||||
});
|
});
|
||||||
let coroutine_option =
|
let coroutine_option =
|
||||||
this.coroutine_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability);
|
this.coroutine_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability);
|
||||||
this.current_item = prev;
|
|
||||||
(body_id, coroutine_option)
|
(body_id, coroutine_option)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1041,7 +1016,7 @@ fn lower_expr_async_closure(
|
|||||||
let outer_decl =
|
let outer_decl =
|
||||||
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
|
FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
|
||||||
|
|
||||||
let body = self.with_new_scopes(|this| {
|
let body = self.with_new_scopes(fn_decl_span, |this| {
|
||||||
// FIXME(cramertj): allow `async` non-`move` closures with arguments.
|
// FIXME(cramertj): allow `async` non-`move` closures with arguments.
|
||||||
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
|
if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
|
||||||
this.tcx.sess.emit_err(AsyncNonMoveClosureNotSupported { fn_decl_span });
|
this.tcx.sess.emit_err(AsyncNonMoveClosureNotSupported { fn_decl_span });
|
||||||
@ -1063,7 +1038,7 @@ fn lower_expr_async_closure(
|
|||||||
async_ret_ty,
|
async_ret_ty,
|
||||||
body.span,
|
body.span,
|
||||||
hir::CoroutineSource::Closure,
|
hir::CoroutineSource::Closure,
|
||||||
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
|
|this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)),
|
||||||
);
|
);
|
||||||
let hir_id = this.lower_node_id(inner_closure_id);
|
let hir_id = this.lower_node_id(inner_closure_id);
|
||||||
this.maybe_forward_track_caller(body.span, closure_hir_id, hir_id);
|
this.maybe_forward_track_caller(body.span, closure_hir_id, hir_id);
|
||||||
@ -1503,7 +1478,9 @@ fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::Expr
|
|||||||
match self.coroutine_kind {
|
match self.coroutine_kind {
|
||||||
Some(hir::CoroutineKind::Gen(_)) => {}
|
Some(hir::CoroutineKind::Gen(_)) => {}
|
||||||
Some(hir::CoroutineKind::Async(_)) => {
|
Some(hir::CoroutineKind::Async(_)) => {
|
||||||
self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span });
|
return hir::ExprKind::Err(
|
||||||
|
self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span }),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Some(hir::CoroutineKind::Coroutine) | None => {
|
Some(hir::CoroutineKind::Coroutine) | None => {
|
||||||
if !self.tcx.features().coroutines {
|
if !self.tcx.features().coroutines {
|
||||||
|
@ -202,9 +202,7 @@ fn lower_item_kind(
|
|||||||
body,
|
body,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
self.with_new_scopes(|this| {
|
self.with_new_scopes(ident.span, |this| {
|
||||||
this.current_item = Some(ident.span);
|
|
||||||
|
|
||||||
// Note: we don't need to change the return type from `T` to
|
// Note: we don't need to change the return type from `T` to
|
||||||
// `impl Future<Output = T>` here because lower_body
|
// `impl Future<Output = T>` here because lower_body
|
||||||
// only cares about the input argument patterns in the function
|
// only cares about the input argument patterns in the function
|
||||||
@ -837,7 +835,6 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
|
AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
|
||||||
self.current_item = Some(i.span);
|
|
||||||
let asyncness = sig.header.asyncness;
|
let asyncness = sig.header.asyncness;
|
||||||
let body_id = self.lower_maybe_async_body(
|
let body_id = self.lower_maybe_async_body(
|
||||||
i.span,
|
i.span,
|
||||||
|
@ -878,7 +878,10 @@ fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_new_scopes<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
|
fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {
|
||||||
|
let current_item = self.current_item;
|
||||||
|
self.current_item = Some(scope_span);
|
||||||
|
|
||||||
let was_in_loop_condition = self.is_in_loop_condition;
|
let was_in_loop_condition = self.is_in_loop_condition;
|
||||||
self.is_in_loop_condition = false;
|
self.is_in_loop_condition = false;
|
||||||
|
|
||||||
@ -890,6 +893,8 @@ fn with_new_scopes<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
|
|||||||
|
|
||||||
self.is_in_loop_condition = was_in_loop_condition;
|
self.is_in_loop_condition = was_in_loop_condition;
|
||||||
|
|
||||||
|
self.current_item = current_item;
|
||||||
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1239,7 +1244,7 @@ fn lower_generic_arg(
|
|||||||
tokens: None,
|
tokens: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ct = self.with_new_scopes(|this| hir::AnonConst {
|
let ct = self.with_new_scopes(span, |this| hir::AnonConst {
|
||||||
def_id,
|
def_id,
|
||||||
hir_id: this.lower_node_id(node_id),
|
hir_id: this.lower_node_id(node_id),
|
||||||
body: this.lower_const_body(path_expr.span, Some(&path_expr)),
|
body: this.lower_const_body(path_expr.span, Some(&path_expr)),
|
||||||
@ -2246,7 +2251,7 @@ fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
|
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
|
||||||
self.with_new_scopes(|this| hir::AnonConst {
|
self.with_new_scopes(c.value.span, |this| hir::AnonConst {
|
||||||
def_id: this.local_def_id(c.id),
|
def_id: this.local_def_id(c.id),
|
||||||
hir_id: this.lower_node_id(c.id),
|
hir_id: this.lower_node_id(c.id),
|
||||||
body: this.lower_const_body(c.value.span, Some(&c.value)),
|
body: this.lower_const_body(c.value.span, Some(&c.value)),
|
||||||
|
@ -255,12 +255,12 @@ fn print_expr_binary(&mut self, op: ast::BinOp, lhs: &ast::Expr, rhs: &ast::Expr
|
|||||||
|
|
||||||
self.print_expr_maybe_paren(lhs, left_prec);
|
self.print_expr_maybe_paren(lhs, left_prec);
|
||||||
self.space();
|
self.space();
|
||||||
self.word_space(op.node.to_string());
|
self.word_space(op.node.as_str());
|
||||||
self.print_expr_maybe_paren(rhs, right_prec)
|
self.print_expr_maybe_paren(rhs, right_prec)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_expr_unary(&mut self, op: ast::UnOp, expr: &ast::Expr) {
|
fn print_expr_unary(&mut self, op: ast::UnOp, expr: &ast::Expr) {
|
||||||
self.word(ast::UnOp::to_string(op));
|
self.word(op.as_str());
|
||||||
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
|
self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,7 +470,7 @@ pub(super) fn print_expr_outer_attr_style(&mut self, expr: &ast::Expr, is_inline
|
|||||||
let prec = AssocOp::Assign.precedence() as i8;
|
let prec = AssocOp::Assign.precedence() as i8;
|
||||||
self.print_expr_maybe_paren(lhs, prec + 1);
|
self.print_expr_maybe_paren(lhs, prec + 1);
|
||||||
self.space();
|
self.space();
|
||||||
self.word(op.node.to_string());
|
self.word(op.node.as_str());
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
self.print_expr_maybe_paren(rhs, prec);
|
self.print_expr_maybe_paren(rhs, prec);
|
||||||
}
|
}
|
||||||
|
@ -653,3 +653,4 @@
|
|||||||
// E0721, // `await` keyword
|
// E0721, // `await` keyword
|
||||||
// E0723, // unstable feature in `const` context
|
// E0723, // unstable feature in `const` context
|
||||||
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
|
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
|
||||||
|
// E0744, // merged into E0728
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
#### Note: this error code is no longer emitted by the compiler.
|
||||||
|
|
||||||
An unsupported expression was used inside a const context.
|
An unsupported expression was used inside a const context.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,edition2018,E0744
|
```ignore (removed error code)
|
||||||
const _: i32 = {
|
const _: i32 = {
|
||||||
async { 0 }.await
|
async { 0 }.await
|
||||||
};
|
};
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::util::parser::ExprPrecedence;
|
use rustc_ast::util::parser::ExprPrecedence;
|
||||||
use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy};
|
use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy};
|
||||||
pub use rustc_ast::{BindingAnnotation, BorrowKind, ByRef, ImplPolarity, IsAuto};
|
pub use rustc_ast::{BinOp, BinOpKind, BindingAnnotation, BorrowKind, ByRef, CaptureBy};
|
||||||
pub use rustc_ast::{CaptureBy, Movability, Mutability};
|
pub use rustc_ast::{ImplPolarity, IsAuto, Movability, Mutability, UnOp};
|
||||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
@ -1174,155 +1174,6 @@ pub enum PatKind<'hir> {
|
|||||||
Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
|
Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
|
||||||
pub enum BinOpKind {
|
|
||||||
/// The `+` operator (addition).
|
|
||||||
Add,
|
|
||||||
/// The `-` operator (subtraction).
|
|
||||||
Sub,
|
|
||||||
/// The `*` operator (multiplication).
|
|
||||||
Mul,
|
|
||||||
/// The `/` operator (division).
|
|
||||||
Div,
|
|
||||||
/// The `%` operator (modulus).
|
|
||||||
Rem,
|
|
||||||
/// The `&&` operator (logical and).
|
|
||||||
And,
|
|
||||||
/// The `||` operator (logical or).
|
|
||||||
Or,
|
|
||||||
/// The `^` operator (bitwise xor).
|
|
||||||
BitXor,
|
|
||||||
/// The `&` operator (bitwise and).
|
|
||||||
BitAnd,
|
|
||||||
/// The `|` operator (bitwise or).
|
|
||||||
BitOr,
|
|
||||||
/// The `<<` operator (shift left).
|
|
||||||
Shl,
|
|
||||||
/// The `>>` operator (shift right).
|
|
||||||
Shr,
|
|
||||||
/// The `==` operator (equality).
|
|
||||||
Eq,
|
|
||||||
/// The `<` operator (less than).
|
|
||||||
Lt,
|
|
||||||
/// The `<=` operator (less than or equal to).
|
|
||||||
Le,
|
|
||||||
/// The `!=` operator (not equal to).
|
|
||||||
Ne,
|
|
||||||
/// The `>=` operator (greater than or equal to).
|
|
||||||
Ge,
|
|
||||||
/// The `>` operator (greater than).
|
|
||||||
Gt,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BinOpKind {
|
|
||||||
pub fn as_str(self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
BinOpKind::Add => "+",
|
|
||||||
BinOpKind::Sub => "-",
|
|
||||||
BinOpKind::Mul => "*",
|
|
||||||
BinOpKind::Div => "/",
|
|
||||||
BinOpKind::Rem => "%",
|
|
||||||
BinOpKind::And => "&&",
|
|
||||||
BinOpKind::Or => "||",
|
|
||||||
BinOpKind::BitXor => "^",
|
|
||||||
BinOpKind::BitAnd => "&",
|
|
||||||
BinOpKind::BitOr => "|",
|
|
||||||
BinOpKind::Shl => "<<",
|
|
||||||
BinOpKind::Shr => ">>",
|
|
||||||
BinOpKind::Eq => "==",
|
|
||||||
BinOpKind::Lt => "<",
|
|
||||||
BinOpKind::Le => "<=",
|
|
||||||
BinOpKind::Ne => "!=",
|
|
||||||
BinOpKind::Ge => ">=",
|
|
||||||
BinOpKind::Gt => ">",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_lazy(self) -> bool {
|
|
||||||
matches!(self, BinOpKind::And | BinOpKind::Or)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_comparison(self) -> bool {
|
|
||||||
match self {
|
|
||||||
BinOpKind::Eq
|
|
||||||
| BinOpKind::Lt
|
|
||||||
| BinOpKind::Le
|
|
||||||
| BinOpKind::Ne
|
|
||||||
| BinOpKind::Gt
|
|
||||||
| BinOpKind::Ge => true,
|
|
||||||
BinOpKind::And
|
|
||||||
| BinOpKind::Or
|
|
||||||
| BinOpKind::Add
|
|
||||||
| BinOpKind::Sub
|
|
||||||
| BinOpKind::Mul
|
|
||||||
| BinOpKind::Div
|
|
||||||
| BinOpKind::Rem
|
|
||||||
| BinOpKind::BitXor
|
|
||||||
| BinOpKind::BitAnd
|
|
||||||
| BinOpKind::BitOr
|
|
||||||
| BinOpKind::Shl
|
|
||||||
| BinOpKind::Shr => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if the binary operator takes its arguments by value.
|
|
||||||
pub fn is_by_value(self) -> bool {
|
|
||||||
!self.is_comparison()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<ast::BinOpKind> for BinOpKind {
|
|
||||||
fn into(self) -> ast::BinOpKind {
|
|
||||||
match self {
|
|
||||||
BinOpKind::Add => ast::BinOpKind::Add,
|
|
||||||
BinOpKind::Sub => ast::BinOpKind::Sub,
|
|
||||||
BinOpKind::Mul => ast::BinOpKind::Mul,
|
|
||||||
BinOpKind::Div => ast::BinOpKind::Div,
|
|
||||||
BinOpKind::Rem => ast::BinOpKind::Rem,
|
|
||||||
BinOpKind::And => ast::BinOpKind::And,
|
|
||||||
BinOpKind::Or => ast::BinOpKind::Or,
|
|
||||||
BinOpKind::BitXor => ast::BinOpKind::BitXor,
|
|
||||||
BinOpKind::BitAnd => ast::BinOpKind::BitAnd,
|
|
||||||
BinOpKind::BitOr => ast::BinOpKind::BitOr,
|
|
||||||
BinOpKind::Shl => ast::BinOpKind::Shl,
|
|
||||||
BinOpKind::Shr => ast::BinOpKind::Shr,
|
|
||||||
BinOpKind::Eq => ast::BinOpKind::Eq,
|
|
||||||
BinOpKind::Lt => ast::BinOpKind::Lt,
|
|
||||||
BinOpKind::Le => ast::BinOpKind::Le,
|
|
||||||
BinOpKind::Ne => ast::BinOpKind::Ne,
|
|
||||||
BinOpKind::Ge => ast::BinOpKind::Ge,
|
|
||||||
BinOpKind::Gt => ast::BinOpKind::Gt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type BinOp = Spanned<BinOpKind>;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
|
|
||||||
pub enum UnOp {
|
|
||||||
/// The `*` operator (dereferencing).
|
|
||||||
Deref,
|
|
||||||
/// The `!` operator (logical negation).
|
|
||||||
Not,
|
|
||||||
/// The `-` operator (negation).
|
|
||||||
Neg,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UnOp {
|
|
||||||
pub fn as_str(self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
Self::Deref => "*",
|
|
||||||
Self::Not => "!",
|
|
||||||
Self::Neg => "-",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if the unary operator takes its argument by value.
|
|
||||||
pub fn is_by_value(self) -> bool {
|
|
||||||
matches!(self, Self::Neg | Self::Not)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A statement.
|
/// A statement.
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub struct Stmt<'hir> {
|
pub struct Stmt<'hir> {
|
||||||
|
@ -448,7 +448,11 @@ fn to_trace(
|
|||||||
) -> TypeTrace<'tcx> {
|
) -> TypeTrace<'tcx> {
|
||||||
TypeTrace {
|
TypeTrace {
|
||||||
cause: cause.clone(),
|
cause: cause.clone(),
|
||||||
values: TraitRefs(ExpectedFound::new(a_is_expected, a, b)),
|
values: PolyTraitRefs(ExpectedFound::new(
|
||||||
|
a_is_expected,
|
||||||
|
ty::Binder::dummy(a),
|
||||||
|
ty::Binder::dummy(b),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1667,9 +1667,7 @@ enum Mismatch<'a> {
|
|||||||
.report(diag);
|
.report(diag);
|
||||||
(false, Mismatch::Fixed("signature"))
|
(false, Mismatch::Fixed("signature"))
|
||||||
}
|
}
|
||||||
ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => {
|
ValuePairs::PolyTraitRefs(_) => (false, Mismatch::Fixed("trait")),
|
||||||
(false, Mismatch::Fixed("trait"))
|
|
||||||
}
|
|
||||||
ValuePairs::Aliases(infer::ExpectedFound { expected, .. }) => {
|
ValuePairs::Aliases(infer::ExpectedFound { expected, .. }) => {
|
||||||
(false, Mismatch::Fixed(self.tcx.def_descr(expected.def_id)))
|
(false, Mismatch::Fixed(self.tcx.def_descr(expected.def_id)))
|
||||||
}
|
}
|
||||||
@ -2219,18 +2217,6 @@ fn values_str(
|
|||||||
infer::Aliases(exp_found) => self.expected_found_str(exp_found),
|
infer::Aliases(exp_found) => self.expected_found_str(exp_found),
|
||||||
infer::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found),
|
infer::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found),
|
||||||
infer::ExistentialProjection(exp_found) => self.expected_found_str(exp_found),
|
infer::ExistentialProjection(exp_found) => self.expected_found_str(exp_found),
|
||||||
infer::TraitRefs(exp_found) => {
|
|
||||||
let pretty_exp_found = ty::error::ExpectedFound {
|
|
||||||
expected: exp_found.expected.print_only_trait_path(),
|
|
||||||
found: exp_found.found.print_only_trait_path(),
|
|
||||||
};
|
|
||||||
match self.expected_found_str(pretty_exp_found) {
|
|
||||||
Some((expected, found, _, _)) if expected == found => {
|
|
||||||
self.expected_found_str(exp_found)
|
|
||||||
}
|
|
||||||
ret => ret,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
infer::PolyTraitRefs(exp_found) => {
|
infer::PolyTraitRefs(exp_found) => {
|
||||||
let pretty_exp_found = ty::error::ExpectedFound {
|
let pretty_exp_found = ty::error::ExpectedFound {
|
||||||
expected: exp_found.expected.print_only_trait_path(),
|
expected: exp_found.expected.print_only_trait_path(),
|
||||||
|
@ -197,11 +197,6 @@ fn try_report_trait_placeholder_mismatch(
|
|||||||
value_pairs: &ValuePairs<'tcx>,
|
value_pairs: &ValuePairs<'tcx>,
|
||||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||||
let (expected_args, found_args, trait_def_id) = match value_pairs {
|
let (expected_args, found_args, trait_def_id) = match value_pairs {
|
||||||
ValuePairs::TraitRefs(ExpectedFound { expected, found })
|
|
||||||
if expected.def_id == found.def_id =>
|
|
||||||
{
|
|
||||||
(expected.args, found.args, expected.def_id)
|
|
||||||
}
|
|
||||||
ValuePairs::PolyTraitRefs(ExpectedFound { expected, found })
|
ValuePairs::PolyTraitRefs(ExpectedFound { expected, found })
|
||||||
if expected.def_id() == found.def_id() =>
|
if expected.def_id() == found.def_id() =>
|
||||||
{
|
{
|
||||||
|
@ -384,7 +384,6 @@ pub enum ValuePairs<'tcx> {
|
|||||||
Regions(ExpectedFound<ty::Region<'tcx>>),
|
Regions(ExpectedFound<ty::Region<'tcx>>),
|
||||||
Terms(ExpectedFound<ty::Term<'tcx>>),
|
Terms(ExpectedFound<ty::Term<'tcx>>),
|
||||||
Aliases(ExpectedFound<ty::AliasTy<'tcx>>),
|
Aliases(ExpectedFound<ty::AliasTy<'tcx>>),
|
||||||
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
|
|
||||||
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
|
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
|
||||||
PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
|
PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
|
||||||
ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
|
ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
|
||||||
|
@ -656,7 +656,7 @@ fn is_expr_delims_necessary(
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
if followed_by_else {
|
if followed_by_else {
|
||||||
match inner.kind {
|
match inner.kind {
|
||||||
ast::ExprKind::Binary(op, ..) if op.node.lazy() => return true,
|
ast::ExprKind::Binary(op, ..) if op.node.is_lazy() => return true,
|
||||||
_ if classify::expr_trailing_brace(inner).is_some() => return true,
|
_ if classify::expr_trailing_brace(inner).is_some() => return true,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -1016,7 +1016,7 @@ fn check_unused_delims_expr(
|
|||||||
rustc_span::source_map::Spanned { node, .. },
|
rustc_span::source_map::Spanned { node, .. },
|
||||||
_,
|
_,
|
||||||
_,
|
_,
|
||||||
) if node.lazy()))
|
) if node.is_lazy()))
|
||||||
{
|
{
|
||||||
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
|
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,6 @@
|
|||||||
//! Otherwise it drops all the values in scope at the last suspension point.
|
//! Otherwise it drops all the values in scope at the last suspension point.
|
||||||
|
|
||||||
use crate::abort_unwinding_calls;
|
use crate::abort_unwinding_calls;
|
||||||
use crate::add_call_guards;
|
|
||||||
use crate::deref_separator::deref_finder;
|
use crate::deref_separator::deref_finder;
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
use crate::pass_manager as pm;
|
use crate::pass_manager as pm;
|
||||||
@ -1168,18 +1167,9 @@ fn create_coroutine_drop_shim<'tcx>(
|
|||||||
simplify::remove_dead_blocks(&mut body);
|
simplify::remove_dead_blocks(&mut body);
|
||||||
|
|
||||||
// Update the body's def to become the drop glue.
|
// Update the body's def to become the drop glue.
|
||||||
// This needs to be updated before the AbortUnwindingCalls pass.
|
|
||||||
let coroutine_instance = body.source.instance;
|
let coroutine_instance = body.source.instance;
|
||||||
let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None);
|
let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None);
|
||||||
let drop_instance = InstanceDef::DropGlue(drop_in_place, Some(coroutine_ty));
|
let drop_instance = InstanceDef::DropGlue(drop_in_place, Some(coroutine_ty));
|
||||||
body.source.instance = drop_instance;
|
|
||||||
|
|
||||||
pm::run_passes_no_validate(
|
|
||||||
tcx,
|
|
||||||
&mut body,
|
|
||||||
&[&abort_unwinding_calls::AbortUnwindingCalls, &add_call_guards::CriticalCallEdges],
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible
|
// Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible
|
||||||
// filename.
|
// filename.
|
||||||
|
@ -74,11 +74,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
|
|||||||
let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args);
|
let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args);
|
||||||
debug!("make_shim({:?}) = {:?}", instance, body);
|
debug!("make_shim({:?}) = {:?}", instance, body);
|
||||||
|
|
||||||
// Run empty passes to mark phase change and perform validation.
|
|
||||||
pm::run_passes(
|
pm::run_passes(
|
||||||
tcx,
|
tcx,
|
||||||
&mut body,
|
&mut body,
|
||||||
&[],
|
&[
|
||||||
|
&abort_unwinding_calls::AbortUnwindingCalls,
|
||||||
|
&add_call_guards::CriticalCallEdges,
|
||||||
|
],
|
||||||
Some(MirPhase::Runtime(RuntimePhase::Optimized)),
|
Some(MirPhase::Runtime(RuntimePhase::Optimized)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -384,10 +384,10 @@ fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
|
|||||||
|
|
||||||
fn check_let_else_init_bool_expr(&self, init: &ast::Expr) {
|
fn check_let_else_init_bool_expr(&self, init: &ast::Expr) {
|
||||||
if let ast::ExprKind::Binary(op, ..) = init.kind {
|
if let ast::ExprKind::Binary(op, ..) = init.kind {
|
||||||
if op.node.lazy() {
|
if op.node.is_lazy() {
|
||||||
self.sess.emit_err(errors::InvalidExpressionInLetElse {
|
self.sess.emit_err(errors::InvalidExpressionInLetElse {
|
||||||
span: init.span,
|
span: init.span,
|
||||||
operator: op.node.to_string(),
|
operator: op.node.as_str(),
|
||||||
sugg: errors::WrapExpressionInParentheses {
|
sugg: errors::WrapExpressionInParentheses {
|
||||||
left: init.span.shrink_to_lo(),
|
left: init.span.shrink_to_lo(),
|
||||||
right: init.span.shrink_to_hi(),
|
right: init.span.shrink_to_hi(),
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
use rustc_span::{sym, Span, Symbol};
|
use rustc_span::{sym, Span, Symbol};
|
||||||
|
|
||||||
use crate::errors::{ExprNotAllowedInContext, SkippingConstChecks};
|
use crate::errors::SkippingConstChecks;
|
||||||
|
|
||||||
/// An expression that is not *always* legal in a const context.
|
/// An expression that is not *always* legal in a const context.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@ -138,11 +138,10 @@ fn const_check_violated(&self, expr: NonConstExpr, span: Span) {
|
|||||||
|
|
||||||
match missing_gates.as_slice() {
|
match missing_gates.as_slice() {
|
||||||
[] => {
|
[] => {
|
||||||
tcx.sess.emit_err(ExprNotAllowedInContext {
|
span_bug!(
|
||||||
span,
|
span,
|
||||||
expr: expr.name(),
|
"we should not have reached this point, since `.await` is denied earlier"
|
||||||
context: const_kind.keyword_name(),
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[missing_primary, ref missing_secondary @ ..] => {
|
[missing_primary, ref missing_secondary @ ..] => {
|
||||||
|
@ -1005,15 +1005,6 @@ pub struct FeaturePreviouslyDeclared<'a, 'b> {
|
|||||||
pub prev_declared: &'b str,
|
pub prev_declared: &'b str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(passes_expr_not_allowed_in_context, code = "E0744")]
|
|
||||||
pub struct ExprNotAllowedInContext<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub expr: String,
|
|
||||||
pub context: &'a str,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct BreakNonLoop<'a> {
|
pub struct BreakNonLoop<'a> {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub head: Option<Span>,
|
pub head: Option<Span>,
|
||||||
|
@ -423,12 +423,14 @@ pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
/// Specialize clones into pre-allocated, uninitialized memory.
|
/// Specialize clones into pre-allocated, uninitialized memory.
|
||||||
/// Used by `Box::clone` and `Rc`/`Arc::make_mut`.
|
/// Used by `Box::clone` and `Rc`/`Arc::make_mut`.
|
||||||
pub(crate) trait WriteCloneIntoRaw: Sized {
|
pub(crate) trait WriteCloneIntoRaw: Sized {
|
||||||
unsafe fn write_clone_into_raw(&self, target: *mut Self);
|
unsafe fn write_clone_into_raw(&self, target: *mut Self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
impl<T: Clone> WriteCloneIntoRaw for T {
|
impl<T: Clone> WriteCloneIntoRaw for T {
|
||||||
#[inline]
|
#[inline]
|
||||||
default unsafe fn write_clone_into_raw(&self, target: *mut Self) {
|
default unsafe fn write_clone_into_raw(&self, target: *mut Self) {
|
||||||
@ -438,6 +440,7 @@ impl<T: Clone> WriteCloneIntoRaw for T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
impl<T: Copy> WriteCloneIntoRaw for T {
|
impl<T: Copy> WriteCloneIntoRaw for T {
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn write_clone_into_raw(&self, target: *mut Self) {
|
unsafe fn write_clone_into_raw(&self, target: *mut Self) {
|
||||||
|
@ -148,6 +148,7 @@ fn fmt(
|
|||||||
|
|
||||||
/// An intermediate trait for specialization of `Extend`.
|
/// An intermediate trait for specialization of `Extend`.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
trait SpecExtend<I: IntoIterator> {
|
trait SpecExtend<I: IntoIterator> {
|
||||||
/// Extends `self` with the contents of the given iterator.
|
/// Extends `self` with the contents of the given iterator.
|
||||||
fn spec_extend(&mut self, iter: I);
|
fn spec_extend(&mut self, iter: I);
|
||||||
|
@ -2023,6 +2023,7 @@ unsafe fn allocate_for_slice_in(len: usize, alloc: &A) -> *mut RcBox<[T]> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
/// Specialization trait used for `From<&[T]>`.
|
/// Specialization trait used for `From<&[T]>`.
|
||||||
trait RcFromSlice<T> {
|
trait RcFromSlice<T> {
|
||||||
fn from_slice(slice: &[T]) -> Self;
|
fn from_slice(slice: &[T]) -> Self;
|
||||||
|
@ -3503,6 +3503,7 @@ fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
/// Specialization trait used for collecting into `Arc<[T]>`.
|
/// Specialization trait used for collecting into `Arc<[T]>`.
|
||||||
trait ToArcSlice<T>: Iterator<Item = T> + Sized {
|
trait ToArcSlice<T>: Iterator<Item = T> + Sized {
|
||||||
fn to_arc_slice(self) -> Arc<[T]>;
|
fn to_arc_slice(self) -> Arc<[T]>;
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use core::iter;
|
use core::iter;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
|
use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
|
||||||
@ -101,6 +102,7 @@
|
|||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
use self::is_zero::IsZero;
|
use self::is_zero::IsZero;
|
||||||
|
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
mod is_zero;
|
mod is_zero;
|
||||||
|
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
@ -2599,6 +2601,7 @@ pub fn from_elem_in<T: Clone, A: Allocator>(elem: T, n: usize, alloc: A) -> Vec<
|
|||||||
<T as SpecFromElem>::from_elem(elem, n, alloc)
|
<T as SpecFromElem>::from_elem(elem, n, alloc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
trait ExtendFromWithinSpec {
|
trait ExtendFromWithinSpec {
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
@ -2607,6 +2610,7 @@ trait ExtendFromWithinSpec {
|
|||||||
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>);
|
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
||||||
default unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
|
default unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
@ -2626,6 +2630,7 @@ impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(no_global_oom_handling))]
|
||||||
impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
|
||||||
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
|
unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
|
||||||
let count = src.len();
|
let count = src.len();
|
||||||
|
@ -24,9 +24,8 @@
|
|||||||
//! which are generated by Rust codegen backends. Additionally, this library can make explicit
|
//! which are generated by Rust codegen backends. Additionally, this library can make explicit
|
||||||
//! calls to `strlen`. Their signatures are the same as found in C, but there are extra
|
//! calls to `strlen`. Their signatures are the same as found in C, but there are extra
|
||||||
//! assumptions about their semantics: For `memcpy`, `memmove`, `memset`, `memcmp`, and `bcmp`, if
|
//! assumptions about their semantics: For `memcpy`, `memmove`, `memset`, `memcmp`, and `bcmp`, if
|
||||||
//! the `n` parameter is 0, the function is assumed to not be UB. Furthermore, for `memcpy`, if
|
//! the `n` parameter is 0, the function is assumed to not be UB, even if the pointers are NULL or
|
||||||
//! source and target pointer are equal, the function is assumed to not be UB.
|
//! dangling. (Note that making extra assumptions about these functions is common among compilers:
|
||||||
//! (Note that these are standard assumptions among compilers:
|
|
||||||
//! [clang](https://reviews.llvm.org/D86993) and [GCC](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#C-Language) do the same.)
|
//! [clang](https://reviews.llvm.org/D86993) and [GCC](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#C-Language) do the same.)
|
||||||
//! These functions are often provided by the system libc, but can also be provided by the
|
//! These functions are often provided by the system libc, but can also be provided by the
|
||||||
//! [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
|
//! [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
|
||||||
|
@ -336,6 +336,7 @@
|
|||||||
#![feature(portable_simd)]
|
#![feature(portable_simd)]
|
||||||
#![feature(prelude_2024)]
|
#![feature(prelude_2024)]
|
||||||
#![feature(ptr_as_uninit)]
|
#![feature(ptr_as_uninit)]
|
||||||
|
#![feature(ptr_from_ref)]
|
||||||
#![feature(raw_os_nonzero)]
|
#![feature(raw_os_nonzero)]
|
||||||
#![feature(round_ties_even)]
|
#![feature(round_ties_even)]
|
||||||
#![feature(slice_internals)]
|
#![feature(slice_internals)]
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
pub mod stdio;
|
pub mod stdio;
|
||||||
pub mod thread;
|
pub mod thread;
|
||||||
pub mod thread_local_key;
|
pub mod thread_local_key;
|
||||||
#[path = "../unsupported/thread_parking.rs"]
|
|
||||||
pub mod thread_parking;
|
pub mod thread_parking;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
|
|
||||||
|
94
library/std/src/sys/xous/thread_parking.rs
Normal file
94
library/std/src/sys/xous/thread_parking.rs
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
use crate::os::xous::ffi::{blocking_scalar, scalar};
|
||||||
|
use crate::os::xous::services::{ticktimer_server, TicktimerScalar};
|
||||||
|
use crate::pin::Pin;
|
||||||
|
use crate::ptr;
|
||||||
|
use crate::sync::atomic::{
|
||||||
|
AtomicI8,
|
||||||
|
Ordering::{Acquire, Release},
|
||||||
|
};
|
||||||
|
use crate::time::Duration;
|
||||||
|
|
||||||
|
const NOTIFIED: i8 = 1;
|
||||||
|
const EMPTY: i8 = 0;
|
||||||
|
const PARKED: i8 = -1;
|
||||||
|
|
||||||
|
pub struct Parker {
|
||||||
|
state: AtomicI8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Parker {
|
||||||
|
pub unsafe fn new_in_place(parker: *mut Parker) {
|
||||||
|
unsafe { parker.write(Parker { state: AtomicI8::new(EMPTY) }) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index(&self) -> usize {
|
||||||
|
ptr::from_ref(self).addr()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn park(self: Pin<&Self>) {
|
||||||
|
// Change NOTIFIED to EMPTY and EMPTY to PARKED.
|
||||||
|
let state = self.state.fetch_sub(1, Acquire);
|
||||||
|
if state == NOTIFIED {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The state was set to PARKED. Wait until the `unpark` wakes us up.
|
||||||
|
blocking_scalar(
|
||||||
|
ticktimer_server(),
|
||||||
|
TicktimerScalar::WaitForCondition(self.index(), 0).into(),
|
||||||
|
)
|
||||||
|
.expect("failed to send WaitForCondition command");
|
||||||
|
|
||||||
|
self.state.swap(EMPTY, Acquire);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn park_timeout(self: Pin<&Self>, timeout: Duration) {
|
||||||
|
// Change NOTIFIED to EMPTY and EMPTY to PARKED.
|
||||||
|
let state = self.state.fetch_sub(1, Acquire);
|
||||||
|
if state == NOTIFIED {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A value of zero indicates an indefinite wait. Clamp the number of
|
||||||
|
// milliseconds to the allowed range.
|
||||||
|
let millis = usize::max(timeout.as_millis().try_into().unwrap_or(usize::MAX), 1);
|
||||||
|
|
||||||
|
let was_timeout = blocking_scalar(
|
||||||
|
ticktimer_server(),
|
||||||
|
TicktimerScalar::WaitForCondition(self.index(), millis).into(),
|
||||||
|
)
|
||||||
|
.expect("failed to send WaitForCondition command")[0]
|
||||||
|
!= 0;
|
||||||
|
|
||||||
|
let state = self.state.swap(EMPTY, Acquire);
|
||||||
|
if was_timeout && state == NOTIFIED {
|
||||||
|
// The state was set to NOTIFIED after we returned from the wait
|
||||||
|
// but before we reset the state. Therefore, a wakeup is on its
|
||||||
|
// way, which we need to consume here.
|
||||||
|
// NOTICE: this is a priority hole.
|
||||||
|
blocking_scalar(
|
||||||
|
ticktimer_server(),
|
||||||
|
TicktimerScalar::WaitForCondition(self.index(), 0).into(),
|
||||||
|
)
|
||||||
|
.expect("failed to send WaitForCondition command");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unpark(self: Pin<&Self>) {
|
||||||
|
let state = self.state.swap(NOTIFIED, Release);
|
||||||
|
if state == PARKED {
|
||||||
|
// The thread is parked, wake it up.
|
||||||
|
blocking_scalar(
|
||||||
|
ticktimer_server(),
|
||||||
|
TicktimerScalar::NotifyCondition(self.index(), 1).into(),
|
||||||
|
)
|
||||||
|
.expect("failed to send NotifyCondition command");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Parker {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
scalar(ticktimer_server(), TicktimerScalar::FreeCondition(self.index()).into()).ok();
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note};
|
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note};
|
||||||
use clippy_utils::is_span_if;
|
use clippy_utils::is_span_if;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp};
|
use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind};
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
@ -144,7 +144,7 @@ fn check_assign(cx: &EarlyContext<'_>, expr: &Expr) {
|
|||||||
let eq_span = lhs.span.between(rhs.span);
|
let eq_span = lhs.span.between(rhs.span);
|
||||||
if let ExprKind::Unary(op, ref sub_rhs) = rhs.kind {
|
if let ExprKind::Unary(op, ref sub_rhs) = rhs.kind {
|
||||||
if let Some(eq_snippet) = snippet_opt(cx, eq_span) {
|
if let Some(eq_snippet) = snippet_opt(cx, eq_span) {
|
||||||
let op = UnOp::to_string(op);
|
let op = op.as_str();
|
||||||
let eqop_span = lhs.span.between(sub_rhs.span);
|
let eqop_span = lhs.span.between(sub_rhs.span);
|
||||||
if eq_snippet.ends_with('=') {
|
if eq_snippet.ends_with('=') {
|
||||||
span_lint_and_note(
|
span_lint_and_note(
|
||||||
@ -177,11 +177,11 @@ fn check_unop(cx: &EarlyContext<'_>, expr: &Expr) {
|
|||||||
&& let unop_operand_span = rhs.span.until(un_rhs.span)
|
&& let unop_operand_span = rhs.span.until(un_rhs.span)
|
||||||
&& let Some(binop_snippet) = snippet_opt(cx, binop_span)
|
&& let Some(binop_snippet) = snippet_opt(cx, binop_span)
|
||||||
&& let Some(unop_operand_snippet) = snippet_opt(cx, unop_operand_span)
|
&& let Some(unop_operand_snippet) = snippet_opt(cx, unop_operand_span)
|
||||||
&& let binop_str = BinOpKind::to_string(&binop.node)
|
&& let binop_str = binop.node.as_str()
|
||||||
// no space after BinOp operator and space after UnOp operator
|
// no space after BinOp operator and space after UnOp operator
|
||||||
&& binop_snippet.ends_with(binop_str) && unop_operand_snippet.ends_with(' ')
|
&& binop_snippet.ends_with(binop_str) && unop_operand_snippet.ends_with(' ')
|
||||||
{
|
{
|
||||||
let unop_str = UnOp::to_string(op);
|
let unop_str = op.as_str();
|
||||||
let eqop_span = lhs.span.between(un_rhs.span);
|
let eqop_span = lhs.span.between(un_rhs.span);
|
||||||
span_lint_and_help(
|
span_lint_and_help(
|
||||||
cx,
|
cx,
|
||||||
|
@ -78,7 +78,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
|||||||
let sugg = format!(
|
let sugg = format!(
|
||||||
"({}) {} ({})",
|
"({}) {} ({})",
|
||||||
snippet_with_applicability(cx, left.span, "..", &mut applicability),
|
snippet_with_applicability(cx, left.span, "..", &mut applicability),
|
||||||
op.to_string(),
|
op.as_str(),
|
||||||
snippet_with_applicability(cx, right.span, "..", &mut applicability)
|
snippet_with_applicability(cx, right.span, "..", &mut applicability)
|
||||||
);
|
);
|
||||||
span_sugg(expr, sugg, applicability);
|
span_sugg(expr, sugg, applicability);
|
||||||
@ -87,7 +87,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
|||||||
let sugg = format!(
|
let sugg = format!(
|
||||||
"({}) {} {}",
|
"({}) {} {}",
|
||||||
snippet_with_applicability(cx, left.span, "..", &mut applicability),
|
snippet_with_applicability(cx, left.span, "..", &mut applicability),
|
||||||
op.to_string(),
|
op.as_str(),
|
||||||
snippet_with_applicability(cx, right.span, "..", &mut applicability)
|
snippet_with_applicability(cx, right.span, "..", &mut applicability)
|
||||||
);
|
);
|
||||||
span_sugg(expr, sugg, applicability);
|
span_sugg(expr, sugg, applicability);
|
||||||
@ -96,7 +96,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
|||||||
let sugg = format!(
|
let sugg = format!(
|
||||||
"{} {} ({})",
|
"{} {} ({})",
|
||||||
snippet_with_applicability(cx, left.span, "..", &mut applicability),
|
snippet_with_applicability(cx, left.span, "..", &mut applicability),
|
||||||
op.to_string(),
|
op.as_str(),
|
||||||
snippet_with_applicability(cx, right.span, "..", &mut applicability)
|
snippet_with_applicability(cx, right.span, "..", &mut applicability)
|
||||||
);
|
);
|
||||||
span_sugg(expr, sugg, applicability);
|
span_sugg(expr, sugg, applicability);
|
||||||
|
@ -298,7 +298,7 @@ fn replace_left_sugg(
|
|||||||
) -> String {
|
) -> String {
|
||||||
format!(
|
format!(
|
||||||
"{left_suggestion} {} {}",
|
"{left_suggestion} {} {}",
|
||||||
binop.op.to_string(),
|
binop.op.as_str(),
|
||||||
snippet_with_applicability(cx, binop.right.span, "..", applicability),
|
snippet_with_applicability(cx, binop.right.span, "..", applicability),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -312,7 +312,7 @@ fn replace_right_sugg(
|
|||||||
format!(
|
format!(
|
||||||
"{} {} {right_suggestion}",
|
"{} {} {right_suggestion}",
|
||||||
snippet_with_applicability(cx, binop.left.span, "..", applicability),
|
snippet_with_applicability(cx, binop.left.span, "..", applicability),
|
||||||
binop.op.to_string(),
|
binop.op.as_str(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String {
|
|||||||
| AssocOp::GreaterEqual => {
|
| AssocOp::GreaterEqual => {
|
||||||
format!(
|
format!(
|
||||||
"{lhs} {} {rhs}",
|
"{lhs} {} {rhs}",
|
||||||
op.to_ast_binop().expect("Those are AST ops").to_string()
|
op.to_ast_binop().expect("Those are AST ops").as_str()
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
AssocOp::Assign => format!("{lhs} = {rhs}"),
|
AssocOp::Assign => format!("{lhs} = {rhs}"),
|
||||||
|
@ -1933,7 +1933,7 @@ fn rewrite_unary_op(
|
|||||||
shape: Shape,
|
shape: Shape,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
// For some reason, an UnOp is not spanned like BinOp!
|
// For some reason, an UnOp is not spanned like BinOp!
|
||||||
rewrite_unary_prefix(context, ast::UnOp::to_string(op), expr, shape)
|
rewrite_unary_prefix(context, op.as_str(), expr, shape)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) enum RhsAssignKind<'ast> {
|
pub(crate) enum RhsAssignKind<'ast> {
|
||||||
|
@ -339,7 +339,7 @@ fn flatten(
|
|||||||
if let Some(pop) = stack.pop() {
|
if let Some(pop) = stack.pop() {
|
||||||
match pop.kind {
|
match pop.kind {
|
||||||
ast::ExprKind::Binary(op, _, ref rhs) => {
|
ast::ExprKind::Binary(op, _, ref rhs) => {
|
||||||
separators.push(op.node.to_string());
|
separators.push(op.node.as_str());
|
||||||
node = rhs;
|
node = rhs;
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -3,9 +3,6 @@
|
|||||||
async fn fun() {
|
async fn fun() {
|
||||||
[1; ().await];
|
[1; ().await];
|
||||||
//~^ error: `await` is only allowed inside `async` functions and blocks
|
//~^ error: `await` is only allowed inside `async` functions and blocks
|
||||||
//~| error: `.await` is not allowed in a `const`
|
|
||||||
//~| error: `.await` is not allowed in a `const`
|
|
||||||
//~| error: `()` is not a future
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,37 +1,12 @@
|
|||||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||||
--> $DIR/issue-70594.rs:4:12
|
--> $DIR/issue-70594.rs:4:12
|
||||||
|
|
|
|
||||||
LL | async fn fun() {
|
|
||||||
| --- this is not `async`
|
|
||||||
LL | [1; ().await];
|
LL | [1; ().await];
|
||||||
| ^^^^^ only allowed inside `async` functions and blocks
|
| ---^^^^^
|
||||||
|
| | |
|
||||||
|
| | only allowed inside `async` functions and blocks
|
||||||
|
| this is not `async`
|
||||||
|
|
||||||
error[E0744]: `.await` is not allowed in a `const`
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/issue-70594.rs:4:9
|
|
||||||
|
|
|
||||||
LL | [1; ().await];
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error[E0744]: `.await` is not allowed in a `const`
|
For more information about this error, try `rustc --explain E0728`.
|
||||||
--> $DIR/issue-70594.rs:4:12
|
|
||||||
|
|
|
||||||
LL | [1; ().await];
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error[E0277]: `()` is not a future
|
|
||||||
--> $DIR/issue-70594.rs:4:12
|
|
||||||
|
|
|
||||||
LL | [1; ().await];
|
|
||||||
| -^^^^^
|
|
||||||
| ||
|
|
||||||
| |`()` is not a future
|
|
||||||
| help: remove the `.await`
|
|
||||||
|
|
|
||||||
= help: the trait `Future` is not implemented for `()`
|
|
||||||
= note: () must be a future or must implement `IntoFuture` to be awaited
|
|
||||||
= note: required for `()` to implement `IntoFuture`
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0728, E0744.
|
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
@ -11,5 +11,4 @@ fn main() {
|
|||||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||||
(|_| 2333).await;
|
(|_| 2333).await;
|
||||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||||
//~| ERROR is not a future
|
|
||||||
}
|
}
|
||||||
|
@ -24,20 +24,6 @@ LL | fn main() {
|
|||||||
LL | (|_| 2333).await;
|
LL | (|_| 2333).await;
|
||||||
| ^^^^^ only allowed inside `async` functions and blocks
|
| ^^^^^ only allowed inside `async` functions and blocks
|
||||||
|
|
||||||
error[E0277]: `{closure@$DIR/issue-62009-1.rs:12:6: 12:9}` is not a future
|
error: aborting due to 3 previous errors
|
||||||
--> $DIR/issue-62009-1.rs:12:16
|
|
||||||
|
|
|
||||||
LL | (|_| 2333).await;
|
|
||||||
| -^^^^^
|
|
||||||
| ||
|
|
||||||
| |`{closure@$DIR/issue-62009-1.rs:12:6: 12:9}` is not a future
|
|
||||||
| help: remove the `.await`
|
|
||||||
|
|
|
||||||
= help: the trait `Future` is not implemented for closure `{closure@$DIR/issue-62009-1.rs:12:6: 12:9}`
|
|
||||||
= note: {closure@$DIR/issue-62009-1.rs:12:6: 12:9} must be a future or must implement `IntoFuture` to be awaited
|
|
||||||
= note: required for `{closure@$DIR/issue-62009-1.rs:12:6: 12:9}` to implement `IntoFuture`
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
For more information about this error, try `rustc --explain E0728`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0728.
|
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
11
tests/ui/coroutine/auxiliary/unwind-aux.rs
Normal file
11
tests/ui/coroutine/auxiliary/unwind-aux.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// compile-flags: -Cpanic=unwind --crate-type=lib
|
||||||
|
// no-prefer-dynamic
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![feature(coroutines)]
|
||||||
|
pub fn run<T>(a: T) {
|
||||||
|
let _ = move || {
|
||||||
|
drop(a);
|
||||||
|
yield;
|
||||||
|
};
|
||||||
|
}
|
13
tests/ui/coroutine/unwind-abort-mix.rs
Normal file
13
tests/ui/coroutine/unwind-abort-mix.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Ensure that coroutine drop glue is valid when mixing different panic
|
||||||
|
// strategies. Regression test for #116953.
|
||||||
|
//
|
||||||
|
// no-prefer-dynamic
|
||||||
|
// build-pass
|
||||||
|
// aux-build:unwind-aux.rs
|
||||||
|
// compile-flags: -Cpanic=abort
|
||||||
|
// needs-unwind
|
||||||
|
extern crate unwind_aux;
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
unwind_aux::run(String::new());
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user