Merge pull request #17 from rust-lang/master

sync with rust-lang/rust master branch
This commit is contained in:
Baoshan 2019-09-05 22:42:04 -07:00 committed by GitHub
commit 414d104729
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
198 changed files with 2719 additions and 1572 deletions

View file

@ -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

View file

@ -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.

View file

@ -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");

View file

@ -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

View file

@ -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")]

View file

@ -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")]

View file

@ -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

View file

@ -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`].
///

View file

@ -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() {

View file

@ -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;
}

View file

@ -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,

View file

@ -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)

View file

@ -10,4 +10,4 @@ path = "lib.rs"
[dependencies]
syntax_pos = { path = "../libsyntax_pos" }
rustc_lexer = { path = "../librustc_lexer" }

View file

@ -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];

View file

@ -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" }

View file

@ -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:

View file

@ -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)

View file

@ -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,

View file

@ -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

View file

@ -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)

View file

@ -291,7 +291,7 @@ impl<'a> LintLevelsBuilder<'a> {
continue;
}
Some(tool_ident.as_str())
Some(tool_ident.name)
} else {
None
};

View file

@ -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.
//

View file

@ -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)

View file

@ -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(

View file

@ -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,

View file

@ -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 {

View file

@ -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);

View file

@ -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,

View file

@ -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.

View file

@ -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 {

View file

@ -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 {

View file

@ -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,

View file

@ -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);

View file

@ -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;

View file

@ -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 {

View file

@ -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

View file

@ -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));
}

View file

@ -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.

View file

@ -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,
))
})
}

View file

@ -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,

View file

@ -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(_), _) => {

View file

@ -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);

View file

@ -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,

View file

@ -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));
}

View file

@ -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"

View file

@ -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())
}
}

View file

@ -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, &param.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! {

View file

@ -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);

View file

@ -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),

View file

@ -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" }

View file

@ -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(()),

View file

@ -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> {

View file

@ -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";

View file

@ -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)

View file

@ -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,

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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)));
}
}
});
}

View file

@ -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(),
}
}

View file

@ -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<'_> {

View file

@ -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()),
}
}
}

View file

@ -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);

View file

@ -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;
}
}
}
}

View file

@ -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),

View file

@ -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>");

View file

@ -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;

View 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()
}
}

View file

@ -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),

View 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,
})
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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;

View file

@ -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",
);

View file

@ -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);

View file

@ -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)
)))
}

View file

@ -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 {
'_'

View file

@ -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);

View file

@ -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)]

View file

@ -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()
}

View file

@ -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
},
_ => {

View file

@ -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
}
}

View file

@ -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();
}

View file

@ -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))
}

View file

@ -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!()
};

View file

@ -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 {

View file

@ -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);

View file

@ -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
}

View file

@ -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

View file

@ -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))
}

View file

@ -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,

View file

@ -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()))
}
}

View file

@ -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