From 3f39dc1b9095bf3808e45a8ff9afc6b9a4d8e9a3 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 1 Jul 2019 01:08:49 +0300 Subject: syntax: Unsupport `foo! bar { ... }` macros in the parser Unreserve `macro_rules` as a macro name --- src/libsyntax/parse/parser.rs | 129 ++++++++++++------------------------------ 1 file changed, 36 insertions(+), 93 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fc206580e38..cbecdb0738b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4353,8 +4353,9 @@ impl<'a> Parser<'a> { (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) } - token::Ident(name, _) if name == sym::macro_rules && - self.look_ahead(1, |t| *t == token::Not) => { + token::Ident(name, false) if name == sym::macro_rules && + self.look_ahead(1, |t| *t == token::Not) && + self.look_ahead(2, |t| t.is_ident()) => { let prev_span = self.prev_span; self.complain_if_pub_macro(&vis.node, prev_span); self.bump(); @@ -4434,34 +4435,6 @@ impl<'a> Parser<'a> { })); } - // it's a macro invocation - let id = match self.token.kind { - token::OpenDelim(_) => Ident::invalid(), // no special identifier - _ => self.parse_ident()?, - }; - - // check that we're pointing at delimiters (need to check - // again after the `if`, because of `parse_ident` - // consuming more tokens). - match self.token.kind { - token::OpenDelim(_) => {} - _ => { - // we only expect an ident if we didn't parse one - // above. - let ident_str = if id.name == kw::Invalid { - "identifier, " - } else { - "" - }; - let tok_str = self.this_token_descr(); - let mut err = self.fatal(&format!("expected {}`(` or `{{`, found {}", - ident_str, - tok_str)); - err.span_label(self.token.span, format!("expected {}`(` or `{{`", ident_str)); - return Err(err) - }, - } - let (delim, tts) = self.expect_delimited_token_tree()?; let hi = self.prev_span; @@ -4471,59 +4444,38 @@ impl<'a> Parser<'a> { MacStmtStyle::NoBraces }; - if id.name == kw::Invalid { - let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim }); - let node = if delim == MacDelimiter::Brace || - self.token == token::Semi || self.token == token::Eof { - StmtKind::Mac(P((mac, style, attrs.into()))) - } - // We used to incorrectly stop parsing macro-expanded statements here. - // If the next token will be an error anyway but could have parsed with the - // earlier behavior, stop parsing here and emit a warning to avoid breakage. - else if macro_legacy_warnings && - self.token.can_begin_expr() && - match self.token.kind { - // These can continue an expression, so we can't stop parsing and warn. - token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) | - token::BinOp(token::Minus) | token::BinOp(token::Star) | - token::BinOp(token::And) | token::BinOp(token::Or) | - token::AndAnd | token::OrOr | - token::DotDot | token::DotDotDot | token::DotDotEq => false, - _ => true, - } { - self.warn_missing_semicolon(); - StmtKind::Mac(P((mac, style, attrs.into()))) - } else { - let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new()); - let e = self.maybe_recover_from_bad_qpath(e, true)?; - let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; - let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; - StmtKind::Expr(e) - }; - Stmt { - id: ast::DUMMY_NODE_ID, - span: lo.to(hi), - node, - } + let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim }); + let node = if delim == MacDelimiter::Brace || + self.token == token::Semi || self.token == token::Eof { + StmtKind::Mac(P((mac, style, attrs.into()))) + } + // We used to incorrectly stop parsing macro-expanded statements here. + // If the next token will be an error anyway but could have parsed with the + // earlier behavior, stop parsing here and emit a warning to avoid breakage. + else if macro_legacy_warnings && + self.token.can_begin_expr() && + match self.token.kind { + // These can continue an expression, so we can't stop parsing and warn. + token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) | + token::BinOp(token::Minus) | token::BinOp(token::Star) | + token::BinOp(token::And) | token::BinOp(token::Or) | + token::AndAnd | token::OrOr | + token::DotDot | token::DotDotDot | token::DotDotEq => false, + _ => true, + } { + self.warn_missing_semicolon(); + StmtKind::Mac(P((mac, style, attrs.into()))) } else { - // if it has a special ident, it's definitely an item - // - // Require a semicolon or braces. - if style != MacStmtStyle::Braces && !self.eat(&token::Semi) { - self.report_invalid_macro_expansion_item(); - } - let span = lo.to(hi); - Stmt { - id: ast::DUMMY_NODE_ID, - span, - node: StmtKind::Item({ - self.mk_item( - span, id /*id is good here*/, - ItemKind::Mac(respan(span, Mac_ { path: pth, tts, delim })), - respan(lo, VisibilityKind::Inherited), - attrs) - }), - } + let e = self.mk_expr(mac.span, ExprKind::Mac(mac), ThinVec::new()); + let e = self.maybe_recover_from_bad_qpath(e, true)?; + let e = self.parse_dot_or_call_expr_with(e, lo, attrs.into())?; + let e = self.parse_assoc_expr_with(0, LhsExpr::AlreadyParsed(e))?; + StmtKind::Expr(e) + }; + Stmt { + id: ast::DUMMY_NODE_ID, + span: lo.to(hi), + node, } } else { // FIXME: Bad copy of attrs @@ -7611,16 +7563,6 @@ impl<'a> Parser<'a> { // item macro. let pth = self.parse_path(PathStyle::Mod)?; self.expect(&token::Not)?; - - // a 'special' identifier (like what `macro_rules!` uses) - // is optional. We should eventually unify invoc syntax - // and remove this. - let id = if self.token.is_ident() { - self.parse_ident()? - } else { - Ident::invalid() // no special identifier - }; - // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item(); @@ -7628,7 +7570,8 @@ impl<'a> Parser<'a> { let hi = self.prev_span; let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts, delim }); - let item = self.mk_item(lo.to(hi), id, ItemKind::Mac(mac), visibility, attrs); + let item = + self.mk_item(lo.to(hi), Ident::invalid(), ItemKind::Mac(mac), visibility, attrs); return Ok(Some(item)); } -- cgit 1.4.1-3-g733a5 From d0dc41a2bdd45531e9d5ef9364027763158b4b85 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 1 Jul 2019 12:20:44 +0300 Subject: Address review comments --- src/libsyntax/parse/parser.rs | 93 +++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 48 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cbecdb0738b..01b642fc96f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4324,52 +4324,49 @@ impl<'a> Parser<'a> { fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span) -> PResult<'a, Option>> { let token_lo = self.token.span; - let (ident, def) = match self.token.kind { - token::Ident(name, false) if name == kw::Macro => { - self.bump(); - let ident = self.parse_ident()?; - let tokens = if self.check(&token::OpenDelim(token::Brace)) { - match self.parse_token_tree() { - TokenTree::Delimited(_, _, tts) => tts, - _ => unreachable!(), - } - } else if self.check(&token::OpenDelim(token::Paren)) { - let args = self.parse_token_tree(); - let body = if self.check(&token::OpenDelim(token::Brace)) { - self.parse_token_tree() - } else { - self.unexpected()?; - unreachable!() - }; - TokenStream::new(vec![ - args.into(), - TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(), - body.into(), - ]) + let (ident, def) = if self.eat_keyword(kw::Macro) { + let ident = self.parse_ident()?; + let tokens = if self.check(&token::OpenDelim(token::Brace)) { + match self.parse_token_tree() { + TokenTree::Delimited(_, _, tts) => tts, + _ => unreachable!(), + } + } else if self.check(&token::OpenDelim(token::Paren)) { + let args = self.parse_token_tree(); + let body = if self.check(&token::OpenDelim(token::Brace)) { + self.parse_token_tree() } else { self.unexpected()?; unreachable!() }; + TokenStream::new(vec![ + args.into(), + TokenTree::token(token::FatArrow, token_lo.to(self.prev_span)).into(), + body.into(), + ]) + } else { + self.unexpected()?; + unreachable!() + }; - (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) - } - token::Ident(name, false) if name == sym::macro_rules && - self.look_ahead(1, |t| *t == token::Not) && - self.look_ahead(2, |t| t.is_ident()) => { - let prev_span = self.prev_span; - self.complain_if_pub_macro(&vis.node, prev_span); - self.bump(); - self.bump(); - - let ident = self.parse_ident()?; - let (delim, tokens) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { - self.report_invalid_macro_expansion_item(); - } + (ident, ast::MacroDef { tokens: tokens.into(), legacy: false }) + } else if self.check_keyword(sym::macro_rules) && + self.look_ahead(1, |t| *t == token::Not) && + self.look_ahead(2, |t| t.is_ident()) { + let prev_span = self.prev_span; + self.complain_if_pub_macro(&vis.node, prev_span); + self.bump(); + self.bump(); - (ident, ast::MacroDef { tokens, legacy: true }) + let ident = self.parse_ident()?; + let (delim, tokens) = self.expect_delimited_token_tree()?; + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } - _ => return Ok(None), + + (ident, ast::MacroDef { tokens, legacy: true }) + } else { + return Ok(None); }; let span = lo.to(self.prev_span); @@ -4413,14 +4410,14 @@ impl<'a> Parser<'a> { !self.is_existential_type_decl() && !self.is_auto_trait_item() && !self.is_async_fn() { - let pth = self.parse_path(PathStyle::Expr)?; + let path = self.parse_path(PathStyle::Expr)?; if !self.eat(&token::Not) { let expr = if self.check(&token::OpenDelim(token::Brace)) { - self.parse_struct_expr(lo, pth, ThinVec::new())? + self.parse_struct_expr(lo, path, ThinVec::new())? } else { let hi = self.prev_span; - self.mk_expr(lo.to(hi), ExprKind::Path(None, pth), ThinVec::new()) + self.mk_expr(lo.to(hi), ExprKind::Path(None, path), ThinVec::new()) }; let expr = self.with_res(Restrictions::STMT_EXPR, |this| { @@ -4444,7 +4441,7 @@ impl<'a> Parser<'a> { MacStmtStyle::NoBraces }; - let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim }); + let mac = respan(lo.to(hi), Mac_ { path, tts, delim }); let node = if delim == MacDelimiter::Brace || self.token == token::Semi || self.token == token::Eof { StmtKind::Mac(P((mac, style, attrs.into()))) @@ -7561,7 +7558,7 @@ impl<'a> Parser<'a> { let mac_lo = self.token.span; // item macro. - let pth = self.parse_path(PathStyle::Mod)?; + let path = self.parse_path(PathStyle::Mod)?; self.expect(&token::Not)?; let (delim, tts) = self.expect_delimited_token_tree()?; if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { @@ -7569,7 +7566,7 @@ impl<'a> Parser<'a> { } let hi = self.prev_span; - let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts, delim }); + let mac = respan(mac_lo.to(hi), Mac_ { path, tts, delim }); let item = self.mk_item(lo.to(hi), Ident::invalid(), ItemKind::Mac(mac), visibility, attrs); return Ok(Some(item)); @@ -7597,9 +7594,9 @@ impl<'a> Parser<'a> { !(self.is_async_fn() && self.token.span.rust_2015()) { let prev_span = self.prev_span; let lo = self.token.span; - let pth = self.parse_path(PathStyle::Mod)?; + let path = self.parse_path(PathStyle::Mod)?; - if pth.segments.len() == 1 { + if path.segments.len() == 1 { if !self.eat(&token::Not) { return Err(self.missing_assoc_item_kind_err(item_kind, prev_span)); } @@ -7619,7 +7616,7 @@ impl<'a> Parser<'a> { self.expect(&token::Semi)?; } - Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts, delim }))) + Ok(Some(respan(lo.to(self.prev_span), Mac_ { path, tts, delim }))) } else { Ok(None) } -- cgit 1.4.1-3-g733a5 From 636f5e6d1120c2bfc264687fbe1e77312c8d2979 Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Sun, 30 Jun 2019 11:30:01 -0700 Subject: Convert more usages over --- src/liballoc/collections/btree/map.rs | 4 ++-- src/liballoc/collections/linked_list.rs | 2 +- src/liballoc/str.rs | 2 +- src/librustc/hir/lowering.rs | 4 ++-- src/librustc/infer/nll_relate/mod.rs | 2 +- src/librustc/infer/outlives/obligations.rs | 2 +- src/librustc/infer/region_constraints/mod.rs | 2 +- src/librustc/middle/region.rs | 2 +- src/librustc/middle/resolve_lifetime.rs | 9 ++++----- src/librustc_codegen_llvm/back/archive.rs | 4 ++-- src/librustc_codegen_ssa/back/command.rs | 2 +- src/librustc_codegen_ssa/back/write.rs | 9 +++------ src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustc_mir/build/matches/simplify.rs | 2 +- src/librustc_mir/util/def_use.rs | 2 +- src/librustc_resolve/macros.rs | 6 +++--- src/librustc_resolve/resolve_imports.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 4 ++-- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/clean/simplify.rs | 2 +- src/librustdoc/html/render.rs | 2 +- src/librustdoc/passes/collapse_docs.rs | 2 +- src/libstd/panicking.rs | 2 +- src/libstd/sync/mpsc/sync.rs | 2 +- src/libstd/sys/windows/pipe.rs | 2 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/tt/transcribe.rs | 2 +- src/libsyntax/parse/parser.rs | 4 ++-- src/libsyntax/test.rs | 4 ++-- src/tools/compiletest/src/runtest.rs | 4 ++-- 30 files changed, 44 insertions(+), 48 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 6b079fc87cc..d9ebc40aa2c 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -770,8 +770,8 @@ impl BTreeMap { } // First, we merge `self` and `other` into a sorted sequence in linear time. - let self_iter = mem::replace(self, BTreeMap::new()).into_iter(); - let other_iter = mem::replace(other, BTreeMap::new()).into_iter(); + let self_iter = mem::take(self).into_iter(); + let other_iter = mem::take(other).into_iter(); let iter = MergeIter { left: self_iter.peekable(), right: other_iter.peekable(), diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 40a82d6feaa..ca9e78bb459 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -708,7 +708,7 @@ impl LinkedList { let len = self.len(); assert!(at <= len, "Cannot split off at a nonexistent index"); if at == 0 { - return mem::replace(self, Self::new()); + return mem::take(self); } else if at == len { return Self::new(); } diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs index 40104554fe5..70a93157c9e 100644 --- a/src/liballoc/str.rs +++ b/src/liballoc/str.rs @@ -203,7 +203,7 @@ impl ToOwned for str { } fn clone_into(&self, target: &mut String) { - let mut b = mem::replace(target, String::new()).into_bytes(); + let mut b = mem::take(target).into_bytes(); self.as_bytes().clone_into(&mut b); *target = unsafe { String::from_utf8_unchecked(b) } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 9c4a208f0f9..2e7a934a769 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1278,8 +1278,8 @@ impl<'a> LoweringContext<'a> { let was_in_loop_condition = self.is_in_loop_condition; self.is_in_loop_condition = false; - let catch_scopes = mem::replace(&mut self.catch_scopes, Vec::new()); - let loop_scopes = mem::replace(&mut self.loop_scopes, Vec::new()); + let catch_scopes = mem::take(&mut self.catch_scopes); + let loop_scopes = mem::take(&mut self.loop_scopes); let ret = f(self); self.catch_scopes = catch_scopes; self.loop_scopes = loop_scopes; diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index a1a93eb5521..a0621af0537 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -364,7 +364,7 @@ where // been fully instantiated and hence the set of scopes we have // doesn't matter -- just to be sure, put an empty vector // in there. - let old_a_scopes = ::std::mem::replace(pair.vid_scopes(self), vec![]); + let old_a_scopes = ::std::mem::take(pair.vid_scopes(self)); // Relate the generalized kind to the original one. let result = pair.relate_generalized_ty(self, generalized_ty); diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index 0ae4446ee63..e1470e4ef02 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -112,7 +112,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { /// Trait queries just want to pass back type obligations "as is" pub fn take_registered_region_obligations(&self) -> Vec<(hir::HirId, RegionObligation<'tcx>)> { - ::std::mem::replace(&mut *self.region_obligations.borrow_mut(), vec![]) + ::std::mem::take(&mut *self.region_obligations.borrow_mut()) } /// Process the region obligations that must be proven (during diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index f2235fe8d6d..b27c39c4f71 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -410,7 +410,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { *any_unifications = false; } - mem::replace(data, RegionConstraintData::default()) + mem::take(data) } pub fn data(&self) -> &RegionConstraintData<'tcx> { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 114684b1524..1a188bad11b 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -1375,7 +1375,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> { let outer_ec = mem::replace(&mut self.expr_and_pat_count, 0); let outer_cx = self.cx; - let outer_ts = mem::replace(&mut self.terminating_scopes, FxHashSet::default()); + let outer_ts = mem::take(&mut self.terminating_scopes); self.terminating_scopes.insert(body.value.hir_id.local_id); if let Some(root_id) = self.cx.root_id { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 412346bab25..dada3a87be5 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -18,7 +18,7 @@ use errors::{Applicability, DiagnosticBuilder}; use rustc_macros::HashStable; use std::borrow::Cow; use std::cell::Cell; -use std::mem::replace; +use std::mem::{replace, take}; use syntax::ast; use syntax::attr; use syntax::ptr::P; @@ -441,7 +441,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_nested_body(&mut self, body: hir::BodyId) { // Each body has their own set of labels, save labels. - let saved = replace(&mut self.labels_in_fn, vec![]); + let saved = take(&mut self.labels_in_fn); let body = self.tcx.hir().body(body); extract_labels(self, body); self.with( @@ -1405,9 +1405,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lifetime_uses, .. } = self; - let labels_in_fn = replace(&mut self.labels_in_fn, vec![]); - let xcrate_object_lifetime_defaults = - replace(&mut self.xcrate_object_lifetime_defaults, DefIdMap::default()); + let labels_in_fn = take(&mut self.labels_in_fn); + let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults); let mut this = LifetimeContext { tcx: *tcx, map: map, diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs index e0e26e9af25..ca3b2b84655 100644 --- a/src/librustc_codegen_llvm/back/archive.rs +++ b/src/librustc_codegen_llvm/back/archive.rs @@ -205,8 +205,8 @@ impl<'a> LlvmArchiveBuilder<'a> { } fn build_with_llvm(&mut self, kind: ArchiveKind) -> io::Result<()> { - let removals = mem::replace(&mut self.removals, Vec::new()); - let mut additions = mem::replace(&mut self.additions, Vec::new()); + let removals = mem::take(&mut self.removals); + let mut additions = mem::take(&mut self.additions); let mut strings = Vec::new(); let mut members = Vec::new(); diff --git a/src/librustc_codegen_ssa/back/command.rs b/src/librustc_codegen_ssa/back/command.rs index 78570cce57d..d610805b5bb 100644 --- a/src/librustc_codegen_ssa/back/command.rs +++ b/src/librustc_codegen_ssa/back/command.rs @@ -110,7 +110,7 @@ impl Command { } pub fn take_args(&mut self) -> Vec { - mem::replace(&mut self.args, Vec::new()) + mem::take(&mut self.args) } /// Returns a `true` if we're pretty sure that this'll blow OS spawn limits, diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 309187ca2ea..5ca38273269 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -1345,12 +1345,9 @@ fn start_executing_work( assert!(!started_lto); started_lto = true; - let needs_fat_lto = - mem::replace(&mut needs_fat_lto, Vec::new()); - let needs_thin_lto = - mem::replace(&mut needs_thin_lto, Vec::new()); - let import_only_modules = - mem::replace(&mut lto_import_only_modules, Vec::new()); + let needs_fat_lto = mem::take(&mut needs_fat_lto); + let needs_thin_lto = mem::take(&mut needs_thin_lto); + let import_only_modules = mem::take(&mut lto_import_only_modules); for (work, cost) in generate_lto_work(&cgcx, needs_fat_lto, needs_thin_lto, import_only_modules) { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 4872440f5bd..58009167e3c 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -275,7 +275,7 @@ fn do_mir_borrowck<'a, 'tcx>( mbcx.analyze_results(&mut state); // entry point for DataflowResultsConsumer // Convert any reservation warnings into lints. - let reservation_warnings = mem::replace(&mut mbcx.reservation_warnings, Default::default()); + let reservation_warnings = mem::take(&mut mbcx.reservation_warnings); for (_, (place, span, location, bk, borrow)) in reservation_warnings { let mut initial_diag = mbcx.report_conflicting_borrow(location, (&place, span), bk, &borrow); diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index b1b5233fbc8..7125eb6850b 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -28,7 +28,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate: &mut Candidate<'pat, 'tcx>) { // repeatedly simplify match pairs until fixed point is reached loop { - let match_pairs = mem::replace(&mut candidate.match_pairs, vec![]); + let match_pairs = mem::take(&mut candidate.match_pairs); let mut changed = false; for match_pair in match_pairs { match self.simplify_match_pair(match_pair, candidate) { diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs index fac752dbf02..59821440c66 100644 --- a/src/librustc_mir/util/def_use.rs +++ b/src/librustc_mir/util/def_use.rs @@ -31,7 +31,7 @@ impl DefUseAnalysis { self.clear(); let mut finder = DefUseFinder { - info: mem::replace(&mut self.info, IndexVec::new()), + info: mem::take(&mut self.info), }; finder.visit_body(body); self.info = finder.info diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 392a46a262f..c544b3f4603 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -946,7 +946,7 @@ impl<'a> Resolver<'a> { }; let macro_resolutions = - mem::replace(&mut *module.multi_segment_macro_resolutions.borrow_mut(), Vec::new()); + mem::take(&mut *module.multi_segment_macro_resolutions.borrow_mut()); for (mut path, path_span, kind, parent_scope, initial_res) in macro_resolutions { // FIXME: Path resolution will ICE if segment IDs present. for seg in &mut path { seg.id = None; } @@ -973,7 +973,7 @@ impl<'a> Resolver<'a> { } let macro_resolutions = - mem::replace(&mut *module.single_segment_macro_resolutions.borrow_mut(), Vec::new()); + mem::take(&mut *module.single_segment_macro_resolutions.borrow_mut()); for (ident, kind, parent_scope, initial_binding) in macro_resolutions { match self.early_resolve_ident_in_lexical_scope(ident, ScopeSet::Macro(kind), &parent_scope, true, true, ident.span) { @@ -998,7 +998,7 @@ impl<'a> Resolver<'a> { } } - let builtin_attrs = mem::replace(&mut *module.builtin_attrs.borrow_mut(), Vec::new()); + let builtin_attrs = mem::take(&mut *module.builtin_attrs.borrow_mut()); for (ident, parent_scope) in builtin_attrs { let _ = self.early_resolve_ident_in_lexical_scope( ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, true, true, ident.span diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index f69849bb4a9..404d728d880 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -682,7 +682,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1; while self.indeterminate_imports.len() < prev_num_indeterminates { prev_num_indeterminates = self.indeterminate_imports.len(); - for import in mem::replace(&mut self.indeterminate_imports, Vec::new()) { + for import in mem::take(&mut self.indeterminate_imports) { match self.resolve_import(&import) { true => self.determined_imports.push(import), false => self.indeterminate_imports.push(import), diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 661883f2ac1..bd4cf9d2086 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -970,9 +970,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { debug!("pick: actual search failed, assemble diagnotics"); - let static_candidates = mem::replace(&mut self.static_candidates, vec![]); + let static_candidates = mem::take(&mut self.static_candidates); let private_candidate = self.private_candidate.take(); - let unsatisfied_predicates = mem::replace(&mut self.unsatisfied_predicates, vec![]); + let unsatisfied_predicates = mem::take(&mut self.unsatisfied_predicates); // things failed, so lets look at all traits, for diagnostic purposes now: self.reset(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3fe048a6986..8fec433e56d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4408,7 +4408,7 @@ pub fn enter_impl_trait(cx: &DocContext<'_>, f: F) -> R where F: FnOnce() -> R, { - let old_bounds = mem::replace(&mut *cx.impl_trait_bounds.borrow_mut(), Default::default()); + let old_bounds = mem::take(&mut *cx.impl_trait_bounds.borrow_mut()); let r = f(); assert!(cx.impl_trait_bounds.borrow().is_empty()); *cx.impl_trait_bounds.borrow_mut() = old_bounds; diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 36e6a6003df..e4fba73b820 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -131,7 +131,7 @@ pub fn ty_params(mut params: Vec) -> Vec { - *bounds = ty_bounds(mem::replace(bounds, Vec::new())); + *bounds = ty_bounds(mem::take(bounds)); } _ => panic!("expected only type parameters"), } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 2080637ecb4..2d6503c9445 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -660,7 +660,7 @@ pub fn run(mut krate: clean::Crate, deref_trait_did, deref_mut_trait_did, owned_box_did, - masked_crates: mem::replace(&mut krate.masked_crates, Default::default()), + masked_crates: mem::take(&mut krate.masked_crates), param_names: external_param_names, aliases: Default::default(), }; diff --git a/src/librustdoc/passes/collapse_docs.rs b/src/librustdoc/passes/collapse_docs.rs index 8666ba357b8..e15a95e2e1a 100644 --- a/src/librustdoc/passes/collapse_docs.rs +++ b/src/librustdoc/passes/collapse_docs.rs @@ -46,7 +46,7 @@ fn collapse(doc_strings: &mut Vec) { let mut docs = vec![]; let mut last_frag: Option = None; - for frag in replace(doc_strings, vec![]) { + for frag in take(doc_strings) { if let Some(mut curr_frag) = last_frag.take() { let curr_kind = curr_frag.kind(); let new_kind = frag.kind(); diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 797d85e941d..952fd9ebfdf 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -364,7 +364,7 @@ fn continue_panic_fmt(info: &PanicInfo<'_>) -> ! { unsafe impl<'a> BoxMeUp for PanicPayload<'a> { fn box_me_up(&mut self) -> *mut (dyn Any + Send) { - let contents = mem::replace(self.fill(), String::new()); + let contents = mem::take(self.fill()); Box::into_raw(Box::new(contents)) } diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs index 3c4f8e077c9..f8fcd3ff5a5 100644 --- a/src/libstd/sync/mpsc/sync.rs +++ b/src/libstd/sync/mpsc/sync.rs @@ -383,7 +383,7 @@ impl Packet { // needs to be careful to destroy the data *outside* of the lock to // prevent deadlock. let _data = if guard.cap != 0 { - mem::replace(&mut guard.buf.buf, Vec::new()) + mem::take(&mut guard.buf.buf) } else { Vec::new() }; diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 493ee8a9a2d..c77f30dfc71 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -342,7 +342,7 @@ impl<'a> Drop for AsyncPipe<'a> { // If anything here fails, there's not really much we can do, so we leak // the buffer/OVERLAPPED pointers to ensure we're at least memory safe. if self.pipe.cancel_io().is_err() || self.result().is_err() { - let buf = mem::replace(self.dst, Vec::new()); + let buf = mem::take(self.dst); let overlapped = Box::new(unsafe { mem::zeroed() }); let overlapped = mem::replace(&mut self.overlapped, overlapped); mem::forget((buf, overlapped)); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 5473f55aa33..c0f721b466e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -307,7 +307,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } else { self.resolve_imports(); if undetermined_invocations.is_empty() { break } - invocations = mem::replace(&mut undetermined_invocations, Vec::new()); + invocations = mem::take(&mut undetermined_invocations); force = !mem::replace(&mut progress, false); continue }; diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index ea7f8e356aa..e04fd2ddc05 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -249,7 +249,7 @@ pub fn transcribe( quoted::TokenTree::Delimited(mut span, delimited) => { span = span.apply_mark(cx.current_expansion.mark); stack.push(Frame::Delimited { forest: delimited, idx: 0, span }); - result_stack.push(mem::replace(&mut result, Vec::new())); + result_stack.push(mem::take(&mut result)); } // Nothing much to do here. Just push the token to the result, being careful to diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 696b5f48385..8ac20f33908 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7699,7 +7699,7 @@ impl<'a> Parser<'a> { let mut tokens = Vec::new(); let prev_collecting = match self.token_cursor.frame.last_token { LastToken::Collecting(ref mut list) => { - Some(mem::replace(list, Vec::new())) + Some(mem::take(list)) } LastToken::Was(ref mut last) => { tokens.extend(last.take()); @@ -7717,7 +7717,7 @@ impl<'a> Parser<'a> { // Pull out the tokens that we've collected from the call to `f` above. let mut collected_tokens = match *last_token { - LastToken::Collecting(ref mut v) => mem::replace(v, Vec::new()), + LastToken::Collecting(ref mut v) => mem::take(v), LastToken::Was(_) => panic!("our vector went away?"), }; diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index f90b76721ee..156fab8834c 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -120,8 +120,8 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { // We don't want to recurse into anything other than mods, since // mods or tests inside of functions will break things if let ast::ItemKind::Mod(mut module) = item.node { - let tests = mem::replace(&mut self.tests, Vec::new()); - let tested_submods = mem::replace(&mut self.tested_submods, Vec::new()); + let tests = mem::take(&mut self.tests); + let tested_submods = mem::take(&mut self.tested_submods); noop_visit_mod(&mut module, self); let tests = mem::replace(&mut self.tests, tests); let tested_submods = mem::replace(&mut self.tested_submods, tested_submods); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 35caf82dd71..6053b538ff3 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -3608,7 +3608,7 @@ fn nocomment_mir_line(line: &str) -> &str { fn read2_abbreviated(mut child: Child) -> io::Result { use crate::read2::read2; - use std::mem::replace; + use std::mem::take; const HEAD_LEN: usize = 160 * 1024; const TAIL_LEN: usize = 256 * 1024; @@ -3632,7 +3632,7 @@ fn read2_abbreviated(mut child: Child) -> io::Result { return; } let tail = bytes.split_off(new_len - TAIL_LEN).into_boxed_slice(); - let head = replace(bytes, Vec::new()); + let head = take(bytes); let skipped = new_len - HEAD_LEN - TAIL_LEN; ProcOutput::Abbreviated { head, -- cgit 1.4.1-3-g733a5 From dc088b26ce39d8a4632d73e62e5440ae474a8cb5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 2 Jul 2019 11:06:01 +0300 Subject: refactor check_for_substitution No behavior change, just flatter and simpler code --- src/libsyntax/parse/lexer/mod.rs | 22 ------ src/libsyntax/parse/lexer/unicode_chars.rs | 117 ++++++++++++++++++----------- 2 files changed, 72 insertions(+), 67 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index ead5d543bec..2309ead55b2 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -84,28 +84,6 @@ impl<'a> StringReader<'a> { Ok(ret_val) } - /// Immutably extract string if found at current position with given delimiters - fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option { - let mut pos = self.pos; - let mut idx = self.src_index(pos); - let mut ch = char_at(&self.src, idx); - if ch != from_ch { - return None; - } - pos = pos + Pos::from_usize(ch.len_utf8()); - let start_pos = pos; - idx = self.src_index(pos); - while idx < self.end_src_index { - ch = char_at(&self.src, idx); - if ch == to_ch { - return Some(self.src[self.src_index(start_pos)..self.src_index(pos)].to_string()); - } - pos = pos + Pos::from_usize(ch.len_utf8()); - idx = self.src_index(pos); - } - return None; - } - fn try_real_token(&mut self) -> Result { let mut t = self.try_next_token()?; loop { diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index 94ce6297fbe..6a870685938 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -1,10 +1,11 @@ // Characters and their corresponding confusables were collected from // http://www.unicode.org/Public/security/10.0.0/confusables.txt -use syntax_pos::{Span, Pos, NO_EXPANSION}; -use errors::{Applicability, DiagnosticBuilder}; use super::StringReader; +use errors::{Applicability, DiagnosticBuilder}; +use syntax_pos::{Pos, Span, NO_EXPANSION}; +#[rustfmt::skip] // for line breaks const UNICODE_ARRAY: &[(char, &str, char)] = &[ ('
', "Line Separator", ' '), ('
', "Paragraph Separator", ' '), @@ -293,8 +294,8 @@ const UNICODE_ARRAY: &[(char, &str, char)] = &[ ('〉', "Right-Pointing Angle Bracket", '>'), ('〉', "Right Angle Bracket", '>'), ('》', "Right Double Angle Bracket", '>'), - ('>', "Fullwidth Greater-Than Sign", '>'), ]; - + ('>', "Fullwidth Greater-Than Sign", '>'), +]; const ASCII_ARRAY: &[(char, &str)] = &[ (' ', "Space"), @@ -321,46 +322,72 @@ const ASCII_ARRAY: &[(char, &str)] = &[ ('+', "Plus Sign"), ('<', "Less-Than Sign"), ('=', "Equals Sign"), - ('>', "Greater-Than Sign"), ]; - -crate fn check_for_substitution<'a>(reader: &StringReader<'a>, - ch: char, - err: &mut DiagnosticBuilder<'a>) -> bool { - UNICODE_ARRAY - .iter() - .find(|&&(c, _, _)| c == ch) - .map(|&(_, u_name, ascii_char)| { - let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION); - match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) { - Some(&(ascii_char, ascii_name)) => { - // special help suggestion for "directed" double quotes - if let Some(s) = reader.peek_delimited('“', '”') { - let msg = format!("Unicode characters '“' (Left Double Quotation Mark) and \ - '”' (Right Double Quotation Mark) look like '{}' ({}), but are not", - ascii_char, ascii_name); - err.span_suggestion( - Span::new(reader.pos, reader.next_pos + Pos::from_usize(s.len()) + - Pos::from_usize('”'.len_utf8()), NO_EXPANSION), - &msg, - format!("\"{}\"", s), - Applicability::MaybeIncorrect); - } else { - let msg = - format!("Unicode character '{}' ({}) looks like '{}' ({}), but it is not", - ch, u_name, ascii_char, ascii_name); - err.span_suggestion( - span, - &msg, - ascii_char.to_string(), - Applicability::MaybeIncorrect); - } - true - }, - None => { - let msg = format!("substitution character not found for '{}'", ch); - reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); - false - } + ('>', "Greater-Than Sign"), +]; + +crate fn check_for_substitution<'a>( + reader: &StringReader<'a>, + ch: char, + err: &mut DiagnosticBuilder<'a>, +) -> bool { + let (u_name, ascii_char) = match UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) { + Some(&(_u_char, u_name, ascii_char)) => (u_name, ascii_char), + None => return false, + }; + + let span = Span::new(reader.pos, reader.next_pos, NO_EXPANSION); + + let ascii_name = match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) { + Some((_ascii_char, ascii_name)) => ascii_name, + None => { + let msg = format!("substitution character not found for '{}'", ch); + reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); + return false + }, + }; + + // special help suggestion for "directed" double quotes + if let Some(s) = reader.peek_delimited('“', '”') { + let msg = format!( + "Unicode characters '“' (Left Double Quotation Mark) and \ + '”' (Right Double Quotation Mark) look like '{}' ({}), but are not", + ascii_char, ascii_name + ); + err.span_suggestion( + Span::new( + reader.pos, + reader.next_pos + Pos::from_usize(s.len()) + Pos::from_usize('”'.len_utf8()), + NO_EXPANSION, + ), + &msg, + format!("\"{}\"", s), + Applicability::MaybeIncorrect, + ); + } else { + let msg = format!( + "Unicode character '{}' ({}) looks like '{}' ({}), but it is not", + ch, u_name, ascii_char, ascii_name + ); + err.span_suggestion( + span, + &msg, + ascii_char.to_string(), + Applicability::MaybeIncorrect, + ); + } + true +} + +impl StringReader<'_> { + /// Immutably extract string if found at current position with given delimiters + fn peek_delimited(&self, from_ch: char, to_ch: char) -> Option<&str> { + let tail = &self.src[self.src_index(self.pos)..]; + let mut chars = tail.chars(); + let first_char = chars.next()?; + if first_char != from_ch { + return None; } - }).unwrap_or(false) + let last_char_idx = chars.as_str().find(to_ch)?; + Some(&chars.as_str()[..last_char_idx]) + } } -- cgit 1.4.1-3-g733a5