mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
hir
: Add Become
expression kind
This commit is contained in:
parent
97bf23d26b
commit
ccb71ff424
@ -277,9 +277,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
ExprKind::Yeet(sub_expr) => self.lower_expr_yeet(e.span, sub_expr.as_deref()),
|
||||
ExprKind::Become(sub_expr) => {
|
||||
let sub_expr = self.lower_expr(sub_expr);
|
||||
|
||||
// FIXME(explicit_tail_calls): Use `hir::ExprKind::Become` once we implemented it
|
||||
hir::ExprKind::Ret(Some(sub_expr))
|
||||
hir::ExprKind::Become(sub_expr)
|
||||
}
|
||||
ExprKind::InlineAsm(asm) => {
|
||||
hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm))
|
||||
|
@ -1719,6 +1719,7 @@ impl Expr<'_> {
|
||||
ExprKind::Break(..) => ExprPrecedence::Break,
|
||||
ExprKind::Continue(..) => ExprPrecedence::Continue,
|
||||
ExprKind::Ret(..) => ExprPrecedence::Ret,
|
||||
ExprKind::Become(..) => ExprPrecedence::Become,
|
||||
ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
|
||||
ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf,
|
||||
ExprKind::Struct(..) => ExprPrecedence::Struct,
|
||||
@ -1776,6 +1777,7 @@ impl Expr<'_> {
|
||||
| ExprKind::Break(..)
|
||||
| ExprKind::Continue(..)
|
||||
| ExprKind::Ret(..)
|
||||
| ExprKind::Become(..)
|
||||
| ExprKind::Let(..)
|
||||
| ExprKind::Loop(..)
|
||||
| ExprKind::Assign(..)
|
||||
@ -1866,6 +1868,7 @@ impl Expr<'_> {
|
||||
| ExprKind::Break(..)
|
||||
| ExprKind::Continue(..)
|
||||
| ExprKind::Ret(..)
|
||||
| ExprKind::Become(..)
|
||||
| ExprKind::Let(..)
|
||||
| ExprKind::Loop(..)
|
||||
| ExprKind::Assign(..)
|
||||
@ -2025,6 +2028,8 @@ pub enum ExprKind<'hir> {
|
||||
Continue(Destination),
|
||||
/// A `return`, with an optional value to be returned.
|
||||
Ret(Option<&'hir Expr<'hir>>),
|
||||
/// A `become`, with the value to be returned.
|
||||
Become(&'hir Expr<'hir>),
|
||||
|
||||
/// Inline assembly (from `asm!`), with its outputs and inputs.
|
||||
InlineAsm(&'hir InlineAsm<'hir>),
|
||||
|
@ -791,6 +791,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
|
||||
ExprKind::Ret(ref optional_expression) => {
|
||||
walk_list!(visitor, visit_expr, optional_expression);
|
||||
}
|
||||
ExprKind::Become(ref expr) => visitor.visit_expr(expr),
|
||||
ExprKind::InlineAsm(ref asm) => {
|
||||
visitor.visit_inline_asm(asm, expression.hir_id);
|
||||
}
|
||||
|
@ -1554,6 +1554,11 @@ impl<'a> State<'a> {
|
||||
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Become(result) => {
|
||||
self.word("become");
|
||||
self.word(" ");
|
||||
self.print_expr_maybe_paren(result, parser::PREC_JUMP);
|
||||
}
|
||||
hir::ExprKind::InlineAsm(asm) => {
|
||||
self.word("asm!");
|
||||
self.print_inline_asm(asm);
|
||||
|
@ -78,8 +78,8 @@ hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang
|
||||
hir_typeck_op_trait_generic_params = `{$method_name}` must not have any generic parameters
|
||||
|
||||
hir_typeck_return_stmt_outside_of_fn_body =
|
||||
return statement outside of function body
|
||||
.encl_body_label = the return is part of this body...
|
||||
{$statement_kind} statement outside of function body
|
||||
.encl_body_label = the {$statement_kind} is part of this body...
|
||||
.encl_fn_label = ...not the enclosing function body
|
||||
|
||||
hir_typeck_struct_expr_non_exhaustive =
|
||||
|
@ -2,7 +2,10 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::fluent_generated as fluent;
|
||||
use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage};
|
||||
use rustc_errors::{
|
||||
AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg, MultiSpan,
|
||||
SubdiagnosticMessage,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::{
|
||||
@ -31,6 +34,24 @@ pub struct ReturnStmtOutsideOfFnBody {
|
||||
pub encl_body_span: Option<Span>,
|
||||
#[label(hir_typeck_encl_fn_label)]
|
||||
pub encl_fn_span: Option<Span>,
|
||||
pub statement_kind: ReturnLikeStatementKind,
|
||||
}
|
||||
|
||||
pub enum ReturnLikeStatementKind {
|
||||
Return,
|
||||
Become,
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for ReturnLikeStatementKind {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
let kind = match self {
|
||||
Self::Return => "return",
|
||||
Self::Become => "become",
|
||||
}
|
||||
.into();
|
||||
|
||||
DiagnosticArgValue::Str(kind)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -5,6 +5,7 @@
|
||||
use crate::cast;
|
||||
use crate::coercion::CoerceMany;
|
||||
use crate::coercion::DynamicCoerceMany;
|
||||
use crate::errors::ReturnLikeStatementKind;
|
||||
use crate::errors::TypeMismatchFruTypo;
|
||||
use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
|
||||
use crate::errors::{
|
||||
@ -324,6 +325,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr),
|
||||
ExprKind::Become(call) => self.check_expr_become(call, expr),
|
||||
ExprKind::Let(let_expr) => self.check_expr_let(let_expr),
|
||||
ExprKind::Loop(body, _, source, _) => {
|
||||
self.check_expr_loop(body, source, expected, expr)
|
||||
@ -735,47 +737,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
if self.ret_coercion.is_none() {
|
||||
let mut err = ReturnStmtOutsideOfFnBody {
|
||||
span: expr.span,
|
||||
encl_body_span: None,
|
||||
encl_fn_span: None,
|
||||
};
|
||||
|
||||
let encl_item_id = self.tcx.hir().get_parent_item(expr.hir_id);
|
||||
|
||||
if let Some(hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Fn(..),
|
||||
span: encl_fn_span,
|
||||
..
|
||||
}))
|
||||
| Some(hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
|
||||
span: encl_fn_span,
|
||||
..
|
||||
}))
|
||||
| Some(hir::Node::ImplItem(hir::ImplItem {
|
||||
kind: hir::ImplItemKind::Fn(..),
|
||||
span: encl_fn_span,
|
||||
..
|
||||
})) = self.tcx.hir().find_by_def_id(encl_item_id.def_id)
|
||||
{
|
||||
// We are inside a function body, so reporting "return statement
|
||||
// outside of function body" needs an explanation.
|
||||
|
||||
let encl_body_owner_id = self.tcx.hir().enclosing_body_owner(expr.hir_id);
|
||||
|
||||
// If this didn't hold, we would not have to report an error in
|
||||
// the first place.
|
||||
assert_ne!(encl_item_id.def_id, encl_body_owner_id);
|
||||
|
||||
let encl_body_id = self.tcx.hir().body_owned_by(encl_body_owner_id);
|
||||
let encl_body = self.tcx.hir().body(encl_body_id);
|
||||
|
||||
err.encl_body_span = Some(encl_body.value.span);
|
||||
err.encl_fn_span = Some(*encl_fn_span);
|
||||
}
|
||||
|
||||
self.tcx.sess.emit_err(err);
|
||||
self.emit_return_outside_of_fn_body(expr, ReturnLikeStatementKind::Return);
|
||||
|
||||
if let Some(e) = expr_opt {
|
||||
// We still have to type-check `e` (issue #86188), but calling
|
||||
@ -815,6 +777,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.tcx.types.never
|
||||
}
|
||||
|
||||
fn check_expr_become(
|
||||
&self,
|
||||
call: &'tcx hir::Expr<'tcx>,
|
||||
expr: &'tcx hir::Expr<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
match &self.ret_coercion {
|
||||
Some(ret_coercion) => {
|
||||
let ret_ty = ret_coercion.borrow().expected_ty();
|
||||
let call_expr_ty = self.check_expr_with_hint(call, ret_ty);
|
||||
|
||||
// N.B. don't coerce here, as tail calls can't support most/all coercions
|
||||
// FIXME(explicit_tail_calls): add a diagnostic note that `become` doesn't allow coercions
|
||||
self.demand_suptype(expr.span, ret_ty, call_expr_ty);
|
||||
}
|
||||
None => {
|
||||
self.emit_return_outside_of_fn_body(expr, ReturnLikeStatementKind::Become);
|
||||
|
||||
// Fallback to simply type checking `call` without hint/demanding the right types.
|
||||
// Best effort to highlight more errors.
|
||||
self.check_expr(call);
|
||||
}
|
||||
}
|
||||
|
||||
self.tcx.types.never
|
||||
}
|
||||
|
||||
/// Check an expression that _is being returned_.
|
||||
/// For example, this is called with `return_expr: $expr` when `return $expr`
|
||||
/// is encountered.
|
||||
///
|
||||
/// Note that this function must only be called in function bodies.
|
||||
///
|
||||
/// `explicit_return` is `true` if we're checking an explicit `return expr`,
|
||||
/// and `false` if we're checking a trailing expression.
|
||||
pub(super) fn check_return_expr(
|
||||
@ -831,10 +825,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let mut span = return_expr.span;
|
||||
// Use the span of the trailing expression for our cause,
|
||||
// not the span of the entire function
|
||||
if !explicit_return {
|
||||
if let ExprKind::Block(body, _) = return_expr.kind && let Some(last_expr) = body.expr {
|
||||
if !explicit_return
|
||||
&& let ExprKind::Block(body, _) = return_expr.kind
|
||||
&& let Some(last_expr) = body.expr
|
||||
{
|
||||
span = last_expr.span;
|
||||
}
|
||||
}
|
||||
ret_coercion.borrow_mut().coerce(
|
||||
self,
|
||||
@ -854,6 +849,55 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit an error because `return` or `become` is used outside of a function body.
|
||||
///
|
||||
/// `expr` is the `return` (`become`) "statement", `kind` is the kind of the statement
|
||||
/// either `Return` or `Become`.
|
||||
fn emit_return_outside_of_fn_body(&self, expr: &hir::Expr<'_>, kind: ReturnLikeStatementKind) {
|
||||
let mut err = ReturnStmtOutsideOfFnBody {
|
||||
span: expr.span,
|
||||
encl_body_span: None,
|
||||
encl_fn_span: None,
|
||||
statement_kind: kind,
|
||||
};
|
||||
|
||||
let encl_item_id = self.tcx.hir().get_parent_item(expr.hir_id);
|
||||
|
||||
if let Some(hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Fn(..),
|
||||
span: encl_fn_span,
|
||||
..
|
||||
}))
|
||||
| Some(hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)),
|
||||
span: encl_fn_span,
|
||||
..
|
||||
}))
|
||||
| Some(hir::Node::ImplItem(hir::ImplItem {
|
||||
kind: hir::ImplItemKind::Fn(..),
|
||||
span: encl_fn_span,
|
||||
..
|
||||
})) = self.tcx.hir().find_by_def_id(encl_item_id.def_id)
|
||||
{
|
||||
// We are inside a function body, so reporting "return statement
|
||||
// outside of function body" needs an explanation.
|
||||
|
||||
let encl_body_owner_id = self.tcx.hir().enclosing_body_owner(expr.hir_id);
|
||||
|
||||
// If this didn't hold, we would not have to report an error in
|
||||
// the first place.
|
||||
assert_ne!(encl_item_id.def_id, encl_body_owner_id);
|
||||
|
||||
let encl_body_id = self.tcx.hir().body_owned_by(encl_body_owner_id);
|
||||
let encl_body = self.tcx.hir().body(encl_body_id);
|
||||
|
||||
err.encl_body_span = Some(encl_body.value.span);
|
||||
err.encl_fn_span = Some(*encl_fn_span);
|
||||
}
|
||||
|
||||
self.tcx.sess.emit_err(err);
|
||||
}
|
||||
|
||||
fn point_at_return_for_opaque_ty_error(
|
||||
&self,
|
||||
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
|
||||
|
@ -326,6 +326,10 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
hir::ExprKind::Become(call) => {
|
||||
self.consume_expr(call);
|
||||
}
|
||||
|
||||
hir::ExprKind::Assign(lhs, rhs, _) => {
|
||||
self.mutate_expr(lhs);
|
||||
self.consume_expr(rhs);
|
||||
|
@ -214,6 +214,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
|
||||
| ExprKind::Break(..)
|
||||
| ExprKind::Continue(..)
|
||||
| ExprKind::Ret(..)
|
||||
| ExprKind::Become(..)
|
||||
| ExprKind::InlineAsm(..)
|
||||
| ExprKind::OffsetOf(..)
|
||||
| ExprKind::Struct(..)
|
||||
@ -451,6 +452,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
ExprKind::Become(_call) => bug!("encountered a tail-call inside a generator"),
|
||||
|
||||
ExprKind::Call(f, args) => {
|
||||
self.visit_expr(f);
|
||||
for arg in args {
|
||||
|
@ -361,6 +361,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
|
||||
| hir::ExprKind::AssignOp(..)
|
||||
| hir::ExprKind::Closure { .. }
|
||||
| hir::ExprKind::Ret(..)
|
||||
| hir::ExprKind::Become(..)
|
||||
| hir::ExprKind::Unary(..)
|
||||
| hir::ExprKind::Yield(..)
|
||||
| hir::ExprKind::MethodCall(..)
|
||||
|
@ -695,6 +695,11 @@ impl<'tcx> Cx<'tcx> {
|
||||
ExprKind::Repeat { value: self.mirror_expr(v), count: *count }
|
||||
}
|
||||
hir::ExprKind::Ret(ref v) => ExprKind::Return { value: v.map(|v| self.mirror_expr(v)) },
|
||||
hir::ExprKind::Become(call) => {
|
||||
// FIXME(explicit_tail_calls): use `ExprKind::Become` once we implemented it
|
||||
// Temporary transform `become` into a `return`, so we can write tests for code before this stage
|
||||
ExprKind::Return { value: Some(self.mirror_expr(call)) }
|
||||
}
|
||||
hir::ExprKind::Break(dest, ref value) => match dest.target_id {
|
||||
Ok(target_id) => ExprKind::Break {
|
||||
label: region::Scope { id: target_id.local_id, data: region::ScopeData::Node },
|
||||
|
@ -302,8 +302,8 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||
[
|
||||
ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type,
|
||||
DropTemps, Let, If, Loop, Match, Closure, Block, Assign, AssignOp, Field, Index,
|
||||
Path, AddrOf, Break, Continue, Ret, InlineAsm, OffsetOf, Struct, Repeat, Yield,
|
||||
Err
|
||||
Path, AddrOf, Break, Continue, Ret, Become, InlineAsm, OffsetOf, Struct, Repeat,
|
||||
Yield, Err
|
||||
]
|
||||
);
|
||||
hir_visit::walk_expr(self, e)
|
||||
|
@ -463,6 +463,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
|
||||
| hir::ExprKind::Lit(_)
|
||||
| hir::ExprKind::ConstBlock(..)
|
||||
| hir::ExprKind::Ret(..)
|
||||
| hir::ExprKind::Become(..)
|
||||
| hir::ExprKind::Block(..)
|
||||
| hir::ExprKind::Assign(..)
|
||||
| hir::ExprKind::AssignOp(..)
|
||||
@ -967,6 +968,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
self.propagate_through_opt_expr(o_e.as_deref(), self.exit_ln)
|
||||
}
|
||||
|
||||
hir::ExprKind::Become(ref e) => {
|
||||
// Ignore succ and subst exit_ln.
|
||||
self.propagate_through_expr(e, self.exit_ln)
|
||||
}
|
||||
|
||||
hir::ExprKind::Break(label, ref opt_expr) => {
|
||||
// Find which label this break jumps to
|
||||
let target = match label.target_id {
|
||||
@ -1408,6 +1414,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||
| hir::ExprKind::DropTemps(..)
|
||||
| hir::ExprKind::Unary(..)
|
||||
| hir::ExprKind::Ret(..)
|
||||
| hir::ExprKind::Become(..)
|
||||
| hir::ExprKind::Break(..)
|
||||
| hir::ExprKind::Continue(..)
|
||||
| hir::ExprKind::Lit(_)
|
||||
|
@ -204,6 +204,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
|
||||
| ExprKind::Continue(..)
|
||||
| ExprKind::Ret(..)
|
||||
| ExprKind::OffsetOf(..)
|
||||
| ExprKind::Become(..)
|
||||
| ExprKind::Struct(..)
|
||||
| ExprKind::Repeat(..)
|
||||
| ExprKind::Yield(..) => {
|
||||
|
@ -11,7 +11,7 @@ use std::path::{Path, PathBuf};
|
||||
const ENTRY_LIMIT: usize = 900;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1896;
|
||||
const ROOT_ENTRY_LIMIT: usize = 870;
|
||||
const ROOT_ENTRY_LIMIT: usize = 871;
|
||||
|
||||
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
||||
"rs", // test source files
|
||||
|
9
tests/ui/explicit-tail-calls/become-outside.array.stderr
Normal file
9
tests/ui/explicit-tail-calls/become-outside.array.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0572]: become statement outside of function body
|
||||
--> $DIR/become-outside.rs:11:17
|
||||
|
|
||||
LL | struct Bad([(); become f()]);
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0572`.
|
@ -0,0 +1,9 @@
|
||||
error[E0572]: become statement outside of function body
|
||||
--> $DIR/become-outside.rs:7:5
|
||||
|
|
||||
LL | become f();
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0572`.
|
15
tests/ui/explicit-tail-calls/become-outside.rs
Normal file
15
tests/ui/explicit-tail-calls/become-outside.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// revisions: constant array
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(explicit_tail_calls)]
|
||||
|
||||
#[cfg(constant)]
|
||||
const _: () = {
|
||||
become f(); //[constant]~ error: become statement outside of function body
|
||||
};
|
||||
|
||||
#[cfg(array)]
|
||||
struct Bad([(); become f()]); //[array]~ error: become statement outside of function body
|
||||
|
||||
fn f() {}
|
||||
|
||||
fn main() {}
|
13
tests/ui/explicit-tail-calls/return-lifetime-sub.rs
Normal file
13
tests/ui/explicit-tail-calls/return-lifetime-sub.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// check-pass
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(explicit_tail_calls)]
|
||||
|
||||
fn _f<'a>() -> &'a [u8] {
|
||||
become _g();
|
||||
}
|
||||
|
||||
fn _g() -> &'static [u8] {
|
||||
&[0, 1, 2, 3]
|
||||
}
|
||||
|
||||
fn main() {}
|
28
tests/ui/explicit-tail-calls/return-mismatches.rs
Normal file
28
tests/ui/explicit-tail-calls/return-mismatches.rs
Normal file
@ -0,0 +1,28 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(explicit_tail_calls)]
|
||||
|
||||
fn _f0<'a>() -> &'static [u8] {
|
||||
become _g0(); //~ error: mismatched types
|
||||
}
|
||||
|
||||
fn _g0() -> &'static [u8; 1] {
|
||||
&[0]
|
||||
}
|
||||
|
||||
fn _f1() {
|
||||
become _g1(); //~ error: mismatched types
|
||||
}
|
||||
|
||||
fn _g1() -> ! {
|
||||
become _g1();
|
||||
}
|
||||
|
||||
fn _f2() -> u32 {
|
||||
become _g2(); //~ error: mismatched types
|
||||
}
|
||||
|
||||
fn _g2() -> u16 {
|
||||
0
|
||||
}
|
||||
|
||||
fn main() {}
|
27
tests/ui/explicit-tail-calls/return-mismatches.stderr
Normal file
27
tests/ui/explicit-tail-calls/return-mismatches.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-mismatches.rs:5:5
|
||||
|
|
||||
LL | become _g0();
|
||||
| ^^^^^^^^^^^^ expected `&[u8]`, found `&[u8; 1]`
|
||||
|
|
||||
= note: expected reference `&'static [u8]`
|
||||
found reference `&'static [u8; 1]`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-mismatches.rs:13:5
|
||||
|
|
||||
LL | become _g1();
|
||||
| ^^^^^^^^^^^^ expected `()`, found `!`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found type `!`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/return-mismatches.rs:21:5
|
||||
|
|
||||
LL | become _g2();
|
||||
| ^^^^^^^^^^^^ expected `u32`, found `u16`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -1,9 +1,9 @@
|
||||
fn main() {
|
||||
//~^ NOTE: not the enclosing function body
|
||||
//~| NOTE: not the enclosing function body
|
||||
//~| NOTE: not the enclosing function body
|
||||
//~| NOTE: not the enclosing function body
|
||||
|_: [_; return || {}] | {};
|
||||
//~^ NOTE: not the enclosing function body
|
||||
//~| NOTE: not the enclosing function body
|
||||
//~| NOTE: not the enclosing function body
|
||||
//~| NOTE: not the enclosing function body
|
||||
|_: [_; return || {}]| {};
|
||||
//~^ ERROR: return statement outside of function body [E0572]
|
||||
//~| NOTE: the return is part of this body...
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
error[E0572]: return statement outside of function body
|
||||
--> $DIR/issue-51714.rs:6:14
|
||||
--> $DIR/issue-51714.rs:6:13
|
||||
|
|
||||
LL | / fn main() {
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | |_: [_; return || {}] | {};
|
||||
| | ^^^^^^^^^^^^ the return is part of this body...
|
||||
LL | | |_: [_; return || {}]| {};
|
||||
| | ^^^^^^^^^^^^ the return is part of this body...
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
|
@ -1,5 +1,5 @@
|
||||
enum Bug {
|
||||
V1 = return [0][0] //~ERROR return statement outside of function body
|
||||
V1 = return [0][0], //~ERROR return statement outside of function body
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
error[E0572]: return statement outside of function body
|
||||
--> $DIR/issue-64620.rs:2:10
|
||||
|
|
||||
LL | V1 = return [0][0]
|
||||
LL | V1 = return [0][0],
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
const C: [(); 42] = {
|
||||
[(); return || {
|
||||
//~^ ERROR: return statement outside of function body [E0572]
|
||||
//~^ ERROR: return statement outside of function body [E0572]
|
||||
let tx;
|
||||
}]
|
||||
};
|
||||
@ -16,7 +16,7 @@ struct S {}
|
||||
trait Tr {
|
||||
fn foo();
|
||||
fn bar() {
|
||||
//~^ NOTE: ...not the enclosing function body
|
||||
//~^ NOTE: ...not the enclosing function body
|
||||
[(); return];
|
||||
//~^ ERROR: return statement outside of function body [E0572]
|
||||
//~| NOTE: the return is part of this body...
|
||||
@ -24,7 +24,7 @@ trait Tr {
|
||||
}
|
||||
impl Tr for S {
|
||||
fn foo() {
|
||||
//~^ NOTE: ...not the enclosing function body
|
||||
//~^ NOTE: ...not the enclosing function body
|
||||
[(); return];
|
||||
//~^ ERROR: return statement outside of function body [E0572]
|
||||
//~| NOTE: the return is part of this body...
|
||||
@ -32,10 +32,10 @@ impl Tr for S {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
//~^ NOTE: ...not the enclosing function body
|
||||
//~^ NOTE: ...not the enclosing function body
|
||||
[(); return || {
|
||||
//~^ ERROR: return statement outside of function body [E0572]
|
||||
//~| NOTE: the return is part of this body...
|
||||
//~^ ERROR: return statement outside of function body [E0572]
|
||||
//~| NOTE: the return is part of this body...
|
||||
let tx;
|
||||
}];
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
// > Suggest `return`ing tail expressions that match return type
|
||||
// > Suggest returning tail expressions that match return type
|
||||
// >
|
||||
// > Some newcomers are confused by the behavior of tail expressions,
|
||||
// > interpreting that "leaving out the `;` makes it the return value".
|
||||
// > To help them go in the right direction, suggest using `return` instead
|
||||
// > To help them go in the right direction, suggest using return instead
|
||||
// > when applicable.
|
||||
// (original commit description for this test)
|
||||
//
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
// revisions: rev1 rev2
|
||||
#![cfg_attr(any(), rev1, rev2)]
|
||||
#![crate_type="lib"]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
#[cfg(any(rev1))]
|
||||
trait T {
|
||||
|
Loading…
Reference in New Issue
Block a user