diff options
| author | Corey Farwell <coreyf@rwell.org> | 2020-12-31 23:27:33 -0500 |
|---|---|---|
| committer | Corey Farwell <coreyf@rwell.org> | 2020-12-31 23:27:33 -0500 |
| commit | d482de30ea70d537dced8ec04a3903e3264cf106 (patch) | |
| tree | 67d6cd380ef7a66e785a54993bb0ca93b07b43ec /compiler/rustc_span | |
| parent | 26cc060756d0456b17fdc53ac5d34e7f7bdc873d (diff) | |
| parent | 99ad5a1a2824fea1ecf60068fd3636beae7ea2da (diff) | |
| download | rust-d482de30ea70d537dced8ec04a3903e3264cf106.tar.gz rust-d482de30ea70d537dced8ec04a3903e3264cf106.zip | |
Merge remote-tracking branch 'origin/master' into frewsxcv-san
Diffstat (limited to 'compiler/rustc_span')
| -rw-r--r-- | compiler/rustc_span/src/edition.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_span/src/hygiene.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_span/src/lev_distance.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_span/src/lib.rs | 68 | ||||
| -rw-r--r-- | compiler/rustc_span/src/source_map.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_span/src/span_encoding.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 111 |
7 files changed, 152 insertions, 82 deletions
diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index 4d0c92f51d7..efbb0a23a6f 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -4,24 +4,25 @@ use std::str::FromStr; use rustc_macros::HashStable_Generic; -/// The edition of the compiler (RFC 2052) +/// The edition of the compiler. (See [RFC 2052](https://github.com/rust-lang/rfcs/blob/master/text/2052-epochs.md).) #[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, Decodable, Eq)] #[derive(HashStable_Generic)] pub enum Edition { - // editions must be kept in order, oldest to newest + // When adding new editions, be sure to do the following: + // + // - update the `ALL_EDITIONS` const + // - update the `EDITION_NAME_LIST` const + // - add a `rust_####()` function to the session + // - update the enum in Cargo's sources as well + // + // Editions *must* be kept in order, oldest to newest. /// The 2015 edition Edition2015, /// The 2018 edition Edition2018, - // when adding new editions, be sure to update: - // - // - Update the `ALL_EDITIONS` const - // - Update the EDITION_NAME_LIST const - // - add a `rust_####()` function to the session - // - update the enum in Cargo's sources as well } -// must be in order from oldest to newest +// Must be in order from oldest to newest. pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; pub const EDITION_NAME_LIST: &str = "2015|2018"; diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 0f82db1d05a..fdc0d225bb8 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1065,7 +1065,7 @@ pub fn decode_syntax_context< parent: SyntaxContext::root(), opaque: SyntaxContext::root(), opaque_and_semitransparent: SyntaxContext::root(), - dollar_crate_name: kw::Invalid, + dollar_crate_name: kw::Empty, }); let mut ctxts = outer_ctxts.lock(); let new_len = raw_id as usize + 1; @@ -1092,7 +1092,7 @@ pub fn decode_syntax_context< ctxt_data, ); // Make sure nothing weird happening while `decode_data` was running - assert_eq!(dummy.dollar_crate_name, kw::Invalid); + assert_eq!(dummy.dollar_crate_name, kw::Empty); }); Ok(new_ctxt) diff --git a/compiler/rustc_span/src/lev_distance.rs b/compiler/rustc_span/src/lev_distance.rs index edc6625a6ea..cea7871923b 100644 --- a/compiler/rustc_span/src/lev_distance.rs +++ b/compiler/rustc_span/src/lev_distance.rs @@ -1,10 +1,16 @@ +//! Levenshtein distances. +//! +//! The [Levenshtein distance] is a metric for measuring the difference between two strings. +//! +//! [Levenshtein distance]: https://en.wikipedia.org/wiki/Levenshtein_distance + use crate::symbol::Symbol; use std::cmp; #[cfg(test)] mod tests; -/// Finds the Levenshtein distance between two strings +/// Finds the Levenshtein distance between two strings. pub fn lev_distance(a: &str, b: &str) -> usize { // cases which don't require further computation if a.is_empty() { @@ -35,14 +41,14 @@ pub fn lev_distance(a: &str, b: &str) -> usize { dcol[t_last + 1] } -/// Finds the best match for a given word in the given iterator +/// Finds the best match for a given word in the given iterator. /// /// As a loose rule to avoid the obviously incorrect suggestions, it takes /// an optional limit for the maximum allowable edit distance, which defaults /// to one-third of the given word. /// -/// Besides Levenshtein, we use case insensitive comparison to improve accuracy on an edge case with -/// a lower(upper)case letters mismatch. +/// Besides Levenshtein, we use case insensitive comparison to improve accuracy +/// on an edge case with a lower(upper)case letters mismatch. #[cold] pub fn find_best_match_for_name( name_vec: &[Symbol], @@ -98,7 +104,7 @@ fn find_match_by_sorted_words(iter_names: &[Symbol], lookup: &str) -> Option<Sym fn sort_by_words(name: &str) -> String { let mut split_words: Vec<&str> = name.split('_').collect(); - // We are sorting primitive &strs and can use unstable sort here + // We are sorting primitive &strs and can use unstable sort here. split_words.sort_unstable(); split_words.join("_") } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index f63a73acbf4..80095307175 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1,4 +1,13 @@ -//! The source positions and related helper functions. +//! Source positions and related helper functions. +//! +//! Important concepts in this module include: +//! +//! - the *span*, represented by [`SpanData`] and related types; +//! - source code as represented by a [`SourceMap`]; and +//! - interned strings, represented by [`Symbol`]s, with some common symbols available statically in the [`sym`] module. +//! +//! Unlike most compilers, the span contains not only the position in the source code, but also various other metadata, +//! such as the edition and macro hygiene. This metadata is stored in [`SyntaxContext`] and [`ExpnData`]. //! //! ## Note //! @@ -124,7 +133,7 @@ pub enum RealFileName { impl RealFileName { /// Returns the path suitable for reading from the file system on the local host. - /// Avoid embedding this in build artifacts; see `stable_name` for that. + /// Avoid embedding this in build artifacts; see `stable_name()` for that. pub fn local_path(&self) -> &Path { match self { RealFileName::Named(p) @@ -133,7 +142,7 @@ impl RealFileName { } /// Returns the path suitable for reading from the file system on the local host. - /// Avoid embedding this in build artifacts; see `stable_name` for that. + /// Avoid embedding this in build artifacts; see `stable_name()` for that. pub fn into_local_path(self) -> PathBuf { match self { RealFileName::Named(p) @@ -143,7 +152,7 @@ impl RealFileName { /// Returns the path suitable for embedding into build artifacts. Note that /// a virtualized path will not correspond to a valid file system path; see - /// `local_path` for something that is more likely to return paths into the + /// `local_path()` for something that is more likely to return paths into the /// local host file system. pub fn stable_name(&self) -> &Path { match self { @@ -173,7 +182,7 @@ pub enum FileName { /// Custom sources for explicit parser calls from plugins and drivers. Custom(String), DocTest(PathBuf, isize), - /// Post-substitution inline assembly from LLVM + /// Post-substitution inline assembly from LLVM. InlineAsm(u64), } @@ -182,7 +191,7 @@ impl std::fmt::Display for FileName { use FileName::*; match *self { Real(RealFileName::Named(ref path)) => write!(fmt, "{}", path.display()), - // FIXME: might be nice to display both compoments of Devirtualized. + // FIXME: might be nice to display both components of Devirtualized. // But for now (to backport fix for issue #70924), best to not // perturb diagnostics so its obvious test suite still works. Real(RealFileName::Devirtualized { ref local_path, virtual_name: _ }) => { @@ -266,14 +275,17 @@ impl FileName { } } +/// Represents a span. +/// /// Spans represent a region of code, used for error reporting. Positions in spans -/// are *absolute* positions from the beginning of the source_map, not positions -/// relative to `SourceFile`s. Methods on the `SourceMap` can be used to relate spans back +/// are *absolute* positions from the beginning of the [`SourceMap`], not positions +/// relative to [`SourceFile`]s. Methods on the `SourceMap` can be used to relate spans back /// to the original source. -/// You must be careful if the span crosses more than one file - you will not be +/// +/// You must be careful if the span crosses more than one file, since you will not be /// able to use many of the functions on spans in source_map and you cannot assume -/// that the length of the `span = hi - lo`; there may be space in the `BytePos` -/// range between files. +/// that the length of the span is equal to `span.hi - span.lo`; there may be space in the +/// [`BytePos`] range between files. /// /// `SpanData` is public because `Span` uses a thread-local interner and can't be /// sent to other threads, but some pieces of performance infra run in a separate thread. @@ -384,7 +396,7 @@ impl Span { Span::new(lo, hi, SyntaxContext::root()) } - /// Returns a new span representing an empty span at the beginning of this span + /// Returns a new span representing an empty span at the beginning of this span. #[inline] pub fn shrink_to_lo(self) -> Span { let span = self.data(); @@ -398,7 +410,7 @@ impl Span { } #[inline] - /// Returns true if hi == lo + /// Returns `true` if `hi == lo`. pub fn is_empty(&self) -> bool { let span = self.data(); span.hi == span.lo @@ -512,7 +524,7 @@ impl Span { } /// Checks if a span is "internal" to a macro in which `unsafe` - /// can be used without triggering the `unsafe_code` lint + /// can be used without triggering the `unsafe_code` lint. // (that is, a macro marked with `#[allow_internal_unsafe]`). pub fn allows_unsafe(&self) -> bool { self.ctxt().outer_expn_data().allow_internal_unsafe @@ -700,6 +712,7 @@ impl Span { } } +/// A span together with some additional data. #[derive(Clone, Debug)] pub struct SpanLabel { /// The span we are going to include in the final snippet. @@ -743,7 +756,7 @@ impl<D: Decoder> Decodable<D> for Span { /// any spans that are debug-printed during the closure's execution. /// /// Normally, the global `TyCtxt` is used to retrieve the `SourceMap` -/// (see `rustc_interface::callbacks::span_debug1). However, some parts +/// (see `rustc_interface::callbacks::span_debug1`). However, some parts /// of the compiler (e.g. `rustc_parse`) may debug-print `Span`s before /// a `TyCtxt` is available. In this case, we fall back to /// the `SourceMap` provided to this function. If that is not available, @@ -994,9 +1007,9 @@ pub enum ExternalSource { Unneeded, Foreign { kind: ExternalSourceKind, - /// This SourceFile's byte-offset within the source_map of its original crate + /// This SourceFile's byte-offset within the source_map of its original crate. original_start_pos: BytePos, - /// The end of this SourceFile within the source_map of its original crate + /// The end of this SourceFile within the source_map of its original crate. original_end_pos: BytePos, }, } @@ -1099,7 +1112,7 @@ impl SourceFileHash { } } -/// A single source in the `SourceMap`. +/// A single source in the [`SourceMap`]. #[derive(Clone)] pub struct SourceFile { /// The name of the file that the source came from. Source that doesn't @@ -1580,7 +1593,7 @@ fn remove_bom(src: &mut String, normalized_pos: &mut Vec<NormalizedPos>) { /// Replaces `\r\n` with `\n` in-place in `src`. /// -/// Returns error if there's a lone `\r` in the string +/// Returns error if there's a lone `\r` in the string. fn normalize_newlines(src: &mut String, normalized_pos: &mut Vec<NormalizedPos>) { if !src.as_bytes().contains(&b'\r') { return; @@ -1705,13 +1718,16 @@ macro_rules! impl_pos { } impl_pos! { - /// A byte offset. Keep this small (currently 32-bits), as AST contains - /// a lot of them. + /// A byte offset. + /// + /// Keep this small (currently 32-bits), as AST contains a lot of them. #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] pub struct BytePos(pub u32); - /// A character offset. Because of multibyte UTF-8 characters, a byte offset - /// is not equivalent to a character offset. The `SourceMap` will convert `BytePos` + /// A character offset. + /// + /// Because of multibyte UTF-8 characters, a byte offset + /// is not equivalent to a character offset. The [`SourceMap`] will convert [`BytePos`] /// values to `CharPos` values as necessary. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] pub struct CharPos(pub usize); @@ -1835,8 +1851,9 @@ fn lookup_line(lines: &[BytePos], pos: BytePos) -> isize { } /// Requirements for a `StableHashingContext` to be used in this crate. -/// This is a hack to allow using the `HashStable_Generic` derive macro -/// instead of implementing everything in librustc_middle. +/// +/// This is a hack to allow using the [`HashStable_Generic`] derive macro +/// instead of implementing everything in rustc_middle. pub trait HashStableContext { fn hash_def_id(&mut self, _: DefId, hasher: &mut StableHasher); fn hash_crate_num(&mut self, _: CrateNum, hasher: &mut StableHasher); @@ -1856,6 +1873,7 @@ where /// offsets into the `SourceMap`). Instead, we hash the (file name, line, column) /// triple, which stays the same even if the containing `SourceFile` has moved /// within the `SourceMap`. + /// /// Also note that we are hashing byte offsets for the column, not unicode /// codepoint offsets. For the purpose of the hash that's sufficient. /// Also, hashing filenames is expensive so we avoid doing it twice when the diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index e9b4eb6e4ab..fefc0cb48dd 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -1,9 +1,11 @@ -//! The `SourceMap` tracks all the source code used within a single crate, mapping +//! Types for tracking pieces of source code within a crate. +//! +//! The [`SourceMap`] tracks all the source code used within a single crate, mapping //! from integer byte positions to the original source code location. Each bit //! of source parsed during crate parsing (typically files, in-memory strings, //! or various bits of macro expansion) cover a continuous range of bytes in the -//! `SourceMap` and are represented by `SourceFile`s. Byte positions are stored in -//! `Span` and used pervasively in the compiler. They are absolute positions +//! `SourceMap` and are represented by [`SourceFile`]s. Byte positions are stored in +//! [`Span`] and used pervasively in the compiler. They are absolute positions //! within the `SourceMap`, which upon request can be converted to line and column //! information, source code snippets, etc. diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index b05e01d666b..ceb9b59b13a 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -12,7 +12,7 @@ use rustc_data_structures::fx::FxIndexSet; /// A compressed span. /// -/// `SpanData` is 12 bytes, which is a bit too big to stick everywhere. `Span` +/// Whereas [`SpanData`] is 12 bytes, which is a bit too big to stick everywhere, `Span` /// is a form that only takes up 8 bytes, with less space for the length and /// context. The vast majority (99.9%+) of `SpanData` instances will fit within /// those 8 bytes; any `SpanData` whose fields don't fit into a `Span` are @@ -42,13 +42,11 @@ use rustc_data_structures::fx::FxIndexSet; /// - `base` is 32 bits in both `Span` and `SpanData`, which means that `base` /// values never cause interning. The number of bits needed for `base` /// depends on the crate size. 32 bits allows up to 4 GiB of code in a crate. -/// `script-servo` is the largest crate in `rustc-perf`, requiring 26 bits -/// for some spans. /// - `len` is 15 bits in `Span` (a u16, minus 1 bit for the tag) and 32 bits /// in `SpanData`, which means that large `len` values will cause interning. /// The number of bits needed for `len` does not depend on the crate size. -/// The most common number of bits for `len` are 0--7, with a peak usually at -/// 3 or 4, and then it drops off quickly from 8 onwards. 15 bits is enough +/// The most common numbers of bits for `len` are from 0 to 7, with a peak usually +/// at 3 or 4, and then it drops off quickly from 8 onwards. 15 bits is enough /// for 99.99%+ of cases, but larger values (sometimes 20+ bits) might occur /// dozens of times in a typical crate. /// - `ctxt` is 16 bits in `Span` and 32 bits in `SpanData`, which means that diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b9c942d61a9..382b7a4f2db 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -13,7 +13,7 @@ use std::fmt; use std::hash::{Hash, Hasher}; use std::str; -use crate::{Span, DUMMY_SP, SESSION_GLOBALS}; +use crate::{Edition, Span, DUMMY_SP, SESSION_GLOBALS}; #[cfg(test)] mod tests; @@ -25,7 +25,7 @@ symbols! { Keywords { // Special reserved identifiers used internally for elided lifetimes, // unnamed method parameters, crate root module, error recovery etc. - Invalid: "", + Empty: "", PathRoot: "{{root}}", DollarCrate: "$crate", Underscore: "_", @@ -460,6 +460,9 @@ symbols! { document_private_items, dotdot_in_tuple_patterns, dotdoteq_in_patterns, + dreg, + dreg_low16, + dreg_low8, drop, drop_in_place, drop_types_in_const, @@ -467,6 +470,7 @@ symbols! { dropck_parametricity, dylib, dyn_trait, + edition_macro_pats, eh_catch_typeinfo, eh_personality, emit_enum, @@ -544,6 +548,7 @@ symbols! { format_args_capture, format_args_nl, freeze, + freg, frem_fast, from, from_desugaring, @@ -627,6 +632,7 @@ symbols! { iter, keyword, kind, + kreg, label, label_break_value, lang, @@ -652,6 +658,7 @@ symbols! { lint_reasons, literal, llvm_asm, + local, local_inner_macros, log10f32, log10f64, @@ -802,6 +809,8 @@ symbols! { partial_ord, passes, pat, + pat2018, + pat2021, path, pattern_parentheses, phantom_data, @@ -854,6 +863,9 @@ symbols! { pub_restricted, pure, pushpop_unsafe, + qreg, + qreg_low4, + qreg_low8, quad_precision_float, question_mark, quote, @@ -875,6 +887,13 @@ symbols! { reexport_test_harness_main, reference, reflect, + reg, + reg16, + reg32, + reg64, + reg_abcd, + reg_byte, + reg_thumb, register_attr, register_tool, relaxed_adts, @@ -1060,6 +1079,8 @@ symbols! { spotlight, sqrtf32, sqrtf64, + sreg, + sreg_low16, sse4a_target_feature, stable, staged_api, @@ -1215,6 +1236,8 @@ symbols! { volatile_load, volatile_set_memory, volatile_store, + vreg, + vreg_low16, warn, wasm_import_module, wasm_target_feature, @@ -1226,6 +1249,9 @@ symbols! { wrapping_mul, wrapping_sub, write_bytes, + xmm_reg, + ymm_reg, + zmm_reg, } } @@ -1250,7 +1276,7 @@ impl Ident { #[inline] pub fn invalid() -> Ident { - Ident::with_dummy_span(kw::Invalid) + Ident::with_dummy_span(kw::Empty) } /// Maps a string to an identifier with a dummy span. @@ -1428,12 +1454,6 @@ impl Symbol { with_interner(|interner| interner.intern(string)) } - /// Access the symbol's chars. This is a slowish operation because it - /// requires locking the symbol interner. - pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R { - with_interner(|interner| f(interner.get(self))) - } - /// Convert to a `SymbolStr`. This is a slowish operation because it /// requires locking the symbol interner. pub fn as_str(self) -> SymbolStr { @@ -1446,6 +1466,10 @@ impl Symbol { self.0.as_u32() } + pub fn is_empty(self) -> bool { + self == kw::Empty + } + /// This method is supposed to be used in error messages, so it's expected to be /// identical to printing the original identifier token written in source code /// (`token_to_string`, `Ident::to_string`), except that symbols don't keep the rawness flag @@ -1457,19 +1481,19 @@ impl Symbol { impl fmt::Debug for Symbol { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.with(|str| fmt::Debug::fmt(&str, f)) + fmt::Debug::fmt(&self.as_str(), f) } } impl fmt::Display for Symbol { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.with(|str| fmt::Display::fmt(&str, f)) + fmt::Display::fmt(&self.as_str(), f) } } impl<S: Encoder> Encodable<S> for Symbol { fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.with(|string| s.emit_str(string)) + s.emit_str(&self.as_str()) } } @@ -1550,8 +1574,7 @@ impl Interner { /// Given that `kw` is imported, use them like `kw::keyword_name`. /// For example `kw::Loop` or `kw::Break`. pub mod kw { - use super::Symbol; - keywords!(); + pub use super::kw_generated::*; } // This module has a very short name because it's used a lot. @@ -1559,22 +1582,23 @@ pub mod kw { /// /// Given that `sym` is imported, use them like `sym::symbol_name`. /// For example `sym::rustfmt` or `sym::u8`. -#[allow(rustc::default_hash_types)] pub mod sym { use super::Symbol; use std::convert::TryInto; - define_symbols!(); + pub use super::sym_generated::*; // Used from a macro in `librustc_feature/accepted.rs` pub use super::kw::MacroRules as macro_rules; - // Get the symbol for an integer. The first few non-negative integers each - // have a static symbol and therefore are fast. + /// Get the symbol for an integer. + /// + /// The first few non-negative integers each have a static symbol and therefore + /// are fast. pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol { if let Result::Ok(idx) = n.try_into() { - if let Option::Some(&sym_) = digits_array.get(idx) { - return sym_; + if idx < 10 { + return Symbol::new(super::SYMBOL_DIGITS_BASE + idx as u32); } } Symbol::intern(&n.to_string()) @@ -1582,12 +1606,32 @@ pub mod sym { } impl Symbol { - fn is_used_keyword_2018(self) -> bool { - self >= kw::Async && self <= kw::Dyn + fn is_special(self) -> bool { + self <= kw::Underscore + } + + fn is_used_keyword_always(self) -> bool { + self >= kw::As && self <= kw::While } - fn is_unused_keyword_2018(self) -> bool { - self == kw::Try + fn is_used_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool { + (self >= kw::Async && self <= kw::Dyn) && edition() >= Edition::Edition2018 + } + + fn is_unused_keyword_always(self) -> bool { + self >= kw::Abstract && self <= kw::Yield + } + + fn is_unused_keyword_conditional(self, edition: impl FnOnce() -> Edition) -> bool { + self == kw::Try && edition() >= Edition::Edition2018 + } + + pub fn is_reserved(self, edition: impl Copy + FnOnce() -> Edition) -> bool { + self.is_special() + || self.is_used_keyword_always() + || self.is_unused_keyword_always() + || self.is_used_keyword_conditional(edition) + || self.is_unused_keyword_conditional(edition) } /// A keyword or reserved identifier that can be used as a path segment. @@ -1605,9 +1649,9 @@ impl Symbol { self == kw::True || self == kw::False } - /// This symbol can be a raw identifier. + /// Returns `true` if this symbol can be a raw identifier. pub fn can_be_raw(self) -> bool { - self != kw::Invalid && self != kw::Underscore && !self.is_path_segment_keyword() + self != kw::Empty && self != kw::Underscore && !self.is_path_segment_keyword() } } @@ -1615,26 +1659,27 @@ impl Ident { // Returns `true` for reserved identifiers used internally for elided lifetimes, // unnamed method parameters, crate root module, error recovery etc. pub fn is_special(self) -> bool { - self.name <= kw::Underscore + self.name.is_special() } /// Returns `true` if the token is a keyword used in the language. pub fn is_used_keyword(self) -> bool { // Note: `span.edition()` is relatively expensive, don't call it unless necessary. - self.name >= kw::As && self.name <= kw::While - || self.name.is_used_keyword_2018() && self.span.rust_2018() + self.name.is_used_keyword_always() + || self.name.is_used_keyword_conditional(|| self.span.edition()) } /// Returns `true` if the token is a keyword reserved for possible future use. pub fn is_unused_keyword(self) -> bool { // Note: `span.edition()` is relatively expensive, don't call it unless necessary. - self.name >= kw::Abstract && self.name <= kw::Yield - || self.name.is_unused_keyword_2018() && self.span.rust_2018() + self.name.is_unused_keyword_always() + || self.name.is_unused_keyword_conditional(|| self.span.edition()) } /// Returns `true` if the token is either a special identifier or a keyword. pub fn is_reserved(self) -> bool { - self.is_special() || self.is_used_keyword() || self.is_unused_keyword() + // Note: `span.edition()` is relatively expensive, don't call it unless necessary. + self.name.is_reserved(|| self.span.edition()) } /// A keyword or reserved identifier that can be used as a path segment. @@ -1654,7 +1699,7 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T { SESSION_GLOBALS.with(|session_globals| f(&mut *session_globals.symbol_interner.lock())) } -/// An alternative to `Symbol`, useful when the chars within the symbol need to +/// An alternative to [`Symbol`], useful when the chars within the symbol need to /// be accessed. It deliberately has limited functionality and should only be /// used for temporary values. /// |
