Auto merge of #67271 - Centril:rollup-i71iqkv, r=Centril
Rollup of 6 pull requests Successful merges: - #66341 (Match `VecDeque::extend` to `Vec::extend_desugared`) - #67243 (LinkedList: drop remaining items when drop panics) - #67247 (Don't suggest wrong snippet in closure) - #67250 (Remove the `DelimSpan` from `NamedMatch::MatchedSeq`.) - #67251 (Require `allow_internal_unstable` for stable min_const_fn using unsta…) - #67269 (parser: recover on `&'lifetime mut? $pat`.) Failed merges: r? @ghost
This commit is contained in:
commit
cf7e019b42
|
@ -808,7 +808,21 @@ impl<T> LinkedList<T> {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
unsafe impl<#[may_dangle] T> Drop for LinkedList<T> {
|
unsafe impl<#[may_dangle] T> Drop for LinkedList<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
while let Some(_) = self.pop_front_node() {}
|
struct DropGuard<'a, T>(&'a mut LinkedList<T>);
|
||||||
|
|
||||||
|
impl<'a, T> Drop for DropGuard<'a, T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// Continue the same loop we do below. This only runs when a destructor has
|
||||||
|
// panicked. If another one panics this will abort.
|
||||||
|
while let Some(_) = self.0.pop_front_node() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(node) = self.pop_front_node() {
|
||||||
|
let guard = DropGuard(self);
|
||||||
|
drop(node);
|
||||||
|
mem::forget(guard);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2809,7 +2809,22 @@ impl<'a, T> IntoIterator for &'a mut VecDeque<T> {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<A> Extend<A> for VecDeque<A> {
|
impl<A> Extend<A> for VecDeque<A> {
|
||||||
fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) {
|
fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) {
|
||||||
iter.into_iter().for_each(move |elt| self.push_back(elt));
|
// This function should be the moral equivalent of:
|
||||||
|
//
|
||||||
|
// for item in iter.into_iter() {
|
||||||
|
// self.push_back(item);
|
||||||
|
// }
|
||||||
|
let mut iter = iter.into_iter();
|
||||||
|
while let Some(element) = iter.next() {
|
||||||
|
if self.len() == self.capacity() {
|
||||||
|
let (lower, _) = iter.size_hint();
|
||||||
|
self.reserve(lower.saturating_add(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
let head = self.head;
|
||||||
|
self.head = self.wrap_add(self.head, 1);
|
||||||
|
unsafe { self.buffer_write(head, element); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::collections::LinkedList;
|
use std::collections::LinkedList;
|
||||||
|
use std::panic::catch_unwind;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic() {
|
fn test_basic() {
|
||||||
|
@ -529,3 +530,109 @@ fn drain_filter_complex() {
|
||||||
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
|
assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7, 9, 11, 13, 15, 17, 19]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_drop() {
|
||||||
|
static mut DROPS: i32 = 0;
|
||||||
|
struct Elem;
|
||||||
|
impl Drop for Elem {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
DROPS += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ring = LinkedList::new();
|
||||||
|
ring.push_back(Elem);
|
||||||
|
ring.push_front(Elem);
|
||||||
|
ring.push_back(Elem);
|
||||||
|
ring.push_front(Elem);
|
||||||
|
drop(ring);
|
||||||
|
|
||||||
|
assert_eq!(unsafe { DROPS }, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_drop_with_pop() {
|
||||||
|
static mut DROPS: i32 = 0;
|
||||||
|
struct Elem;
|
||||||
|
impl Drop for Elem {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
DROPS += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ring = LinkedList::new();
|
||||||
|
ring.push_back(Elem);
|
||||||
|
ring.push_front(Elem);
|
||||||
|
ring.push_back(Elem);
|
||||||
|
ring.push_front(Elem);
|
||||||
|
|
||||||
|
drop(ring.pop_back());
|
||||||
|
drop(ring.pop_front());
|
||||||
|
assert_eq!(unsafe { DROPS }, 2);
|
||||||
|
|
||||||
|
drop(ring);
|
||||||
|
assert_eq!(unsafe { DROPS }, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_drop_clear() {
|
||||||
|
static mut DROPS: i32 = 0;
|
||||||
|
struct Elem;
|
||||||
|
impl Drop for Elem {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
DROPS += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ring = LinkedList::new();
|
||||||
|
ring.push_back(Elem);
|
||||||
|
ring.push_front(Elem);
|
||||||
|
ring.push_back(Elem);
|
||||||
|
ring.push_front(Elem);
|
||||||
|
ring.clear();
|
||||||
|
assert_eq!(unsafe { DROPS }, 4);
|
||||||
|
|
||||||
|
drop(ring);
|
||||||
|
assert_eq!(unsafe { DROPS }, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_drop_panic() {
|
||||||
|
static mut DROPS: i32 = 0;
|
||||||
|
|
||||||
|
struct D(bool);
|
||||||
|
|
||||||
|
impl Drop for D {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
DROPS += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.0 {
|
||||||
|
panic!("panic in `drop`");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut q = LinkedList::new();
|
||||||
|
q.push_back(D(false));
|
||||||
|
q.push_back(D(false));
|
||||||
|
q.push_back(D(false));
|
||||||
|
q.push_back(D(false));
|
||||||
|
q.push_back(D(false));
|
||||||
|
q.push_front(D(false));
|
||||||
|
q.push_front(D(false));
|
||||||
|
q.push_front(D(true));
|
||||||
|
|
||||||
|
catch_unwind(move || drop(q)).ok();
|
||||||
|
|
||||||
|
assert_eq!(unsafe { DROPS }, 8);
|
||||||
|
}
|
||||||
|
|
|
@ -223,18 +223,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
fn report(&mut self, error: GroupedMoveError<'tcx>) {
|
fn report(&mut self, error: GroupedMoveError<'tcx>) {
|
||||||
let (mut err, err_span) = {
|
let (mut err, err_span) = {
|
||||||
let (span, original_path, kind): (Span, &Place<'tcx>, &IllegalMoveOriginKind<'_>) =
|
let (span, use_spans, original_path, kind,):
|
||||||
|
(
|
||||||
|
Span,
|
||||||
|
Option<UseSpans>,
|
||||||
|
&Place<'tcx>,
|
||||||
|
&IllegalMoveOriginKind<'_>,
|
||||||
|
) =
|
||||||
match error {
|
match error {
|
||||||
GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. } |
|
GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. } |
|
||||||
GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } => {
|
GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } => {
|
||||||
(span, original_path, kind)
|
(span, None, original_path, kind)
|
||||||
}
|
}
|
||||||
GroupedMoveError::OtherIllegalMove {
|
GroupedMoveError::OtherIllegalMove {
|
||||||
use_spans,
|
use_spans,
|
||||||
ref original_path,
|
ref original_path,
|
||||||
ref kind
|
ref kind
|
||||||
} => {
|
} => {
|
||||||
(use_spans.args_or_use(), original_path, kind)
|
(use_spans.args_or_use(), Some(use_spans), original_path, kind)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
debug!("report: original_path={:?} span={:?}, kind={:?} \
|
debug!("report: original_path={:?} span={:?}, kind={:?} \
|
||||||
|
@ -250,6 +256,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
original_path,
|
original_path,
|
||||||
target_place,
|
target_place,
|
||||||
span,
|
span,
|
||||||
|
use_spans,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
|
IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
|
||||||
|
@ -296,6 +303,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
move_place: &Place<'tcx>,
|
move_place: &Place<'tcx>,
|
||||||
deref_target_place: &Place<'tcx>,
|
deref_target_place: &Place<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
use_spans: Option<UseSpans>,
|
||||||
) -> DiagnosticBuilder<'a> {
|
) -> DiagnosticBuilder<'a> {
|
||||||
// Inspect the type of the content behind the
|
// Inspect the type of the content behind the
|
||||||
// borrow to provide feedback about why this
|
// borrow to provide feedback about why this
|
||||||
|
@ -416,7 +424,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
|
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
|
||||||
let is_option = move_ty.starts_with("std::option::Option");
|
let is_option = move_ty.starts_with("std::option::Option");
|
||||||
let is_result = move_ty.starts_with("std::result::Result");
|
let is_result = move_ty.starts_with("std::result::Result");
|
||||||
if is_option || is_result {
|
if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
span,
|
span,
|
||||||
&format!("consider borrowing the `{}`'s content", if is_option {
|
&format!("consider borrowing the `{}`'s content", if is_option {
|
||||||
|
|
|
@ -80,7 +80,7 @@ fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, fn_def_id: DefId) -> Mc
|
||||||
for ty in ty.walk() {
|
for ty in ty.walk() {
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
ty::Ref(_, _, hir::Mutability::Mutable) => {
|
ty::Ref(_, _, hir::Mutability::Mutable) => {
|
||||||
if !tcx.features().const_mut_refs {
|
if !feature_allowed(tcx, fn_def_id, sym::const_mut_refs) {
|
||||||
return Err((
|
return Err((
|
||||||
span,
|
span,
|
||||||
"mutable references in const fn are unstable".into(),
|
"mutable references in const fn are unstable".into(),
|
||||||
|
@ -220,7 +220,7 @@ fn check_statement(
|
||||||
}
|
}
|
||||||
|
|
||||||
| StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _)
|
| StatementKind::FakeRead(FakeReadCause::ForMatchedPlace, _)
|
||||||
if !tcx.features().const_if_match
|
if !feature_allowed(tcx, def_id, sym::const_if_match)
|
||||||
=> {
|
=> {
|
||||||
Err((span, "loops and conditional expressions are not stable in const fn".into()))
|
Err((span, "loops and conditional expressions are not stable in const fn".into()))
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ fn check_place(
|
||||||
while let &[ref proj_base @ .., elem] = cursor {
|
while let &[ref proj_base @ .., elem] = cursor {
|
||||||
cursor = proj_base;
|
cursor = proj_base;
|
||||||
match elem {
|
match elem {
|
||||||
ProjectionElem::Downcast(..) if !tcx.features().const_if_match
|
ProjectionElem::Downcast(..) if !feature_allowed(tcx, def_id, sym::const_if_match)
|
||||||
=> return Err((span, "`match` or `if let` in `const fn` is unstable".into())),
|
=> return Err((span, "`match` or `if let` in `const fn` is unstable".into())),
|
||||||
ProjectionElem::Downcast(_symbol, _variant_index) => {}
|
ProjectionElem::Downcast(_symbol, _variant_index) => {}
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ fn check_terminator(
|
||||||
|
|
||||||
| TerminatorKind::FalseEdges { .. }
|
| TerminatorKind::FalseEdges { .. }
|
||||||
| TerminatorKind::SwitchInt { .. }
|
| TerminatorKind::SwitchInt { .. }
|
||||||
if !tcx.features().const_if_match
|
if !feature_allowed(tcx, def_id, sym::const_if_match)
|
||||||
=> Err((
|
=> Err((
|
||||||
span,
|
span,
|
||||||
"loops and conditional expressions are not stable in const fn".into(),
|
"loops and conditional expressions are not stable in const fn".into(),
|
||||||
|
@ -341,7 +341,7 @@ fn check_terminator(
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(ecstaticmorse): We probably want to allow `Unreachable` unconditionally.
|
// FIXME(ecstaticmorse): We probably want to allow `Unreachable` unconditionally.
|
||||||
TerminatorKind::Unreachable if tcx.features().const_if_match => Ok(()),
|
TerminatorKind::Unreachable if feature_allowed(tcx, def_id, sym::const_if_match) => Ok(()),
|
||||||
|
|
||||||
| TerminatorKind::Abort | TerminatorKind::Unreachable => {
|
| TerminatorKind::Abort | TerminatorKind::Unreachable => {
|
||||||
Err((span, "const fn with unreachable code is not stable".into()))
|
Err((span, "const fn with unreachable code is not stable".into()))
|
||||||
|
|
|
@ -459,18 +459,28 @@ impl<'a> Parser<'a> {
|
||||||
/// Parse `&pat` / `&mut pat`.
|
/// Parse `&pat` / `&mut pat`.
|
||||||
fn parse_pat_deref(&mut self, expected: Expected) -> PResult<'a, PatKind> {
|
fn parse_pat_deref(&mut self, expected: Expected) -> PResult<'a, PatKind> {
|
||||||
self.expect_and()?;
|
self.expect_and()?;
|
||||||
|
self.recover_lifetime_in_deref_pat();
|
||||||
let mutbl = self.parse_mutability();
|
let mutbl = self.parse_mutability();
|
||||||
|
|
||||||
if let token::Lifetime(name) = self.token.kind {
|
|
||||||
let mut err = self.fatal(&format!("unexpected lifetime `{}` in pattern", name));
|
|
||||||
err.span_label(self.token.span, "unexpected lifetime");
|
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
let subpat = self.parse_pat_with_range_pat(false, expected)?;
|
let subpat = self.parse_pat_with_range_pat(false, expected)?;
|
||||||
Ok(PatKind::Ref(subpat, mutbl))
|
Ok(PatKind::Ref(subpat, mutbl))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn recover_lifetime_in_deref_pat(&mut self) {
|
||||||
|
if let token::Lifetime(name) = self.token.kind {
|
||||||
|
self.bump(); // `'a`
|
||||||
|
|
||||||
|
let span = self.prev_span;
|
||||||
|
self.struct_span_err(span, &format!("unexpected lifetime `{}` in pattern", name))
|
||||||
|
.span_suggestion(
|
||||||
|
span,
|
||||||
|
"remove the lifetime",
|
||||||
|
String::new(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse a tuple or parenthesis pattern.
|
/// Parse a tuple or parenthesis pattern.
|
||||||
fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
|
fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
|
||||||
let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or_inner())?;
|
let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or_inner())?;
|
||||||
|
|
|
@ -83,7 +83,7 @@ use syntax::print::pprust;
|
||||||
use syntax::sess::ParseSess;
|
use syntax::sess::ParseSess;
|
||||||
use syntax::symbol::{kw, sym, Symbol};
|
use syntax::symbol::{kw, sym, Symbol};
|
||||||
use syntax::token::{self, DocComment, Nonterminal, Token};
|
use syntax::token::{self, DocComment, Nonterminal, Token};
|
||||||
use syntax::tokenstream::{DelimSpan, TokenStream};
|
use syntax::tokenstream::TokenStream;
|
||||||
|
|
||||||
use errors::{PResult, FatalError};
|
use errors::{PResult, FatalError};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
@ -164,11 +164,6 @@ struct MatcherPos<'root, 'tt> {
|
||||||
/// The position of the "dot" in this matcher
|
/// The position of the "dot" in this matcher
|
||||||
idx: usize,
|
idx: usize,
|
||||||
|
|
||||||
/// The first span of source that the beginning of this matcher corresponds to. In other
|
|
||||||
/// words, the token in the source whose span is `sp_open` is matched against the first token of
|
|
||||||
/// the matcher.
|
|
||||||
sp_open: Span,
|
|
||||||
|
|
||||||
/// For each named metavar in the matcher, we keep track of token trees matched against the
|
/// For each named metavar in the matcher, we keep track of token trees matched against the
|
||||||
/// metavar by the black box parser. In particular, there may be more than one match per
|
/// metavar by the black box parser. In particular, there may be more than one match per
|
||||||
/// metavar if we are in a repetition (each repetition matches each of the variables).
|
/// metavar if we are in a repetition (each repetition matches each of the variables).
|
||||||
|
@ -307,8 +302,8 @@ fn create_matches(len: usize) -> Box<[Lrc<NamedMatchVec>]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates the top-level matcher position in which the "dot" is before the first token of the
|
/// Generates the top-level matcher position in which the "dot" is before the first token of the
|
||||||
/// matcher `ms` and we are going to start matching at the span `open` in the source.
|
/// matcher `ms`.
|
||||||
fn initial_matcher_pos<'root, 'tt>(ms: &'tt [TokenTree], open: Span) -> MatcherPos<'root, 'tt> {
|
fn initial_matcher_pos<'root, 'tt>(ms: &'tt [TokenTree]) -> MatcherPos<'root, 'tt> {
|
||||||
let match_idx_hi = count_names(ms);
|
let match_idx_hi = count_names(ms);
|
||||||
let matches = create_matches(match_idx_hi);
|
let matches = create_matches(match_idx_hi);
|
||||||
MatcherPos {
|
MatcherPos {
|
||||||
|
@ -316,8 +311,6 @@ fn initial_matcher_pos<'root, 'tt>(ms: &'tt [TokenTree], open: Span) -> MatcherP
|
||||||
top_elts: TtSeq(ms), // "elts" is an abbr. for "elements"
|
top_elts: TtSeq(ms), // "elts" is an abbr. for "elements"
|
||||||
// The "dot" is before the first token of the matcher
|
// The "dot" is before the first token of the matcher
|
||||||
idx: 0,
|
idx: 0,
|
||||||
// We start matching at the span `open` in the source code
|
|
||||||
sp_open: open,
|
|
||||||
|
|
||||||
// Initialize `matches` to a bunch of empty `Vec`s -- one for each metavar in `top_elts`.
|
// Initialize `matches` to a bunch of empty `Vec`s -- one for each metavar in `top_elts`.
|
||||||
// `match_lo` for `top_elts` is 0 and `match_hi` is `matches.len()`. `match_cur` is 0 since
|
// `match_lo` for `top_elts` is 0 and `match_hi` is `matches.len()`. `match_cur` is 0 since
|
||||||
|
@ -355,7 +348,7 @@ fn initial_matcher_pos<'root, 'tt>(ms: &'tt [TokenTree], open: Span) -> MatcherP
|
||||||
/// token tree it was derived from.
|
/// token tree it was derived from.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
crate enum NamedMatch {
|
crate enum NamedMatch {
|
||||||
MatchedSeq(Lrc<NamedMatchVec>, DelimSpan),
|
MatchedSeq(Lrc<NamedMatchVec>),
|
||||||
MatchedNonterminal(Lrc<Nonterminal>),
|
MatchedNonterminal(Lrc<Nonterminal>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,8 +490,7 @@ fn inner_parse_loop<'root, 'tt>(
|
||||||
// Add matches from this repetition to the `matches` of `up`
|
// Add matches from this repetition to the `matches` of `up`
|
||||||
for idx in item.match_lo..item.match_hi {
|
for idx in item.match_lo..item.match_hi {
|
||||||
let sub = item.matches[idx].clone();
|
let sub = item.matches[idx].clone();
|
||||||
let span = DelimSpan::from_pair(item.sp_open, token.span);
|
new_pos.push_match(idx, MatchedSeq(sub));
|
||||||
new_pos.push_match(idx, MatchedSeq(sub, span));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the "dot" past the repetition in `up`
|
// Move the "dot" past the repetition in `up`
|
||||||
|
@ -552,7 +544,7 @@ fn inner_parse_loop<'root, 'tt>(
|
||||||
new_item.match_cur += seq.num_captures;
|
new_item.match_cur += seq.num_captures;
|
||||||
new_item.idx += 1;
|
new_item.idx += 1;
|
||||||
for idx in item.match_cur..item.match_cur + seq.num_captures {
|
for idx in item.match_cur..item.match_cur + seq.num_captures {
|
||||||
new_item.push_match(idx, MatchedSeq(Lrc::new(smallvec![]), sp));
|
new_item.push_match(idx, MatchedSeq(Lrc::new(smallvec![])));
|
||||||
}
|
}
|
||||||
cur_items.push(new_item);
|
cur_items.push(new_item);
|
||||||
}
|
}
|
||||||
|
@ -568,7 +560,6 @@ fn inner_parse_loop<'root, 'tt>(
|
||||||
match_cur: item.match_cur,
|
match_cur: item.match_cur,
|
||||||
match_hi: item.match_cur + seq.num_captures,
|
match_hi: item.match_cur + seq.num_captures,
|
||||||
up: Some(item),
|
up: Some(item),
|
||||||
sp_open: sp.open,
|
|
||||||
top_elts: Tt(TokenTree::Sequence(sp, seq)),
|
top_elts: Tt(TokenTree::Sequence(sp, seq)),
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
@ -663,7 +654,7 @@ pub(super) fn parse(
|
||||||
//
|
//
|
||||||
// This MatcherPos instance is allocated on the stack. All others -- and
|
// This MatcherPos instance is allocated on the stack. All others -- and
|
||||||
// there are frequently *no* others! -- are allocated on the heap.
|
// there are frequently *no* others! -- are allocated on the heap.
|
||||||
let mut initial = initial_matcher_pos(ms, parser.token.span);
|
let mut initial = initial_matcher_pos(ms);
|
||||||
let mut cur_items = smallvec![MatcherPosHandle::Ref(&mut initial)];
|
let mut cur_items = smallvec![MatcherPosHandle::Ref(&mut initial)];
|
||||||
let mut next_items = Vec::new();
|
let mut next_items = Vec::new();
|
||||||
|
|
||||||
|
|
|
@ -379,7 +379,7 @@ pub fn compile_declarative_macro(
|
||||||
|
|
||||||
// Extract the arguments:
|
// Extract the arguments:
|
||||||
let lhses = match argument_map[&lhs_nm] {
|
let lhses = match argument_map[&lhs_nm] {
|
||||||
MatchedSeq(ref s, _) => s
|
MatchedSeq(ref s) => s
|
||||||
.iter()
|
.iter()
|
||||||
.map(|m| {
|
.map(|m| {
|
||||||
if let MatchedNonterminal(ref nt) = *m {
|
if let MatchedNonterminal(ref nt) = *m {
|
||||||
|
@ -402,7 +402,7 @@ pub fn compile_declarative_macro(
|
||||||
};
|
};
|
||||||
|
|
||||||
let rhses = match argument_map[&rhs_nm] {
|
let rhses = match argument_map[&rhs_nm] {
|
||||||
MatchedSeq(ref s, _) => s
|
MatchedSeq(ref s) => s
|
||||||
.iter()
|
.iter()
|
||||||
.map(|m| {
|
.map(|m| {
|
||||||
if let MatchedNonterminal(ref nt) = *m {
|
if let MatchedNonterminal(ref nt) = *m {
|
||||||
|
|
|
@ -299,7 +299,7 @@ fn lookup_cur_matched<'a>(
|
||||||
for &(idx, _) in repeats {
|
for &(idx, _) in repeats {
|
||||||
match matched {
|
match matched {
|
||||||
MatchedNonterminal(_) => break,
|
MatchedNonterminal(_) => break,
|
||||||
MatchedSeq(ref ads, _) => matched = ads.get(idx).unwrap(),
|
MatchedSeq(ref ads) => matched = ads.get(idx).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ fn lockstep_iter_size(
|
||||||
match lookup_cur_matched(name, interpolations, repeats) {
|
match lookup_cur_matched(name, interpolations, repeats) {
|
||||||
Some(matched) => match matched {
|
Some(matched) => match matched {
|
||||||
MatchedNonterminal(_) => LockstepIterSize::Unconstrained,
|
MatchedNonterminal(_) => LockstepIterSize::Unconstrained,
|
||||||
MatchedSeq(ref ads, _) => LockstepIterSize::Constraint(ads.len(), name),
|
MatchedSeq(ref ads) => LockstepIterSize::Constraint(ads.len(), name),
|
||||||
},
|
},
|
||||||
_ => LockstepIterSize::Unconstrained,
|
_ => LockstepIterSize::Unconstrained,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
|
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
|
#![feature(const_fn)]
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
x: usize
|
x: usize
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#![feature(const_panic)]
|
#![feature(const_panic)]
|
||||||
#![feature(const_if_match)]
|
#![feature(const_if_match)]
|
||||||
|
#![feature(const_fn)]
|
||||||
|
|
||||||
const X: u32 = 4;
|
const X: u32 = 4;
|
||||||
const Y: u32 = 5;
|
const Y: u32 = 5;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
#![feature(const_if_match)]
|
#![feature(const_if_match)]
|
||||||
|
#![feature(const_fn)]
|
||||||
|
|
||||||
enum E {
|
enum E {
|
||||||
A,
|
A,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: fatal error triggered by #[rustc_error]
|
error: fatal error triggered by #[rustc_error]
|
||||||
--> $DIR/feature-gate-const-if-match.rs:108:1
|
--> $DIR/feature-gate-const-if-match.rs:109:1
|
||||||
|
|
|
|
||||||
LL | / fn main() {
|
LL | / fn main() {
|
||||||
LL | | let _ = [0; {
|
LL | | let _ = [0; {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![cfg_attr(if_match, feature(const_if_match))]
|
#![cfg_attr(if_match, feature(const_if_match))]
|
||||||
|
#![feature(const_fn)]
|
||||||
|
|
||||||
const _: i32 = if true { //[stock]~ ERROR `if` is not allowed in a `const`
|
const _: i32 = if true { //[stock]~ ERROR `if` is not allowed in a `const`
|
||||||
5
|
5
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0658]: `if` is not allowed in a `const`
|
error[E0658]: `if` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:10:16
|
--> $DIR/feature-gate-const-if-match.rs:11:16
|
||||||
|
|
|
|
||||||
LL | const _: i32 = if true {
|
LL | const _: i32 = if true {
|
||||||
| ________________^
|
| ________________^
|
||||||
|
@ -13,7 +13,7 @@ LL | | };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const`
|
error[E0658]: `if` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:16:16
|
--> $DIR/feature-gate-const-if-match.rs:17:16
|
||||||
|
|
|
|
||||||
LL | const _: i32 = if let Some(true) = Some(false) {
|
LL | const _: i32 = if let Some(true) = Some(false) {
|
||||||
| ________________^
|
| ________________^
|
||||||
|
@ -27,7 +27,7 @@ LL | | };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `match` is not allowed in a `const`
|
error[E0658]: `match` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:22:16
|
--> $DIR/feature-gate-const-if-match.rs:23:16
|
||||||
|
|
|
|
||||||
LL | const _: i32 = match 1 {
|
LL | const _: i32 = match 1 {
|
||||||
| ________________^
|
| ________________^
|
||||||
|
@ -41,7 +41,7 @@ LL | | };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `static`
|
error[E0658]: `if` is not allowed in a `static`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:29:13
|
--> $DIR/feature-gate-const-if-match.rs:30:13
|
||||||
|
|
|
|
||||||
LL | let x = if true { 0 } else { 1 };
|
LL | let x = if true { 0 } else { 1 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -50,7 +50,7 @@ LL | let x = if true { 0 } else { 1 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `match` is not allowed in a `static`
|
error[E0658]: `match` is not allowed in a `static`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:31:13
|
--> $DIR/feature-gate-const-if-match.rs:32:13
|
||||||
|
|
|
|
||||||
LL | let x = match x { 0 => 1, _ => 0 };
|
LL | let x = match x { 0 => 1, _ => 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -59,7 +59,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `static`
|
error[E0658]: `if` is not allowed in a `static`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:33:5
|
--> $DIR/feature-gate-const-if-match.rs:34:5
|
||||||
|
|
|
|
||||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -68,7 +68,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `static mut`
|
error[E0658]: `if` is not allowed in a `static mut`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:38:13
|
--> $DIR/feature-gate-const-if-match.rs:39:13
|
||||||
|
|
|
|
||||||
LL | let x = if true { 0 } else { 1 };
|
LL | let x = if true { 0 } else { 1 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -77,7 +77,7 @@ LL | let x = if true { 0 } else { 1 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `match` is not allowed in a `static mut`
|
error[E0658]: `match` is not allowed in a `static mut`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:40:13
|
--> $DIR/feature-gate-const-if-match.rs:41:13
|
||||||
|
|
|
|
||||||
LL | let x = match x { 0 => 1, _ => 0 };
|
LL | let x = match x { 0 => 1, _ => 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -86,7 +86,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `static mut`
|
error[E0658]: `if` is not allowed in a `static mut`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:42:5
|
--> $DIR/feature-gate-const-if-match.rs:43:5
|
||||||
|
|
|
|
||||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -95,7 +95,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const fn`
|
error[E0658]: `if` is not allowed in a `const fn`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:47:5
|
--> $DIR/feature-gate-const-if-match.rs:48:5
|
||||||
|
|
|
|
||||||
LL | if true { 5 } else { 6 }
|
LL | if true { 5 } else { 6 }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -104,7 +104,7 @@ LL | if true { 5 } else { 6 }
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const fn`
|
error[E0658]: `if` is not allowed in a `const fn`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:51:5
|
--> $DIR/feature-gate-const-if-match.rs:52:5
|
||||||
|
|
|
|
||||||
LL | / if let Some(true) = a {
|
LL | / if let Some(true) = a {
|
||||||
LL | | 0
|
LL | | 0
|
||||||
|
@ -117,7 +117,7 @@ LL | | }
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `match` is not allowed in a `const fn`
|
error[E0658]: `match` is not allowed in a `const fn`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:59:5
|
--> $DIR/feature-gate-const-if-match.rs:60:5
|
||||||
|
|
|
|
||||||
LL | / match i {
|
LL | / match i {
|
||||||
LL | | i if i > 10 => i,
|
LL | | i if i > 10 => i,
|
||||||
|
@ -130,7 +130,7 @@ LL | | }
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const fn`
|
error[E0658]: `if` is not allowed in a `const fn`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:90:17
|
--> $DIR/feature-gate-const-if-match.rs:91:17
|
||||||
|
|
|
|
||||||
LL | let x = if y { 0 } else { 1 };
|
LL | let x = if y { 0 } else { 1 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -139,7 +139,7 @@ LL | let x = if y { 0 } else { 1 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `match` is not allowed in a `const fn`
|
error[E0658]: `match` is not allowed in a `const fn`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:92:17
|
--> $DIR/feature-gate-const-if-match.rs:93:17
|
||||||
|
|
|
|
||||||
LL | let x = match x { 0 => 1, _ => 0 };
|
LL | let x = match x { 0 => 1, _ => 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -148,7 +148,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const fn`
|
error[E0658]: `if` is not allowed in a `const fn`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:94:9
|
--> $DIR/feature-gate-const-if-match.rs:95:9
|
||||||
|
|
|
|
||||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -157,7 +157,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const`
|
error[E0658]: `if` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:110:17
|
--> $DIR/feature-gate-const-if-match.rs:111:17
|
||||||
|
|
|
|
||||||
LL | let x = if false { 0 } else { 1 };
|
LL | let x = if false { 0 } else { 1 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -166,7 +166,7 @@ LL | let x = if false { 0 } else { 1 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `match` is not allowed in a `const`
|
error[E0658]: `match` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:112:17
|
--> $DIR/feature-gate-const-if-match.rs:113:17
|
||||||
|
|
|
|
||||||
LL | let x = match x { 0 => 1, _ => 0 };
|
LL | let x = match x { 0 => 1, _ => 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -175,7 +175,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const`
|
error[E0658]: `if` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:114:9
|
--> $DIR/feature-gate-const-if-match.rs:115:9
|
||||||
|
|
|
|
||||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -184,7 +184,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const`
|
error[E0658]: `if` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:67:21
|
--> $DIR/feature-gate-const-if-match.rs:68:21
|
||||||
|
|
|
|
||||||
LL | const IF: i32 = if true { 5 } else { 6 };
|
LL | const IF: i32 = if true { 5 } else { 6 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -193,7 +193,7 @@ LL | const IF: i32 = if true { 5 } else { 6 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const`
|
error[E0658]: `if` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:70:25
|
--> $DIR/feature-gate-const-if-match.rs:71:25
|
||||||
|
|
|
|
||||||
LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
|
LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -202,7 +202,7 @@ LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `match` is not allowed in a `const`
|
error[E0658]: `match` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:73:24
|
--> $DIR/feature-gate-const-if-match.rs:74:24
|
||||||
|
|
|
|
||||||
LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -211,7 +211,7 @@ LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const`
|
error[E0658]: `if` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:78:21
|
--> $DIR/feature-gate-const-if-match.rs:79:21
|
||||||
|
|
|
|
||||||
LL | const IF: i32 = if true { 5 } else { 6 };
|
LL | const IF: i32 = if true { 5 } else { 6 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -220,7 +220,7 @@ LL | const IF: i32 = if true { 5 } else { 6 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `if` is not allowed in a `const`
|
error[E0658]: `if` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:81:25
|
--> $DIR/feature-gate-const-if-match.rs:82:25
|
||||||
|
|
|
|
||||||
LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
|
LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -229,7 +229,7 @@ LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0658]: `match` is not allowed in a `const`
|
error[E0658]: `match` is not allowed in a `const`
|
||||||
--> $DIR/feature-gate-const-if-match.rs:84:24
|
--> $DIR/feature-gate-const-if-match.rs:85:24
|
||||||
|
|
|
|
||||||
LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -238,7 +238,7 @@ LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0019]: constant contains unimplemented expression type
|
error[E0019]: constant contains unimplemented expression type
|
||||||
--> $DIR/feature-gate-const-if-match.rs:114:21
|
--> $DIR/feature-gate-const-if-match.rs:115:21
|
||||||
|
|
|
|
||||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||||
| ^
|
| ^
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#![feature(const_if_match)]
|
#![feature(const_if_match)]
|
||||||
#![feature(const_panic)]
|
#![feature(const_panic)]
|
||||||
|
#![feature(const_fn)]
|
||||||
|
|
||||||
const X: i32 = {
|
const X: i32 = {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
#![feature(const_if_match)]
|
#![feature(const_if_match, const_fn)]
|
||||||
|
|
||||||
enum Foo {
|
enum Foo {
|
||||||
Prob,
|
Prob,
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
fn main() {
|
||||||
|
let &'a x = &0; //~ ERROR unexpected lifetime `'a` in pattern
|
||||||
|
let &'a mut y = &mut 0; //~ ERROR unexpected lifetime `'a` in pattern
|
||||||
|
|
||||||
|
let _recovery_witness: () = 0; //~ ERROR mismatched types
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
error: unexpected lifetime `'a` in pattern
|
||||||
|
--> $DIR/lifetime-in-pattern-recover.rs:2:10
|
||||||
|
|
|
||||||
|
LL | let &'a x = &0;
|
||||||
|
| ^^ help: remove the lifetime
|
||||||
|
|
||||||
|
error: unexpected lifetime `'a` in pattern
|
||||||
|
--> $DIR/lifetime-in-pattern-recover.rs:3:10
|
||||||
|
|
|
||||||
|
LL | let &'a mut y = &mut 0;
|
||||||
|
| ^^ help: remove the lifetime
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/lifetime-in-pattern-recover.rs:5:33
|
||||||
|
|
|
||||||
|
LL | let _recovery_witness: () = 0;
|
||||||
|
| -- ^ expected `()`, found integer
|
||||||
|
| |
|
||||||
|
| expected due to this
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -1,5 +1,6 @@
|
||||||
fn test(&'a str) {
|
fn test(&'a str) {
|
||||||
//~^ ERROR unexpected lifetime `'a` in pattern
|
//~^ ERROR unexpected lifetime `'a` in pattern
|
||||||
|
//~| ERROR expected one of `:`, `@`, or `|`, found `)`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -2,7 +2,13 @@ error: unexpected lifetime `'a` in pattern
|
||||||
--> $DIR/lifetime-in-pattern.rs:1:10
|
--> $DIR/lifetime-in-pattern.rs:1:10
|
||||||
|
|
|
|
||||||
LL | fn test(&'a str) {
|
LL | fn test(&'a str) {
|
||||||
| ^^ unexpected lifetime
|
| ^^ help: remove the lifetime
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: expected one of `:`, `@`, or `|`, found `)`
|
||||||
|
--> $DIR/lifetime-in-pattern.rs:1:16
|
||||||
|
|
|
||||||
|
LL | fn test(&'a str) {
|
||||||
|
| ^ expected one of `:`, `@`, or `|`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ error: unexpected lifetime `'a` in pattern
|
||||||
--> $DIR/self-vs-path-ambiguity.rs:9:11
|
--> $DIR/self-vs-path-ambiguity.rs:9:11
|
||||||
|
|
|
|
||||||
LL | fn i(&'a self::S: &S) {}
|
LL | fn i(&'a self::S: &S) {}
|
||||||
| ^^ unexpected lifetime
|
| ^^ help: remove the lifetime
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
struct NotCopyable;
|
||||||
|
|
||||||
|
fn func<F: FnMut() -> H, H: FnMut()>(_: F) {}
|
||||||
|
|
||||||
|
fn parse() {
|
||||||
|
let mut var = None;
|
||||||
|
func(|| {
|
||||||
|
// Shouldn't suggest `move ||.as_ref()` here
|
||||||
|
move || {
|
||||||
|
//~^ ERROR: cannot move out of `var`
|
||||||
|
var = Some(NotCopyable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,18 @@
|
||||||
|
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
|
||||||
|
--> $DIR/option-content-move2.rs:9:9
|
||||||
|
|
|
||||||
|
LL | let mut var = None;
|
||||||
|
| ------- captured outer variable
|
||||||
|
...
|
||||||
|
LL | move || {
|
||||||
|
| ^^^^^^^ move out of `var` occurs here
|
||||||
|
LL |
|
||||||
|
LL | var = Some(NotCopyable);
|
||||||
|
| ---
|
||||||
|
| |
|
||||||
|
| move occurs because `var` has type `std::option::Option<NotCopyable>`, which does not implement the `Copy` trait
|
||||||
|
| move occurs due to use in closure
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0507`.
|
Loading…
Reference in New Issue