Merge pull request #17 from rust-lang/master
sync with rust-lang/rust master branch
This commit is contained in:
commit
414d104729
198 changed files with 2719 additions and 1572 deletions
21
Cargo.lock
21
Cargo.lock
|
@ -1011,6 +1011,7 @@ dependencies = [
|
|||
name = "fmt_macros"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_lexer",
|
||||
"syntax_pos",
|
||||
]
|
||||
|
||||
|
@ -2324,9 +2325,9 @@ checksum = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
|
|||
|
||||
[[package]]
|
||||
name = "polonius-engine"
|
||||
version = "0.9.0"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6b8a5defa2aef9ba4999aaa745fbc01c622ecea35964a306adc3e44be4f3b5b"
|
||||
checksum = "50fa9dbfd0d3d60594da338cfe6f94028433eecae4b11b7e83fd99759227bbfe"
|
||||
dependencies = [
|
||||
"datafrog",
|
||||
"log",
|
||||
|
@ -2372,7 +2373,7 @@ version = "0.4.30"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3290,7 +3291,7 @@ dependencies = [
|
|||
name = "rustc_lexer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-xid 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3368,6 +3369,7 @@ dependencies = [
|
|||
"rustc_apfloat",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_lexer",
|
||||
"rustc_target",
|
||||
"serialize",
|
||||
"smallvec",
|
||||
|
@ -3976,7 +3978,7 @@ checksum = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3988,7 +3990,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unicode-xid",
|
||||
"unicode-xid 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4017,6 +4019,7 @@ dependencies = [
|
|||
"log",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_lexer",
|
||||
"rustc_target",
|
||||
"smallvec",
|
||||
"syntax",
|
||||
|
@ -4532,6 +4535,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_categories"
|
||||
version = "0.1.1"
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 432ca26686c11d396eed6a59499f93ce1bf2433c
|
||||
Subproject commit 5ca585c4a7552efb546e7681c3de0712f4ae4fdc
|
|
@ -1 +1 @@
|
|||
Subproject commit d191a0cdd3b92648e0f1e53b13140a14677cc65b
|
||||
Subproject commit 090c015f7939665866432c334957bd536c811870
|
|
@ -1 +1 @@
|
|||
Subproject commit 580839d90aacd537f0293697096fa8355bc4e673
|
||||
Subproject commit e76be6b2dc84c6a992e186157efe29d625e29b94
|
|
@ -105,5 +105,6 @@ The following table shows known good combinations of toolchain versions.
|
|||
| Rust 1.34 | ✗ | ✓ |
|
||||
| Rust 1.35 | ✗ | ✓ |
|
||||
| Rust 1.36 | ✗ | ✓ |
|
||||
| Rust 1.37 | ✗ | ✓ |
|
||||
|
||||
Note that the compatibility policy for this feature might change in the future.
|
||||
|
|
|
@ -57,12 +57,12 @@ extern crate rustc;
|
|||
extern crate rustc_driver;
|
||||
|
||||
use syntax::parse::token::{self, Token};
|
||||
use syntax::tokenstream::TokenTree;
|
||||
use syntax::tokenstream::{TokenTree, TokenStream};
|
||||
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
|
||||
use syntax_pos::Span;
|
||||
use rustc_driver::plugin::Registry;
|
||||
|
||||
fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
|
||||
fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: TokenStream)
|
||||
-> Box<dyn MacResult + 'static> {
|
||||
|
||||
static NUMERALS: &'static [(&'static str, usize)] = &[
|
||||
|
@ -78,7 +78,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
|
|||
return DummyResult::any(sp);
|
||||
}
|
||||
|
||||
let text = match args[0] {
|
||||
let text = match args.into_trees().next().unwrap() {
|
||||
TokenTree::Token(Token { kind: token::Ident(s, _), .. }) => s.to_string(),
|
||||
_ => {
|
||||
cx.span_err(sp, "argument should be a single identifier");
|
||||
|
|
|
@ -547,29 +547,6 @@ impl char {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this `char` satisfies the `XID_Start` Unicode property, and false
|
||||
/// otherwise.
|
||||
///
|
||||
/// `XID_Start` is a Unicode Derived Property specified in
|
||||
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
||||
/// mostly similar to `ID_Start` but modified for closure under `NFKx`.
|
||||
#[unstable(feature = "unicode_internals", issue = "0")]
|
||||
pub fn is_xid_start(self) -> bool {
|
||||
derived_property::XID_Start(self)
|
||||
}
|
||||
|
||||
/// Returns `true` if this `char` satisfies the `XID_Continue` Unicode property, and false
|
||||
/// otherwise.
|
||||
///
|
||||
/// `XID_Continue` is a Unicode Derived Property specified in
|
||||
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
||||
/// mostly similar to `ID_Continue` but modified for closure under NFKx.
|
||||
#[unstable(feature = "unicode_internals", issue = "0")]
|
||||
#[inline]
|
||||
pub fn is_xid_continue(self) -> bool {
|
||||
derived_property::XID_Continue(self)
|
||||
}
|
||||
|
||||
/// Returns `true` if this `char` is lowercase.
|
||||
///
|
||||
/// 'Lowercase' is defined according to the terms of the Unicode Derived Core
|
||||
|
|
|
@ -9,14 +9,22 @@
|
|||
//! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
|
||||
//! partial orderings between values, respectively. Implementing them overloads
|
||||
//! the `<`, `<=`, `>`, and `>=` operators.
|
||||
//! * [`Ordering`][cmp::Ordering] is an enum returned by the
|
||||
//! main functions of [`Ord`] and [`PartialOrd`], and describes an ordering.
|
||||
//! * [`Reverse`][cmp::Reverse] is a struct that allows you to easily reverse
|
||||
//! an ordering.
|
||||
//! * [`max`][cmp::max] and [`min`][cmp::min] are functions that build off of
|
||||
//! [`Ord`] and allow you to find the maximum or minimum of two values.
|
||||
//! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and
|
||||
//! [`PartialOrd`], and describes an ordering.
|
||||
//! * [`Reverse`] is a struct that allows you to easily reverse an ordering.
|
||||
//! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you
|
||||
//! to find the maximum or minimum of two values.
|
||||
//!
|
||||
//! For more details, see the respective documentation of each item in the list.
|
||||
//!
|
||||
//! [`Eq`]: trait.Eq.html
|
||||
//! [`PartialEq`]: trait.PartialEq.html
|
||||
//! [`Ord`]: trait.Ord.html
|
||||
//! [`PartialOrd`]: trait.PartialOrd.html
|
||||
//! [`Ordering`]: enum.Ordering.html
|
||||
//! [`Reverse`]: struct.Reverse.html
|
||||
//! [`max`]: fn.max.html
|
||||
//! [`min`]: fn.min.html
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
|
|
|
@ -66,13 +66,6 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
|
|||
{
|
||||
self.iter.rfind(predicate)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
|
||||
P: FnMut(Self::Item) -> bool
|
||||
{
|
||||
self.iter.position(predicate)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
|
|
@ -462,7 +462,7 @@ impl<P: Deref<Target: Unpin>> Pin<P> {
|
|||
/// can ignore the pinning invariants when unwrapping it.
|
||||
///
|
||||
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
|
||||
#[unstable(feature = "pin_into_inner", issue = "60245")]
|
||||
#[stable(feature = "pin_into_inner", since = "1.39.0")]
|
||||
#[inline(always)]
|
||||
pub fn into_inner(pin: Pin<P>) -> P {
|
||||
pin.pointer
|
||||
|
@ -569,7 +569,7 @@ impl<P: Deref> Pin<P> {
|
|||
///
|
||||
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
|
||||
/// [`Pin::into_inner`]: #method.into_inner
|
||||
#[unstable(feature = "pin_into_inner", issue = "60245")]
|
||||
#[stable(feature = "pin_into_inner", since = "1.39.0")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
|
||||
pin.pointer
|
||||
|
|
|
@ -820,6 +820,87 @@ impl<T, E> Result<T, E> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Copy, E> Result<&T, E> {
|
||||
/// Maps a `Result<&T, E>` to a `Result<T, E>` by copying the contents of the
|
||||
/// `Ok` part.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(result_copied)]
|
||||
/// let val = 12;
|
||||
/// let x: Result<&i32, i32> = Ok(&val);
|
||||
/// assert_eq!(x, Ok(&12));
|
||||
/// let copied = x.copied();
|
||||
/// assert_eq!(copied, Ok(12));
|
||||
/// ```
|
||||
#[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
|
||||
pub fn copied(self) -> Result<T, E> {
|
||||
self.map(|&t| t)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy, E> Result<&mut T, E> {
|
||||
/// Maps a `Result<&mut T, E>` to a `Result<T, E>` by copying the contents of the
|
||||
/// `Ok` part.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(result_copied)]
|
||||
/// let mut val = 12;
|
||||
/// let x: Result<&mut i32, i32> = Ok(&mut val);
|
||||
/// assert_eq!(x, Ok(&mut 12));
|
||||
/// let copied = x.copied();
|
||||
/// assert_eq!(copied, Ok(12));
|
||||
/// ```
|
||||
#[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
|
||||
pub fn copied(self) -> Result<T, E> {
|
||||
self.map(|&mut t| t)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone, E> Result<&T, E> {
|
||||
/// Maps a `Result<&T, E>` to a `Result<T, E>` by cloning the contents of the
|
||||
/// `Ok` part.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(result_cloned)]
|
||||
/// let val = 12;
|
||||
/// let x: Result<&i32, i32> = Ok(&val);
|
||||
/// assert_eq!(x, Ok(&12));
|
||||
/// let cloned = x.cloned();
|
||||
/// assert_eq!(cloned, Ok(12));
|
||||
/// ```
|
||||
#[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
|
||||
pub fn cloned(self) -> Result<T, E> {
|
||||
self.map(|t| t.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone, E> Result<&mut T, E> {
|
||||
/// Maps a `Result<&mut T, E>` to a `Result<T, E>` by cloning the contents of the
|
||||
/// `Ok` part.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(result_cloned)]
|
||||
/// let mut val = 12;
|
||||
/// let x: Result<&mut i32, i32> = Ok(&mut val);
|
||||
/// assert_eq!(x, Ok(&mut 12));
|
||||
/// let cloned = x.cloned();
|
||||
/// assert_eq!(cloned, Ok(12));
|
||||
/// ```
|
||||
#[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
|
||||
pub fn cloned(self) -> Result<T, E> {
|
||||
self.map(|t| t.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<T, E: fmt::Debug> Result<T, E> {
|
||||
/// Unwraps a result, yielding the content of an [`Ok`].
|
||||
///
|
||||
|
|
|
@ -1688,6 +1688,12 @@ fn test_rposition() {
|
|||
assert!(v.iter().rposition(g).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev_rposition() {
|
||||
let v = [0, 0, 1, 1];
|
||||
assert_eq!(v.iter().rev().rposition(|&x| x == 1), Some(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_rposition_panic() {
|
||||
|
|
|
@ -13,8 +13,3 @@ pub mod derived_property {
|
|||
pub mod conversions {
|
||||
pub use crate::unicode::tables::conversions::{to_lower, to_upper};
|
||||
}
|
||||
|
||||
// For use in libsyntax
|
||||
pub mod property {
|
||||
pub use crate::unicode::tables::property::Pattern_White_Space;
|
||||
}
|
||||
|
|
|
@ -890,384 +890,9 @@ pub(crate) mod derived_property {
|
|||
Uppercase_table.lookup(c)
|
||||
}
|
||||
|
||||
const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x03ff000000000000, 0x07fffffe87fffffe, 0x04a0040000000000, 0xff7fffffff7fffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
|
||||
0xffffffffffffffff, 0xb8dfffffffffffff, 0xfffffffbffffd7c0, 0xffbfffffffffffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffcfb, 0xffffffffffffffff,
|
||||
0xfffeffffffffffff, 0xffffffff027fffff, 0xbffffffffffe01ff, 0x000787ffffff00b6,
|
||||
0xffffffff07ff0000, 0xffffc3ffffffffff, 0xffffffffffffffff, 0x9ffffdff9fefffff,
|
||||
0xffffffffffff0000, 0xffffffffffffe7ff, 0x0003ffffffffffff, 0x243fffffffffffff
|
||||
],
|
||||
r2: [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 4, 32, 33, 34, 4, 4, 4, 4, 4, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 4, 4, 4, 4, 4, 4, 4, 4, 43, 44, 45, 46, 47, 4, 48, 49, 50, 51, 52, 53, 54, 55,
|
||||
56, 57, 58, 59, 60, 4, 61, 4, 62, 63, 64, 65, 66, 4, 4, 4, 67, 4, 4, 4, 4, 68, 69, 70,
|
||||
71, 72, 73, 74, 75, 76, 77, 78, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 79, 80, 4, 81, 82, 83, 84, 85, 60, 60, 60, 60, 60, 60, 60, 60, 86,
|
||||
42, 87, 88, 89, 4, 90, 91, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 52, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 92, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 93, 94, 4, 4, 4, 4, 95, 96, 4, 97, 98, 4, 99, 100, 101, 62, 4, 102, 103,
|
||||
104, 4, 105, 106, 107, 4, 108, 109, 110, 4, 111, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 112, 113, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
|
||||
60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 103, 4, 114,
|
||||
115, 116, 97, 117, 4, 118, 4, 4, 119, 120, 121, 122, 123, 124, 4, 125, 126, 127, 128,
|
||||
129
|
||||
],
|
||||
r3: &[
|
||||
0x00003fffffffffff, 0x000007ff0fffffff, 0x3fdfffff00000000, 0xfffffffbfff80000,
|
||||
0xffffffffffffffff, 0xfffeffcfffffffff, 0xf3c5fdfffff99fef, 0x5003ffcfb080799f,
|
||||
0xd36dfdfffff987ee, 0x003fffc05e023987, 0xf3edfdfffffbbfee, 0xfe00ffcf00013bbf,
|
||||
0xf3edfdfffff99fee, 0x0002ffcfb0c0399f, 0xc3ffc718d63dc7ec, 0x0000ffc000813dc7,
|
||||
0xe3fffdfffffddfff, 0x0000ffcf07603ddf, 0xf3effdfffffddfef, 0x0006ffcf40603ddf,
|
||||
0xfffffffffffddfef, 0xfc00ffcf80f07ddf, 0x2ffbfffffc7fffec, 0x000cffc0ff5f847f,
|
||||
0x07fffffffffffffe, 0x0000000003ff7fff, 0x3fffffaffffff7d6, 0x00000000f3ff3f5f,
|
||||
0xc2a003ff03000001, 0xfffe1ffffffffeff, 0x1ffffffffeffffdf, 0x0000000000000040,
|
||||
0xffffffffffff03ff, 0xffffffff3fffffff, 0xf7ffffffffff20bf, 0xffffffff3d7f3dff,
|
||||
0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0003fe00e7ffffff,
|
||||
0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff,
|
||||
0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x001fffff001fdfff, 0x000ddfff000fffff,
|
||||
0x000003ff308fffff, 0xffffffff03ff3800, 0x01ffffffffffffff, 0xffff07ffffffffff,
|
||||
0x003fffffffffffff, 0x0fff0fff7fffffff, 0x001f3fffffffffc0, 0xffff0fffffffffff,
|
||||
0x0000000007ff03ff, 0xffffffff0fffffff, 0x9fffffff7fffffff, 0x3fff008003ff03ff,
|
||||
0x0000000000000000, 0x000ff80003ff0fff, 0x000fffffffffffff, 0x00ffffffffffffff,
|
||||
0x3fffffffffffe3ff, 0xe7ffffffffff01ff, 0x07fffffffff70000, 0xfbffffffffffffff,
|
||||
0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc,
|
||||
0x8000000000000000, 0x8002000000100001, 0x000000001fff0000, 0x0001ffe21fff0000,
|
||||
0xf3fffd503f2ffc84, 0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff,
|
||||
0xffffffff7fffffff, 0x000ff81fffffffff, 0xffff20bfffffffff, 0x800080ffffffffff,
|
||||
0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x1f3efffe000000e0, 0xfffffffee67fffff,
|
||||
0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000,
|
||||
0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000fffffff1fff,
|
||||
0xbff0ffffffffffff, 0x0003ffffffffffff, 0xfffffffcff800000, 0xfffffffffffff9ff,
|
||||
0xff8000000000007c, 0x000000ffffffffff, 0xe8ffffff03ff003f, 0xffff3fffffffffff,
|
||||
0x1fffffff000fffff, 0x7fffffff03ff8001, 0x007fffffffffffff, 0xfc7fffff03ff3fff,
|
||||
0x007cffff38000007, 0xffff7f7f007e7e7e, 0xffff00fff7ffffff, 0x03ff37ffffffffff,
|
||||
0xffff000fffffffff, 0x0ffffffffffff87f, 0x0000000003ffffff, 0x5f7ffdffe0f8007f,
|
||||
0xffffffffffffffdb, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
|
||||
0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0x0018ffff0000ffff,
|
||||
0xaa8a00000000e000, 0x1fffffffffffffff, 0x87fffffe03ff0000, 0xffffffc007fffffe,
|
||||
0x7fffffffffffffff, 0x000000001cfcfcfc
|
||||
],
|
||||
r4: [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 13,
|
||||
14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
|
||||
],
|
||||
r5: &[
|
||||
0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16, 4, 4, 2, 2, 2,
|
||||
2, 17, 18, 4, 4, 19, 20, 21, 22, 23, 4, 24, 4, 25, 26, 27, 28, 29, 30, 31, 4, 2, 32, 33,
|
||||
33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 37, 2, 38, 3, 39, 40, 41, 2, 42, 43, 4, 44, 45,
|
||||
46, 47, 4, 4, 2, 48, 2, 49, 4, 4, 50, 51, 2, 52, 53, 54, 55, 4, 4, 4, 3, 4, 56, 57, 4,
|
||||
4, 58, 59, 60, 61, 62, 53, 4, 4, 4, 4, 63, 64, 65, 4, 66, 67, 68, 4, 4, 4, 4, 37, 4, 4,
|
||||
4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 2, 70, 2, 2, 2, 71, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 2, 2, 2, 2, 2, 2, 2, 2, 53, 73, 4, 74, 17, 75, 76, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
|
||||
4, 4, 2, 77, 78, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 80, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 81, 2, 2, 2, 2,
|
||||
2, 82, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 83, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 85, 86, 4, 4, 87, 4, 4, 4, 4, 4, 4, 2, 88, 89, 90, 91, 92, 2, 2, 2, 2, 93, 94, 95,
|
||||
96, 97, 98, 4, 4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 102, 4, 4, 4, 103, 104, 4, 4, 4, 4, 4, 105, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 106, 2, 107, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 109, 110, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 111, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 113, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 114, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 115, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
|
||||
],
|
||||
r6: &[
|
||||
0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
|
||||
0x0000000000000000, 0x001fffffffffffff, 0x2000000000000000, 0xffffffff1fffffff,
|
||||
0x000000010001ffff, 0xffffe000ffffffff, 0x07ffffffffff07ff, 0xffffffff3fffffff,
|
||||
0x00000000003eff0f, 0xffff03ff3fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff,
|
||||
0x0000000fffffffff, 0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f,
|
||||
0x007fffff003fffff, 0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff,
|
||||
0xc0ffffffffffffff, 0x873ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff,
|
||||
0x0000007ffffffeff, 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff,
|
||||
0x00000000000001ff, 0x0007ffffffffffff, 0x03ff00ffffffffff, 0xffff00801fffffff,
|
||||
0x000000000001ffff, 0x007fffff00000000, 0x8000ffc00000007f, 0x03ff01ffffff0000,
|
||||
0xffdfffffffffffff, 0x004fffffffff0070, 0x0000000017ff1e1f, 0x40fffffffffbffff,
|
||||
0xffff01ffbfffbd7f, 0x03ff07ffffffffff, 0xfbedfdfffff99fef, 0x001f1fcfe081399f,
|
||||
0x00000000c3ff07ff, 0x0000000003ff00bf, 0xff3fffffffffffff, 0x000000003f000001,
|
||||
0x0000000003ff0011, 0x01ffffffffffffff, 0x00000000000003ff, 0x03ff0fffe7ffffff,
|
||||
0xffffffff00000000, 0x800003ffffffffff, 0xfffffcff00000000, 0x0000001bfcffffff,
|
||||
0x7fffffffffffffff, 0xffffffffffff0080, 0x0000000023ffffff, 0xff7ffffffffffdff,
|
||||
0xfffc000003ff0001, 0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf03ff00ff,
|
||||
0x000003ff01fb7fff, 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f,
|
||||
0x000000000000007f, 0x000003ff7fffffff, 0x001f3fffffff0000, 0xe0fffff803ff000f,
|
||||
0x000000000000ffff, 0xffffffffffff87ff, 0x00000000ffff80ff, 0x0000000b00000000,
|
||||
0x00ffffffffffffff, 0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff,
|
||||
0x0000000063ff01ff, 0xf807e3e000000000, 0x00003c0000000fe7, 0x000000000000001c,
|
||||
0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
|
||||
0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
|
||||
0xffff7fffffff7fff, 0xfffffdfffffffdff, 0xffffffffffffcff7, 0xf87fffffffffffff,
|
||||
0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, 0x3fff1fffffffffff,
|
||||
0x00000000000043ff, 0x03ffffffffffffff, 0x00000000007f001f, 0x0000000003ff0fff,
|
||||
0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff,
|
||||
0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff, 0x0000ffffffffffff
|
||||
],
|
||||
};
|
||||
|
||||
pub fn XID_Continue(c: char) -> bool {
|
||||
XID_Continue_table.lookup(c)
|
||||
}
|
||||
|
||||
const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
|
||||
0x0000000000000000, 0xb8df000000000000, 0xfffffffbffffd740, 0xffbfffffffffffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff,
|
||||
0xfffeffffffffffff, 0xffffffff027fffff, 0x00000000000001ff, 0x000787ffffff0000,
|
||||
0xffffffff00000000, 0xfffec000000007ff, 0xffffffffffffffff, 0x9c00c060002fffff,
|
||||
0x0000fffffffd0000, 0xffffffffffffe000, 0x0002003fffffffff, 0x043007fffffffc00
|
||||
],
|
||||
r2: [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 23, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 34, 34, 34, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 34, 34, 34, 34, 34, 34, 34, 34, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 57, 58, 59, 60, 3, 61, 62, 63, 64, 65, 66, 67, 68, 34, 34, 34, 3, 34, 34,
|
||||
34, 34, 69, 70, 71, 72, 3, 73, 74, 3, 75, 76, 77, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 78,
|
||||
79, 34, 80, 81, 82, 83, 84, 3, 3, 3, 3, 3, 3, 3, 3, 85, 42, 86, 87, 88, 34, 89, 90, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 53, 3, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 91, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 92, 93, 34, 34, 34, 34, 94,
|
||||
95, 96, 91, 97, 34, 98, 99, 100, 48, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
|
||||
111, 112, 34, 113, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 34, 34, 114, 115, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34,
|
||||
116, 34, 117, 118, 119, 120, 121, 34, 122, 34, 34, 123, 124, 125, 126, 3, 127, 34, 128,
|
||||
129, 130, 131, 132
|
||||
],
|
||||
r3: &[
|
||||
0x00000110043fffff, 0x000007ff01ffffff, 0x3fdfffff00000000, 0x0000000000000000,
|
||||
0x23fffffffffffff0, 0xfffe0003ff010000, 0x23c5fdfffff99fe1, 0x10030003b0004000,
|
||||
0x036dfdfffff987e0, 0x001c00005e000000, 0x23edfdfffffbbfe0, 0x0200000300010000,
|
||||
0x23edfdfffff99fe0, 0x00020003b0000000, 0x03ffc718d63dc7e8, 0x0000000000010000,
|
||||
0x23fffdfffffddfe0, 0x0000000307000000, 0x23effdfffffddfe1, 0x0006000340000000,
|
||||
0x27fffffffffddfe0, 0xfc00000380704000, 0x2ffbfffffc7fffe0, 0x000000000000007f,
|
||||
0x0005fffffffffffe, 0x2005ffaffffff7d6, 0x00000000f000005f, 0x0000000000000001,
|
||||
0x00001ffffffffeff, 0x0000000000001f00, 0x800007ffffffffff, 0xffe1c0623c3f0000,
|
||||
0xffffffff00004003, 0xf7ffffffffff20bf, 0xffffffffffffffff, 0xffffffff3d7f3dff,
|
||||
0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0000000007ffffff,
|
||||
0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff,
|
||||
0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x0003ffff0003dfff, 0x0001dfff0003ffff,
|
||||
0x000fffffffffffff, 0x0000000010800000, 0xffffffff00000000, 0x01ffffffffffffff,
|
||||
0xffff05ffffffffff, 0x003fffffffffffff, 0x000000007fffffff, 0x001f3fffffff0000,
|
||||
0xffff0fffffffffff, 0x00000000000003ff, 0xffffffff007fffff, 0x00000000001fffff,
|
||||
0x0000008000000000, 0x000fffffffffffe0, 0x0000000000000fe0, 0xfc00c001fffffff8,
|
||||
0x0000003fffffffff, 0x0000000fffffffff, 0x3ffffffffc00e000, 0xe7ffffffffff01ff,
|
||||
0x046fde0000000000, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff,
|
||||
0x1fdc1fff0fcf1fdc, 0x8002000000000000, 0x000000001fff0000, 0xf3fffd503f2ffc84,
|
||||
0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff, 0xffffffff7fffffff,
|
||||
0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff,
|
||||
0x000000007f7f7f7f, 0x1f3e03fe000000e0, 0xfffffffee07fffff, 0xf7ffffffffffffff,
|
||||
0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000, 0x0000ffffffffffff,
|
||||
0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff, 0x80007fffffffffff,
|
||||
0xffffffff3fffffff, 0xfffffffcff800000, 0xfffffffffffff9ff, 0xff8000000000007c,
|
||||
0x00000007fffff7bb, 0x000ffffffffffffc, 0x68fc000000000000, 0xffff003ffffffc00,
|
||||
0x1fffffff0000007f, 0x0007fffffffffff0, 0x7c00ffdf00008000, 0x000001ffffffffff,
|
||||
0xc47fffff00000ff7, 0x3e62ffffffffffff, 0x001c07ff38000005, 0xffff7f7f007e7e7e,
|
||||
0xffff00fff7ffffff, 0x00000007ffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
|
||||
0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffa0f8007f, 0xffffffffffffffdb,
|
||||
0x0003ffffffffffff, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
|
||||
0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0xaa8a000000000000,
|
||||
0x1fffffffffffffff, 0x07fffffe00000000, 0xffffffc007fffffe, 0x7fffffff3fffffff,
|
||||
0x000000001cfcfcfc
|
||||
],
|
||||
r4: [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 13,
|
||||
14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
|
||||
],
|
||||
r5: &[
|
||||
0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2,
|
||||
2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32,
|
||||
32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 35, 36, 4, 37, 38, 39, 40, 41, 42, 43, 4, 44,
|
||||
20, 45, 46, 4, 4, 5, 47, 48, 49, 4, 4, 50, 51, 48, 52, 53, 4, 54, 4, 4, 4, 55, 4, 56,
|
||||
57, 4, 4, 58, 59, 60, 61, 62, 63, 4, 4, 4, 4, 64, 65, 66, 4, 67, 68, 69, 4, 4, 4, 4, 70,
|
||||
4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 2, 50, 2, 2, 2, 72, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 63, 20, 4, 74, 48, 75, 66, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 2, 4, 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 80, 2,
|
||||
2, 2, 2, 2, 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 85, 86, 87, 88, 2, 2, 2, 2, 89, 90,
|
||||
91, 92, 93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 95, 96, 4, 4, 4, 4, 4, 55, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 97, 2, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 103,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 104, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 105, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
|
||||
],
|
||||
r6: &[
|
||||
0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
|
||||
0x0000000000000000, 0x001fffffffffffff, 0xffffffff1fffffff, 0x000000000001ffff,
|
||||
0xffffe000ffffffff, 0x003fffffffff07ff, 0xffffffff3fffffff, 0x00000000003eff0f,
|
||||
0xffff00003fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff, 0x0000000fffffffff,
|
||||
0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f, 0x007fffff003fffff,
|
||||
0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff, 0xc0ffffffffffffff,
|
||||
0x003ffffffeef0001, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff,
|
||||
0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff,
|
||||
0x0007ffffffffffff, 0xffff00801fffffff, 0x000000000000003f, 0x007fffff00000000,
|
||||
0x00fffffffffffff8, 0x0000fffffffffff8, 0x000001ffffff0000, 0x0000007ffffffff8,
|
||||
0x0047ffffffff0010, 0x0007fffffffffff8, 0x000000001400001e, 0x00000ffffffbffff,
|
||||
0xffff01ffbfffbd7f, 0x23edfdfffff99fe0, 0x00000003e0010000, 0x0000000080000780,
|
||||
0x0000ffffffffffff, 0x00000000000000b0, 0x00007fffffffffff, 0x000000000f000000,
|
||||
0x0000000000000010, 0x010007ffffffffff, 0x0000000007ffffff, 0x00000fffffffffff,
|
||||
0xffffffff00000000, 0x80000000ffffffff, 0xfffffcff00000000, 0x0000000a0001ffff,
|
||||
0x0407fffffffff801, 0xfffffffff0010000, 0x00000000200003ff, 0x01ffffffffffffff,
|
||||
0x00007ffffffffdff, 0xfffc000000000001, 0x000000000000ffff, 0x0001fffffffffb7f,
|
||||
0xfffffdbf00000040, 0x00000000010003ff, 0x0007ffff00000000, 0x0000000003ffffff,
|
||||
0x000000000000000f, 0x000000000000007f, 0x00003fffffff0000, 0xe0fffff80000000f,
|
||||
0x00000000000107ff, 0x00000000fff80000, 0x0000000b00000000, 0x00ffffffffffffff,
|
||||
0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000003ff01ff,
|
||||
0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
|
||||
0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
|
||||
0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x3f801fffffffffff,
|
||||
0x0000000000004000, 0x000000000000001f, 0x000000000000080f, 0x0af7fe96ffffffef,
|
||||
0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff, 0xffff0003ffffffff,
|
||||
0x00000001ffffffff, 0x000000003fffffff
|
||||
],
|
||||
};
|
||||
|
||||
pub fn XID_Start(c: char) -> bool {
|
||||
XID_Start_table.lookup(c)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub(crate) mod property {
|
||||
const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
|
||||
r1: &[
|
||||
0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
|
||||
],
|
||||
r2: &[
|
||||
0x0000000100003e00, 0x0000000000000000, 0x0000000000000020, 0x000003000000c000
|
||||
],
|
||||
};
|
||||
|
||||
pub fn Pattern_White_Space(c: char) -> bool {
|
||||
Pattern_White_Space_table.lookup(c)
|
||||
}
|
||||
|
||||
const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
|
||||
r1: &[
|
||||
0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
|
|
|
@ -728,7 +728,7 @@ def generate_property_module(mod, grouped_categories, category_subset):
|
|||
|
||||
yield "pub(crate) mod %s {\n" % mod
|
||||
for cat in sorted(category_subset):
|
||||
if cat in ("Cc", "White_Space", "Pattern_White_Space"):
|
||||
if cat in ("Cc", "White_Space"):
|
||||
generator = generate_small_bool_trie("%s_table" % cat, grouped_categories[cat])
|
||||
else:
|
||||
generator = generate_bool_trie("%s_table" % cat, grouped_categories[cat])
|
||||
|
@ -841,19 +841,18 @@ def main():
|
|||
unicode_data = load_unicode_data(get_path(UnicodeFiles.UNICODE_DATA))
|
||||
load_special_casing(get_path(UnicodeFiles.SPECIAL_CASING), unicode_data)
|
||||
|
||||
want_derived = {"XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase",
|
||||
want_derived = {"Alphabetic", "Lowercase", "Uppercase",
|
||||
"Cased", "Case_Ignorable", "Grapheme_Extend"}
|
||||
derived = load_properties(get_path(UnicodeFiles.DERIVED_CORE_PROPERTIES), want_derived)
|
||||
|
||||
props = load_properties(get_path(UnicodeFiles.PROPS),
|
||||
{"White_Space", "Join_Control", "Noncharacter_Code_Point",
|
||||
"Pattern_White_Space"})
|
||||
{"White_Space", "Join_Control", "Noncharacter_Code_Point"})
|
||||
|
||||
# Category tables
|
||||
for (name, categories, category_subset) in (
|
||||
("general_category", unicode_data.general_categories, ["N", "Cc"]),
|
||||
("derived_property", derived, want_derived),
|
||||
("property", props, ["White_Space", "Pattern_White_Space"])
|
||||
("property", props, ["White_Space"])
|
||||
):
|
||||
for fragment in generate_property_module(name, categories, category_subset):
|
||||
buf.write(fragment)
|
||||
|
|
|
@ -10,4 +10,4 @@ path = "lib.rs"
|
|||
|
||||
[dependencies]
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
||||
rustc_lexer = { path = "../librustc_lexer" }
|
||||
|
|
|
@ -597,12 +597,11 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parses a word starting at the current position. A word is considered to
|
||||
/// be an alphabetic character followed by any number of alphanumeric
|
||||
/// characters.
|
||||
/// Parses a word starting at the current position. A word is the same as
|
||||
/// Rust identifier, except that it can't start with `_` character.
|
||||
fn word(&mut self) -> &'a str {
|
||||
let start = match self.cur.peek() {
|
||||
Some(&(pos, c)) if c.is_xid_start() => {
|
||||
Some(&(pos, c)) if c != '_' && rustc_lexer::is_id_start(c) => {
|
||||
self.cur.next();
|
||||
pos
|
||||
}
|
||||
|
@ -611,7 +610,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
};
|
||||
while let Some(&(pos, c)) = self.cur.peek() {
|
||||
if c.is_xid_continue() {
|
||||
if rustc_lexer::is_id_continue(c) {
|
||||
self.cur.next();
|
||||
} else {
|
||||
return &self.input[start..pos];
|
||||
|
|
|
@ -21,7 +21,7 @@ scoped-tls = "1.0"
|
|||
log = { version = "0.4", features = ["release_max_level_info", "std"] }
|
||||
rustc-rayon = "0.2.0"
|
||||
rustc-rayon-core = "0.2.0"
|
||||
polonius-engine = "0.9.0"
|
||||
polonius-engine = "0.10.0"
|
||||
rustc_apfloat = { path = "../librustc_apfloat" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
rustc_macros = { path = "../librustc_macros" }
|
||||
|
|
|
@ -39,7 +39,7 @@ Generally, `Self: Sized` is used to indicate that the trait should not be used
|
|||
as a trait object. If the trait comes from your own crate, consider removing
|
||||
this restriction.
|
||||
|
||||
### Method references the `Self` type in its arguments or return type
|
||||
### Method references the `Self` type in its parameters or return type
|
||||
|
||||
This happens when a trait has a method like the following:
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
|||
});
|
||||
|
||||
let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| {
|
||||
let name = cstore.crate_name_untracked(cnum).as_str();
|
||||
let name = cstore.crate_name_untracked(cnum).as_interned_str();
|
||||
let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
|
||||
let hash = cstore.crate_hash_untracked(cnum);
|
||||
(name, disambiguator, hash)
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::mem;
|
|||
use syntax::ast;
|
||||
use syntax::feature_gate;
|
||||
use syntax::parse::token;
|
||||
use syntax::symbol::{InternedString, LocalInternedString};
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax::tokenstream;
|
||||
use syntax_pos::SourceFile;
|
||||
|
||||
|
@ -39,27 +39,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
|
||||
#[inline]
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let s: &str = &**self;
|
||||
s.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
|
||||
type KeyType = LocalInternedString;
|
||||
|
||||
#[inline]
|
||||
fn to_stable_hash_key(&self,
|
||||
_: &StableHashingContext<'a>)
|
||||
-> LocalInternedString {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
|
||||
#[inline]
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
|
|
|
@ -1136,12 +1136,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
if let Some((expected, found)) = expected_found {
|
||||
match (terr, is_simple_error, expected == found) {
|
||||
(&TypeError::Sorts(ref values), false, true) => {
|
||||
let sort_string = | a_type: Ty<'tcx> |
|
||||
if let ty::Opaque(def_id, _) = a_type.sty {
|
||||
format!(" (opaque type at {})", self.tcx.sess.source_map()
|
||||
.mk_substr_filename(self.tcx.def_span(def_id)))
|
||||
} else {
|
||||
format!(" ({})", a_type.sort_string(self.tcx))
|
||||
};
|
||||
diag.note_expected_found_extra(
|
||||
&"type",
|
||||
expected,
|
||||
found,
|
||||
&format!(" ({})", values.expected.sort_string(self.tcx)),
|
||||
&format!(" ({})", values.found.sort_string(self.tcx)),
|
||||
&sort_string(values.expected),
|
||||
&sort_string(values.found),
|
||||
);
|
||||
}
|
||||
(_, false, _) => {
|
||||
|
@ -1627,7 +1634,7 @@ impl<'tcx> ObligationCause<'tcx> {
|
|||
MainFunctionType => Error0580("main function has wrong type"),
|
||||
StartFunctionType => Error0308("start function has wrong type"),
|
||||
IntrinsicType => Error0308("intrinsic has wrong type"),
|
||||
MethodReceiver => Error0308("mismatched method receiver"),
|
||||
MethodReceiver => Error0308("mismatched `self` parameter type"),
|
||||
|
||||
// In the case where we have no more specific thing to
|
||||
// say, also take a look at the error code, maybe we can
|
||||
|
|
|
@ -33,7 +33,7 @@ use crate::util::common::time;
|
|||
use std::default::Default as StdDefault;
|
||||
use syntax::ast;
|
||||
use syntax::edition;
|
||||
use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
|
||||
use syntax_pos::{MultiSpan, Span, symbol::Symbol};
|
||||
use errors::DiagnosticBuilder;
|
||||
use crate::hir;
|
||||
use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
|
@ -405,7 +405,7 @@ impl LintStore {
|
|||
pub fn check_lint_name(
|
||||
&self,
|
||||
lint_name: &str,
|
||||
tool_name: Option<LocalInternedString>,
|
||||
tool_name: Option<Symbol>,
|
||||
) -> CheckLintNameResult<'_> {
|
||||
let complete_name = if let Some(tool_name) = tool_name {
|
||||
format!("{}::{}", tool_name, lint_name)
|
||||
|
|
|
@ -291,7 +291,7 @@ impl<'a> LintLevelsBuilder<'a> {
|
|||
continue;
|
||||
}
|
||||
|
||||
Some(tool_ident.as_str())
|
||||
Some(tool_ident.name)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
|
|
@ -1808,6 +1808,23 @@ pub enum ProjectionElem<V, T> {
|
|||
Downcast(Option<Symbol>, VariantIdx),
|
||||
}
|
||||
|
||||
impl<V, T> ProjectionElem<V, T> {
|
||||
/// Returns `true` if the target of this projection may refer to a different region of memory
|
||||
/// than the base.
|
||||
fn is_indirect(&self) -> bool {
|
||||
match self {
|
||||
Self::Deref => true,
|
||||
|
||||
| Self::Field(_, _)
|
||||
| Self::Index(_)
|
||||
| Self::ConstantIndex { .. }
|
||||
| Self::Subslice { .. }
|
||||
| Self::Downcast(_, _)
|
||||
=> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Alias for projections as they appear in places, where the base is a place
|
||||
/// and the index is a local.
|
||||
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
|
||||
|
@ -1869,6 +1886,14 @@ impl<'tcx> Place<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if this `Place` contains a `Deref` projection.
|
||||
///
|
||||
/// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
|
||||
/// same region of memory as its base.
|
||||
pub fn is_indirect(&self) -> bool {
|
||||
self.iterate(|_, mut projections| projections.any(|proj| proj.elem.is_indirect()))
|
||||
}
|
||||
|
||||
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
|
||||
/// a single deref of a local.
|
||||
//
|
||||
|
|
|
@ -1384,7 +1384,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
let mut reported_violations = FxHashSet::default();
|
||||
for violation in violations {
|
||||
if reported_violations.insert(violation.clone()) {
|
||||
err.note(&violation.error_msg());
|
||||
match violation.span() {
|
||||
Some(span) => err.span_label(span, violation.error_msg()),
|
||||
None => err.note(&violation.error_msg()),
|
||||
};
|
||||
}
|
||||
}
|
||||
Some(err)
|
||||
|
|
|
@ -20,7 +20,7 @@ use std::borrow::Cow;
|
|||
use std::iter::{self};
|
||||
use syntax::ast::{self};
|
||||
use syntax::symbol::InternedString;
|
||||
use syntax_pos::Span;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum ObjectSafetyViolation {
|
||||
|
@ -32,10 +32,10 @@ pub enum ObjectSafetyViolation {
|
|||
SupertraitSelf,
|
||||
|
||||
/// Method has something illegal.
|
||||
Method(ast::Name, MethodViolationCode),
|
||||
Method(ast::Name, MethodViolationCode, Span),
|
||||
|
||||
/// Associated const.
|
||||
AssocConst(ast::Name),
|
||||
AssocConst(ast::Name, Span),
|
||||
}
|
||||
|
||||
impl ObjectSafetyViolation {
|
||||
|
@ -46,22 +46,35 @@ impl ObjectSafetyViolation {
|
|||
ObjectSafetyViolation::SupertraitSelf =>
|
||||
"the trait cannot use `Self` as a type parameter \
|
||||
in the supertraits or where-clauses".into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) =>
|
||||
format!("method `{}` has no receiver", name).into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) =>
|
||||
format!("method `{}` references the `Self` type \
|
||||
in its arguments or return type", name).into(),
|
||||
ObjectSafetyViolation::Method(name,
|
||||
MethodViolationCode::WhereClauseReferencesSelf(_)) =>
|
||||
format!("method `{}` references the `Self` type in where clauses", name).into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) =>
|
||||
format!("associated function `{}` has no `self` parameter", name).into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!(
|
||||
"method `{}` references the `Self` type in its parameters or return type",
|
||||
name,
|
||||
).into(),
|
||||
ObjectSafetyViolation::Method(
|
||||
name,
|
||||
MethodViolationCode::WhereClauseReferencesSelf,
|
||||
_,
|
||||
) => format!("method `{}` references the `Self` type in where clauses", name).into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) =>
|
||||
format!("method `{}` has generic type parameters", name).into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) =>
|
||||
format!("method `{}`'s receiver cannot be dispatched on", name).into(),
|
||||
ObjectSafetyViolation::AssocConst(name) =>
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) =>
|
||||
format!("method `{}`'s `self` parameter cannot be dispatched on", name).into(),
|
||||
ObjectSafetyViolation::AssocConst(name, _) =>
|
||||
format!("the trait cannot contain associated consts like `{}`", name).into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Option<Span> {
|
||||
// When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so
|
||||
// diagnostics use a `note` instead of a `span_label`.
|
||||
match *self {
|
||||
ObjectSafetyViolation::AssocConst(_, span) |
|
||||
ObjectSafetyViolation::Method(_, _, span) if span != DUMMY_SP => Some(span),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Reasons a method might not be object-safe.
|
||||
|
@ -74,7 +87,7 @@ pub enum MethodViolationCode {
|
|||
ReferencesSelf,
|
||||
|
||||
/// e.g., `fn foo(&self) where Self: Clone`
|
||||
WhereClauseReferencesSelf(Span),
|
||||
WhereClauseReferencesSelf,
|
||||
|
||||
/// e.g., `fn foo<A>()`
|
||||
Generic,
|
||||
|
@ -88,9 +101,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
/// astconv -- currently, `Self` in supertraits. This is needed
|
||||
/// because `object_safety_violations` can't be used during
|
||||
/// type collection.
|
||||
pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
|
||||
-> Vec<ObjectSafetyViolation>
|
||||
{
|
||||
pub fn astconv_object_safety_violations(
|
||||
self,
|
||||
trait_def_id: DefId,
|
||||
) -> Vec<ObjectSafetyViolation> {
|
||||
debug_assert!(self.generics_of(trait_def_id).has_self);
|
||||
let violations = traits::supertrait_def_ids(self, trait_def_id)
|
||||
.filter(|&def_id| self.predicates_reference_self(def_id, true))
|
||||
|
@ -128,7 +142,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
match self.virtual_call_violation_for_method(trait_def_id, method) {
|
||||
None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
|
||||
None | Some(MethodViolationCode::WhereClauseReferencesSelf) => true,
|
||||
Some(_) => false,
|
||||
}
|
||||
}
|
||||
|
@ -138,12 +152,15 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
let mut violations: Vec<_> = self.associated_items(trait_def_id)
|
||||
.filter(|item| item.kind == ty::AssocKind::Method)
|
||||
.filter_map(|item|
|
||||
self.object_safety_violation_for_method(trait_def_id, &item)
|
||||
.map(|code| ObjectSafetyViolation::Method(item.ident.name, code))
|
||||
self.object_safety_violation_for_method(trait_def_id, &item).map(|code| {
|
||||
ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span)
|
||||
})
|
||||
).filter(|violation| {
|
||||
if let ObjectSafetyViolation::Method(_,
|
||||
MethodViolationCode::WhereClauseReferencesSelf(span)) = violation
|
||||
{
|
||||
if let ObjectSafetyViolation::Method(
|
||||
_,
|
||||
MethodViolationCode::WhereClauseReferencesSelf,
|
||||
span,
|
||||
) = violation {
|
||||
// Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
|
||||
// It's also hard to get a use site span, so we use the method definition span.
|
||||
self.lint_node_note(
|
||||
|
@ -169,7 +186,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
|
||||
violations.extend(self.associated_items(trait_def_id)
|
||||
.filter(|item| item.kind == ty::AssocKind::Const)
|
||||
.map(|item| ObjectSafetyViolation::AssocConst(item.ident.name)));
|
||||
.map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)));
|
||||
|
||||
debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
|
||||
trait_def_id,
|
||||
|
@ -325,8 +342,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
.visit_tys_shallow(|t| {
|
||||
self.contains_illegal_self_type_reference(trait_def_id, t)
|
||||
}) {
|
||||
let span = self.def_span(method.def_id);
|
||||
return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
|
||||
return Some(MethodViolationCode::WhereClauseReferencesSelf);
|
||||
}
|
||||
|
||||
let receiver_ty = self.liberate_late_bound_regions(
|
||||
|
|
|
@ -9,10 +9,9 @@ use syntax::ast::{MetaItem, NestedMetaItem};
|
|||
use syntax::attr;
|
||||
use syntax::symbol::{Symbol, kw, sym};
|
||||
use syntax_pos::Span;
|
||||
use syntax_pos::symbol::LocalInternedString;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OnUnimplementedFormatString(LocalInternedString);
|
||||
pub struct OnUnimplementedFormatString(Symbol);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OnUnimplementedDirective {
|
||||
|
@ -89,19 +88,19 @@ impl<'tcx> OnUnimplementedDirective {
|
|||
if item.check_name(sym::message) && message.is_none() {
|
||||
if let Some(message_) = item.value_str() {
|
||||
message = Some(OnUnimplementedFormatString::try_parse(
|
||||
tcx, trait_def_id, message_.as_str(), span)?);
|
||||
tcx, trait_def_id, message_, span)?);
|
||||
continue;
|
||||
}
|
||||
} else if item.check_name(sym::label) && label.is_none() {
|
||||
if let Some(label_) = item.value_str() {
|
||||
label = Some(OnUnimplementedFormatString::try_parse(
|
||||
tcx, trait_def_id, label_.as_str(), span)?);
|
||||
tcx, trait_def_id, label_, span)?);
|
||||
continue;
|
||||
}
|
||||
} else if item.check_name(sym::note) && note.is_none() {
|
||||
if let Some(note_) = item.value_str() {
|
||||
note = Some(OnUnimplementedFormatString::try_parse(
|
||||
tcx, trait_def_id, note_.as_str(), span)?);
|
||||
tcx, trait_def_id, note_, span)?);
|
||||
continue;
|
||||
}
|
||||
} else if item.check_name(sym::on) && is_root &&
|
||||
|
@ -154,7 +153,7 @@ impl<'tcx> OnUnimplementedDirective {
|
|||
message: None,
|
||||
subcommands: vec![],
|
||||
label: Some(OnUnimplementedFormatString::try_parse(
|
||||
tcx, trait_def_id, value.as_str(), attr.span)?),
|
||||
tcx, trait_def_id, value, attr.span)?),
|
||||
note: None,
|
||||
}))
|
||||
} else {
|
||||
|
@ -218,7 +217,7 @@ impl<'tcx> OnUnimplementedFormatString {
|
|||
fn try_parse(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
from: LocalInternedString,
|
||||
from: Symbol,
|
||||
err_sp: Span,
|
||||
) -> Result<Self, ErrorReported> {
|
||||
let result = OnUnimplementedFormatString(from);
|
||||
|
@ -234,7 +233,8 @@ impl<'tcx> OnUnimplementedFormatString {
|
|||
) -> Result<(), ErrorReported> {
|
||||
let name = tcx.item_name(trait_def_id);
|
||||
let generics = tcx.generics_of(trait_def_id);
|
||||
let parser = Parser::new(&self.0, None, vec![], false);
|
||||
let s = self.0.as_str();
|
||||
let parser = Parser::new(&s, None, vec![], false);
|
||||
let mut result = Ok(());
|
||||
for token in parser {
|
||||
match token {
|
||||
|
@ -294,7 +294,8 @@ impl<'tcx> OnUnimplementedFormatString {
|
|||
}).collect::<FxHashMap<Symbol, String>>();
|
||||
let empty_string = String::new();
|
||||
|
||||
let parser = Parser::new(&self.0, None, vec![], false);
|
||||
let s = self.0.as_str();
|
||||
let parser = Parser::new(&s, None, vec![], false);
|
||||
parser.map(|p|
|
||||
match p {
|
||||
Piece::String(s) => s,
|
||||
|
|
|
@ -46,7 +46,7 @@ use std::ops::Range;
|
|||
use syntax::ast::{self, Name, Ident, NodeId};
|
||||
use syntax::attr;
|
||||
use syntax::ext::hygiene::ExpnId;
|
||||
use syntax::symbol::{kw, sym, Symbol, LocalInternedString, InternedString};
|
||||
use syntax::symbol::{kw, sym, Symbol, InternedString};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use smallvec;
|
||||
|
@ -3386,10 +3386,6 @@ impl SymbolName {
|
|||
name: InternedString::intern(name)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> LocalInternedString {
|
||||
self.name.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SymbolName {
|
||||
|
|
|
@ -709,8 +709,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
substs: SubstsRef<'tcx>,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
if self.found_recursion {
|
||||
None
|
||||
} else if self.seen_opaque_tys.insert(def_id) {
|
||||
return None;
|
||||
}
|
||||
let substs = substs.fold_with(self);
|
||||
if self.seen_opaque_tys.insert(def_id) {
|
||||
let generic_ty = self.tcx.type_of(def_id);
|
||||
let concrete_ty = generic_ty.subst(self.tcx, substs);
|
||||
let expanded_ty = self.fold_ty(concrete_ty);
|
||||
|
|
|
@ -5,7 +5,6 @@ use crate::context::CodegenCx;
|
|||
use crate::type_::Type;
|
||||
use crate::type_of::LayoutLlvmExt;
|
||||
use crate::value::Value;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate};
|
||||
use rustc_codegen_ssa::MemFlags;
|
||||
use libc::{c_uint, c_char};
|
||||
|
@ -24,6 +23,7 @@ use std::ffi::CStr;
|
|||
use std::ops::{Deref, Range};
|
||||
use std::ptr;
|
||||
use std::iter::TrustedLen;
|
||||
use syntax::symbol::Symbol;
|
||||
|
||||
// All Builders must have an llfn associated with them
|
||||
#[must_use]
|
||||
|
@ -561,7 +561,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
|
||||
let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
|
||||
cg_elem.val.store(&mut body_bx,
|
||||
PlaceRef::new_sized(current, cg_elem.layout, align));
|
||||
PlaceRef::new_sized_aligned(current, cg_elem.layout, align));
|
||||
|
||||
let next = body_bx.inbounds_gep(current, &[self.const_usize(1)]);
|
||||
body_bx.br(header_bx.llbb());
|
||||
|
@ -1082,8 +1082,8 @@ impl StaticBuilderMethods for Builder<'a, 'll, 'tcx> {
|
|||
|
||||
fn static_panic_msg(
|
||||
&mut self,
|
||||
msg: Option<LocalInternedString>,
|
||||
filename: LocalInternedString,
|
||||
msg: Option<Symbol>,
|
||||
filename: Symbol,
|
||||
line: Self::Value,
|
||||
col: Self::Value,
|
||||
kind: &str,
|
||||
|
|
|
@ -37,7 +37,7 @@ pub fn get_fn(
|
|||
return llfn;
|
||||
}
|
||||
|
||||
let sym = tcx.symbol_name(instance).as_str();
|
||||
let sym = tcx.symbol_name(instance).name.as_str();
|
||||
debug!("get_fn({:?}: {:?}) => {}", instance, sig, sym);
|
||||
|
||||
// Create a fn pointer with the substituted signature.
|
||||
|
|
|
@ -17,7 +17,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
|
|||
|
||||
use libc::{c_uint, c_char};
|
||||
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::ast::Mutability;
|
||||
|
||||
pub use crate::context::CodegenCx;
|
||||
|
@ -122,7 +122,7 @@ impl CodegenCx<'ll, 'tcx> {
|
|||
|
||||
fn const_cstr(
|
||||
&self,
|
||||
s: LocalInternedString,
|
||||
s: Symbol,
|
||||
null_terminated: bool,
|
||||
) -> &'ll Value {
|
||||
unsafe {
|
||||
|
@ -130,9 +130,10 @@ impl CodegenCx<'ll, 'tcx> {
|
|||
return llval;
|
||||
}
|
||||
|
||||
let s_str = s.as_str();
|
||||
let sc = llvm::LLVMConstStringInContext(self.llcx,
|
||||
s.as_ptr() as *const c_char,
|
||||
s.len() as c_uint,
|
||||
s_str.as_ptr() as *const c_char,
|
||||
s_str.len() as c_uint,
|
||||
!null_terminated as Bool);
|
||||
let sym = self.generate_local_symbol_name("str");
|
||||
let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{
|
||||
|
@ -147,8 +148,8 @@ impl CodegenCx<'ll, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
|
||||
let len = s.len();
|
||||
pub fn const_str_slice(&self, s: Symbol) -> &'ll Value {
|
||||
let len = s.as_str().len();
|
||||
let cs = consts::ptrcast(self.const_cstr(s, false),
|
||||
self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)));
|
||||
self.const_fat_ptr(cs, self.const_usize(len as u64))
|
||||
|
@ -348,7 +349,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
)};
|
||||
self.const_bitcast(llval, llty)
|
||||
};
|
||||
PlaceRef::new_sized(llval, layout, alloc.align)
|
||||
PlaceRef::new_sized(llval, layout)
|
||||
}
|
||||
|
||||
fn const_ptrcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
|
||||
|
|
|
@ -11,12 +11,11 @@ use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint,
|
|||
Pointer, ErrorHandled, GlobalId};
|
||||
use rustc::mir::mono::MonoItem;
|
||||
use rustc::hir::Node;
|
||||
use syntax_pos::Span;
|
||||
use rustc_target::abi::HasDataLayout;
|
||||
use syntax::symbol::sym;
|
||||
use syntax_pos::symbol::LocalInternedString;
|
||||
use rustc::ty::{self, Ty, Instance};
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
use syntax::symbol::{Symbol, sym};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc::ty::layout::{self, Size, Align, LayoutOf};
|
||||
|
||||
|
@ -122,10 +121,11 @@ fn check_and_apply_linkage(
|
|||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
attrs: &CodegenFnAttrs,
|
||||
ty: Ty<'tcx>,
|
||||
sym: LocalInternedString,
|
||||
sym: Symbol,
|
||||
span: Span
|
||||
) -> &'ll Value {
|
||||
let llty = cx.layout_of(ty).llvm_type(cx);
|
||||
let sym = sym.as_str();
|
||||
if let Some(linkage) = attrs.linkage {
|
||||
debug!("get_static: sym={} linkage={:?}", sym, linkage);
|
||||
|
||||
|
@ -221,7 +221,7 @@ impl CodegenCx<'ll, 'tcx> {
|
|||
def_id);
|
||||
|
||||
let ty = instance.ty(self.tcx);
|
||||
let sym = self.tcx.symbol_name(instance).as_str();
|
||||
let sym = self.tcx.symbol_name(instance).name.as_symbol();
|
||||
|
||||
debug!("get_static: sym={} instance={:?}", sym, instance);
|
||||
|
||||
|
@ -232,11 +232,12 @@ impl CodegenCx<'ll, 'tcx> {
|
|||
Node::Item(&hir::Item {
|
||||
ref attrs, span, node: hir::ItemKind::Static(..), ..
|
||||
}) => {
|
||||
if self.get_declared_value(&sym[..]).is_some() {
|
||||
let sym_str = sym.as_str();
|
||||
if self.get_declared_value(&sym_str).is_some() {
|
||||
span_bug!(span, "Conflicting symbol names for static?");
|
||||
}
|
||||
|
||||
let g = self.define_global(&sym[..], llty).unwrap();
|
||||
let g = self.define_global(&sym_str, llty).unwrap();
|
||||
|
||||
if !self.tcx.is_reachable_non_generic(def_id) {
|
||||
unsafe {
|
||||
|
|
|
@ -29,7 +29,7 @@ use std::cell::{Cell, RefCell};
|
|||
use std::iter;
|
||||
use std::str;
|
||||
use std::sync::Arc;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax::source_map::{DUMMY_SP, Span};
|
||||
use crate::abi::Abi;
|
||||
|
||||
|
@ -52,7 +52,7 @@ pub struct CodegenCx<'ll, 'tcx> {
|
|||
pub vtables:
|
||||
RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>,
|
||||
/// Cache of constant strings,
|
||||
pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'ll Value>>,
|
||||
pub const_cstr_cache: RefCell<FxHashMap<Symbol, &'ll Value>>,
|
||||
|
||||
/// Reverse-direction for const ptrs cast from globals.
|
||||
/// Key is a Value holding a *T,
|
||||
|
|
|
@ -2251,7 +2251,7 @@ pub fn create_global_var_metadata(
|
|||
None
|
||||
} else {
|
||||
let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
|
||||
Some(SmallCStr::new(&linkage_name.as_str()))
|
||||
Some(SmallCStr::new(&linkage_name.name.as_str()))
|
||||
};
|
||||
|
||||
let global_align = cx.align_of(variable_type);
|
||||
|
|
|
@ -290,7 +290,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
let scope_line = span_start(self, span).line;
|
||||
|
||||
let function_name = CString::new(name).unwrap();
|
||||
let linkage_name = SmallCStr::new(&linkage_name.as_str());
|
||||
let linkage_name = SmallCStr::new(&linkage_name.name.as_str());
|
||||
|
||||
let mut flags = DIFlags::FlagPrototyped;
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
let name = &*tcx.item_name(def_id).as_str();
|
||||
|
||||
let llret_ty = self.layout_of(ret_ty).llvm_type(self);
|
||||
let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align.abi);
|
||||
let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout);
|
||||
|
||||
let simple = get_simple_intrinsic(self, name);
|
||||
let llval = match name {
|
||||
|
|
|
@ -121,7 +121,7 @@ fn reachable_non_generics_provider(
|
|||
})
|
||||
.map(|def_id| {
|
||||
let export_level = if special_runtime_crate {
|
||||
let name = tcx.symbol_name(Instance::mono(tcx, def_id)).as_str();
|
||||
let name = tcx.symbol_name(Instance::mono(tcx, def_id)).name.as_str();
|
||||
// We can probably do better here by just ensuring that
|
||||
// it has hidden visibility rather than public
|
||||
// visibility, as this is primarily here to ensure it's
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::traits::*;
|
|||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::Pos;
|
||||
|
||||
use super::{FunctionCx, LocalRef};
|
||||
|
@ -397,7 +397,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
|
||||
// Get the location information.
|
||||
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
|
||||
let filename = LocalInternedString::intern(&loc.file.name.to_string());
|
||||
let filename = Symbol::intern(&loc.file.name.to_string());
|
||||
let line = bx.const_u32(loc.line as u32);
|
||||
let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
|
||||
|
||||
|
@ -418,8 +418,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
vec![file_line_col, index, len])
|
||||
}
|
||||
_ => {
|
||||
let str = msg.description();
|
||||
let msg_str = LocalInternedString::intern(str);
|
||||
let msg_str = Symbol::intern(msg.description());
|
||||
let msg_file_line_col = bx.static_panic_msg(
|
||||
Some(msg_str),
|
||||
filename,
|
||||
|
@ -531,7 +530,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let layout = bx.layout_of(ty);
|
||||
if layout.abi.is_uninhabited() {
|
||||
let loc = bx.sess().source_map().lookup_char_pos(span.lo());
|
||||
let filename = LocalInternedString::intern(&loc.file.name.to_string());
|
||||
let filename = Symbol::intern(&loc.file.name.to_string());
|
||||
let line = bx.const_u32(loc.line as u32);
|
||||
let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
|
||||
|
||||
|
@ -539,7 +538,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
"Attempted to instantiate uninhabited type {}",
|
||||
ty
|
||||
);
|
||||
let msg_str = LocalInternedString::intern(&str);
|
||||
let msg_str = Symbol::intern(&str);
|
||||
let msg_file_line_col = bx.static_panic_msg(
|
||||
Some(msg_str),
|
||||
filename,
|
||||
|
@ -989,7 +988,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
|
||||
// Handle both by-ref and immediate tuples.
|
||||
if let Ref(llval, None, align) = tuple.val {
|
||||
let tuple_ptr = PlaceRef::new_sized(llval, tuple.layout, align);
|
||||
let tuple_ptr = PlaceRef::new_sized_aligned(llval, tuple.layout, align);
|
||||
for i in 0..tuple.layout.fields.count() {
|
||||
let field_ptr = tuple_ptr.project_field(bx, i);
|
||||
let field = bx.load_operand(field_ptr);
|
||||
|
@ -1203,7 +1202,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let llty = bx.backend_type(src.layout);
|
||||
let cast_ptr = bx.pointercast(dst.llval, bx.type_ptr_to(llty));
|
||||
let align = src.layout.align.abi.min(dst.align);
|
||||
src.val.store(bx, PlaceRef::new_sized(cast_ptr, src.layout, align));
|
||||
src.val.store(bx, PlaceRef::new_sized_aligned(cast_ptr, src.layout, align));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -289,7 +289,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
if local == mir::RETURN_PLACE && fx.fn_ty.ret.is_indirect() {
|
||||
debug!("alloc: {:?} (return place) -> place", local);
|
||||
let llretptr = bx.get_param(0);
|
||||
LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align.abi))
|
||||
LocalRef::Place(PlaceRef::new_sized(llretptr, layout))
|
||||
} else if memory_locals.contains(local) {
|
||||
debug!("alloc: {:?} -> place", local);
|
||||
if layout.is_unsized() {
|
||||
|
@ -548,7 +548,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
let llarg = bx.get_param(llarg_idx);
|
||||
bx.set_value_name(llarg, &name);
|
||||
llarg_idx += 1;
|
||||
PlaceRef::new_sized(llarg, arg.layout, arg.layout.align.abi)
|
||||
PlaceRef::new_sized(llarg, arg.layout)
|
||||
} else if arg.is_unsized_indirect() {
|
||||
// As the storage for the indirect argument lives during
|
||||
// the whole function call, we just copy the fat pointer.
|
||||
|
|
|
@ -485,7 +485,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
bx.load_operand(PlaceRef::new_sized(
|
||||
bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))),
|
||||
layout,
|
||||
layout.align.abi,
|
||||
))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -30,6 +30,19 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
|
|||
pub fn new_sized(
|
||||
llval: V,
|
||||
layout: TyLayout<'tcx>,
|
||||
) -> PlaceRef<'tcx, V> {
|
||||
assert!(!layout.is_unsized());
|
||||
PlaceRef {
|
||||
llval,
|
||||
llextra: None,
|
||||
layout,
|
||||
align: layout.align.abi
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_sized_aligned(
|
||||
llval: V,
|
||||
layout: TyLayout<'tcx>,
|
||||
align: Align,
|
||||
) -> PlaceRef<'tcx, V> {
|
||||
assert!(!layout.is_unsized());
|
||||
|
@ -45,14 +58,13 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
|
|||
bx: &mut Bx,
|
||||
llval: V,
|
||||
layout: TyLayout<'tcx>,
|
||||
align: Align,
|
||||
) -> PlaceRef<'tcx, V> {
|
||||
assert!(!bx.cx().type_has_metadata(layout.ty));
|
||||
PlaceRef {
|
||||
llval,
|
||||
llextra: None,
|
||||
layout,
|
||||
align
|
||||
align: layout.align.abi
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +76,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
|
|||
debug!("alloca({:?}: {:?})", name, layout);
|
||||
assert!(!layout.is_unsized(), "tried to statically allocate unsized place");
|
||||
let tmp = bx.alloca(bx.cx().backend_type(layout), name, layout.align.abi);
|
||||
Self::new_sized(tmp, layout, layout.align.abi)
|
||||
Self::new_sized(tmp, layout)
|
||||
}
|
||||
|
||||
/// Returns a place for an indirect reference to an unsized place.
|
||||
|
@ -482,7 +494,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let llval = bx.cx().const_undef(
|
||||
bx.cx().type_ptr_to(bx.cx().backend_type(layout))
|
||||
);
|
||||
PlaceRef::new_sized(llval, layout, layout.align.abi)
|
||||
PlaceRef::new_sized(llval, layout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -498,7 +510,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
// with a static that is an extern_type.
|
||||
let layout = cx.layout_of(self.monomorphize(&ty));
|
||||
let static_ = bx.get_static(*def_id);
|
||||
PlaceRef::new_thin_place(bx, static_, layout, layout.align.abi)
|
||||
PlaceRef::new_thin_place(bx, static_, layout)
|
||||
},
|
||||
mir::PlaceRef {
|
||||
base,
|
||||
|
|
|
@ -71,7 +71,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
scratch.storage_dead(&mut bx);
|
||||
}
|
||||
OperandValue::Ref(llref, None, align) => {
|
||||
let source = PlaceRef::new_sized(llref, operand.layout, align);
|
||||
let source = PlaceRef::new_sized_aligned(llref, operand.layout, align);
|
||||
base::coerce_unsized_into(&mut bx, source, dest);
|
||||
}
|
||||
OperandValue::Ref(_, Some(_), _) => {
|
||||
|
|
|
@ -58,7 +58,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
|
|||
self.to_raw_string(),
|
||||
cx.codegen_unit().name());
|
||||
|
||||
let symbol_name = self.symbol_name(cx.tcx()).as_str();
|
||||
let symbol_name = self.symbol_name(cx.tcx()).name.as_str();
|
||||
|
||||
debug!("symbol {}", &symbol_name);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::BackendTypes;
|
||||
use syntax_pos::symbol::LocalInternedString;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::layout::Align;
|
||||
|
||||
|
@ -12,8 +12,8 @@ pub trait StaticBuilderMethods: BackendTypes {
|
|||
fn get_static(&mut self, def_id: DefId) -> Self::Value;
|
||||
fn static_panic_msg(
|
||||
&mut self,
|
||||
msg: Option<LocalInternedString>,
|
||||
filename: LocalInternedString,
|
||||
msg: Option<Symbol>,
|
||||
filename: Symbol,
|
||||
line: Self::Value,
|
||||
col: Self::Value,
|
||||
kind: &str,
|
||||
|
|
|
@ -40,7 +40,7 @@ impl SymbolNamesTest<'tcx> {
|
|||
let instance = Instance::mono(tcx, def_id);
|
||||
let mangled = self.tcx.symbol_name(instance);
|
||||
tcx.sess.span_err(attr.span, &format!("symbol-name({})", mangled));
|
||||
if let Ok(demangling) = rustc_demangle::try_demangle(&mangled.as_str()) {
|
||||
if let Ok(demangling) = rustc_demangle::try_demangle(&mangled.name.as_str()) {
|
||||
tcx.sess.span_err(attr.span, &format!("demangling({})", demangling));
|
||||
tcx.sess.span_err(attr.span, &format!("demangling-alt({:#})", demangling));
|
||||
}
|
||||
|
|
|
@ -4,12 +4,12 @@ name = "rustc_lexer"
|
|||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
# Note that this crate purposefully does not depend on other rustc crates
|
||||
[dependencies]
|
||||
unicode-xid = { version = "0.1.0", optional = true }
|
||||
|
||||
# Note: do not remove this blank `[lib]` section.
|
||||
# This will be used when publishing this crate as `rustc-ap-rustc_lexer`.
|
||||
[lib]
|
||||
doctest = false
|
||||
name = "rustc_lexer"
|
||||
|
||||
# Note that this crate purposefully does not depend on other rustc crates
|
||||
[dependencies]
|
||||
unicode-xid = "0.2.0"
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// We want to be able to build this crate with a stable compiler, so feature
|
||||
// flags should be optional.
|
||||
#![cfg_attr(not(feature = "unicode-xid"), feature(unicode_internals))]
|
||||
// We want to be able to build this crate with a stable compiler, so no
|
||||
// `#![feature]` attributes should be added.
|
||||
|
||||
mod cursor;
|
||||
pub mod unescape;
|
||||
|
@ -103,6 +102,62 @@ pub fn tokenize(mut input: &str) -> impl Iterator<Item = Token> + '_ {
|
|||
})
|
||||
}
|
||||
|
||||
// See [UAX #31](http://unicode.org/reports/tr31) for definitions of these
|
||||
// classes.
|
||||
|
||||
/// True if `c` is considered a whitespace according to Rust language definition.
|
||||
pub fn is_whitespace(c: char) -> bool {
|
||||
// This is Pattern_White_Space.
|
||||
//
|
||||
// Note that this set is stable (ie, it doesn't change with different
|
||||
// Unicode versions), so it's ok to just hard-code the values.
|
||||
|
||||
match c {
|
||||
// Usual ASCII suspects
|
||||
| '\u{0009}' // \t
|
||||
| '\u{000A}' // \n
|
||||
| '\u{000B}' // vertical tab
|
||||
| '\u{000C}' // form feed
|
||||
| '\u{000D}' // \r
|
||||
| '\u{0020}' // space
|
||||
|
||||
// NEXT LINE from latin1
|
||||
| '\u{0085}'
|
||||
|
||||
// Bidi markers
|
||||
| '\u{200E}' // LEFT-TO-RIGHT MARK
|
||||
| '\u{200F}' // RIGHT-TO-LEFT MARK
|
||||
|
||||
// Dedicated whitespace characters from Unicode
|
||||
| '\u{2028}' // LINE SEPARATOR
|
||||
| '\u{2029}' // PARAGRAPH SEPARATOR
|
||||
=> true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// True if `c` is valid as a first character of an identifier.
|
||||
pub fn is_id_start(c: char) -> bool {
|
||||
// This is XID_Start OR '_' (which formally is not a XID_Start).
|
||||
// We also add fast-path for ascii idents
|
||||
('a' <= c && c <= 'z')
|
||||
|| ('A' <= c && c <= 'Z')
|
||||
|| c == '_'
|
||||
|| (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_start(c))
|
||||
}
|
||||
|
||||
/// True if `c` is valid as a non-first character of an identifier.
|
||||
pub fn is_id_continue(c: char) -> bool {
|
||||
// This is exactly XID_Continue.
|
||||
// We also add fast-path for ascii idents
|
||||
('a' <= c && c <= 'z')
|
||||
|| ('A' <= c && c <= 'Z')
|
||||
|| ('0' <= c && c <= '9')
|
||||
|| c == '_'
|
||||
|| (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
|
||||
}
|
||||
|
||||
|
||||
impl Cursor<'_> {
|
||||
fn advance_token(&mut self) -> Token {
|
||||
let first_char = self.bump().unwrap();
|
||||
|
@ -112,9 +167,9 @@ impl Cursor<'_> {
|
|||
'*' => self.block_comment(),
|
||||
_ => Slash,
|
||||
},
|
||||
c if character_properties::is_whitespace(c) => self.whitespace(),
|
||||
c if is_whitespace(c) => self.whitespace(),
|
||||
'r' => match (self.nth_char(0), self.nth_char(1)) {
|
||||
('#', c1) if character_properties::is_id_start(c1) => self.raw_ident(),
|
||||
('#', c1) if is_id_start(c1) => self.raw_ident(),
|
||||
('#', _) | ('"', _) => {
|
||||
let (n_hashes, started, terminated) = self.raw_double_quoted_string();
|
||||
let suffix_start = self.len_consumed();
|
||||
|
@ -159,7 +214,7 @@ impl Cursor<'_> {
|
|||
}
|
||||
_ => self.ident(),
|
||||
},
|
||||
c if character_properties::is_id_start(c) => self.ident(),
|
||||
c if is_id_start(c) => self.ident(),
|
||||
c @ '0'..='9' => {
|
||||
let literal_kind = self.number(c);
|
||||
let suffix_start = self.len_consumed();
|
||||
|
@ -247,8 +302,8 @@ impl Cursor<'_> {
|
|||
}
|
||||
|
||||
fn whitespace(&mut self) -> TokenKind {
|
||||
debug_assert!(character_properties::is_whitespace(self.prev()));
|
||||
while character_properties::is_whitespace(self.nth_char(0)) {
|
||||
debug_assert!(is_whitespace(self.prev()));
|
||||
while is_whitespace(self.nth_char(0)) {
|
||||
self.bump();
|
||||
}
|
||||
Whitespace
|
||||
|
@ -258,19 +313,19 @@ impl Cursor<'_> {
|
|||
debug_assert!(
|
||||
self.prev() == 'r'
|
||||
&& self.nth_char(0) == '#'
|
||||
&& character_properties::is_id_start(self.nth_char(1))
|
||||
&& is_id_start(self.nth_char(1))
|
||||
);
|
||||
self.bump();
|
||||
self.bump();
|
||||
while character_properties::is_id_continue(self.nth_char(0)) {
|
||||
while is_id_continue(self.nth_char(0)) {
|
||||
self.bump();
|
||||
}
|
||||
RawIdent
|
||||
}
|
||||
|
||||
fn ident(&mut self) -> TokenKind {
|
||||
debug_assert!(character_properties::is_id_start(self.prev()));
|
||||
while character_properties::is_id_continue(self.nth_char(0)) {
|
||||
debug_assert!(is_id_start(self.prev()));
|
||||
while is_id_continue(self.nth_char(0)) {
|
||||
self.bump();
|
||||
}
|
||||
Ident
|
||||
|
@ -315,7 +370,7 @@ impl Cursor<'_> {
|
|||
// integer literal followed by field/method access or a range pattern
|
||||
// (`0..2` and `12.foo()`)
|
||||
'.' if self.nth_char(1) != '.'
|
||||
&& !character_properties::is_id_start(self.nth_char(1)) =>
|
||||
&& !is_id_start(self.nth_char(1)) =>
|
||||
{
|
||||
// might have stuff after the ., and if it does, it needs to start
|
||||
// with a number
|
||||
|
@ -345,7 +400,7 @@ impl Cursor<'_> {
|
|||
fn lifetime_or_char(&mut self) -> TokenKind {
|
||||
debug_assert!(self.prev() == '\'');
|
||||
let mut starts_with_number = false;
|
||||
if (character_properties::is_id_start(self.nth_char(0))
|
||||
if (is_id_start(self.nth_char(0))
|
||||
|| self.nth_char(0).is_digit(10) && {
|
||||
starts_with_number = true;
|
||||
true
|
||||
|
@ -353,7 +408,7 @@ impl Cursor<'_> {
|
|||
&& self.nth_char(1) != '\''
|
||||
{
|
||||
self.bump();
|
||||
while character_properties::is_id_continue(self.nth_char(0)) {
|
||||
while is_id_continue(self.nth_char(0)) {
|
||||
self.bump();
|
||||
}
|
||||
|
||||
|
@ -495,66 +550,13 @@ impl Cursor<'_> {
|
|||
}
|
||||
|
||||
fn eat_literal_suffix(&mut self) {
|
||||
if !character_properties::is_id_start(self.nth_char(0)) {
|
||||
if !is_id_start(self.nth_char(0)) {
|
||||
return;
|
||||
}
|
||||
self.bump();
|
||||
|
||||
while character_properties::is_id_continue(self.nth_char(0)) {
|
||||
while is_id_continue(self.nth_char(0)) {
|
||||
self.bump();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod character_properties {
|
||||
// this is Pattern_White_Space
|
||||
#[cfg(feature = "unicode-xid")]
|
||||
pub fn is_whitespace(c: char) -> bool {
|
||||
match c {
|
||||
'\u{0009}' | '\u{000A}' | '\u{000B}' | '\u{000C}' | '\u{000D}' | '\u{0020}'
|
||||
| '\u{0085}' | '\u{200E}' | '\u{200F}' | '\u{2028}' | '\u{2029}' => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unicode-xid"))]
|
||||
pub fn is_whitespace(c: char) -> bool {
|
||||
core::unicode::property::Pattern_White_Space(c)
|
||||
}
|
||||
|
||||
// this is XID_Start OR '_' (which formally is not a XID_Start)
|
||||
#[cfg(feature = "unicode-xid")]
|
||||
pub fn is_id_start(c: char) -> bool {
|
||||
('a' <= c && c <= 'z')
|
||||
|| ('A' <= c && c <= 'Z')
|
||||
|| c == '_'
|
||||
|| (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_start(c))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unicode-xid"))]
|
||||
pub fn is_id_start(c: char) -> bool {
|
||||
('a' <= c && c <= 'z')
|
||||
|| ('A' <= c && c <= 'Z')
|
||||
|| c == '_'
|
||||
|| (c > '\x7f' && c.is_xid_start())
|
||||
}
|
||||
|
||||
// this is XID_Continue
|
||||
#[cfg(feature = "unicode-xid")]
|
||||
pub fn is_id_continue(c: char) -> bool {
|
||||
('a' <= c && c <= 'z')
|
||||
|| ('A' <= c && c <= 'Z')
|
||||
|| ('0' <= c && c <= '9')
|
||||
|| c == '_'
|
||||
|| (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unicode-xid"))]
|
||||
pub fn is_id_continue(c: char) -> bool {
|
||||
('a' <= c && c <= 'z')
|
||||
|| ('A' <= c && c <= 'Z')
|
||||
|| ('0' <= c && c <= '9')
|
||||
|| c == '_'
|
||||
|| (c > '\x7f' && c.is_xid_continue())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -398,18 +398,37 @@ impl UnusedParens {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_unused_parens_pat(&self,
|
||||
cx: &EarlyContext<'_>,
|
||||
value: &ast::Pat,
|
||||
msg: &str) {
|
||||
if let ast::PatKind::Paren(_) = value.node {
|
||||
fn check_unused_parens_pat(
|
||||
&self,
|
||||
cx: &EarlyContext<'_>,
|
||||
value: &ast::Pat,
|
||||
avoid_or: bool,
|
||||
avoid_mut: bool,
|
||||
) {
|
||||
use ast::{PatKind, BindingMode::ByValue, Mutability::Mutable};
|
||||
|
||||
if let PatKind::Paren(inner) = &value.node {
|
||||
match inner.node {
|
||||
// The lint visitor will visit each subpattern of `p`. We do not want to lint
|
||||
// any range pattern no matter where it occurs in the pattern. For something like
|
||||
// `&(a..=b)`, there is a recursive `check_pat` on `a` and `b`, but we will assume
|
||||
// that if there are unnecessary parens they serve a purpose of readability.
|
||||
PatKind::Range(..) => return,
|
||||
// Avoid `p0 | .. | pn` if we should.
|
||||
PatKind::Or(..) if avoid_or => return,
|
||||
// Avoid `mut x` and `mut x @ p` if we should:
|
||||
PatKind::Ident(ByValue(Mutable), ..) if avoid_mut => return,
|
||||
// Otherwise proceed with linting.
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let pattern_text = if let Ok(snippet) = cx.sess().source_map()
|
||||
.span_to_snippet(value.span) {
|
||||
snippet
|
||||
} else {
|
||||
pprust::pat_to_string(value)
|
||||
};
|
||||
Self::remove_outer_parens(cx, value.span, &pattern_text, msg, (false, false));
|
||||
Self::remove_outer_parens(cx, value.span, &pattern_text, "pattern", (false, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,6 +493,13 @@ impl EarlyLintPass for UnusedParens {
|
|||
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||
use syntax::ast::ExprKind::*;
|
||||
let (value, msg, followed_by_block, left_pos, right_pos) = match e.node {
|
||||
Let(ref pats, ..) => {
|
||||
for p in pats {
|
||||
self.check_unused_parens_pat(cx, p, false, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
If(ref cond, ref block, ..) => {
|
||||
let left = e.span.lo() + syntax_pos::BytePos(2);
|
||||
let right = block.span.lo();
|
||||
|
@ -486,7 +512,8 @@ impl EarlyLintPass for UnusedParens {
|
|||
(cond, "`while` condition", true, Some(left), Some(right))
|
||||
},
|
||||
|
||||
ForLoop(_, ref cond, ref block, ..) => {
|
||||
ForLoop(ref pat, ref cond, ref block, ..) => {
|
||||
self.check_unused_parens_pat(cx, pat, false, false);
|
||||
(cond, "`for` head expression", true, None, Some(block.span.lo()))
|
||||
}
|
||||
|
||||
|
@ -531,26 +558,46 @@ impl EarlyLintPass for UnusedParens {
|
|||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
|
||||
use ast::PatKind::{Paren, Range};
|
||||
// The lint visitor will visit each subpattern of `p`. We do not want to lint any range
|
||||
// pattern no matter where it occurs in the pattern. For something like `&(a..=b)`, there
|
||||
// is a recursive `check_pat` on `a` and `b`, but we will assume that if there are
|
||||
// unnecessary parens they serve a purpose of readability.
|
||||
if let Paren(ref pat) = p.node {
|
||||
match pat.node {
|
||||
Range(..) => {}
|
||||
_ => self.check_unused_parens_pat(cx, &p, "pattern")
|
||||
}
|
||||
use ast::{PatKind::*, Mutability};
|
||||
match &p.node {
|
||||
// Do not lint on `(..)` as that will result in the other arms being useless.
|
||||
Paren(_)
|
||||
// The other cases do not contain sub-patterns.
|
||||
| Wild | Rest | Lit(..) | Mac(..) | Range(..) | Ident(.., None) | Path(..) => return,
|
||||
// These are list-like patterns; parens can always be removed.
|
||||
TupleStruct(_, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
|
||||
self.check_unused_parens_pat(cx, p, false, false);
|
||||
},
|
||||
Struct(_, fps, _) => for f in fps {
|
||||
self.check_unused_parens_pat(cx, &f.pat, false, false);
|
||||
},
|
||||
// Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
|
||||
Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false),
|
||||
// Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
|
||||
// Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
|
||||
Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Immutable),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
|
||||
if let ast::StmtKind::Local(ref local) = s.node {
|
||||
self.check_unused_parens_pat(cx, &local.pat, false, false);
|
||||
|
||||
if let Some(ref value) = local.init {
|
||||
self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) {
|
||||
self.check_unused_parens_pat(cx, ¶m.pat, true, false);
|
||||
}
|
||||
|
||||
fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
|
||||
for p in &arm.pats {
|
||||
self.check_unused_parens_pat(cx, p, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
|
|
|
@ -54,7 +54,7 @@ fn main() {
|
|||
// LLVM are compiled the same way, but for us that's typically the case.
|
||||
//
|
||||
// We *want* detect this cross compiling situation by asking llvm-config
|
||||
// what it's host-target is. If that's not the TARGET, then we're cross
|
||||
// what its host-target is. If that's not the TARGET, then we're cross
|
||||
// compiling. Unfortunately `llvm-config` seems either be buggy, or we're
|
||||
// misconfiguring it, because the `i686-pc-windows-gnu` build of LLVM will
|
||||
// report itself with a `--host-target` of `x86_64-pc-windows-gnu`. This
|
||||
|
@ -62,7 +62,7 @@ fn main() {
|
|||
// havoc ensues.
|
||||
//
|
||||
// In any case, if we're cross compiling, this generally just means that we
|
||||
// can't trust all the output of llvm-config becaues it might be targeted
|
||||
// can't trust all the output of llvm-config because it might be targeted
|
||||
// for the host rather than the target. As a result a bunch of blocks below
|
||||
// are gated on `if !is_crossed`
|
||||
let target = env::var("TARGET").expect("TARGET was not set");
|
||||
|
@ -166,7 +166,7 @@ fn main() {
|
|||
|
||||
let (llvm_kind, llvm_link_arg) = detect_llvm_link();
|
||||
|
||||
// Link in all LLVM libraries, if we're uwring the "wrong" llvm-config then
|
||||
// Link in all LLVM libraries, if we're using the "wrong" llvm-config then
|
||||
// we don't pick up system libs because unfortunately they're for the host
|
||||
// of llvm-config, not the target that we're attempting to link.
|
||||
let mut cmd = Command::new(&llvm_config);
|
||||
|
|
|
@ -1354,7 +1354,7 @@ impl EncodeContext<'tcx> {
|
|||
let def_id = self.tcx.hir().local_def_id(macro_def.hir_id);
|
||||
Entry {
|
||||
kind: EntryKind::MacroDef(self.lazy(MacroDef {
|
||||
body: pprust::tokens_to_string(macro_def.body.clone()),
|
||||
body: pprust::tts_to_string(macro_def.body.clone()),
|
||||
legacy: macro_def.legacy,
|
||||
})),
|
||||
visibility: self.lazy(ty::Visibility::Public),
|
||||
|
|
|
@ -15,11 +15,12 @@ either = "1.5.0"
|
|||
dot = { path = "../libgraphviz", package = "graphviz" }
|
||||
log = "0.4"
|
||||
log_settings = "0.1.1"
|
||||
polonius-engine = "0.9.0"
|
||||
polonius-engine = "0.10.0"
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
rustc_errors = { path = "../librustc_errors" }
|
||||
rustc_lexer = { path = "../librustc_lexer" }
|
||||
rustc_serialize = { path = "../libserialize", package = "serialize" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
|
|
@ -336,7 +336,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let local = &self.body.local_decls[local_index];
|
||||
match local.name {
|
||||
Some(name) if !local.from_compiler_desugaring() => {
|
||||
buf.push_str(name.as_str().get());
|
||||
buf.push_str(&name.as_str());
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(()),
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::borrow_check::location::LocationIndex;
|
|||
use polonius_engine::Output;
|
||||
|
||||
use crate::dataflow::indexes::BorrowIndex;
|
||||
use crate::dataflow::move_paths::HasMoveData;
|
||||
use crate::dataflow::move_paths::{HasMoveData, MovePathIndex};
|
||||
use crate::dataflow::Borrows;
|
||||
use crate::dataflow::EverInitializedPlaces;
|
||||
use crate::dataflow::MaybeUninitializedPlaces;
|
||||
|
@ -21,7 +21,7 @@ use either::Either;
|
|||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
||||
crate type PoloniusOutput = Output<RegionVid, BorrowIndex, LocationIndex, Local>;
|
||||
crate type PoloniusOutput = Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
|
||||
|
||||
// (forced to be `pub` due to its use as an associated type below.)
|
||||
crate struct Flows<'b, 'tcx> {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use core::unicode::property::Pattern_White_Space;
|
||||
|
||||
use rustc::mir::*;
|
||||
use rustc::ty;
|
||||
use rustc_errors::{DiagnosticBuilder,Applicability};
|
||||
|
@ -526,7 +524,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||
let suggestion;
|
||||
let to_remove;
|
||||
if pat_snippet.starts_with("mut")
|
||||
&& pat_snippet["mut".len()..].starts_with(Pattern_White_Space)
|
||||
&& pat_snippet["mut".len()..].starts_with(rustc_lexer::is_whitespace)
|
||||
{
|
||||
suggestion = pat_snippet["mut".len()..].trim_start();
|
||||
to_remove = "&mut";
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use core::unicode::property::Pattern_White_Space;
|
||||
use rustc::hir;
|
||||
use rustc::hir::Node;
|
||||
use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Body};
|
||||
|
@ -715,7 +714,7 @@ fn annotate_struct_field(
|
|||
fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<String> {
|
||||
let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).ok()?;
|
||||
if hi_src.starts_with("ref")
|
||||
&& hi_src["ref".len()..].starts_with(Pattern_White_Space)
|
||||
&& hi_src["ref".len()..].starts_with(rustc_lexer::is_whitespace)
|
||||
{
|
||||
let replacement = format!("ref mut{}", &hi_src["ref".len()..]);
|
||||
Some(replacement)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::borrow_check::location::{LocationIndex, LocationTable};
|
||||
use crate::dataflow::indexes::BorrowIndex;
|
||||
use crate::dataflow::indexes::{BorrowIndex, MovePathIndex};
|
||||
use polonius_engine::AllFacts as PoloniusAllFacts;
|
||||
use polonius_engine::Atom;
|
||||
use rustc::mir::Local;
|
||||
|
@ -11,7 +11,7 @@ use std::fs::{self, File};
|
|||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
crate type AllFacts = PoloniusAllFacts<RegionVid, BorrowIndex, LocationIndex, Local>;
|
||||
crate type AllFacts = PoloniusAllFacts<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
|
||||
|
||||
crate trait AllFactsExt {
|
||||
/// Returns `true` if there is a need to gather `AllFacts` given the
|
||||
|
@ -58,14 +58,17 @@ impl AllFactsExt for AllFacts {
|
|||
cfg_edge,
|
||||
killed,
|
||||
outlives,
|
||||
region_live_at,
|
||||
invalidates,
|
||||
var_used,
|
||||
var_defined,
|
||||
var_drop_used,
|
||||
var_uses_region,
|
||||
var_drops_region,
|
||||
var_initialized_on_exit,
|
||||
child,
|
||||
path_belongs_to_var,
|
||||
initialized_at,
|
||||
moved_out_at,
|
||||
path_accessed_at,
|
||||
])
|
||||
}
|
||||
Ok(())
|
||||
|
@ -84,6 +87,12 @@ impl Atom for LocationIndex {
|
|||
}
|
||||
}
|
||||
|
||||
impl Atom for MovePathIndex {
|
||||
fn index(self) -> usize {
|
||||
Idx::index(self)
|
||||
}
|
||||
}
|
||||
|
||||
struct FactWriter<'w> {
|
||||
location_table: &'w LocationTable,
|
||||
dir: &'w Path,
|
||||
|
|
|
@ -4,14 +4,15 @@ use crate::borrow_check::nll::facts::AllFactsExt;
|
|||
use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
|
||||
use crate::borrow_check::nll::region_infer::values::RegionValueElements;
|
||||
use crate::dataflow::indexes::BorrowIndex;
|
||||
use crate::dataflow::move_paths::MoveData;
|
||||
use crate::dataflow::move_paths::{InitLocation, MoveData, MovePathIndex, InitKind};
|
||||
use crate::dataflow::FlowAtLocation;
|
||||
use crate::dataflow::MaybeInitializedPlaces;
|
||||
use crate::transform::MirSource;
|
||||
use crate::borrow_check::Upvar;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Local, Body, Promoted};
|
||||
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements,
|
||||
Local, Location, Body, LocalKind, BasicBlock, Promoted};
|
||||
use rustc::ty::{self, RegionKind, RegionVid};
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc_errors::Diagnostic;
|
||||
|
@ -69,6 +70,85 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
|
|||
universal_regions
|
||||
}
|
||||
|
||||
|
||||
// This function populates an AllFacts instance with base facts related to
|
||||
// MovePaths and needed for the move analysis.
|
||||
fn populate_polonius_move_facts(
|
||||
all_facts: &mut AllFacts,
|
||||
move_data: &MoveData<'_>,
|
||||
location_table: &LocationTable,
|
||||
body: &Body<'_>) {
|
||||
all_facts
|
||||
.path_belongs_to_var
|
||||
.extend(
|
||||
move_data
|
||||
.rev_lookup
|
||||
.iter_locals_enumerated()
|
||||
.map(|(v, &m)| (m, v)));
|
||||
|
||||
for (child, move_path) in move_data.move_paths.iter_enumerated() {
|
||||
all_facts
|
||||
.child
|
||||
.extend(
|
||||
move_path
|
||||
.parents(&move_data.move_paths)
|
||||
.iter()
|
||||
.map(|&parent| (child, parent)));
|
||||
}
|
||||
|
||||
// initialized_at
|
||||
for init in move_data.inits.iter() {
|
||||
|
||||
match init.location {
|
||||
InitLocation::Statement(location) => {
|
||||
let block_data = &body[location.block];
|
||||
let is_terminator = location.statement_index == block_data.statements.len();
|
||||
|
||||
if is_terminator && init.kind == InitKind::NonPanicPathOnly {
|
||||
// We are at the terminator of an init that has a panic path,
|
||||
// and where the init should not happen on panic
|
||||
|
||||
for &successor in block_data.terminator().successors() {
|
||||
if body[successor].is_cleanup {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The initialization happened in (or rather, when arriving at)
|
||||
// the successors, but not in the unwind block.
|
||||
let first_statement = Location { block: successor, statement_index: 0};
|
||||
all_facts
|
||||
.initialized_at
|
||||
.push((init.path, location_table.start_index(first_statement)));
|
||||
}
|
||||
|
||||
} else {
|
||||
// In all other cases, the initialization just happens at the
|
||||
// midpoint, like any other effect.
|
||||
all_facts.initialized_at.push((init.path, location_table.mid_index(location)));
|
||||
}
|
||||
},
|
||||
// Arguments are initialized on function entry
|
||||
InitLocation::Argument(local) => {
|
||||
assert!(body.local_kind(local) == LocalKind::Arg);
|
||||
let fn_entry = Location {block: BasicBlock::from_u32(0u32), statement_index: 0 };
|
||||
all_facts.initialized_at.push((init.path, location_table.start_index(fn_entry)));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// moved_out_at
|
||||
// deinitialisation is assumed to always happen!
|
||||
all_facts
|
||||
.moved_out_at
|
||||
.extend(
|
||||
move_data
|
||||
.moves
|
||||
.iter()
|
||||
.map(|mo| (mo.path, location_table.mid_index(mo.source))));
|
||||
}
|
||||
|
||||
/// Computes the (non-lexical) regions from the input MIR.
|
||||
///
|
||||
/// This may result in errors being reported.
|
||||
|
@ -87,7 +167,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
|
|||
errors_buffer: &mut Vec<Diagnostic>,
|
||||
) -> (
|
||||
RegionInferenceContext<'tcx>,
|
||||
Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex, Local>>>,
|
||||
Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>>>,
|
||||
Option<ClosureRegionRequirements<'tcx>>,
|
||||
) {
|
||||
let mut all_facts = if AllFacts::enabled(infcx.tcx) {
|
||||
|
@ -123,6 +203,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
|
|||
all_facts
|
||||
.universal_region
|
||||
.extend(universal_regions.universal_regions());
|
||||
populate_polonius_move_facts(all_facts, move_data, location_table, body);
|
||||
}
|
||||
|
||||
// Create the region inference context, taking ownership of the
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements};
|
||||
use crate::util::liveness::{categorize, DefUse};
|
||||
use rustc::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc::mir::{Local, Location, Body};
|
||||
use rustc::mir::{Body, Local, Location};
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc_data_structures::vec_linked_list as vll;
|
||||
|
||||
|
@ -72,16 +72,10 @@ impl LocalUseMap {
|
|||
|
||||
let mut locals_with_use_data: IndexVec<Local, bool> =
|
||||
IndexVec::from_elem_n(false, body.local_decls.len());
|
||||
live_locals
|
||||
.iter()
|
||||
.for_each(|&local| locals_with_use_data[local] = true);
|
||||
live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);
|
||||
|
||||
LocalUseMapBuild {
|
||||
local_use_map: &mut local_use_map,
|
||||
elements,
|
||||
locals_with_use_data,
|
||||
}
|
||||
.visit_body(body);
|
||||
LocalUseMapBuild { local_use_map: &mut local_use_map, elements, locals_with_use_data }
|
||||
.visit_body(body);
|
||||
|
||||
local_use_map
|
||||
}
|
||||
|
@ -151,10 +145,8 @@ impl LocalUseMapBuild<'_> {
|
|||
location: Location,
|
||||
) {
|
||||
let point_index = elements.point_from_location(location);
|
||||
let appearance_index = appearances.push(Appearance {
|
||||
point_index,
|
||||
next: *first_appearance,
|
||||
});
|
||||
let appearance_index =
|
||||
appearances.push(Appearance { point_index, next: *first_appearance });
|
||||
*first_appearance = Some(appearance_index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,9 +58,9 @@ pub(super) fn generate<'tcx>(
|
|||
};
|
||||
|
||||
if !live_locals.is_empty() {
|
||||
trace::trace(typeck, body, elements, flow_inits, move_data, live_locals, location_table);
|
||||
trace::trace(typeck, body, elements, flow_inits, move_data, live_locals);
|
||||
|
||||
polonius::populate_var_liveness_facts(typeck, body, location_table);
|
||||
polonius::populate_access_facts(typeck, body, location_table, move_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,28 @@
|
|||
use crate::borrow_check::location::{LocationIndex, LocationTable};
|
||||
use crate::dataflow::indexes::MovePathIndex;
|
||||
use crate::dataflow::move_paths::{LookupResult, MoveData};
|
||||
use crate::util::liveness::{categorize, DefUse};
|
||||
use rustc::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc::mir::{Body, Local, Location};
|
||||
use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
|
||||
use rustc::mir::{Body, Local, Location, Place};
|
||||
use rustc::ty::subst::Kind;
|
||||
use rustc::ty::Ty;
|
||||
|
||||
use super::TypeChecker;
|
||||
|
||||
type VarPointRelations = Vec<(Local, LocationIndex)>;
|
||||
type MovePathPointRelations = Vec<(MovePathIndex, LocationIndex)>;
|
||||
|
||||
struct LivenessPointFactsExtractor<'me> {
|
||||
struct UseFactsExtractor<'me> {
|
||||
var_defined: &'me mut VarPointRelations,
|
||||
var_used: &'me mut VarPointRelations,
|
||||
location_table: &'me LocationTable,
|
||||
var_drop_used: &'me mut VarPointRelations,
|
||||
move_data: &'me MoveData<'me>,
|
||||
path_accessed_at: &'me mut MovePathPointRelations,
|
||||
}
|
||||
|
||||
// A Visitor to walk through the MIR and extract point-wise facts
|
||||
impl LivenessPointFactsExtractor<'_> {
|
||||
impl UseFactsExtractor<'_> {
|
||||
fn location_to_index(&self, location: Location) -> LocationIndex {
|
||||
self.location_table.mid_index(location)
|
||||
}
|
||||
|
@ -30,15 +36,50 @@ impl LivenessPointFactsExtractor<'_> {
|
|||
debug!("LivenessFactsExtractor::insert_use()");
|
||||
self.var_used.push((local, self.location_to_index(location)));
|
||||
}
|
||||
|
||||
fn insert_drop_use(&mut self, local: Local, location: Location) {
|
||||
debug!("LivenessFactsExtractor::insert_drop_use()");
|
||||
self.var_drop_used.push((local, self.location_to_index(location)));
|
||||
}
|
||||
|
||||
fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
|
||||
debug!("LivenessFactsExtractor::insert_path_access({:?}, {:?})", path, location);
|
||||
self.path_accessed_at.push((path, self.location_to_index(location)));
|
||||
}
|
||||
|
||||
fn place_to_mpi(&self, place: &Place<'_>) -> Option<MovePathIndex> {
|
||||
match self.move_data.rev_lookup.find(place.as_ref()) {
|
||||
LookupResult::Exact(mpi) => Some(mpi),
|
||||
LookupResult::Parent(mmpi) => mmpi,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> {
|
||||
impl Visitor<'tcx> for UseFactsExtractor<'_> {
|
||||
fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
|
||||
match categorize(context) {
|
||||
Some(DefUse::Def) => self.insert_def(local, location),
|
||||
Some(DefUse::Use) => self.insert_use(local, location),
|
||||
Some(DefUse::Drop) => self.insert_drop_use(local, location),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
|
||||
self.super_place(place, context, location);
|
||||
match context {
|
||||
PlaceContext::NonMutatingUse(_) => {
|
||||
if let Some(mpi) = self.place_to_mpi(place) {
|
||||
self.insert_path_access(mpi, location);
|
||||
}
|
||||
}
|
||||
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
|
||||
if let Some(mpi) = self.place_to_mpi(place) {
|
||||
self.insert_path_access(mpi, location);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
// NOTE: Drop handling is now done in trace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,23 +95,27 @@ fn add_var_uses_regions(typeck: &mut TypeChecker<'_, 'tcx>, local: Local, ty: Ty
|
|||
});
|
||||
}
|
||||
|
||||
pub(super) fn populate_var_liveness_facts(
|
||||
pub(super) fn populate_access_facts(
|
||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
mir: &Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
location_table: &LocationTable,
|
||||
move_data: &MoveData<'_>,
|
||||
) {
|
||||
debug!("populate_var_liveness_facts()");
|
||||
|
||||
if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
|
||||
LivenessPointFactsExtractor {
|
||||
UseFactsExtractor {
|
||||
var_defined: &mut facts.var_defined,
|
||||
var_used: &mut facts.var_used,
|
||||
var_drop_used: &mut facts.var_drop_used,
|
||||
path_accessed_at: &mut facts.path_accessed_at,
|
||||
location_table,
|
||||
move_data,
|
||||
}
|
||||
.visit_body(mir);
|
||||
.visit_body(body);
|
||||
}
|
||||
|
||||
for (local, local_decl) in mir.local_decls.iter_enumerated() {
|
||||
for (local, local_decl) in body.local_decls.iter_enumerated() {
|
||||
add_var_uses_regions(typeck, local, local_decl.ty);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use crate::borrow_check::location::LocationTable;
|
||||
use crate::borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements};
|
||||
use crate::borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap;
|
||||
use crate::borrow_check::nll::type_check::liveness::polonius;
|
||||
|
@ -38,7 +37,6 @@ pub(super) fn trace(
|
|||
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
live_locals: Vec<Local>,
|
||||
location_table: &LocationTable,
|
||||
) {
|
||||
debug!("trace()");
|
||||
|
||||
|
@ -52,7 +50,6 @@ pub(super) fn trace(
|
|||
local_use_map,
|
||||
move_data,
|
||||
drop_data: FxHashMap::default(),
|
||||
location_table,
|
||||
};
|
||||
|
||||
LivenessResults::new(cx).compute_for_all_locals(live_locals);
|
||||
|
@ -82,9 +79,6 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
|
|||
/// Index indicating where each variable is assigned, used, or
|
||||
/// dropped.
|
||||
local_use_map: &'me LocalUseMap,
|
||||
|
||||
/// Maps between a MIR Location and a LocationIndex
|
||||
location_table: &'me LocationTable,
|
||||
}
|
||||
|
||||
struct DropData<'tcx> {
|
||||
|
@ -131,12 +125,6 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
|||
for local in live_locals {
|
||||
self.reset_local_state();
|
||||
self.add_defs_for(local);
|
||||
|
||||
// FIXME: this is temporary until we can generate our own initialization
|
||||
if self.cx.typeck.borrowck_context.all_facts.is_some() {
|
||||
self.add_polonius_var_initialized_on_exit_for(local)
|
||||
}
|
||||
|
||||
self.compute_use_live_points_for(local);
|
||||
self.compute_drop_live_points_for(local);
|
||||
|
||||
|
@ -157,63 +145,6 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// WARNING: panics if self.cx.typeck.borrowck_context.all_facts != None
|
||||
//
|
||||
// FIXME: this analysis (the initialization tracking) should be
|
||||
// done in Polonius, but isn't yet.
|
||||
fn add_polonius_var_initialized_on_exit_for(&mut self, local: Local) {
|
||||
let move_path = self.cx.move_data.rev_lookup.find_local(local);
|
||||
let facts = self.cx.typeck.borrowck_context.all_facts.as_mut().unwrap();
|
||||
for block in self.cx.body.basic_blocks().indices() {
|
||||
debug!("polonius: generating initialization facts for {:?} in {:?}", local, block);
|
||||
|
||||
// iterate through the block, applying the effects of each statement
|
||||
// up to and including location, and populate `var_initialized_on_exit`
|
||||
self.cx.flow_inits.reset_to_entry_of(block);
|
||||
let start_location = Location { block, statement_index: 0 };
|
||||
self.cx.flow_inits.apply_local_effect(start_location);
|
||||
|
||||
for statement_index in 0..self.cx.body[block].statements.len() {
|
||||
let current_location = Location { block, statement_index };
|
||||
|
||||
self.cx.flow_inits.reconstruct_statement_effect(current_location);
|
||||
|
||||
// statement has not yet taken effect:
|
||||
if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
|
||||
facts
|
||||
.var_initialized_on_exit
|
||||
.push((local, self.cx.location_table.start_index(current_location)));
|
||||
}
|
||||
|
||||
// statement has now taken effect
|
||||
self.cx.flow_inits.apply_local_effect(current_location);
|
||||
|
||||
if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
|
||||
facts
|
||||
.var_initialized_on_exit
|
||||
.push((local, self.cx.location_table.mid_index(current_location)));
|
||||
}
|
||||
}
|
||||
|
||||
let terminator_location = self.cx.body.terminator_loc(block);
|
||||
|
||||
if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
|
||||
facts
|
||||
.var_initialized_on_exit
|
||||
.push((local, self.cx.location_table.start_index(terminator_location)));
|
||||
}
|
||||
|
||||
// apply the effects of the terminator and push it if needed
|
||||
self.cx.flow_inits.reset_to_exit_of(block);
|
||||
|
||||
if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
|
||||
facts
|
||||
.var_initialized_on_exit
|
||||
.push((local, self.cx.location_table.mid_index(terminator_location)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear the value of fields that are "per local variable".
|
||||
fn reset_local_state(&mut self) {
|
||||
self.defs.clear();
|
||||
|
@ -273,11 +204,6 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
|||
debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,);
|
||||
|
||||
if self.cx.initialized_at_terminator(location.block, mpi) {
|
||||
// FIXME: this analysis (the initialization tracking) should be
|
||||
// done in Polonius, but isn't yet.
|
||||
if let Some(facts) = self.cx.typeck.borrowck_context.all_facts {
|
||||
facts.var_drop_used.push((local, self.cx.location_table.mid_index(location)));
|
||||
}
|
||||
if self.drop_live_at.insert(drop_point) {
|
||||
self.drop_locations.push(location);
|
||||
self.stack.push(drop_point);
|
||||
|
@ -468,13 +394,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
|||
) {
|
||||
debug!("add_use_live_facts_for(value={:?})", value);
|
||||
|
||||
Self::make_all_regions_live(
|
||||
self.elements,
|
||||
&mut self.typeck,
|
||||
value,
|
||||
live_at,
|
||||
self.location_table,
|
||||
)
|
||||
Self::make_all_regions_live(self.elements, &mut self.typeck, value, live_at)
|
||||
}
|
||||
|
||||
/// Some variable with type `live_ty` is "drop live" at `location`
|
||||
|
@ -525,13 +445,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
|||
// All things in the `outlives` array may be touched by
|
||||
// the destructor and must be live at this point.
|
||||
for &kind in &drop_data.dropck_result.kinds {
|
||||
Self::make_all_regions_live(
|
||||
self.elements,
|
||||
&mut self.typeck,
|
||||
kind,
|
||||
live_at,
|
||||
self.location_table,
|
||||
);
|
||||
Self::make_all_regions_live(self.elements, &mut self.typeck, kind, live_at);
|
||||
|
||||
polonius::add_var_drops_regions(&mut self.typeck, dropped_local, &kind);
|
||||
}
|
||||
|
@ -542,7 +456,6 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
|||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
value: impl TypeFoldable<'tcx>,
|
||||
live_at: &HybridBitSet<PointIndex>,
|
||||
location_table: &LocationTable,
|
||||
) {
|
||||
debug!("make_all_regions_live(value={:?})", value);
|
||||
debug!(
|
||||
|
@ -559,15 +472,6 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
|
|||
.constraints
|
||||
.liveness_constraints
|
||||
.add_elements(live_region_vid, live_at);
|
||||
|
||||
// FIXME: remove this when we can generate our own region-live-at reliably
|
||||
if let Some(facts) = typeck.borrowck_context.all_facts {
|
||||
for point in live_at.iter() {
|
||||
let loc = elements.to_location(point);
|
||||
facts.region_live_at.push((live_region_vid, location_table.start_index(loc)));
|
||||
facts.region_live_at.push((live_region_vid, location_table.mid_index(loc)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::borrow_check::places_conflict;
|
|||
use crate::borrow_check::AccessDepth;
|
||||
use crate::dataflow::indexes::BorrowIndex;
|
||||
use rustc::mir::{BasicBlock, Location, Body, Place, PlaceBase};
|
||||
use rustc::mir::{ProjectionElem, BorrowKind};
|
||||
use rustc::mir::BorrowKind;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc_data_structures::graph::dominators::Dominators;
|
||||
|
||||
|
@ -133,20 +133,11 @@ pub(super) fn is_active<'tcx>(
|
|||
/// Determines if a given borrow is borrowing local data
|
||||
/// This is called for all Yield statements on movable generators
|
||||
pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
|
||||
place.iterate(|place_base, place_projection| {
|
||||
match place_base {
|
||||
PlaceBase::Static(..) => return false,
|
||||
PlaceBase::Local(..) => {},
|
||||
}
|
||||
match place.base {
|
||||
PlaceBase::Static(_) => false,
|
||||
|
||||
for proj in place_projection {
|
||||
// Reborrow of already borrowed data is ignored
|
||||
// Any errors will be caught on the initial borrow
|
||||
if proj.elem == ProjectionElem::Deref {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
// Reborrow of already borrowed data is ignored
|
||||
// Any errors will be caught on the initial borrow
|
||||
PlaceBase::Local(_) => !place.is_indirect(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,19 +93,10 @@ struct BorrowedLocalsVisitor<'gk> {
|
|||
}
|
||||
|
||||
fn find_local(place: &Place<'_>) -> Option<Local> {
|
||||
place.iterate(|place_base, place_projection| {
|
||||
for proj in place_projection {
|
||||
if proj.elem == ProjectionElem::Deref {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
if let PlaceBase::Local(local) = place_base {
|
||||
Some(*local)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
match place.base {
|
||||
PlaceBase::Local(local) if !place.is_indirect() => Some(local),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for BorrowedLocalsVisitor<'_> {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
//! `a[x]` would still overlap them both. But that is not this
|
||||
//! representation does today.)
|
||||
|
||||
use rustc::mir::{Local, PlaceElem, Operand, ProjectionElem};
|
||||
use rustc::mir::{Local, Operand, PlaceElem, ProjectionElem};
|
||||
use rustc::ty::Ty;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
|
@ -26,36 +26,36 @@ pub trait Lift {
|
|||
}
|
||||
impl<'tcx> Lift for Operand<'tcx> {
|
||||
type Abstract = AbstractOperand;
|
||||
fn lift(&self) -> Self::Abstract { AbstractOperand }
|
||||
fn lift(&self) -> Self::Abstract {
|
||||
AbstractOperand
|
||||
}
|
||||
}
|
||||
impl Lift for Local {
|
||||
type Abstract = AbstractOperand;
|
||||
fn lift(&self) -> Self::Abstract { AbstractOperand }
|
||||
fn lift(&self) -> Self::Abstract {
|
||||
AbstractOperand
|
||||
}
|
||||
}
|
||||
impl<'tcx> Lift for Ty<'tcx> {
|
||||
type Abstract = AbstractType;
|
||||
fn lift(&self) -> Self::Abstract { AbstractType }
|
||||
fn lift(&self) -> Self::Abstract {
|
||||
AbstractType
|
||||
}
|
||||
}
|
||||
impl<'tcx> Lift for PlaceElem<'tcx> {
|
||||
type Abstract = AbstractElem;
|
||||
fn lift(&self) -> Self::Abstract {
|
||||
match *self {
|
||||
ProjectionElem::Deref =>
|
||||
ProjectionElem::Deref,
|
||||
ProjectionElem::Field(ref f, ty) =>
|
||||
ProjectionElem::Field(f.clone(), ty.lift()),
|
||||
ProjectionElem::Index(ref i) =>
|
||||
ProjectionElem::Index(i.lift()),
|
||||
ProjectionElem::Subslice {from, to} =>
|
||||
ProjectionElem::Subslice { from: from, to: to },
|
||||
ProjectionElem::ConstantIndex {offset,min_length,from_end} =>
|
||||
ProjectionElem::ConstantIndex {
|
||||
offset,
|
||||
min_length,
|
||||
from_end,
|
||||
},
|
||||
ProjectionElem::Downcast(a, u) =>
|
||||
ProjectionElem::Downcast(a, u.clone()),
|
||||
ProjectionElem::Deref => ProjectionElem::Deref,
|
||||
ProjectionElem::Field(ref f, ty) => ProjectionElem::Field(f.clone(), ty.lift()),
|
||||
ProjectionElem::Index(ref i) => ProjectionElem::Index(i.lift()),
|
||||
ProjectionElem::Subslice { from, to } => {
|
||||
ProjectionElem::Subslice { from: from, to: to }
|
||||
}
|
||||
ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
|
||||
ProjectionElem::ConstantIndex { offset, min_length, from_end }
|
||||
}
|
||||
ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::tcx::RvalueInitializationState;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::mem;
|
||||
|
||||
use super::abs_domain::Lift;
|
||||
use super::{LocationMap, MoveData, MovePath, MovePathLookup, MovePathIndex, MoveOut, MoveOutIndex};
|
||||
use super::{MoveError, InitIndex, Init, InitLocation, LookupResult, InitKind};
|
||||
use super::IllegalMoveOriginKind::*;
|
||||
use super::{Init, InitIndex, InitKind, InitLocation, LookupResult, MoveError};
|
||||
use super::{
|
||||
LocationMap, MoveData, MoveOut, MoveOutIndex, MovePath, MovePathIndex, MovePathLookup,
|
||||
};
|
||||
|
||||
struct MoveDataBuilder<'a, 'tcx> {
|
||||
body: &'a Body<'tcx>,
|
||||
|
@ -33,15 +35,19 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
|||
moves: IndexVec::new(),
|
||||
loc_map: LocationMap::new(body),
|
||||
rev_lookup: MovePathLookup {
|
||||
locals: body.local_decls.indices().map(|i| {
|
||||
Self::new_move_path(
|
||||
&mut move_paths,
|
||||
&mut path_map,
|
||||
&mut init_path_map,
|
||||
None,
|
||||
Place::from(i),
|
||||
)
|
||||
}).collect(),
|
||||
locals: body
|
||||
.local_decls
|
||||
.indices()
|
||||
.map(|i| {
|
||||
Self::new_move_path(
|
||||
&mut move_paths,
|
||||
&mut path_map,
|
||||
&mut init_path_map,
|
||||
None,
|
||||
Place::from(i),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
projections: Default::default(),
|
||||
},
|
||||
move_paths,
|
||||
|
@ -49,27 +55,22 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
|||
inits: IndexVec::new(),
|
||||
init_loc_map: LocationMap::new(body),
|
||||
init_path_map,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn new_move_path(move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
|
||||
path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
|
||||
init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
|
||||
parent: Option<MovePathIndex>,
|
||||
place: Place<'tcx>)
|
||||
-> MovePathIndex
|
||||
{
|
||||
let move_path = move_paths.push(MovePath {
|
||||
next_sibling: None,
|
||||
first_child: None,
|
||||
parent,
|
||||
place,
|
||||
});
|
||||
fn new_move_path(
|
||||
move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
|
||||
path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
|
||||
init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
|
||||
parent: Option<MovePathIndex>,
|
||||
place: Place<'tcx>,
|
||||
) -> MovePathIndex {
|
||||
let move_path =
|
||||
move_paths.push(MovePath { next_sibling: None, first_child: None, parent, place });
|
||||
|
||||
if let Some(parent) = parent {
|
||||
let next_sibling =
|
||||
mem::replace(&mut move_paths[parent].first_child, Some(move_path));
|
||||
let next_sibling = mem::replace(&mut move_paths[parent].first_child, Some(move_path));
|
||||
move_paths[move_path].next_sibling = next_sibling;
|
||||
}
|
||||
|
||||
|
@ -91,9 +92,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
/// problematic for borrowck.
|
||||
///
|
||||
/// Maybe we should have separate "borrowck" and "moveck" modes.
|
||||
fn move_path_for(&mut self, place: &Place<'tcx>)
|
||||
-> Result<MovePathIndex, MoveError<'tcx>>
|
||||
{
|
||||
fn move_path_for(&mut self, place: &Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
|
||||
debug!("lookup({:?})", place);
|
||||
place.iterate(|place_base, place_projection| {
|
||||
let mut base = match place_base {
|
||||
|
@ -108,39 +107,46 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
let tcx = self.builder.tcx;
|
||||
let place_ty = Place::ty_from(place_base, &proj.base, body, tcx).ty;
|
||||
match place_ty.sty {
|
||||
ty::Ref(..) | ty::RawPtr(..) =>
|
||||
ty::Ref(..) | ty::RawPtr(..) => {
|
||||
return Err(MoveError::cannot_move_out_of(
|
||||
self.loc,
|
||||
BorrowedContent {
|
||||
target_place: Place {
|
||||
base: place_base.clone(),
|
||||
projection: Some(Box::new(proj.clone())),
|
||||
}
|
||||
})),
|
||||
ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() =>
|
||||
return Err(MoveError::cannot_move_out_of(self.loc,
|
||||
InteriorOfTypeWithDestructor {
|
||||
container_ty: place_ty
|
||||
})),
|
||||
},
|
||||
},
|
||||
));
|
||||
}
|
||||
ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
|
||||
return Err(MoveError::cannot_move_out_of(
|
||||
self.loc,
|
||||
InteriorOfTypeWithDestructor { container_ty: place_ty },
|
||||
));
|
||||
}
|
||||
// move out of union - always move the entire union
|
||||
ty::Adt(adt, _) if adt.is_union() =>
|
||||
return Err(MoveError::UnionMove { path: base }),
|
||||
ty::Slice(_) =>
|
||||
ty::Adt(adt, _) if adt.is_union() => {
|
||||
return Err(MoveError::UnionMove { path: base });
|
||||
}
|
||||
ty::Slice(_) => {
|
||||
return Err(MoveError::cannot_move_out_of(
|
||||
self.loc,
|
||||
InteriorOfSliceOrArray {
|
||||
ty: place_ty, is_index: match proj.elem {
|
||||
ty: place_ty,
|
||||
is_index: match proj.elem {
|
||||
ProjectionElem::Index(..) => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
},
|
||||
})),
|
||||
},
|
||||
));
|
||||
}
|
||||
ty::Array(..) => match proj.elem {
|
||||
ProjectionElem::Index(..) =>
|
||||
ProjectionElem::Index(..) => {
|
||||
return Err(MoveError::cannot_move_out_of(
|
||||
self.loc,
|
||||
InteriorOfSliceOrArray {
|
||||
ty: place_ty, is_index: true
|
||||
})),
|
||||
InteriorOfSliceOrArray { ty: place_ty, is_index: true },
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
// FIXME: still badly broken
|
||||
}
|
||||
|
@ -186,7 +192,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
|
||||
impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
||||
fn finalize(
|
||||
self
|
||||
self,
|
||||
) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<(Place<'tcx>, MoveError<'tcx>)>)> {
|
||||
debug!("{}", {
|
||||
debug!("moves for {:?}:", self.body.span);
|
||||
|
@ -200,11 +206,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
|||
"done dumping moves"
|
||||
});
|
||||
|
||||
if !self.errors.is_empty() {
|
||||
Err((self.data, self.errors))
|
||||
} else {
|
||||
Ok(self.data)
|
||||
}
|
||||
if !self.errors.is_empty() { Err((self.data, self.errors)) } else { Ok(self.data) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,10 +224,7 @@ pub(super) fn gather_moves<'tcx>(
|
|||
builder.gather_statement(source, stmt);
|
||||
}
|
||||
|
||||
let terminator_loc = Location {
|
||||
block: bb,
|
||||
statement_index: block.statements.len()
|
||||
};
|
||||
let terminator_loc = Location { block: bb, statement_index: block.statements.len() };
|
||||
builder.gather_terminator(terminator_loc, block.terminator());
|
||||
}
|
||||
|
||||
|
@ -238,11 +237,12 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
|||
let path = self.data.rev_lookup.locals[arg];
|
||||
|
||||
let init = self.data.inits.push(Init {
|
||||
path, kind: InitKind::Deep, location: InitLocation::Argument(arg),
|
||||
path,
|
||||
kind: InitKind::Deep,
|
||||
location: InitLocation::Argument(arg),
|
||||
});
|
||||
|
||||
debug!("gather_args: adding init {:?} of {:?} for argument {:?}",
|
||||
init, path, arg);
|
||||
debug!("gather_args: adding init {:?} of {:?} for argument {:?}", init, path, arg);
|
||||
|
||||
self.data.init_path_map[path].push(init);
|
||||
}
|
||||
|
@ -297,26 +297,26 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
StatementKind::StorageDead(local) => {
|
||||
self.gather_move(&Place::from(local));
|
||||
}
|
||||
StatementKind::SetDiscriminant{ .. } => {
|
||||
span_bug!(stmt.source_info.span,
|
||||
"SetDiscriminant should not exist during borrowck");
|
||||
StatementKind::SetDiscriminant { .. } => {
|
||||
span_bug!(
|
||||
stmt.source_info.span,
|
||||
"SetDiscriminant should not exist during borrowck"
|
||||
);
|
||||
}
|
||||
StatementKind::Retag { .. } |
|
||||
StatementKind::AscribeUserType(..) |
|
||||
StatementKind::Nop => {}
|
||||
StatementKind::Retag { .. }
|
||||
| StatementKind::AscribeUserType(..)
|
||||
| StatementKind::Nop => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn gather_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
|
||||
match *rvalue {
|
||||
Rvalue::Use(ref operand) |
|
||||
Rvalue::Repeat(ref operand, _) |
|
||||
Rvalue::Cast(_, ref operand, _) |
|
||||
Rvalue::UnaryOp(_, ref operand) => {
|
||||
self.gather_operand(operand)
|
||||
}
|
||||
Rvalue::BinaryOp(ref _binop, ref lhs, ref rhs) |
|
||||
Rvalue::CheckedBinaryOp(ref _binop, ref lhs, ref rhs) => {
|
||||
Rvalue::Use(ref operand)
|
||||
| Rvalue::Repeat(ref operand, _)
|
||||
| Rvalue::Cast(_, ref operand, _)
|
||||
| Rvalue::UnaryOp(_, ref operand) => self.gather_operand(operand),
|
||||
Rvalue::BinaryOp(ref _binop, ref lhs, ref rhs)
|
||||
| Rvalue::CheckedBinaryOp(ref _binop, ref lhs, ref rhs) => {
|
||||
self.gather_operand(lhs);
|
||||
self.gather_operand(rhs);
|
||||
}
|
||||
|
@ -325,11 +325,11 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
self.gather_operand(operand);
|
||||
}
|
||||
}
|
||||
Rvalue::Ref(..) |
|
||||
Rvalue::Discriminant(..) |
|
||||
Rvalue::Len(..) |
|
||||
Rvalue::NullaryOp(NullOp::SizeOf, _) |
|
||||
Rvalue::NullaryOp(NullOp::Box, _) => {
|
||||
Rvalue::Ref(..)
|
||||
| Rvalue::Discriminant(..)
|
||||
| Rvalue::Len(..)
|
||||
| Rvalue::NullaryOp(NullOp::SizeOf, _)
|
||||
| Rvalue::NullaryOp(NullOp::Box, _) => {
|
||||
// This returns an rvalue with uninitialized contents. We can't
|
||||
// move out of it here because it is an rvalue - assignments always
|
||||
// completely initialize their place.
|
||||
|
@ -346,13 +346,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
|
||||
fn gather_terminator(&mut self, term: &Terminator<'tcx>) {
|
||||
match term.kind {
|
||||
TerminatorKind::Goto { target: _ } |
|
||||
TerminatorKind::Resume |
|
||||
TerminatorKind::Abort |
|
||||
TerminatorKind::GeneratorDrop |
|
||||
TerminatorKind::FalseEdges { .. } |
|
||||
TerminatorKind::FalseUnwind { .. } |
|
||||
TerminatorKind::Unreachable => { }
|
||||
TerminatorKind::Goto { target: _ }
|
||||
| TerminatorKind::Resume
|
||||
| TerminatorKind::Abort
|
||||
| TerminatorKind::GeneratorDrop
|
||||
| TerminatorKind::FalseEdges { .. }
|
||||
| TerminatorKind::FalseUnwind { .. }
|
||||
| TerminatorKind::Unreachable => {}
|
||||
|
||||
TerminatorKind::Return => {
|
||||
self.gather_move(&Place::RETURN_PLACE);
|
||||
|
@ -399,9 +399,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
|
||||
fn gather_operand(&mut self, operand: &Operand<'tcx>) {
|
||||
match *operand {
|
||||
Operand::Constant(..) |
|
||||
Operand::Copy(..) => {} // not-a-move
|
||||
Operand::Move(ref place) => { // a move
|
||||
Operand::Constant(..) | Operand::Copy(..) => {} // not-a-move
|
||||
Operand::Move(ref place) => {
|
||||
// a move
|
||||
self.gather_move(place);
|
||||
}
|
||||
}
|
||||
|
@ -419,8 +419,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
};
|
||||
let move_out = self.builder.data.moves.push(MoveOut { path: path, source: self.loc });
|
||||
|
||||
debug!("gather_move({:?}, {:?}): adding move {:?} of {:?}",
|
||||
self.loc, place, move_out, path);
|
||||
debug!(
|
||||
"gather_move({:?}, {:?}): adding move {:?} of {:?}",
|
||||
self.loc, place, move_out, path
|
||||
);
|
||||
|
||||
self.builder.data.path_map[path].push(move_out);
|
||||
self.builder.data.loc_map[self.loc].push(move_out);
|
||||
|
@ -452,8 +454,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
|||
kind,
|
||||
});
|
||||
|
||||
debug!("gather_init({:?}, {:?}): adding init {:?} of {:?}",
|
||||
self.loc, place, init, path);
|
||||
debug!(
|
||||
"gather_init({:?}, {:?}): adding init {:?} of {:?}",
|
||||
self.loc, place, init, path
|
||||
);
|
||||
|
||||
self.builder.data.init_path_map[path].push(init);
|
||||
self.builder.data.init_loc_map[self.loc].push(init);
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use rustc::ty::{Ty, TyCtxt};
|
||||
use core::slice::Iter;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::{Ty, TyCtxt};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc_data_structures::indexed_vec::{Enumerated, Idx, IndexVec};
|
||||
use smallvec::SmallVec;
|
||||
use syntax_pos::{Span};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use std::fmt;
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
@ -137,12 +138,17 @@ impl<T> IndexMut<Location> for LocationMap<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> LocationMap<T> where T: Default + Clone {
|
||||
impl<T> LocationMap<T>
|
||||
where
|
||||
T: Default + Clone,
|
||||
{
|
||||
fn new(body: &Body<'_>) -> Self {
|
||||
LocationMap {
|
||||
map: body.basic_blocks().iter().map(|block| {
|
||||
vec![T::default(); block.statements.len()+1]
|
||||
}).collect()
|
||||
map: body
|
||||
.basic_blocks()
|
||||
.iter()
|
||||
.map(|block| vec![T::default(); block.statements.len() + 1])
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +184,6 @@ pub struct Init {
|
|||
pub kind: InitKind,
|
||||
}
|
||||
|
||||
|
||||
/// Initializations can be from an argument or from a statement. Arguments
|
||||
/// do not have locations, in those cases the `Local` is kept..
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -224,7 +229,7 @@ pub struct MovePathLookup {
|
|||
/// subsequent search so that it is solely relative to that
|
||||
/// base-place). For the remaining lookup, we map the projection
|
||||
/// elem to the associated MovePathIndex.
|
||||
projections: FxHashMap<(MovePathIndex, AbstractElem), MovePathIndex>
|
||||
projections: FxHashMap<(MovePathIndex, AbstractElem), MovePathIndex>,
|
||||
}
|
||||
|
||||
mod builder;
|
||||
|
@ -232,7 +237,7 @@ mod builder;
|
|||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum LookupResult {
|
||||
Exact(MovePathIndex),
|
||||
Parent(Option<MovePathIndex>)
|
||||
Parent(Option<MovePathIndex>),
|
||||
}
|
||||
|
||||
impl MovePathLookup {
|
||||
|
@ -262,6 +267,12 @@ impl MovePathLookup {
|
|||
pub fn find_local(&self, local: Local) -> MovePathIndex {
|
||||
self.locals[local]
|
||||
}
|
||||
|
||||
/// An enumerated iterator of `local`s and their associated
|
||||
/// `MovePathIndex`es.
|
||||
pub fn iter_locals_enumerated(&self) -> Enumerated<Local, Iter<'_, MovePathIndex>> {
|
||||
self.locals.iter_enumerated()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -289,7 +300,7 @@ pub(crate) enum IllegalMoveOriginKind<'tcx> {
|
|||
InteriorOfTypeWithDestructor { container_ty: Ty<'tcx> },
|
||||
|
||||
/// Illegal move due to attempt to move out of a slice or array.
|
||||
InteriorOfSliceOrArray { ty: Ty<'tcx>, is_index: bool, },
|
||||
InteriorOfSliceOrArray { ty: Ty<'tcx>, is_index: bool },
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -318,11 +329,15 @@ impl<'tcx> MoveData<'tcx> {
|
|||
pub fn base_local(&self, mut mpi: MovePathIndex) -> Option<Local> {
|
||||
loop {
|
||||
let path = &self.move_paths[mpi];
|
||||
if let Place {
|
||||
base: PlaceBase::Local(l),
|
||||
projection: None,
|
||||
} = path.place { return Some(l); }
|
||||
if let Some(parent) = path.parent { mpi = parent; continue } else { return None }
|
||||
if let Place { base: PlaceBase::Local(l), projection: None } = path.place {
|
||||
return Some(l);
|
||||
}
|
||||
if let Some(parent) = path.parent {
|
||||
mpi = parent;
|
||||
continue;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -585,8 +585,9 @@ where
|
|||
use rustc::mir::StaticKind;
|
||||
|
||||
Ok(match place_static.kind {
|
||||
StaticKind::Promoted(promoted, _) => {
|
||||
let instance = self.frame().instance;
|
||||
StaticKind::Promoted(promoted, promoted_substs) => {
|
||||
let substs = self.subst_from_frame_and_normalize_erasing_regions(promoted_substs);
|
||||
let instance = ty::Instance::new(place_static.def_id, substs);
|
||||
self.const_eval_raw(GlobalId {
|
||||
instance,
|
||||
promoted: Some(promoted),
|
||||
|
|
|
@ -777,7 +777,7 @@ where
|
|||
debug!("CodegenUnit {}:", cgu.name());
|
||||
|
||||
for (mono_item, linkage) in cgu.items() {
|
||||
let symbol_name = mono_item.symbol_name(tcx).as_str();
|
||||
let symbol_name = mono_item.symbol_name(tcx).name.as_str();
|
||||
let symbol_hash_start = symbol_name.rfind('h');
|
||||
let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..])
|
||||
.unwrap_or("<no hash>");
|
||||
|
|
|
@ -405,13 +405,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
}
|
||||
|
||||
let arg = self.eval_operand(arg, source_info)?;
|
||||
let oflo_check = self.tcx.sess.overflow_checks();
|
||||
let val = self.use_ecx(source_info, |this| {
|
||||
let prim = this.ecx.read_immediate(arg)?;
|
||||
match op {
|
||||
UnOp::Neg => {
|
||||
// Need to do overflow check here: For actual CTFE, MIR
|
||||
// generation emits code that does this before calling the op.
|
||||
if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
|
||||
// We check overflow in debug mode already
|
||||
// so should only check in release mode.
|
||||
if !oflo_check
|
||||
&& prim.layout.ty.is_signed()
|
||||
&& prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
|
||||
throw_panic!(OverflowNeg)
|
||||
}
|
||||
}
|
||||
|
@ -485,7 +488,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
Scalar::from_bool(overflow).into(),
|
||||
)
|
||||
} else {
|
||||
if overflow {
|
||||
// We check overflow in debug mode already
|
||||
// so should only check in release mode.
|
||||
if !self.tcx.sess.overflow_checks() && overflow {
|
||||
let err = err_panic!(Overflow(op)).into();
|
||||
let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
|
||||
return None;
|
||||
|
|
26
src/librustc_target/spec/linux_kernel_base.rs
Normal file
26
src/librustc_target/spec/linux_kernel_base.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, RelroLevel, TargetOptions};
|
||||
use std::default::Default;
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
let mut pre_link_args = LinkArgs::new();
|
||||
pre_link_args.insert(
|
||||
LinkerFlavor::Gcc,
|
||||
vec!["-Wl,--as-needed".to_string(), "-Wl,-z,noexecstack".to_string()],
|
||||
);
|
||||
|
||||
TargetOptions {
|
||||
disable_redzone: true,
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
stack_probes: true,
|
||||
eliminate_frame_pointer: false,
|
||||
linker_is_gnu: true,
|
||||
position_independent_executables: true,
|
||||
needs_plt: true,
|
||||
relro_level: RelroLevel::Full,
|
||||
relocation_model: "static".to_string(),
|
||||
target_family: Some("unix".to_string()),
|
||||
pre_link_args,
|
||||
|
||||
..Default::default()
|
||||
}
|
||||
}
|
|
@ -53,6 +53,7 @@ mod freebsd_base;
|
|||
mod haiku_base;
|
||||
mod hermit_base;
|
||||
mod linux_base;
|
||||
mod linux_kernel_base;
|
||||
mod linux_musl_base;
|
||||
mod openbsd_base;
|
||||
mod netbsd_base;
|
||||
|
@ -386,6 +387,8 @@ supported_targets! {
|
|||
("thumbv7neon-linux-androideabi", thumbv7neon_linux_androideabi),
|
||||
("aarch64-linux-android", aarch64_linux_android),
|
||||
|
||||
("x86_64-linux-kernel", x86_64_linux_kernel),
|
||||
|
||||
("aarch64-unknown-freebsd", aarch64_unknown_freebsd),
|
||||
("armv6-unknown-freebsd", armv6_unknown_freebsd),
|
||||
("armv7-unknown-freebsd", armv7_unknown_freebsd),
|
||||
|
|
31
src/librustc_target/spec/x86_64_linux_kernel.rs
Normal file
31
src/librustc_target/spec/x86_64_linux_kernel.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
// This defines the amd64 target for the Linux Kernel. See the linux-kernel-base module for
|
||||
// generic Linux kernel options.
|
||||
|
||||
use crate::spec::{LinkerFlavor, Target, TargetResult};
|
||||
|
||||
pub fn target() -> TargetResult {
|
||||
let mut base = super::linux_kernel_base::opts();
|
||||
base.cpu = "x86-64".to_string();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.features =
|
||||
"-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float"
|
||||
.to_string();
|
||||
base.code_model = Some("kernel".to_string());
|
||||
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
|
||||
|
||||
Ok(Target {
|
||||
// FIXME: Some dispute, the linux-on-clang folks think this should use "Linux"
|
||||
llvm_target: "x86_64-elf".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_pointer_width: "64".to_string(),
|
||||
target_c_int_width: "32".to_string(),
|
||||
data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
|
||||
target_os: "none".to_string(),
|
||||
target_env: "gnu".to_string(),
|
||||
target_vendor: "unknown".to_string(),
|
||||
arch: "x86_64".to_string(),
|
||||
linker_flavor: LinkerFlavor::Gcc,
|
||||
|
||||
options: base,
|
||||
})
|
||||
}
|
|
@ -19,7 +19,7 @@ use crate::astconv::AstConv as _;
|
|||
|
||||
use errors::{Applicability, DiagnosticBuilder};
|
||||
use syntax::ast;
|
||||
use syntax::symbol::{Symbol, LocalInternedString, kw, sym};
|
||||
use syntax::symbol::{Symbol, kw, sym};
|
||||
use syntax::source_map::Span;
|
||||
use syntax::util::lev_distance::find_best_match_for_name;
|
||||
use rustc::hir;
|
||||
|
@ -1244,7 +1244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
_ => {
|
||||
// prevent all specified fields from being suggested
|
||||
let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str());
|
||||
let skip_fields = skip_fields.iter().map(|ref x| x.ident.name);
|
||||
if let Some(field_name) = Self::suggest_field_name(
|
||||
variant,
|
||||
&field.ident.as_str(),
|
||||
|
@ -1288,11 +1288,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// Return an hint about the closest match in field names
|
||||
fn suggest_field_name(variant: &'tcx ty::VariantDef,
|
||||
field: &str,
|
||||
skip: Vec<LocalInternedString>)
|
||||
skip: Vec<Symbol>)
|
||||
-> Option<Symbol> {
|
||||
let names = variant.fields.iter().filter_map(|field| {
|
||||
// ignore already set fields and private fields from non-local crates
|
||||
if skip.iter().any(|x| *x == field.ident.as_str()) ||
|
||||
if skip.iter().any(|&x| x == field.ident.name) ||
|
||||
(!variant.def_id.is_local() && field.vis != Visibility::Public)
|
||||
{
|
||||
None
|
||||
|
|
|
@ -1420,8 +1420,8 @@ fn check_opaque_for_cycles<'tcx>(
|
|||
tcx.sess, span, E0733,
|
||||
"recursion in an `async fn` requires boxing",
|
||||
)
|
||||
.span_label(span, "an `async fn` cannot invoke itself directly")
|
||||
.note("a recursive `async fn` must be rewritten to return a boxed future.")
|
||||
.span_label(span, "recursive `async fn`")
|
||||
.note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
|
||||
.emit();
|
||||
} else {
|
||||
let mut err = struct_span_err!(
|
||||
|
@ -3687,6 +3687,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
|
||||
/// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
|
||||
/// when given code like the following:
|
||||
/// ```text
|
||||
/// if false { return 0i32; } else { 1u32 }
|
||||
/// // ^^^^ point at this instead of the whole `if` expression
|
||||
/// ```
|
||||
fn get_expr_coercion_span(&self, expr: &hir::Expr) -> syntax_pos::Span {
|
||||
if let hir::ExprKind::Match(_, arms, _) = &expr.node {
|
||||
let arm_spans: Vec<Span> = arms.iter().filter_map(|arm| {
|
||||
self.in_progress_tables
|
||||
.and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
|
||||
.and_then(|arm_ty| {
|
||||
if arm_ty.is_never() {
|
||||
None
|
||||
} else {
|
||||
Some(match &arm.body.node {
|
||||
// Point at the tail expression when possible.
|
||||
hir::ExprKind::Block(block, _) => block.expr
|
||||
.as_ref()
|
||||
.map(|e| e.span)
|
||||
.unwrap_or(block.span),
|
||||
_ => arm.body.span,
|
||||
})
|
||||
}
|
||||
})
|
||||
}).collect();
|
||||
if arm_spans.len() == 1 {
|
||||
return arm_spans[0];
|
||||
}
|
||||
}
|
||||
expr.span
|
||||
}
|
||||
|
||||
fn check_block_with_expected(
|
||||
&self,
|
||||
blk: &'tcx hir::Block,
|
||||
|
@ -3746,12 +3780,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let coerce = ctxt.coerce.as_mut().unwrap();
|
||||
if let Some(tail_expr_ty) = tail_expr_ty {
|
||||
let tail_expr = tail_expr.unwrap();
|
||||
let cause = self.cause(tail_expr.span,
|
||||
ObligationCauseCode::BlockTailExpression(blk.hir_id));
|
||||
coerce.coerce(self,
|
||||
&cause,
|
||||
tail_expr,
|
||||
tail_expr_ty);
|
||||
let span = self.get_expr_coercion_span(tail_expr);
|
||||
let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
|
||||
coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
|
||||
} else {
|
||||
// Subtle: if there is no explicit tail expression,
|
||||
// that is typically equivalent to a tail expression
|
||||
|
|
|
@ -762,19 +762,19 @@ fn check_opaque_types<'fcx, 'tcx>(
|
|||
substituted_predicates
|
||||
}
|
||||
|
||||
const HELP_FOR_SELF_TYPE: &str =
|
||||
"consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
|
||||
`self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
|
||||
of the previous types except `Self`)";
|
||||
|
||||
fn check_method_receiver<'fcx, 'tcx>(
|
||||
fcx: &FnCtxt<'fcx, 'tcx>,
|
||||
method_sig: &hir::MethodSig,
|
||||
method: &ty::AssocItem,
|
||||
self_ty: Ty<'tcx>,
|
||||
) {
|
||||
const HELP_FOR_SELF_TYPE: &str =
|
||||
"consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
|
||||
`self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
|
||||
of the previous types except `Self`)";
|
||||
// Check that the method has a valid receiver type, given the type `Self`.
|
||||
debug!("check_method_receiver({:?}, self_ty={:?})",
|
||||
method, self_ty);
|
||||
debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty);
|
||||
|
||||
if !method.method_has_self_argument {
|
||||
return;
|
||||
|
@ -805,12 +805,7 @@ fn check_method_receiver<'fcx, 'tcx>(
|
|||
if fcx.tcx.features().arbitrary_self_types {
|
||||
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
|
||||
// Report error; `arbitrary_self_types` was enabled.
|
||||
fcx.tcx.sess.diagnostic().mut_span_err(
|
||||
span, &format!("invalid method receiver type: {:?}", receiver_ty)
|
||||
).note("type of `self` must be `Self` or a type that dereferences to it")
|
||||
.help(HELP_FOR_SELF_TYPE)
|
||||
.code(DiagnosticId::Error("E0307".into()))
|
||||
.emit();
|
||||
e0307(fcx, span, receiver_ty);
|
||||
}
|
||||
} else {
|
||||
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) {
|
||||
|
@ -830,17 +825,22 @@ fn check_method_receiver<'fcx, 'tcx>(
|
|||
.emit();
|
||||
} else {
|
||||
// Report error; would not have worked with `arbitrary_self_types`.
|
||||
fcx.tcx.sess.diagnostic().mut_span_err(
|
||||
span, &format!("invalid method receiver type: {:?}", receiver_ty)
|
||||
).note("type must be `Self` or a type that dereferences to it")
|
||||
.help(HELP_FOR_SELF_TYPE)
|
||||
.code(DiagnosticId::Error("E0307".into()))
|
||||
.emit();
|
||||
e0307(fcx, span, receiver_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn e0307(fcx: &FnCtxt<'fcx, 'tcx>, span: Span, receiver_ty: Ty<'_>) {
|
||||
fcx.tcx.sess.diagnostic().mut_span_err(
|
||||
span,
|
||||
&format!("invalid `self` parameter type: {:?}", receiver_ty)
|
||||
).note("type of `self` must be `Self` or a type that dereferences to it")
|
||||
.help(HELP_FOR_SELF_TYPE)
|
||||
.code(DiagnosticId::Error("E0307".into()))
|
||||
.emit();
|
||||
}
|
||||
|
||||
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
|
||||
/// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
|
||||
/// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
|
||||
|
|
|
@ -212,7 +212,7 @@ match string {
|
|||
E0033: r##"
|
||||
This error indicates that a pointer to a trait type cannot be implicitly
|
||||
dereferenced by a pattern. Every trait defines a type, but because the
|
||||
size of trait implementors isn't fixed, this type has no compile-time size.
|
||||
size of trait implementers isn't fixed, this type has no compile-time size.
|
||||
Therefore, all accesses to trait types must be through pointers. If you
|
||||
encounter this error you should try to avoid dereferencing the pointer.
|
||||
|
||||
|
@ -2425,6 +2425,87 @@ struct Bar<S, T> { x: Foo<S, T> }
|
|||
```
|
||||
"##,
|
||||
|
||||
E0307: r##"
|
||||
This error indicates that the `self` parameter in a method has an invalid
|
||||
"reciever type".
|
||||
|
||||
Methods take a special first parameter, of which there are three variants:
|
||||
`self`, `&self`, and `&mut self`. These are syntactic sugar for
|
||||
`self: Self`, `self: &Self`, and `self: &mut Self` respectively.
|
||||
|
||||
```
|
||||
# struct Foo;
|
||||
trait Trait {
|
||||
fn foo(&self);
|
||||
// ^^^^^ `self` here is a reference to the receiver object
|
||||
}
|
||||
|
||||
impl Trait for Foo {
|
||||
fn foo(&self) {}
|
||||
// ^^^^^ the receiver type is `&Foo`
|
||||
}
|
||||
```
|
||||
|
||||
The type `Self` acts as an alias to the type of the current trait
|
||||
implementer, or "receiver type". Besides the already mentioned `Self`,
|
||||
`&Self` and `&mut Self` valid receiver types, the following are also valid:
|
||||
`self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, and `self: Pin<P>`
|
||||
(where P is one of the previous types except `Self`). Note that `Self` can
|
||||
also be the underlying implementing type, like `Foo` in the following
|
||||
example:
|
||||
|
||||
```
|
||||
# struct Foo;
|
||||
# trait Trait {
|
||||
# fn foo(&self);
|
||||
# }
|
||||
impl Trait for Foo {
|
||||
fn foo(self: &Foo) {}
|
||||
}
|
||||
```
|
||||
|
||||
E0307 will be emitted by the compiler when using an invalid reciver type,
|
||||
like in the following example:
|
||||
|
||||
```compile_fail,E0307
|
||||
# struct Foo;
|
||||
# struct Bar;
|
||||
# trait Trait {
|
||||
# fn foo(&self);
|
||||
# }
|
||||
impl Trait for Foo {
|
||||
fn foo(self: &Bar) {}
|
||||
}
|
||||
```
|
||||
|
||||
The nightly feature [Arbintrary self types][AST] extends the accepted
|
||||
set of receiver types to also include any type that can dereference to
|
||||
`Self`:
|
||||
|
||||
```
|
||||
#![feature(arbitrary_self_types)]
|
||||
|
||||
struct Foo;
|
||||
struct Bar;
|
||||
|
||||
// Because you can dereference `Bar` into `Foo`...
|
||||
impl std::ops::Deref for Bar {
|
||||
type Target = Foo;
|
||||
|
||||
fn deref(&self) -> &Foo {
|
||||
&Foo
|
||||
}
|
||||
}
|
||||
|
||||
impl Foo {
|
||||
fn foo(self: Bar) {}
|
||||
// ^^^^^^^^^ ...it can be used as the receiver type
|
||||
}
|
||||
```
|
||||
|
||||
[AST]: https://doc.rust-lang.org/unstable-book/language-features/arbitrary-self-types.html
|
||||
"##,
|
||||
|
||||
E0321: r##"
|
||||
A cross-crate opt-out trait was implemented on something which wasn't a struct
|
||||
or enum type. Erroneous code example:
|
||||
|
@ -4851,7 +4932,6 @@ register_diagnostics! {
|
|||
// E0247,
|
||||
// E0248, // value used as a type, now reported earlier during resolution as E0412
|
||||
// E0249,
|
||||
E0307, // invalid method `self` type
|
||||
// E0319, // trait impls for defaulted traits allowed just for structs/enums
|
||||
// E0372, // coherence not object safe
|
||||
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
|
||||
|
|
|
@ -344,7 +344,7 @@ if (!DOMTokenList.prototype.remove) {
|
|||
var set_fragment = function(name) {
|
||||
if (browserSupportsHistoryApi()) {
|
||||
history.replaceState(null, null, "#" + name);
|
||||
window.hashchange();
|
||||
highlightSourceLines(null);
|
||||
} else {
|
||||
location.replace("#" + name);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ extern crate rustc_interface;
|
|||
extern crate rustc_metadata;
|
||||
extern crate rustc_target;
|
||||
extern crate rustc_typeck;
|
||||
extern crate rustc_lexer;
|
||||
extern crate serialize;
|
||||
extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
|
|
|
@ -81,7 +81,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
|
|||
// We couldn't calculate the span of the markdown block that had the error, so our
|
||||
// diagnostics are going to be a bit lacking.
|
||||
let mut diag = self.cx.sess().struct_span_warn(
|
||||
super::span_of_attrs(&item.attrs),
|
||||
super::span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
|
||||
"doc comment contains an invalid Rust code block",
|
||||
);
|
||||
|
||||
|
|
|
@ -465,7 +465,7 @@ fn resolution_failure(
|
|||
}
|
||||
};
|
||||
let attrs = &item.attrs;
|
||||
let sp = span_of_attrs(attrs);
|
||||
let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
|
||||
|
||||
let mut diag = cx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
|
||||
|
@ -517,7 +517,7 @@ fn ambiguity_error(
|
|||
}
|
||||
};
|
||||
let attrs = &item.attrs;
|
||||
let sp = span_of_attrs(attrs);
|
||||
let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
|
||||
|
||||
let mut msg = format!("`{}` is ", path_str);
|
||||
|
||||
|
|
|
@ -339,7 +339,7 @@ pub fn look_for_tests<'tcx>(
|
|||
find_testable_code(&dox, &mut tests, ErrorCodes::No);
|
||||
|
||||
if check_missing_code == true && tests.found_tests == 0 {
|
||||
let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span());
|
||||
let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span());
|
||||
let mut diag = cx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::MISSING_DOC_CODE_EXAMPLES,
|
||||
hir_id,
|
||||
|
@ -352,20 +352,23 @@ pub fn look_for_tests<'tcx>(
|
|||
let mut diag = cx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::PRIVATE_DOC_TESTS,
|
||||
hir_id,
|
||||
span_of_attrs(&item.attrs),
|
||||
span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
|
||||
"Documentation test in private item");
|
||||
diag.emit();
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a span encompassing all the given attributes.
|
||||
crate fn span_of_attrs(attrs: &clean::Attributes) -> Span {
|
||||
crate fn span_of_attrs(attrs: &clean::Attributes) -> Option<Span> {
|
||||
if attrs.doc_strings.is_empty() {
|
||||
return DUMMY_SP;
|
||||
return None;
|
||||
}
|
||||
let start = attrs.doc_strings[0].span();
|
||||
if start == DUMMY_SP {
|
||||
return None;
|
||||
}
|
||||
let end = attrs.doc_strings.last().expect("No doc strings provided").span();
|
||||
start.to(end)
|
||||
Some(start.to(end))
|
||||
}
|
||||
|
||||
/// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code.
|
||||
|
@ -391,7 +394,7 @@ crate fn source_span_for_markdown_range(
|
|||
let snippet = cx
|
||||
.sess()
|
||||
.source_map()
|
||||
.span_to_snippet(span_of_attrs(attrs))
|
||||
.span_to_snippet(span_of_attrs(attrs)?)
|
||||
.ok()?;
|
||||
|
||||
let starting_line = markdown[..md_range.start].matches('\n').count();
|
||||
|
@ -441,10 +444,8 @@ crate fn source_span_for_markdown_range(
|
|||
}
|
||||
}
|
||||
|
||||
let sp = span_of_attrs(attrs).from_inner(InnerSpan::new(
|
||||
Some(span_of_attrs(attrs)?.from_inner(InnerSpan::new(
|
||||
md_range.start + start_bytes,
|
||||
md_range.end + start_bytes + end_bytes,
|
||||
));
|
||||
|
||||
Some(sp)
|
||||
)))
|
||||
}
|
||||
|
|
|
@ -763,8 +763,8 @@ impl Tester for Collector {
|
|||
// We use these headings as test names, so it's good if
|
||||
// they're valid identifiers.
|
||||
let name = name.chars().enumerate().map(|(i, c)| {
|
||||
if (i == 0 && c.is_xid_start()) ||
|
||||
(i != 0 && c.is_xid_continue()) {
|
||||
if (i == 0 && rustc_lexer::is_id_start(c)) ||
|
||||
(i != 0 && rustc_lexer::is_id_continue(c)) {
|
||||
c
|
||||
} else {
|
||||
'_'
|
||||
|
|
|
@ -371,6 +371,14 @@ where
|
|||
loop {
|
||||
if g.len == g.buf.len() {
|
||||
unsafe {
|
||||
// FIXME(danielhenrymantilla): #42788
|
||||
//
|
||||
// - This creates a (mut) reference to a slice of
|
||||
// _uninitialized_ integers, which is **undefined behavior**
|
||||
//
|
||||
// - Only the standard library gets to soundly "ignore" this,
|
||||
// based on its privileged knowledge of unstable rustc
|
||||
// internals;
|
||||
g.buf.reserve(reservation_size(r));
|
||||
let capacity = g.buf.capacity();
|
||||
g.buf.set_len(capacity);
|
||||
|
|
|
@ -244,7 +244,6 @@
|
|||
#![feature(cfg_target_has_atomic)]
|
||||
#![feature(cfg_target_thread_local)]
|
||||
#![feature(char_error_internals)]
|
||||
#![feature(checked_duration_since)]
|
||||
#![feature(clamp)]
|
||||
#![feature(compiler_builtins_lib)]
|
||||
#![feature(concat_idents)]
|
||||
|
|
|
@ -27,8 +27,7 @@ impl Condvar {
|
|||
|
||||
pub unsafe fn wait(&self, mutex: &Mutex) {
|
||||
let guard = self.inner.lock();
|
||||
mutex.unlock();
|
||||
WaitQueue::wait(guard);
|
||||
WaitQueue::wait(guard, || mutex.unlock());
|
||||
mutex.lock()
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ impl Mutex {
|
|||
let mut guard = self.inner.lock();
|
||||
if *guard.lock_var() {
|
||||
// Another thread has the lock, wait
|
||||
WaitQueue::wait(guard)
|
||||
WaitQueue::wait(guard, ||{})
|
||||
// Another thread has passed the lock to us
|
||||
} else {
|
||||
// We are just now obtaining the lock
|
||||
|
@ -83,7 +83,7 @@ impl ReentrantMutex {
|
|||
match guard.lock_var().owner {
|
||||
Some(tcs) if tcs != thread::current() => {
|
||||
// Another thread has the lock, wait
|
||||
WaitQueue::wait(guard);
|
||||
WaitQueue::wait(guard, ||{});
|
||||
// Another thread has passed the lock to us
|
||||
},
|
||||
_ => {
|
||||
|
|
|
@ -31,7 +31,7 @@ impl RWLock {
|
|||
if *wguard.lock_var() || !wguard.queue_empty() {
|
||||
// Another thread has or is waiting for the write lock, wait
|
||||
drop(wguard);
|
||||
WaitQueue::wait(rguard);
|
||||
WaitQueue::wait(rguard, ||{});
|
||||
// Another thread has passed the lock to us
|
||||
} else {
|
||||
// No waiting writers, acquire the read lock
|
||||
|
@ -62,7 +62,7 @@ impl RWLock {
|
|||
if *wguard.lock_var() || rguard.lock_var().is_some() {
|
||||
// Another thread has the lock, wait
|
||||
drop(rguard);
|
||||
WaitQueue::wait(wguard);
|
||||
WaitQueue::wait(wguard, ||{});
|
||||
// Another thread has passed the lock to us
|
||||
} else {
|
||||
// We are just now obtaining the lock
|
||||
|
@ -97,6 +97,7 @@ impl RWLock {
|
|||
if let Ok(mut wguard) = WaitQueue::notify_one(wguard) {
|
||||
// A writer was waiting, pass the lock
|
||||
*wguard.lock_var_mut() = true;
|
||||
wguard.drop_after(rguard);
|
||||
} else {
|
||||
// No writers were waiting, the lock is released
|
||||
rtassert!(rguard.queue_empty());
|
||||
|
@ -117,21 +118,26 @@ impl RWLock {
|
|||
rguard: SpinMutexGuard<'_, WaitVariable<Option<NonZeroUsize>>>,
|
||||
wguard: SpinMutexGuard<'_, WaitVariable<bool>>,
|
||||
) {
|
||||
if let Err(mut wguard) = WaitQueue::notify_one(wguard) {
|
||||
// No writers waiting, release the write lock
|
||||
*wguard.lock_var_mut() = false;
|
||||
if let Ok(mut rguard) = WaitQueue::notify_all(rguard) {
|
||||
// One or more readers were waiting, pass the lock to them
|
||||
if let NotifiedTcs::All { count } = rguard.notified_tcs() {
|
||||
*rguard.lock_var_mut() = Some(count)
|
||||
match WaitQueue::notify_one(wguard) {
|
||||
Err(mut wguard) => {
|
||||
// No writers waiting, release the write lock
|
||||
*wguard.lock_var_mut() = false;
|
||||
if let Ok(mut rguard) = WaitQueue::notify_all(rguard) {
|
||||
// One or more readers were waiting, pass the lock to them
|
||||
if let NotifiedTcs::All { count } = rguard.notified_tcs() {
|
||||
*rguard.lock_var_mut() = Some(count)
|
||||
} else {
|
||||
unreachable!() // called notify_all
|
||||
}
|
||||
rguard.drop_after(wguard);
|
||||
} else {
|
||||
unreachable!() // called notify_all
|
||||
// No readers waiting, the lock is released
|
||||
}
|
||||
} else {
|
||||
// No readers waiting, the lock is released
|
||||
},
|
||||
Ok(wguard) => {
|
||||
// There was a thread waiting for write, just pass the lock
|
||||
wguard.drop_after(rguard);
|
||||
}
|
||||
} else {
|
||||
// There was a thread waiting for write, just pass the lock
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,12 @@ impl<'a, T> WaitGuard<'a, T> {
|
|||
pub fn notified_tcs(&self) -> NotifiedTcs {
|
||||
self.notified_tcs
|
||||
}
|
||||
|
||||
/// Drop this `WaitGuard`, after dropping another `guard`.
|
||||
pub fn drop_after<U>(self, guard: U) {
|
||||
drop(guard);
|
||||
drop(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Deref for WaitGuard<'a, T> {
|
||||
|
@ -140,7 +146,7 @@ impl WaitQueue {
|
|||
/// until a wakeup event.
|
||||
///
|
||||
/// This function does not return until this thread has been awoken.
|
||||
pub fn wait<T>(mut guard: SpinMutexGuard<'_, WaitVariable<T>>) {
|
||||
pub fn wait<T, F: FnOnce()>(mut guard: SpinMutexGuard<'_, WaitVariable<T>>, before_wait: F) {
|
||||
// very unsafe: check requirements of UnsafeList::push
|
||||
unsafe {
|
||||
let mut entry = UnsafeListEntry::new(SpinMutex::new(WaitEntry {
|
||||
|
@ -149,6 +155,7 @@ impl WaitQueue {
|
|||
}));
|
||||
let entry = guard.queue.inner.push(&mut entry);
|
||||
drop(guard);
|
||||
before_wait();
|
||||
while !entry.lock().wake {
|
||||
// don't panic, this would invalidate `entry` during unwinding
|
||||
let eventset = rtunwrap!(Ok, usercalls::wait(EV_UNPARK, WAIT_INDEFINITE));
|
||||
|
@ -545,7 +552,7 @@ mod tests {
|
|||
assert!(WaitQueue::notify_one(wq2.lock()).is_ok());
|
||||
});
|
||||
|
||||
WaitQueue::wait(locked);
|
||||
WaitQueue::wait(locked, ||{});
|
||||
|
||||
t1.join().unwrap();
|
||||
}
|
||||
|
|
|
@ -221,7 +221,6 @@ impl Instant {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(checked_duration_since)]
|
||||
/// use std::time::{Duration, Instant};
|
||||
/// use std::thread::sleep;
|
||||
///
|
||||
|
@ -231,7 +230,7 @@ impl Instant {
|
|||
/// println!("{:?}", new_now.checked_duration_since(now));
|
||||
/// println!("{:?}", now.checked_duration_since(new_now)); // None
|
||||
/// ```
|
||||
#[unstable(feature = "checked_duration_since", issue = "58402")]
|
||||
#[stable(feature = "checked_duration_since", since = "1.39.0")]
|
||||
pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
|
||||
self.0.checked_sub_instant(&earlier.0)
|
||||
}
|
||||
|
@ -242,7 +241,6 @@ impl Instant {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(checked_duration_since)]
|
||||
/// use std::time::{Duration, Instant};
|
||||
/// use std::thread::sleep;
|
||||
///
|
||||
|
@ -252,7 +250,7 @@ impl Instant {
|
|||
/// println!("{:?}", new_now.saturating_duration_since(now));
|
||||
/// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns
|
||||
/// ```
|
||||
#[unstable(feature = "checked_duration_since", issue = "58402")]
|
||||
#[stable(feature = "checked_duration_since", since = "1.39.0")]
|
||||
pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
|
||||
self.checked_duration_since(earlier).unwrap_or(Duration::new(0, 0))
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::ext::base::{ExtCtxt, MacEager, MacResult};
|
|||
use crate::parse::token::{self, Token};
|
||||
use crate::ptr::P;
|
||||
use crate::symbol::kw;
|
||||
use crate::tokenstream::{TokenTree};
|
||||
use crate::tokenstream::{TokenTree, TokenStream};
|
||||
|
||||
use smallvec::smallvec;
|
||||
use syntax_pos::Span;
|
||||
|
@ -27,12 +27,11 @@ pub type ErrorMap = BTreeMap<Name, ErrorInfo>;
|
|||
|
||||
pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt<'_>,
|
||||
span: Span,
|
||||
token_tree: &[TokenTree])
|
||||
tts: TokenStream)
|
||||
-> Box<dyn MacResult+'cx> {
|
||||
let code = match token_tree {
|
||||
[
|
||||
TokenTree::Token(Token { kind: token::Ident(code, _), .. })
|
||||
] => code,
|
||||
assert_eq!(tts.len(), 1);
|
||||
let code = match tts.into_trees().next() {
|
||||
Some(TokenTree::Token(Token { kind: token::Ident(code, _), .. })) => code,
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
|
@ -62,20 +61,21 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt<'_>,
|
|||
|
||||
pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>,
|
||||
span: Span,
|
||||
token_tree: &[TokenTree])
|
||||
tts: TokenStream)
|
||||
-> Box<dyn MacResult+'cx> {
|
||||
let (code, description) = match token_tree {
|
||||
[
|
||||
TokenTree::Token(Token { kind: token::Ident(code, _), .. })
|
||||
] => {
|
||||
(*code, None)
|
||||
},
|
||||
[
|
||||
TokenTree::Token(Token { kind: token::Ident(code, _), .. }),
|
||||
TokenTree::Token(Token { kind: token::Comma, .. }),
|
||||
TokenTree::Token(Token { kind: token::Literal(token::Lit { symbol, .. }), ..})
|
||||
] => {
|
||||
(*code, Some(*symbol))
|
||||
assert!(tts.len() == 1 || tts.len() == 3);
|
||||
let mut cursor = tts.into_trees();
|
||||
let code = match cursor.next() {
|
||||
Some(TokenTree::Token(Token { kind: token::Ident(code, _), .. })) => code,
|
||||
_ => unreachable!()
|
||||
};
|
||||
let description = match (cursor.next(), cursor.next()) {
|
||||
(None, None) => None,
|
||||
(
|
||||
Some(TokenTree::Token(Token { kind: token::Comma, .. })),
|
||||
Some(TokenTree::Token(Token { kind: token::Literal(token::Lit { symbol, .. }), ..}))
|
||||
) => {
|
||||
Some(symbol)
|
||||
},
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
@ -121,12 +121,12 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>,
|
|||
|
||||
pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
|
||||
span: Span,
|
||||
token_tree: &[TokenTree])
|
||||
tts: TokenStream)
|
||||
-> Box<dyn MacResult+'cx> {
|
||||
assert_eq!(token_tree.len(), 3);
|
||||
let ident = match &token_tree[2] {
|
||||
assert_eq!(tts.len(), 3);
|
||||
let ident = match tts.into_trees().nth(2) {
|
||||
// DIAGNOSTICS ident.
|
||||
&TokenTree::Token(Token { kind: token::Ident(name, _), span })
|
||||
Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }))
|
||||
=> Ident::new(name, span),
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::parse::token;
|
|||
use crate::ptr::P;
|
||||
use crate::symbol::{kw, sym, Ident, Symbol};
|
||||
use crate::{ThinVec, MACRO_ARGUMENTS};
|
||||
use crate::tokenstream::{self, TokenStream, TokenTree};
|
||||
use crate::tokenstream::{self, TokenStream};
|
||||
use crate::visit::Visitor;
|
||||
|
||||
use errors::{DiagnosticBuilder, DiagnosticId};
|
||||
|
@ -235,18 +235,18 @@ pub trait TTMacroExpander {
|
|||
}
|
||||
|
||||
pub type MacroExpanderFn =
|
||||
for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, &[tokenstream::TokenTree])
|
||||
for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream)
|
||||
-> Box<dyn MacResult+'cx>;
|
||||
|
||||
impl<F> TTMacroExpander for F
|
||||
where F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, &[tokenstream::TokenTree])
|
||||
where F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream)
|
||||
-> Box<dyn MacResult+'cx>
|
||||
{
|
||||
fn expand<'cx>(
|
||||
&self,
|
||||
ecx: &'cx mut ExtCtxt<'_>,
|
||||
span: Span,
|
||||
input: TokenStream,
|
||||
mut input: TokenStream,
|
||||
) -> Box<dyn MacResult+'cx> {
|
||||
struct AvoidInterpolatedIdents;
|
||||
|
||||
|
@ -268,10 +268,8 @@ impl<F> TTMacroExpander for F
|
|||
mut_visit::noop_visit_mac(mac, self)
|
||||
}
|
||||
}
|
||||
|
||||
let input: Vec<_> =
|
||||
input.trees().map(|mut tt| { AvoidInterpolatedIdents.visit_tt(&mut tt); tt }).collect();
|
||||
(*self)(ecx, span, &input)
|
||||
AvoidInterpolatedIdents.visit_tts(&mut input);
|
||||
(*self)(ecx, span, input)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -677,7 +675,7 @@ impl SyntaxExtension {
|
|||
}
|
||||
|
||||
pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
|
||||
fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: &[TokenTree])
|
||||
fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: TokenStream)
|
||||
-> Box<dyn MacResult + 'cx> {
|
||||
DummyResult::any(span)
|
||||
}
|
||||
|
@ -811,9 +809,8 @@ impl<'a> ExtCtxt<'a> {
|
|||
pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
|
||||
expand::MacroExpander::new(self, true)
|
||||
}
|
||||
|
||||
pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree]) -> parser::Parser<'a> {
|
||||
parse::stream_to_parser(self.parse_sess, tts.iter().cloned().collect(), MACRO_ARGUMENTS)
|
||||
pub fn new_parser_from_tts(&self, stream: TokenStream) -> parser::Parser<'a> {
|
||||
parse::stream_to_parser(self.parse_sess, stream, MACRO_ARGUMENTS)
|
||||
}
|
||||
pub fn source_map(&self) -> &'a SourceMap { self.parse_sess.source_map() }
|
||||
pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
|
||||
|
@ -1019,7 +1016,7 @@ pub fn expr_to_string(cx: &mut ExtCtxt<'_>, expr: P<ast::Expr>, err_msg: &str)
|
|||
/// done as rarely as possible).
|
||||
pub fn check_zero_tts(cx: &ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: &[tokenstream::TokenTree],
|
||||
tts: TokenStream,
|
||||
name: &str) {
|
||||
if !tts.is_empty() {
|
||||
cx.span_err(sp, &format!("{} takes no arguments", name));
|
||||
|
@ -1030,7 +1027,7 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>,
|
|||
/// expect exactly one string literal, or emit an error and return `None`.
|
||||
pub fn get_single_str_from_tts(cx: &mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: &[tokenstream::TokenTree],
|
||||
tts: TokenStream,
|
||||
name: &str)
|
||||
-> Option<String> {
|
||||
let mut p = cx.new_parser_from_tts(tts);
|
||||
|
@ -1053,7 +1050,7 @@ pub fn get_single_str_from_tts(cx: &mut ExtCtxt<'_>,
|
|||
/// parsing error, emit a non-fatal error and return `None`.
|
||||
pub fn get_exprs_from_tts(cx: &mut ExtCtxt<'_>,
|
||||
sp: Span,
|
||||
tts: &[tokenstream::TokenTree]) -> Option<Vec<P<ast::Expr>>> {
|
||||
tts: TokenStream) -> Option<Vec<P<ast::Expr>>> {
|
||||
let mut p = cx.new_parser_from_tts(tts);
|
||||
let mut es = Vec::new();
|
||||
while p.token != token::Eof {
|
||||
|
|
|
@ -701,7 +701,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
path: &Path,
|
||||
span: Span,
|
||||
) -> AstFragment {
|
||||
let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::<Vec<_>>());
|
||||
let mut parser = self.cx.new_parser_from_tts(toks);
|
||||
match parser.parse_ast_fragment(kind, false) {
|
||||
Ok(fragment) => {
|
||||
parser.ensure_complete_parse(path, kind.name(), span);
|
||||
|
|
|
@ -322,8 +322,7 @@ impl Ident {
|
|||
fn is_valid(string: &str) -> bool {
|
||||
let mut chars = string.chars();
|
||||
if let Some(start) = chars.next() {
|
||||
(start == '_' || start.is_xid_start())
|
||||
&& chars.all(|cont| cont == '_' || cont.is_xid_continue())
|
||||
rustc_lexer::is_id_start(start) && chars.all(rustc_lexer::is_id_continue)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
|
@ -889,6 +889,36 @@ impl<'a> Parser<'a> {
|
|||
hi = path.span;
|
||||
return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs));
|
||||
}
|
||||
if self.token.is_path_start() {
|
||||
let path = self.parse_path(PathStyle::Expr)?;
|
||||
|
||||
// `!`, as an operator, is prefix, so we know this isn't that
|
||||
if self.eat(&token::Not) {
|
||||
// MACRO INVOCATION expression
|
||||
let (delim, tts) = self.expect_delimited_token_tree()?;
|
||||
hi = self.prev_span;
|
||||
ex = ExprKind::Mac(Mac {
|
||||
path,
|
||||
tts,
|
||||
delim,
|
||||
span: lo.to(hi),
|
||||
prior_type_ascription: self.last_type_ascription,
|
||||
});
|
||||
} else if self.check(&token::OpenDelim(token::Brace)) {
|
||||
if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
|
||||
return expr;
|
||||
} else {
|
||||
hi = path.span;
|
||||
ex = ExprKind::Path(None, path);
|
||||
}
|
||||
} else {
|
||||
hi = path.span;
|
||||
ex = ExprKind::Path(None, path);
|
||||
}
|
||||
|
||||
let expr = self.mk_expr(lo.to(hi), ex, attrs);
|
||||
return self.maybe_recover_from_bad_qpath(expr, true);
|
||||
}
|
||||
if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
|
||||
return self.parse_lambda_expr(attrs);
|
||||
}
|
||||
|
@ -1007,32 +1037,6 @@ impl<'a> Parser<'a> {
|
|||
let (await_hi, e_kind) = self.parse_incorrect_await_syntax(lo, self.prev_span)?;
|
||||
hi = await_hi;
|
||||
ex = e_kind;
|
||||
} else if self.token.is_path_start() {
|
||||
let path = self.parse_path(PathStyle::Expr)?;
|
||||
|
||||
// `!`, as an operator, is prefix, so we know this isn't that
|
||||
if self.eat(&token::Not) {
|
||||
// MACRO INVOCATION expression
|
||||
let (delim, tts) = self.expect_delimited_token_tree()?;
|
||||
hi = self.prev_span;
|
||||
ex = ExprKind::Mac(Mac {
|
||||
path,
|
||||
tts,
|
||||
delim,
|
||||
span: lo.to(hi),
|
||||
prior_type_ascription: self.last_type_ascription,
|
||||
});
|
||||
} else if self.check(&token::OpenDelim(token::Brace)) {
|
||||
if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
|
||||
return expr;
|
||||
} else {
|
||||
hi = path.span;
|
||||
ex = ExprKind::Path(None, path);
|
||||
}
|
||||
} else {
|
||||
hi = path.span;
|
||||
ex = ExprKind::Path(None, path);
|
||||
}
|
||||
} else {
|
||||
if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
|
||||
// Don't complain about bare semicolons after unclosed braces
|
||||
|
|
|
@ -356,11 +356,7 @@ pub fn tt_to_string(tt: tokenstream::TokenTree) -> String {
|
|||
to_string(|s| s.print_tt(tt, false))
|
||||
}
|
||||
|
||||
pub fn tts_to_string(tts: &[tokenstream::TokenTree]) -> String {
|
||||
tokens_to_string(tts.iter().cloned().collect())
|
||||
}
|
||||
|
||||
pub fn tokens_to_string(tokens: TokenStream) -> String {
|
||||
pub fn tts_to_string(tokens: TokenStream) -> String {
|
||||
to_string(|s| s.print_tts(tokens, false))
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
|
|||
(None, None) => return true,
|
||||
(None, _) => return false,
|
||||
(Some(&a), None) => {
|
||||
if is_pattern_whitespace(a) {
|
||||
if rustc_lexer::is_whitespace(a) {
|
||||
break // trailing whitespace check is out of loop for borrowck
|
||||
} else {
|
||||
return false
|
||||
|
@ -72,11 +72,11 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
|
|||
(Some(&a), Some(&b)) => (a, b)
|
||||
};
|
||||
|
||||
if is_pattern_whitespace(a) && is_pattern_whitespace(b) {
|
||||
if rustc_lexer::is_whitespace(a) && rustc_lexer::is_whitespace(b) {
|
||||
// skip whitespace for a and b
|
||||
scan_for_non_ws_or_end(&mut a_iter);
|
||||
scan_for_non_ws_or_end(&mut b_iter);
|
||||
} else if is_pattern_whitespace(a) {
|
||||
} else if rustc_lexer::is_whitespace(a) {
|
||||
// skip whitespace for a
|
||||
scan_for_non_ws_or_end(&mut a_iter);
|
||||
} else if a == b {
|
||||
|
@ -88,20 +88,16 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
|
|||
}
|
||||
|
||||
// check if a has *only* trailing whitespace
|
||||
a_iter.all(is_pattern_whitespace)
|
||||
a_iter.all(rustc_lexer::is_whitespace)
|
||||
}
|
||||
|
||||
/// Advances the given peekable `Iterator` until it reaches a non-whitespace character
|
||||
fn scan_for_non_ws_or_end<I: Iterator<Item = char>>(iter: &mut Peekable<I>) {
|
||||
while iter.peek().copied().map(|c| is_pattern_whitespace(c)) == Some(true) {
|
||||
while iter.peek().copied().map(|c| rustc_lexer::is_whitespace(c)) == Some(true) {
|
||||
iter.next();
|
||||
}
|
||||
}
|
||||
|
||||
fn is_pattern_whitespace(c: char) -> bool {
|
||||
rustc_lexer::character_properties::is_whitespace(c)
|
||||
}
|
||||
|
||||
/// Identify a position in the text by the Nth occurrence of a string.
|
||||
struct Position {
|
||||
string: &'static str,
|
||||
|
|
|
@ -506,7 +506,7 @@ impl Cursor {
|
|||
|
||||
impl fmt::Display for TokenStream {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(&pprust::tokens_to_string(self.clone()))
|
||||
f.write_str(&pprust::tts_to_string(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,3 +18,4 @@ rustc_target = { path = "../librustc_target" }
|
|||
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
rustc_lexer = { path = "../librustc_lexer" }
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue