Auto merge of #39470 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 9 pull requests - Successful merges: #38823, #39196, #39299, #39319, #39373, #39383, #39416, #39420, #39427 - Failed merges:
This commit is contained in:
commit
eedaa94e33
1
.mailmap
1
.mailmap
@ -167,6 +167,7 @@ Ožbolt Menegatti <ozbolt.menegatti@gmail.com> gareins <ozbolt.menegatti@gmail.c
|
|||||||
Paul Faria <paul_faria@ultimatesoftware.com> Paul Faria <Nashenas88@gmail.com>
|
Paul Faria <paul_faria@ultimatesoftware.com> Paul Faria <Nashenas88@gmail.com>
|
||||||
Peer Aramillo Irizar <peer.aramillo.irizar@gmail.com> parir <peer.aramillo.irizar@gmail.com>
|
Peer Aramillo Irizar <peer.aramillo.irizar@gmail.com> parir <peer.aramillo.irizar@gmail.com>
|
||||||
Peter Elmers <peter.elmers@yahoo.com> <peter.elmers@rice.edu>
|
Peter Elmers <peter.elmers@yahoo.com> <peter.elmers@rice.edu>
|
||||||
|
Peter Liniker <peter.liniker+github@gmail.com>
|
||||||
Peter Zotov <whitequark@whitequark.org>
|
Peter Zotov <whitequark@whitequark.org>
|
||||||
Phil Dawes <phil@phildawes.net> Phil Dawes <pdawes@drw.com>
|
Phil Dawes <phil@phildawes.net> Phil Dawes <pdawes@drw.com>
|
||||||
Philipp Brüschweiler <blei42@gmail.com> <blei42@gmail.com>
|
Philipp Brüschweiler <blei42@gmail.com> <blei42@gmail.com>
|
||||||
|
@ -499,6 +499,10 @@ be imported in every test with `mod common;`
|
|||||||
That's all there is to the `tests` directory. The `tests` module isn't needed
|
That's all there is to the `tests` directory. The `tests` module isn't needed
|
||||||
here, since the whole thing is focused on tests.
|
here, since the whole thing is focused on tests.
|
||||||
|
|
||||||
|
Note, when building integration tests, cargo will not pass the `test` attribute
|
||||||
|
to the compiler. It means that all parts in `cfg(test)` won't be included in
|
||||||
|
the build used in your integration tests.
|
||||||
|
|
||||||
Let's finally check out that third section: documentation tests.
|
Let's finally check out that third section: documentation tests.
|
||||||
|
|
||||||
# Documentation tests
|
# Documentation tests
|
||||||
|
@ -199,24 +199,42 @@ assert (unsafely) that a generic type's destructor is *guaranteed* to
|
|||||||
not access any expired data, even if its type gives it the capability
|
not access any expired data, even if its type gives it the capability
|
||||||
to do so.
|
to do so.
|
||||||
|
|
||||||
That attribute is called `unsafe_destructor_blind_to_params`.
|
That attribute is called `may_dangle` and was introduced in [RFC 1327]
|
||||||
|
(https://github.com/rust-lang/rfcs/blob/master/text/1327-dropck-param-eyepatch.md).
|
||||||
To deploy it on the Inspector example from above, we would write:
|
To deploy it on the Inspector example from above, we would write:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
struct Inspector<'a>(&'a u8, &'static str);
|
struct Inspector<'a>(&'a u8, &'static str);
|
||||||
|
|
||||||
impl<'a> Drop for Inspector<'a> {
|
unsafe impl<#[may_dangle] 'a> Drop for Inspector<'a> {
|
||||||
#[unsafe_destructor_blind_to_params]
|
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
println!("Inspector(_, {}) knows when *not* to inspect.", self.1);
|
println!("Inspector(_, {}) knows when *not* to inspect.", self.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This attribute has the word `unsafe` in it because the compiler is not
|
Use of this attribute requires the `Drop` impl to be marked `unsafe` because the
|
||||||
checking the implicit assertion that no potentially expired data
|
compiler is not checking the implicit assertion that no potentially expired data
|
||||||
(e.g. `self.0` above) is accessed.
|
(e.g. `self.0` above) is accessed.
|
||||||
|
|
||||||
|
The attribute can be applied to any number of lifetime and type parameters. In
|
||||||
|
the following example, we assert that we access no data behind a reference of
|
||||||
|
lifetime `'b` and that the only uses of `T` will be moves or drops, but omit
|
||||||
|
the attribute from `'a` and `U`, because we do access data with that lifetime
|
||||||
|
and that type:
|
||||||
|
|
||||||
|
```rust,ignore
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
struct Inspector<'a, 'b, T, U: Display>(&'a u8, &'b u8, T, U);
|
||||||
|
|
||||||
|
unsafe impl<'a, #[may_dangle] 'b, #[may_dangle] T, U: Display> Drop for Inspector<'a, 'b, T, U> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("Inspector({}, _, _, {})", self.0, self.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
It is sometimes obvious that no such access can occur, like the case above.
|
It is sometimes obvious that no such access can occur, like the case above.
|
||||||
However, when dealing with a generic type parameter, such access can
|
However, when dealing with a generic type parameter, such access can
|
||||||
occur indirectly. Examples of such indirect access are:
|
occur indirectly. Examples of such indirect access are:
|
||||||
@ -263,7 +281,7 @@ some other method invoked by the destructor, rather than being written
|
|||||||
directly within it.
|
directly within it.
|
||||||
|
|
||||||
In all of the above cases where the `&'a u8` is accessed in the
|
In all of the above cases where the `&'a u8` is accessed in the
|
||||||
destructor, adding the `#[unsafe_destructor_blind_to_params]`
|
destructor, adding the `#[may_dangle]`
|
||||||
attribute makes the type vulnerable to misuse that the borrower
|
attribute makes the type vulnerable to misuse that the borrower
|
||||||
checker will not catch, inviting havoc. It is better to avoid adding
|
checker will not catch, inviting havoc. It is better to avoid adding
|
||||||
the attribute.
|
the attribute.
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
//! pointer to the same value in the heap. When the last [`Rc`] pointer to a
|
//! pointer to the same value in the heap. When the last [`Rc`] pointer to a
|
||||||
//! given value is destroyed, the pointed-to value is also destroyed.
|
//! given value is destroyed, the pointed-to value is also destroyed.
|
||||||
//!
|
//!
|
||||||
//! Shared references in Rust disallow mutation by default, and `Rc` is no
|
//! Shared references in Rust disallow mutation by default, and [`Rc`]
|
||||||
//! exception. If you need to mutate through an [`Rc`], use [`Cell`] or
|
//! is no exception: you cannot obtain a mutable reference to
|
||||||
//! [`RefCell`].
|
//! something inside an [`Rc`]. If you need mutability, put a [`Cell`]
|
||||||
|
//! or [`RefCell`] inside the [`Rc`]; see [an example of mutability
|
||||||
|
//! inside an Rc][mutability].
|
||||||
//!
|
//!
|
||||||
//! [`Rc`] uses non-atomic reference counting. This means that overhead is very
|
//! [`Rc`] uses non-atomic reference counting. This means that overhead is very
|
||||||
//! low, but an [`Rc`] cannot be sent between threads, and consequently [`Rc`]
|
//! low, but an [`Rc`] cannot be sent between threads, and consequently [`Rc`]
|
||||||
@ -214,6 +216,7 @@
|
|||||||
//! [upgrade]: struct.Weak.html#method.upgrade
|
//! [upgrade]: struct.Weak.html#method.upgrade
|
||||||
//! [`None`]: ../../std/option/enum.Option.html#variant.None
|
//! [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||||
//! [assoc]: ../../book/method-syntax.html#associated-functions
|
//! [assoc]: ../../book/method-syntax.html#associated-functions
|
||||||
|
//! [mutability]: ../../std/cell/index.html#introducing-mutability-inside-of-something-immutable
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")]
|
#![stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
||||||
|
@ -109,7 +109,6 @@ pub mod util {
|
|||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod ppaux;
|
pub mod ppaux;
|
||||||
pub mod nodemap;
|
pub mod nodemap;
|
||||||
pub mod num;
|
|
||||||
pub mod fs;
|
pub mod fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
pub trait ToPrimitive {
|
|
||||||
fn to_i8(&self) -> Option<i8>;
|
|
||||||
fn to_i16(&self) -> Option<i16>;
|
|
||||||
fn to_i32(&self) -> Option<i32>;
|
|
||||||
fn to_i64(&self) -> Option<i64>;
|
|
||||||
fn to_u8(&self) -> Option<u8>;
|
|
||||||
fn to_u16(&self) -> Option<u16>;
|
|
||||||
fn to_u32(&self) -> Option<u32>;
|
|
||||||
fn to_u64(&self) -> Option<u64>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToPrimitive for i64 {
|
|
||||||
fn to_i8(&self) -> Option<i8> {
|
|
||||||
if *self < i8::min_value() as i64 || *self > i8::max_value() as i64 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(*self as i8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn to_i16(&self) -> Option<i16> {
|
|
||||||
if *self < i16::min_value() as i64 || *self > i16::max_value() as i64 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(*self as i16)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn to_i32(&self) -> Option<i32> {
|
|
||||||
if *self < i32::min_value() as i64 || *self > i32::max_value() as i64 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(*self as i32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn to_i64(&self) -> Option<i64> {
|
|
||||||
Some(*self)
|
|
||||||
}
|
|
||||||
fn to_u8(&self) -> Option<u8> {
|
|
||||||
if *self < 0 || *self > u8::max_value() as i64 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(*self as u8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn to_u16(&self) -> Option<u16> {
|
|
||||||
if *self < 0 || *self > u16::max_value() as i64 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(*self as u16)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn to_u32(&self) -> Option<u32> {
|
|
||||||
if *self < 0 || *self > u32::max_value() as i64 {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(*self as u32)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn to_u64(&self) -> Option<u64> {
|
|
||||||
if *self < 0 {None} else {Some(*self as u64)}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToPrimitive for u64 {
|
|
||||||
fn to_i8(&self) -> Option<i8> {
|
|
||||||
if *self > i8::max_value() as u64 {None} else {Some(*self as i8)}
|
|
||||||
}
|
|
||||||
fn to_i16(&self) -> Option<i16> {
|
|
||||||
if *self > i16::max_value() as u64 {None} else {Some(*self as i16)}
|
|
||||||
}
|
|
||||||
fn to_i32(&self) -> Option<i32> {
|
|
||||||
if *self > i32::max_value() as u64 {None} else {Some(*self as i32)}
|
|
||||||
}
|
|
||||||
fn to_i64(&self) -> Option<i64> {
|
|
||||||
if *self > i64::max_value() as u64 {None} else {Some(*self as i64)}
|
|
||||||
}
|
|
||||||
fn to_u8(&self) -> Option<u8> {
|
|
||||||
if *self > u8::max_value() as u64 {None} else {Some(*self as u8)}
|
|
||||||
}
|
|
||||||
fn to_u16(&self) -> Option<u16> {
|
|
||||||
if *self > u16::max_value() as u64 {None} else {Some(*self as u16)}
|
|
||||||
}
|
|
||||||
fn to_u32(&self) -> Option<u32> {
|
|
||||||
if *self > u32::max_value() as u64 {None} else {Some(*self as u32)}
|
|
||||||
}
|
|
||||||
fn to_u64(&self) -> Option<u64> {
|
|
||||||
Some(*self)
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,8 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
//#![allow(non_camel_case_types)]
|
|
||||||
|
|
||||||
use rustc::middle::const_val::ConstVal::*;
|
use rustc::middle::const_val::ConstVal::*;
|
||||||
use rustc::middle::const_val::ConstVal;
|
use rustc::middle::const_val::ConstVal;
|
||||||
use self::ErrKind::*;
|
use self::ErrKind::*;
|
||||||
|
@ -804,7 +804,7 @@ extern "C" {
|
|||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMRustAddHandler(CatchSwitch: ValueRef, Handler: BasicBlockRef);
|
pub fn LLVMRustAddHandler(CatchSwitch: ValueRef, Handler: BasicBlockRef);
|
||||||
pub fn LLVMRustSetPersonalityFn(B: BuilderRef, Pers: ValueRef);
|
pub fn LLVMSetPersonalityFn(Func: ValueRef, Pers: ValueRef);
|
||||||
|
|
||||||
// Add a case to the switch instruction
|
// Add a case to the switch instruction
|
||||||
pub fn LLVMAddCase(Switch: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef);
|
pub fn LLVMAddCase(Switch: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef);
|
||||||
|
@ -16,8 +16,6 @@ use rustc::hir;
|
|||||||
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
pub fn ast_block(&mut self,
|
pub fn ast_block(&mut self,
|
||||||
destination: &Lvalue<'tcx>,
|
destination: &Lvalue<'tcx>,
|
||||||
// FIXME(#32959): temporary measure for the issue
|
|
||||||
dest_is_unit: bool,
|
|
||||||
mut block: BasicBlock,
|
mut block: BasicBlock,
|
||||||
ast_block: &'tcx hir::Block)
|
ast_block: &'tcx hir::Block)
|
||||||
-> BlockAnd<()> {
|
-> BlockAnd<()> {
|
||||||
@ -83,8 +81,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
// of the block.
|
// of the block.
|
||||||
if let Some(expr) = expr {
|
if let Some(expr) = expr {
|
||||||
unpack!(block = this.into(destination, block, expr));
|
unpack!(block = this.into(destination, block, expr));
|
||||||
} else if dest_is_unit {
|
} else {
|
||||||
// FIXME(#31472)
|
|
||||||
let source_info = this.source_info(span);
|
let source_info = this.source_info(span);
|
||||||
this.cfg.push_assign_unit(block, source_info, destination);
|
this.cfg.push_assign_unit(block, source_info, destination);
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||||||
this.in_scope(extent, block, |this| this.into(destination, block, value))
|
this.in_scope(extent, block, |this| this.into(destination, block, value))
|
||||||
}
|
}
|
||||||
ExprKind::Block { body: ast_block } => {
|
ExprKind::Block { body: ast_block } => {
|
||||||
this.ast_block(destination, expr.ty.is_nil(), block, ast_block)
|
this.ast_block(destination, block, ast_block)
|
||||||
}
|
}
|
||||||
ExprKind::Match { discriminant, arms } => {
|
ExprKind::Match { discriminant, arms } => {
|
||||||
this.match_expr(destination, expr_span, block, discriminant, arms)
|
this.match_expr(destination, expr_span, block, discriminant, arms)
|
||||||
|
@ -1107,7 +1107,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
|
|
||||||
pub fn set_personality_fn(&self, personality: ValueRef) {
|
pub fn set_personality_fn(&self, personality: ValueRef) {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustSetPersonalityFn(self.llbuilder, personality);
|
llvm::LLVMSetPersonalityFn(self.llfn(), personality);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +319,9 @@ pub fn trans_mir<'a, 'tcx: 'a>(
|
|||||||
mircx.cleanup_kinds.iter_enumerated().map(|(bb, cleanup_kind)| {
|
mircx.cleanup_kinds.iter_enumerated().map(|(bb, cleanup_kind)| {
|
||||||
if let CleanupKind::Funclet = *cleanup_kind {
|
if let CleanupKind::Funclet = *cleanup_kind {
|
||||||
let bcx = mircx.get_builder(bb);
|
let bcx = mircx.get_builder(bb);
|
||||||
bcx.set_personality_fn(mircx.ccx.eh_personality());
|
unsafe {
|
||||||
|
llvm::LLVMSetPersonalityFn(mircx.llfn, mircx.ccx.eh_personality());
|
||||||
|
}
|
||||||
if base::wants_msvc_seh(ccx.sess()) {
|
if base::wants_msvc_seh(ccx.sess()) {
|
||||||
return Some(Funclet::new(bcx.cleanup_pad(None, &[])));
|
return Some(Funclet::new(bcx.cleanup_pad(None, &[])));
|
||||||
}
|
}
|
||||||
|
@ -1806,12 +1806,13 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||||||
String::new()
|
String::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut unsafety_flag = "";
|
let unsafety_flag = match myitem.inner {
|
||||||
if let clean::FunctionItem(ref func) = myitem.inner {
|
clean::FunctionItem(ref func) | clean::ForeignFunctionItem(ref func)
|
||||||
if func.unsafety == hir::Unsafety::Unsafe {
|
if func.unsafety == hir::Unsafety::Unsafe => {
|
||||||
unsafety_flag = "<a title='unsafe function' href='#'><sup>⚠</sup></a>";
|
"<a title='unsafe function' href='#'><sup>⚠</sup></a>"
|
||||||
}
|
}
|
||||||
}
|
_ => "",
|
||||||
|
};
|
||||||
|
|
||||||
let doc_value = myitem.doc_value().unwrap_or("");
|
let doc_value = myitem.doc_value().unwrap_or("");
|
||||||
write!(w, "
|
write!(w, "
|
||||||
|
@ -2456,9 +2456,21 @@ impl<'a> Parser<'a> {
|
|||||||
Some(f) => f,
|
Some(f) => f,
|
||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
err.help(&format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
|
let sugg = pprust::to_string(|s| {
|
||||||
float.trunc() as usize,
|
use print::pprust::PrintState;
|
||||||
format!(".{}", fstr.splitn(2, ".").last().unwrap())));
|
use print::pp::word;
|
||||||
|
s.popen()?;
|
||||||
|
s.print_expr(&e)?;
|
||||||
|
word(&mut s.s, ".")?;
|
||||||
|
s.print_usize(float.trunc() as usize)?;
|
||||||
|
s.pclose()?;
|
||||||
|
word(&mut s.s, ".")?;
|
||||||
|
word(&mut s.s, fstr.splitn(2, ".").last().unwrap())
|
||||||
|
});
|
||||||
|
err.span_suggestion(
|
||||||
|
prev_span,
|
||||||
|
"try parenthesizing the first index",
|
||||||
|
sugg);
|
||||||
}
|
}
|
||||||
return Err(err);
|
return Err(err);
|
||||||
|
|
||||||
@ -3900,7 +3912,14 @@ impl<'a> Parser<'a> {
|
|||||||
if self.eat(&token::Semi) {
|
if self.eat(&token::Semi) {
|
||||||
stmt_span.hi = self.prev_span.hi;
|
stmt_span.hi = self.prev_span.hi;
|
||||||
}
|
}
|
||||||
e.span_help(stmt_span, "try placing this code inside a block");
|
let sugg = pprust::to_string(|s| {
|
||||||
|
use print::pprust::{PrintState, INDENT_UNIT};
|
||||||
|
s.ibox(INDENT_UNIT)?;
|
||||||
|
s.bopen()?;
|
||||||
|
s.print_stmt(&stmt)?;
|
||||||
|
s.bclose_maybe_open(stmt.span, INDENT_UNIT, false)
|
||||||
|
});
|
||||||
|
e.span_suggestion(stmt_span, "try placing this code inside a block", sugg);
|
||||||
}
|
}
|
||||||
Err(mut e) => {
|
Err(mut e) => {
|
||||||
self.recover_stmt_(SemiColonMode::Break);
|
self.recover_stmt_(SemiColonMode::Break);
|
||||||
|
@ -1082,14 +1082,6 @@ extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void LLVMRustSetPersonalityFn(LLVMBuilderRef B,
|
|
||||||
LLVMValueRef Personality) {
|
|
||||||
#if LLVM_VERSION_GE(3, 8)
|
|
||||||
unwrap(B)->GetInsertBlock()->getParent()->setPersonalityFn(
|
|
||||||
cast<Function>(unwrap(Personality)));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LLVM_VERSION_GE(3, 8)
|
#if LLVM_VERSION_GE(3, 8)
|
||||||
extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
|
extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
|
||||||
LLVMValueRef *Inputs,
|
LLVMValueRef *Inputs,
|
||||||
|
@ -15,6 +15,7 @@ fn main() {
|
|||||||
{
|
{
|
||||||
if (foo)
|
if (foo)
|
||||||
bar; //~ ERROR expected `{`, found `bar`
|
bar; //~ ERROR expected `{`, found `bar`
|
||||||
//^ HELP try placing this code inside a block
|
//~^ HELP try placing this code inside a block
|
||||||
|
//~| SUGGESTION { bar; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,6 @@
|
|||||||
|
|
||||||
fn main () {
|
fn main () {
|
||||||
(1, (2, 3)).1.1; //~ ERROR unexpected token
|
(1, (2, 3)).1.1; //~ ERROR unexpected token
|
||||||
//~^ HELP try parenthesizing the first index; e.g., `(foo.1).1`
|
//~^ HELP try parenthesizing the first index
|
||||||
|
//~| SUGGESTION ((1, (2, 3)).1).1
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user