Rollup merge of #65402 - michaelwoerister:pgo-troubleshooting-docs, r=alexcrichton
Add troubleshooting section to PGO chapter in rustc book.
- Adds a note about using `-pgo-warn-missing-function` in order to spot mistakes in PGO setup.
- Mentions cargo symbol name issue fixed in 1.39.
Nominating for backport.
r? @alexcrichton
diff --git a/Cargo.lock b/Cargo.lock
index 844320f..6d40b19 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -556,9 +556,9 @@
[[package]]
name = "compiletest_rs"
-version = "0.3.23"
+version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb783fe7afb90ec3d3e49ccaf9196d29ab63c6ed61d4b0695839daa580ae3a3d"
+checksum = "676a74b493d50ac33cacd83fd536597e6b52c0b46b9856f7b9c809d82fef4ac0"
dependencies = [
"diff",
"filetime",
diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs
index 68cbc36..1e39b7f 100644
--- a/src/liballoc/fmt.rs
+++ b/src/liballoc/fmt.rs
@@ -80,250 +80,6 @@
//! arguments which have names. Like with positional parameters, it is not
//! valid to provide named parameters that are unused by the format string.
//!
-//! ## Argument types
-//!
-//! Each argument's type is dictated by the format string.
-//! There are various parameters which require a particular type, however.
-//! An example is the `{:.*}` syntax, which sets the number of decimal places
-//! in floating-point types:
-//!
-//! ```
-//! let formatted_number = format!("{:.*}", 2, 1.234567);
-//!
-//! assert_eq!("1.23", formatted_number)
-//! ```
-//!
-//! If this syntax is used, then the number of characters to print precedes the
-//! actual object being formatted, and the number of characters must have the
-//! type [`usize`].
-//!
-//! ## Formatting traits
-//!
-//! When requesting that an argument be formatted with a particular type, you
-//! are actually requesting that an argument ascribes to a particular trait.
-//! This allows multiple actual types to be formatted via `{:x}` (like [`i8`] as
-//! well as [`isize`]). The current mapping of types to traits is:
-//!
-//! * *nothing* ⇒ [`Display`]
-//! * `?` ⇒ [`Debug`]
-//! * `x?` ⇒ [`Debug`] with lower-case hexadecimal integers
-//! * `X?` ⇒ [`Debug`] with upper-case hexadecimal integers
-//! * `o` ⇒ [`Octal`](trait.Octal.html)
-//! * `x` ⇒ [`LowerHex`](trait.LowerHex.html)
-//! * `X` ⇒ [`UpperHex`](trait.UpperHex.html)
-//! * `p` ⇒ [`Pointer`](trait.Pointer.html)
-//! * `b` ⇒ [`Binary`]
-//! * `e` ⇒ [`LowerExp`](trait.LowerExp.html)
-//! * `E` ⇒ [`UpperExp`](trait.UpperExp.html)
-//!
-//! What this means is that any type of argument which implements the
-//! [`fmt::Binary`][`Binary`] trait can then be formatted with `{:b}`. Implementations
-//! are provided for these traits for a number of primitive types by the
-//! standard library as well. If no format is specified (as in `{}` or `{:6}`),
-//! then the format trait used is the [`Display`] trait.
-//!
-//! When implementing a format trait for your own type, you will have to
-//! implement a method of the signature:
-//!
-//! ```
-//! # #![allow(dead_code)]
-//! # use std::fmt;
-//! # struct Foo; // our custom type
-//! # impl fmt::Display for Foo {
-//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-//! # write!(f, "testing, testing")
-//! # } }
-//! ```
-//!
-//! Your type will be passed as `self` by-reference, and then the function
-//! should emit output into the `f.buf` stream. It is up to each format trait
-//! implementation to correctly adhere to the requested formatting parameters.
-//! The values of these parameters will be listed in the fields of the
-//! [`Formatter`] struct. In order to help with this, the [`Formatter`] struct also
-//! provides some helper methods.
-//!
-//! Additionally, the return value of this function is [`fmt::Result`] which is a
-//! type alias of [`Result`]`<(), `[`std::fmt::Error`]`>`. Formatting implementations
-//! should ensure that they propagate errors from the [`Formatter`][`Formatter`] (e.g., when
-//! calling [`write!`]). However, they should never return errors spuriously. That
-//! is, a formatting implementation must and may only return an error if the
-//! passed-in [`Formatter`] returns an error. This is because, contrary to what
-//! the function signature might suggest, string formatting is an infallible
-//! operation. This function only returns a result because writing to the
-//! underlying stream might fail and it must provide a way to propagate the fact
-//! that an error has occurred back up the stack.
-//!
-//! An example of implementing the formatting traits would look
-//! like:
-//!
-//! ```
-//! use std::fmt;
-//!
-//! #[derive(Debug)]
-//! struct Vector2D {
-//! x: isize,
-//! y: isize,
-//! }
-//!
-//! impl fmt::Display for Vector2D {
-//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-//! // The `f` value implements the `Write` trait, which is what the
-//! // write! macro is expecting. Note that this formatting ignores the
-//! // various flags provided to format strings.
-//! write!(f, "({}, {})", self.x, self.y)
-//! }
-//! }
-//!
-//! // Different traits allow different forms of output of a type. The meaning
-//! // of this format is to print the magnitude of a vector.
-//! impl fmt::Binary for Vector2D {
-//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-//! let magnitude = (self.x * self.x + self.y * self.y) as f64;
-//! let magnitude = magnitude.sqrt();
-//!
-//! // Respect the formatting flags by using the helper method
-//! // `pad_integral` on the Formatter object. See the method
-//! // documentation for details, and the function `pad` can be used
-//! // to pad strings.
-//! let decimals = f.precision().unwrap_or(3);
-//! let string = format!("{:.*}", decimals, magnitude);
-//! f.pad_integral(true, "", &string)
-//! }
-//! }
-//!
-//! fn main() {
-//! let myvector = Vector2D { x: 3, y: 4 };
-//!
-//! println!("{}", myvector); // => "(3, 4)"
-//! println!("{:?}", myvector); // => "Vector2D {x: 3, y:4}"
-//! println!("{:10.3b}", myvector); // => " 5.000"
-//! }
-//! ```
-//!
-//! ### `fmt::Display` vs `fmt::Debug`
-//!
-//! These two formatting traits have distinct purposes:
-//!
-//! - [`fmt::Display`][`Display`] implementations assert that the type can be faithfully
-//! represented as a UTF-8 string at all times. It is **not** expected that
-//! all types implement the [`Display`] trait.
-//! - [`fmt::Debug`][`Debug`] implementations should be implemented for **all** public types.
-//! Output will typically represent the internal state as faithfully as possible.
-//! The purpose of the [`Debug`] trait is to facilitate debugging Rust code. In
-//! most cases, using `#[derive(Debug)]` is sufficient and recommended.
-//!
-//! Some examples of the output from both traits:
-//!
-//! ```
-//! assert_eq!(format!("{} {:?}", 3, 4), "3 4");
-//! assert_eq!(format!("{} {:?}", 'a', 'b'), "a 'b'");
-//! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\"");
-//! ```
-//!
-//! ## Related macros
-//!
-//! There are a number of related macros in the [`format!`] family. The ones that
-//! are currently implemented are:
-//!
-//! ```ignore (only-for-syntax-highlight)
-//! format! // described above
-//! write! // first argument is a &mut io::Write, the destination
-//! writeln! // same as write but appends a newline
-//! print! // the format string is printed to the standard output
-//! println! // same as print but appends a newline
-//! eprint! // the format string is printed to the standard error
-//! eprintln! // same as eprint but appends a newline
-//! format_args! // described below.
-//! ```
-//!
-//! ### `write!`
-//!
-//! This and [`writeln!`] are two macros which are used to emit the format string
-//! to a specified stream. This is used to prevent intermediate allocations of
-//! format strings and instead directly write the output. Under the hood, this
-//! function is actually invoking the [`write_fmt`] function defined on the
-//! [`std::io::Write`] trait. Example usage is:
-//!
-//! ```
-//! # #![allow(unused_must_use)]
-//! use std::io::Write;
-//! let mut w = Vec::new();
-//! write!(&mut w, "Hello {}!", "world");
-//! ```
-//!
-//! ### `print!`
-//!
-//! This and [`println!`] emit their output to stdout. Similarly to the [`write!`]
-//! macro, the goal of these macros is to avoid intermediate allocations when
-//! printing output. Example usage is:
-//!
-//! ```
-//! print!("Hello {}!", "world");
-//! println!("I have a newline {}", "character at the end");
-//! ```
-//! ### `eprint!`
-//!
-//! The [`eprint!`] and [`eprintln!`] macros are identical to
-//! [`print!`] and [`println!`], respectively, except they emit their
-//! output to stderr.
-//!
-//! ### `format_args!`
-//!
-//! This is a curious macro which is used to safely pass around
-//! an opaque object describing the format string. This object
-//! does not require any heap allocations to create, and it only
-//! references information on the stack. Under the hood, all of
-//! the related macros are implemented in terms of this. First
-//! off, some example usage is:
-//!
-//! ```
-//! # #![allow(unused_must_use)]
-//! use std::fmt;
-//! use std::io::{self, Write};
-//!
-//! let mut some_writer = io::stdout();
-//! write!(&mut some_writer, "{}", format_args!("print with a {}", "macro"));
-//!
-//! fn my_fmt_fn(args: fmt::Arguments) {
-//! write!(&mut io::stdout(), "{}", args);
-//! }
-//! my_fmt_fn(format_args!(", or a {} too", "function"));
-//! ```
-//!
-//! The result of the [`format_args!`] macro is a value of type [`fmt::Arguments`].
-//! This structure can then be passed to the [`write`] and [`format`] functions
-//! inside this module in order to process the format string.
-//! The goal of this macro is to even further prevent intermediate allocations
-//! when dealing formatting strings.
-//!
-//! For example, a logging library could use the standard formatting syntax, but
-//! it would internally pass around this structure until it has been determined
-//! where output should go to.
-//!
-//! # Syntax
-//!
-//! The syntax for the formatting language used is drawn from other languages,
-//! so it should not be too alien. Arguments are formatted with Python-like
-//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like
-//! `%`. The actual grammar for the formatting syntax is:
-//!
-//! ```text
-//! format_string := <text> [ maybe-format <text> ] *
-//! maybe-format := '{' '{' | '}' '}' | <format>
-//! format := '{' [ argument ] [ ':' format_spec ] '}'
-//! argument := integer | identifier
-//!
-//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
-//! fill := character
-//! align := '<' | '^' | '>'
-//! sign := '+' | '-'
-//! width := count
-//! precision := count | '*'
-//! type := identifier | '?' | ''
-//! count := parameter | integer
-//! parameter := argument '$'
-//! ```
-//!
//! # Formatting Parameters
//!
//! Each argument being formatted can be transformed by a number of formatting
@@ -479,6 +235,234 @@
//! them with the same character. For example, the `{` character is escaped with
//! `{{` and the `}` character is escaped with `}}`.
//!
+//! # Syntax
+//!
+//! To summarize, you can find the full grammar of format strings.
+//! The syntax for the formatting language used is drawn from other languages,
+//! so it should not be too alien. Arguments are formatted with Python-like
+//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like
+//! `%`. The actual grammar for the formatting syntax is:
+//!
+//! ```text
+//! format_string := <text> [ maybe-format <text> ] *
+//! maybe-format := '{' '{' | '}' '}' | <format>
+//! format := '{' [ argument ] [ ':' format_spec ] '}'
+//! argument := integer | identifier
+//!
+//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
+//! fill := character
+//! align := '<' | '^' | '>'
+//! sign := '+' | '-'
+//! width := count
+//! precision := count | '*'
+//! type := identifier | '?' | ''
+//! count := parameter | integer
+//! parameter := argument '$'
+//! ```
+//!
+//! # Formatting traits
+//!
+//! When requesting that an argument be formatted with a particular type, you
+//! are actually requesting that an argument ascribes to a particular trait.
+//! This allows multiple actual types to be formatted via `{:x}` (like [`i8`] as
+//! well as [`isize`]). The current mapping of types to traits is:
+//!
+//! * *nothing* ⇒ [`Display`]
+//! * `?` ⇒ [`Debug`]
+//! * `x?` ⇒ [`Debug`] with lower-case hexadecimal integers
+//! * `X?` ⇒ [`Debug`] with upper-case hexadecimal integers
+//! * `o` ⇒ [`Octal`](trait.Octal.html)
+//! * `x` ⇒ [`LowerHex`](trait.LowerHex.html)
+//! * `X` ⇒ [`UpperHex`](trait.UpperHex.html)
+//! * `p` ⇒ [`Pointer`](trait.Pointer.html)
+//! * `b` ⇒ [`Binary`]
+//! * `e` ⇒ [`LowerExp`](trait.LowerExp.html)
+//! * `E` ⇒ [`UpperExp`](trait.UpperExp.html)
+//!
+//! What this means is that any type of argument which implements the
+//! [`fmt::Binary`][`Binary`] trait can then be formatted with `{:b}`. Implementations
+//! are provided for these traits for a number of primitive types by the
+//! standard library as well. If no format is specified (as in `{}` or `{:6}`),
+//! then the format trait used is the [`Display`] trait.
+//!
+//! When implementing a format trait for your own type, you will have to
+//! implement a method of the signature:
+//!
+//! ```
+//! # #![allow(dead_code)]
+//! # use std::fmt;
+//! # struct Foo; // our custom type
+//! # impl fmt::Display for Foo {
+//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+//! # write!(f, "testing, testing")
+//! # } }
+//! ```
+//!
+//! Your type will be passed as `self` by-reference, and then the function
+//! should emit output into the `f.buf` stream. It is up to each format trait
+//! implementation to correctly adhere to the requested formatting parameters.
+//! The values of these parameters will be listed in the fields of the
+//! [`Formatter`] struct. In order to help with this, the [`Formatter`] struct also
+//! provides some helper methods.
+//!
+//! Additionally, the return value of this function is [`fmt::Result`] which is a
+//! type alias of [`Result`]`<(), `[`std::fmt::Error`]`>`. Formatting implementations
+//! should ensure that they propagate errors from the [`Formatter`][`Formatter`] (e.g., when
+//! calling [`write!`]). However, they should never return errors spuriously. That
+//! is, a formatting implementation must and may only return an error if the
+//! passed-in [`Formatter`] returns an error. This is because, contrary to what
+//! the function signature might suggest, string formatting is an infallible
+//! operation. This function only returns a result because writing to the
+//! underlying stream might fail and it must provide a way to propagate the fact
+//! that an error has occurred back up the stack.
+//!
+//! An example of implementing the formatting traits would look
+//! like:
+//!
+//! ```
+//! use std::fmt;
+//!
+//! #[derive(Debug)]
+//! struct Vector2D {
+//! x: isize,
+//! y: isize,
+//! }
+//!
+//! impl fmt::Display for Vector2D {
+//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+//! // The `f` value implements the `Write` trait, which is what the
+//! // write! macro is expecting. Note that this formatting ignores the
+//! // various flags provided to format strings.
+//! write!(f, "({}, {})", self.x, self.y)
+//! }
+//! }
+//!
+//! // Different traits allow different forms of output of a type. The meaning
+//! // of this format is to print the magnitude of a vector.
+//! impl fmt::Binary for Vector2D {
+//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+//! let magnitude = (self.x * self.x + self.y * self.y) as f64;
+//! let magnitude = magnitude.sqrt();
+//!
+//! // Respect the formatting flags by using the helper method
+//! // `pad_integral` on the Formatter object. See the method
+//! // documentation for details, and the function `pad` can be used
+//! // to pad strings.
+//! let decimals = f.precision().unwrap_or(3);
+//! let string = format!("{:.*}", decimals, magnitude);
+//! f.pad_integral(true, "", &string)
+//! }
+//! }
+//!
+//! fn main() {
+//! let myvector = Vector2D { x: 3, y: 4 };
+//!
+//! println!("{}", myvector); // => "(3, 4)"
+//! println!("{:?}", myvector); // => "Vector2D {x: 3, y:4}"
+//! println!("{:10.3b}", myvector); // => " 5.000"
+//! }
+//! ```
+//!
+//! ### `fmt::Display` vs `fmt::Debug`
+//!
+//! These two formatting traits have distinct purposes:
+//!
+//! - [`fmt::Display`][`Display`] implementations assert that the type can be faithfully
+//! represented as a UTF-8 string at all times. It is **not** expected that
+//! all types implement the [`Display`] trait.
+//! - [`fmt::Debug`][`Debug`] implementations should be implemented for **all** public types.
+//! Output will typically represent the internal state as faithfully as possible.
+//! The purpose of the [`Debug`] trait is to facilitate debugging Rust code. In
+//! most cases, using `#[derive(Debug)]` is sufficient and recommended.
+//!
+//! Some examples of the output from both traits:
+//!
+//! ```
+//! assert_eq!(format!("{} {:?}", 3, 4), "3 4");
+//! assert_eq!(format!("{} {:?}", 'a', 'b'), "a 'b'");
+//! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\"");
+//! ```
+//!
+//! # Related macros
+//!
+//! There are a number of related macros in the [`format!`] family. The ones that
+//! are currently implemented are:
+//!
+//! ```ignore (only-for-syntax-highlight)
+//! format! // described above
+//! write! // first argument is a &mut io::Write, the destination
+//! writeln! // same as write but appends a newline
+//! print! // the format string is printed to the standard output
+//! println! // same as print but appends a newline
+//! eprint! // the format string is printed to the standard error
+//! eprintln! // same as eprint but appends a newline
+//! format_args! // described below.
+//! ```
+//!
+//! ### `write!`
+//!
+//! This and [`writeln!`] are two macros which are used to emit the format string
+//! to a specified stream. This is used to prevent intermediate allocations of
+//! format strings and instead directly write the output. Under the hood, this
+//! function is actually invoking the [`write_fmt`] function defined on the
+//! [`std::io::Write`] trait. Example usage is:
+//!
+//! ```
+//! # #![allow(unused_must_use)]
+//! use std::io::Write;
+//! let mut w = Vec::new();
+//! write!(&mut w, "Hello {}!", "world");
+//! ```
+//!
+//! ### `print!`
+//!
+//! This and [`println!`] emit their output to stdout. Similarly to the [`write!`]
+//! macro, the goal of these macros is to avoid intermediate allocations when
+//! printing output. Example usage is:
+//!
+//! ```
+//! print!("Hello {}!", "world");
+//! println!("I have a newline {}", "character at the end");
+//! ```
+//! ### `eprint!`
+//!
+//! The [`eprint!`] and [`eprintln!`] macros are identical to
+//! [`print!`] and [`println!`], respectively, except they emit their
+//! output to stderr.
+//!
+//! ### `format_args!`
+//!
+//! This is a curious macro which is used to safely pass around
+//! an opaque object describing the format string. This object
+//! does not require any heap allocations to create, and it only
+//! references information on the stack. Under the hood, all of
+//! the related macros are implemented in terms of this. First
+//! off, some example usage is:
+//!
+//! ```
+//! # #![allow(unused_must_use)]
+//! use std::fmt;
+//! use std::io::{self, Write};
+//!
+//! let mut some_writer = io::stdout();
+//! write!(&mut some_writer, "{}", format_args!("print with a {}", "macro"));
+//!
+//! fn my_fmt_fn(args: fmt::Arguments) {
+//! write!(&mut io::stdout(), "{}", args);
+//! }
+//! my_fmt_fn(format_args!(", or a {} too", "function"));
+//! ```
+//!
+//! The result of the [`format_args!`] macro is a value of type [`fmt::Arguments`].
+//! This structure can then be passed to the [`write`] and [`format`] functions
+//! inside this module in order to process the format string.
+//! The goal of this macro is to even further prevent intermediate allocations
+//! when dealing formatting strings.
+//!
+//! For example, a logging library could use the standard formatting syntax, but
+//! it would internally pass around this structure until it has been determined
+//! where output should go to.
+//!
//! [`usize`]: ../../std/primitive.usize.html
//! [`isize`]: ../../std/primitive.isize.html
//! [`i8`]: ../../std/primitive.i8.html
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index 50b6ef5..3d501ca 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -2005,6 +2005,24 @@
transparent wrapper around a float. This can make a difference for the ABI.
"##,
+E0697: r##"
+A closure has been used as `static`.
+
+Erroneous code example:
+
+```compile_fail,E0697
+fn main() {
+ static || {}; // used as `static`
+}
+```
+
+Closures cannot be used as `static`. They "save" the environment,
+and as such a static closure would save only a static environment
+which would consist only of variables with a static lifetime. Given
+this it would be better to use a proper function. The easiest fix
+is to remove the `static` keyword.
+"##,
+
E0698: r##"
When using generators (or async) all type variables must be bound so a
generator can be constructed.
@@ -2191,7 +2209,6 @@
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
- E0697, // closures cannot be static
// E0707, // multiple elided lifetimes used in arguments of `async fn`
E0708, // `async` non-`move` closures with parameters are not currently
// supported
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 72fd054..e9788a5 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -67,10 +67,11 @@
use syntax::ext::base::SpecialDerives;
use syntax::ext::hygiene::ExpnId;
use syntax::print::pprust;
+use syntax::tokenstream::{TokenStream, TokenTree};
+use syntax::parse::token::{self, Nonterminal, Token};
+use syntax::sess::ParseSess;
use syntax::source_map::{respan, ExpnData, ExpnKind, DesugaringKind, Spanned};
use syntax::symbol::{kw, sym, Symbol};
-use syntax::tokenstream::{TokenStream, TokenTree};
-use syntax::parse::token::{self, Token};
use syntax::visit::{self, Visitor};
use syntax_pos::Span;
@@ -86,6 +87,11 @@
resolver: &'a mut dyn Resolver,
+ /// HACK(Centril): there is a cyclic dependency between the parser and lowering
+ /// if we don't have this function pointer. To avoid that dependency so that
+ /// librustc is independent of the parser, we use dynamic dispatch here.
+ nt_to_tokenstream: NtToTokenstream,
+
/// The items being lowered are collected here.
items: BTreeMap<hir::HirId, hir::Item>,
@@ -180,6 +186,8 @@
fn has_derives(&self, node_id: NodeId, derives: SpecialDerives) -> bool;
}
+type NtToTokenstream = fn(&Nonterminal, &ParseSess, Span) -> TokenStream;
+
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
/// and if so, what meaning it has.
#[derive(Debug)]
@@ -236,6 +244,7 @@
dep_graph: &DepGraph,
krate: &Crate,
resolver: &mut dyn Resolver,
+ nt_to_tokenstream: NtToTokenstream,
) -> hir::Crate {
// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
@@ -249,6 +258,7 @@
sess,
cstore,
resolver,
+ nt_to_tokenstream,
items: BTreeMap::new(),
trait_items: BTreeMap::new(),
impl_items: BTreeMap::new(),
@@ -1022,7 +1032,7 @@
fn lower_token(&mut self, token: Token) -> TokenStream {
match token.kind {
token::Interpolated(nt) => {
- let tts = nt.to_tokenstream(&self.sess.parse_sess, token.span);
+ let tts = (self.nt_to_tokenstream)(&nt, &self.sess.parse_sess, token.span);
self.lower_token_stream(tts)
}
_ => TokenTree::Token(token).into(),
@@ -3281,10 +3291,14 @@
let id = self.sess.next_node_id();
self.new_named_lifetime(id, span, hir::LifetimeName::Error)
}
- // This is the normal case.
- AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
-
- AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
+ // `PassThrough` is the normal case.
+ // `new_error_lifetime`, which would usually be used in the case of `ReportError`,
+ // is unsuitable here, as these can occur from missing lifetime parameters in a
+ // `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
+ // lifetime. Instead, we simply create an implicit lifetime, which will be checked
+ // later, at which point a suitable error will be emitted.
+ | AnonymousLifetimeMode::PassThrough
+ | AnonymousLifetimeMode::ReportError => self.new_implicit_lifetime(span),
}
}
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 6cffaa8..b852098 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1,10 +1,10 @@
use rustc_target::spec::abi::Abi;
use syntax::ast;
use syntax::source_map::{SourceMap, Spanned};
-use syntax::parse::ParseSess;
use syntax::print::pp::{self, Breaks};
use syntax::print::pp::Breaks::{Consistent, Inconsistent};
use syntax::print::pprust::{self, Comments, PrintState};
+use syntax::sess::ParseSess;
use syntax::symbol::kw;
use syntax::util::parser::{self, AssocOp, Fixity};
use syntax_pos::{self, BytePos, FileName};
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index f1192c7..f606885 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -200,7 +200,7 @@
{
sp = param.span;
}
- (format!("the lifetime {} as defined on", br.name), sp)
+ (format!("the lifetime `{}` as defined on", br.name), sp)
}
ty::ReFree(ty::FreeRegion {
bound_region: ty::BoundRegion::BrNamed(_, name),
@@ -213,7 +213,7 @@
{
sp = param.span;
}
- (format!("the lifetime {} as defined on", name), sp)
+ (format!("the lifetime `{}` as defined on", name), sp)
}
ty::ReFree(ref fr) => match fr.bound_region {
ty::BrAnon(idx) => (
@@ -221,7 +221,7 @@
self.hir().span(node),
),
_ => (
- format!("the lifetime {} as defined on", region),
+ format!("the lifetime `{}` as defined on", region),
cm.def_span(self.hir().span(node)),
),
},
diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs
index f11f94c..6f55ade 100644
--- a/src/librustc/infer/lexical_region_resolve/mod.rs
+++ b/src/librustc/infer/lexical_region_resolve/mod.rs
@@ -304,7 +304,7 @@
}
fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
- self.iterate_until_fixed_point("Expansion", |constraint| {
+ self.iterate_until_fixed_point(|constraint| {
debug!("expansion: constraint={:?}", constraint);
let (a_region, b_vid, b_data, retain) = match *constraint {
Constraint::RegSubVar(a_region, b_vid) => {
@@ -360,13 +360,21 @@
match *b_data {
VarValue::Value(cur_region) => {
// Identical scopes can show up quite often, if the fixed point
- // iteration converges slowly, skip them
+ // iteration converges slowly. Skip them. This is purely an
+ // optimization.
if let (ReScope(a_scope), ReScope(cur_scope)) = (a_region, cur_region) {
if a_scope == cur_scope {
return false;
}
}
+ // This is a specialized version of the `lub_concrete_regions`
+ // check below for a common case, here purely as an
+ // optimization.
+ if let ReEmpty = a_region {
+ return false;
+ }
+
let mut lub = self.lub_concrete_regions(a_region, cur_region);
if lub == cur_region {
return false;
@@ -407,8 +415,6 @@
/// Returns the smallest region `c` such that `a <= c` and `b <= c`.
fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
- let tcx = self.tcx();
-
match (a, b) {
(&ty::ReClosureBound(..), _)
| (_, &ty::ReClosureBound(..))
@@ -468,7 +474,7 @@
// otherwise, we don't know what the free region is,
// so we must conservatively say the LUB is static:
- tcx.lifetimes.re_static
+ self.tcx().lifetimes.re_static
}
(&ReScope(a_id), &ReScope(b_id)) => {
@@ -476,7 +482,7 @@
// subtype of the region corresponding to an inner
// block.
let lub = self.region_rels.region_scope_tree.nearest_common_ancestor(a_id, b_id);
- tcx.mk_region(ReScope(lub))
+ self.tcx().mk_region(ReScope(lub))
}
(&ReEarlyBound(_), &ReEarlyBound(_))
@@ -490,7 +496,7 @@
if a == b {
a
} else {
- tcx.lifetimes.re_static
+ self.tcx().lifetimes.re_static
}
}
}
@@ -860,7 +866,7 @@
}
}
- fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F)
+ fn iterate_until_fixed_point<F>(&self, mut body: F)
where
F: FnMut(&Constraint<'tcx>) -> (bool, bool),
{
@@ -870,7 +876,7 @@
while changed {
changed = false;
iteration += 1;
- debug!("---- {} Iteration {}{}", "#", tag, iteration);
+ debug!("---- Expansion iteration {}", iteration);
constraints.retain(|constraint| {
let (edge_changed, retain) = body(constraint);
if edge_changed {
@@ -880,7 +886,7 @@
retain
});
}
- debug!("---- {} Complete after {} iteration(s)", tag, iteration);
+ debug!("---- Expansion complete after {} iteration(s)", iteration);
}
fn bound_is_met(
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 197ca19..8943fc3 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -56,7 +56,7 @@
#![feature(test)]
#![feature(in_band_lifetimes)]
#![feature(crate_visibility_modifier)]
-#![feature(proc_macro_hygiene)]
+#![cfg_attr(bootstrap, feature(proc_macro_hygiene))]
#![feature(log_syntax)]
#![feature(associated_type_bounds)]
#![feature(rustc_attrs)]
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 28afe973..60b1b19 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -12,6 +12,7 @@
use syntax::ast;
use syntax::attr;
use syntax::feature_gate;
+use syntax::print::pprust;
use syntax::source_map::MultiSpan;
use syntax::symbol::{Symbol, sym};
@@ -285,7 +286,7 @@
tool_ident.span,
E0710,
"an unknown tool name found in scoped lint: `{}`",
- meta_item.path
+ pprust::path_to_string(&meta_item.path),
);
continue;
}
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 065959e..2170a28 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -32,6 +32,12 @@
pub rmeta: Option<(PathBuf, PathKind)>,
}
+impl CrateSource {
+ pub fn paths(&self) -> impl Iterator<Item = &PathBuf> {
+ self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).map(|p| &p.0)
+ }
+}
+
#[derive(RustcEncodable, RustcDecodable, Copy, Clone,
Ord, PartialOrd, Eq, PartialEq, Debug, HashStable)]
pub enum DepKind {
@@ -208,7 +214,6 @@
fn crate_is_private_dep_untracked(&self, cnum: CrateNum) -> bool;
fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator;
fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
- fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics;
fn postorder_cnums_untracked(&self) -> Vec<CrateNum>;
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 31d250f..a122d84 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -708,15 +708,22 @@
match param.kind {
GenericParamKind::Lifetime { .. } => {
let (name, reg) = Region::early(&self.tcx.hir(), &mut index, ¶m);
+ let def_id = if let Region::EarlyBound(_ ,def_id , _) = reg {
+ def_id
+ } else {
+ bug!();
+ };
if let hir::ParamName::Plain(param_name) = name {
if param_name.name == kw::UnderscoreLifetime {
// Pick the elided lifetime "definition" if one exists
// and use it to make an elision scope.
+ self.lifetime_uses.insert(def_id.clone(), LifetimeUseSet::Many);
elision = Some(reg);
} else {
lifetimes.insert(name, reg);
}
} else {
+ self.lifetime_uses.insert(def_id.clone(), LifetimeUseSet::Many);
lifetimes.insert(name, reg);
}
}
@@ -1615,7 +1622,6 @@
_ => None,
} {
debug!("id = {:?} span = {:?} name = {:?}", id, span, name);
-
if name.name == kw::UnderscoreLifetime {
continue;
}
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 71967b5..ac99ccd 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -389,10 +389,6 @@
/// Free-form case. Only for errors that are never caught!
Unsupported(String),
- /// FIXME(#64506) Error used to work around accessing projections of
- /// uninhabited types.
- UninhabitedValue,
-
// -- Everything below is not categorized yet --
FunctionAbiMismatch(Abi, Abi),
FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>),
@@ -556,8 +552,6 @@
not a power of two"),
Unsupported(ref msg) =>
write!(f, "{}", msg),
- UninhabitedValue =>
- write!(f, "tried to use an uninhabited value"),
}
}
}
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 0facf30..675e3bb 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -16,14 +16,15 @@
use syntax::ast::{self, IntTy, UintTy, MetaItemKind};
use syntax::source_map::{FileName, FilePathMapping};
use syntax::edition::{Edition, EDITION_NAME_LIST, DEFAULT_EDITION};
-use syntax::parse::{ParseSess, new_parser_from_source_str};
+use syntax::parse::new_parser_from_source_str;
use syntax::parse::token;
+use syntax::sess::ParseSess;
use syntax::symbol::{sym, Symbol};
use syntax::feature_gate::UnstableFeatures;
use syntax::source_map::SourceMap;
use errors::emitter::HumanReadableErrorType;
-use errors::{ColorConfig, FatalError, Handler};
+use errors::{ColorConfig, FatalError, Handler, SourceMapperDyn};
use getopts;
@@ -1857,6 +1858,7 @@
impl errors::emitter::Emitter for NullEmitter {
fn emit_diagnostic(&mut self, _: &errors::Diagnostic) {}
+ fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>> { None }
}
// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
@@ -2038,11 +2040,7 @@
return error_format;
}
-pub fn build_session_options_and_crate_config(
- matches: &getopts::Matches,
-) -> (Options, FxHashSet<(String, Option<String>)>) {
- let color = parse_color(matches);
-
+fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
let edition = match matches.opt_str("edition") {
Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_|
early_error(
@@ -2069,19 +2067,14 @@
)
}
- let (json_rendered, json_artifact_notifications) = parse_json(matches);
+ edition
+}
- let error_format = parse_error_format(matches, color, json_rendered);
-
- let unparsed_crate_types = matches.opt_strs("crate-type");
- let crate_types = parse_crate_types_from_list(unparsed_crate_types)
- .unwrap_or_else(|e| early_error(error_format, &e[..]));
-
-
- let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
-
- let mut debugging_opts = build_debugging_options(matches, error_format);
-
+fn check_debug_option_stability(
+ debugging_opts: &DebuggingOptions,
+ error_format: ErrorOutputType,
+ json_rendered: HumanReadableErrorType,
+) {
if !debugging_opts.unstable_options {
if let ErrorOutputType::Json { pretty: true, json_rendered } = error_format {
early_error(
@@ -2097,7 +2090,13 @@
);
}
}
+}
+fn parse_output_types(
+ debugging_opts: &DebuggingOptions,
+ matches: &getopts::Matches,
+ error_format: ErrorOutputType,
+) -> OutputTypes {
let mut output_types = BTreeMap::new();
if !debugging_opts.parse_only {
for list in matches.opt_strs("emit") {
@@ -2122,14 +2121,19 @@
if output_types.is_empty() {
output_types.insert(OutputType::Exe, None);
}
+ OutputTypes(output_types)
+}
- let mut cg = build_codegen_options(matches, error_format);
- let mut codegen_units = cg.codegen_units;
+fn should_override_cgus_and_disable_thinlto(
+ output_types: &OutputTypes,
+ matches: &getopts::Matches,
+ error_format: ErrorOutputType,
+ mut codegen_units: Option<usize>,
+) -> (bool, Option<usize>) {
let mut disable_thinlto = false;
-
// Issue #30063: if user requests LLVM-related output to one
// particular path, disable codegen-units.
- let incompatible: Vec<_> = output_types
+ let incompatible: Vec<_> = output_types.0
.iter()
.map(|ot_path| ot_path.0)
.filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file())
@@ -2161,6 +2165,17 @@
}
}
+ if codegen_units == Some(0) {
+ early_error(
+ error_format,
+ "value for codegen units must be a positive non-zero integer",
+ );
+ }
+
+ (disable_thinlto, codegen_units)
+}
+
+fn check_thread_count(debugging_opts: &DebuggingOptions, error_format: ErrorOutputType) {
if debugging_opts.threads == 0 {
early_error(
error_format,
@@ -2174,16 +2189,15 @@
"optimization fuel is incompatible with multiple threads",
);
}
+}
- if codegen_units == Some(0) {
- early_error(
- error_format,
- "value for codegen units must be a positive non-zero integer",
- );
- }
-
- let incremental = match (&debugging_opts.incremental, &cg.incremental) {
- (&Some(ref path1), &Some(ref path2)) => {
+fn select_incremental_path(
+ debugging_opts: &DebuggingOptions,
+ cg: &CodegenOptions,
+ error_format: ErrorOutputType,
+) -> Option<PathBuf> {
+ match (&debugging_opts.incremental, &cg.incremental) {
+ (Some(path1), Some(path2)) => {
if path1 != path2 {
early_error(
error_format,
@@ -2197,25 +2211,19 @@
Some(path1)
}
}
- (&Some(ref path), &None) => Some(path),
- (&None, &Some(ref path)) => Some(path),
- (&None, &None) => None,
- }.map(|m| PathBuf::from(m));
+ (Some(path), None) => Some(path),
+ (None, Some(path)) => Some(path),
+ (None, None) => None,
+ }.map(|m| PathBuf::from(m))
+}
- if debugging_opts.profile && incremental.is_some() {
- early_error(
- error_format,
- "can't instrument with gcov profiling when compiling incrementally",
- );
- }
-
- if cg.profile_generate.enabled() && cg.profile_use.is_some() {
- early_error(
- error_format,
- "options `-C profile-generate` and `-C profile-use` are exclusive",
- );
- }
-
+fn collect_print_requests(
+ cg: &mut CodegenOptions,
+ dopts: &mut DebuggingOptions,
+ matches: &getopts::Matches,
+ is_unstable_enabled: bool,
+ error_format: ErrorOutputType,
+) -> Vec<PrintRequest> {
let mut prints = Vec::<PrintRequest>::new();
if cg.target_cpu.as_ref().map_or(false, |s| s == "help") {
prints.push(PrintRequest::TargetCPUs);
@@ -2233,72 +2241,105 @@
prints.push(PrintRequest::CodeModels);
cg.code_model = None;
}
- if debugging_opts
+ if dopts
.tls_model
.as_ref()
.map_or(false, |s| s == "help")
{
prints.push(PrintRequest::TlsModels);
- debugging_opts.tls_model = None;
+ dopts.tls_model = None;
}
- let cg = cg;
+ prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s {
+ "crate-name" => PrintRequest::CrateName,
+ "file-names" => PrintRequest::FileNames,
+ "sysroot" => PrintRequest::Sysroot,
+ "cfg" => PrintRequest::Cfg,
+ "target-list" => PrintRequest::TargetList,
+ "target-cpus" => PrintRequest::TargetCPUs,
+ "target-features" => PrintRequest::TargetFeatures,
+ "relocation-models" => PrintRequest::RelocationModels,
+ "code-models" => PrintRequest::CodeModels,
+ "tls-models" => PrintRequest::TlsModels,
+ "native-static-libs" => PrintRequest::NativeStaticLibs,
+ "target-spec-json" => {
+ if is_unstable_enabled {
+ PrintRequest::TargetSpec
+ } else {
+ early_error(
+ error_format,
+ "the `-Z unstable-options` flag must also be passed to \
+ enable the target-spec-json print option",
+ );
+ }
+ }
+ req => early_error(error_format, &format!("unknown print request `{}`", req)),
+ }));
- let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
- let target_triple = if let Some(target) = matches.opt_str("target") {
- if target.ends_with(".json") {
+ prints
+}
+
+fn parse_target_triple(matches: &getopts::Matches, error_format: ErrorOutputType) -> TargetTriple {
+ match matches.opt_str("target") {
+ Some(target) if target.ends_with(".json") => {
let path = Path::new(&target);
TargetTriple::from_path(&path).unwrap_or_else(|_|
early_error(error_format, &format!("target file {:?} does not exist", path)))
- } else {
- TargetTriple::TargetTriple(target)
}
+ Some(target) => TargetTriple::TargetTriple(target),
+ _ => TargetTriple::from_triple(host_triple()),
+ }
+}
+
+fn parse_opt_level(
+ matches: &getopts::Matches,
+ cg: &CodegenOptions,
+ error_format: ErrorOutputType,
+) -> OptLevel {
+ // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
+ // to use them interchangeably. However, because they're technically different flags,
+ // we need to work out manually which should take precedence if both are supplied (i.e.
+ // the rightmost flag). We do this by finding the (rightmost) position of both flags and
+ // comparing them. Note that if a flag is not found, its position will be `None`, which
+ // always compared less than `Some(_)`.
+ let max_o = matches.opt_positions("O").into_iter().max();
+ let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
+ if let Some("opt-level") = s.splitn(2, '=').next() {
+ Some(i)
+ } else {
+ None
+ }
+ }).max();
+ if max_o > max_c {
+ OptLevel::Default
} else {
- TargetTriple::from_triple(host_triple())
- };
- let opt_level = {
- // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
- // to use them interchangeably. However, because they're technically different flags,
- // we need to work out manually which should take precedence if both are supplied (i.e.
- // the rightmost flag). We do this by finding the (rightmost) position of both flags and
- // comparing them. Note that if a flag is not found, its position will be `None`, which
- // always compared less than `Some(_)`.
- let max_o = matches.opt_positions("O").into_iter().max();
- let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
- if let Some("opt-level") = s.splitn(2, '=').next() {
- Some(i)
- } else {
- None
- }
- }).max();
- if max_o > max_c {
- OptLevel::Default
- } else {
- match cg.opt_level.as_ref().map(String::as_ref) {
- None => OptLevel::No,
- Some("0") => OptLevel::No,
- Some("1") => OptLevel::Less,
- Some("2") => OptLevel::Default,
- Some("3") => OptLevel::Aggressive,
- Some("s") => OptLevel::Size,
- Some("z") => OptLevel::SizeMin,
- Some(arg) => {
- early_error(
- error_format,
- &format!(
- "optimization level needs to be \
- between 0-3, s or z (instead was `{}`)",
- arg
- ),
- );
- }
+ match cg.opt_level.as_ref().map(String::as_ref) {
+ None => OptLevel::No,
+ Some("0") => OptLevel::No,
+ Some("1") => OptLevel::Less,
+ Some("2") => OptLevel::Default,
+ Some("3") => OptLevel::Aggressive,
+ Some("s") => OptLevel::Size,
+ Some("z") => OptLevel::SizeMin,
+ Some(arg) => {
+ early_error(
+ error_format,
+ &format!(
+ "optimization level needs to be \
+ between 0-3, s or z (instead was `{}`)",
+ arg
+ ),
+ );
}
}
- };
- // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
- // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
- // for more details.
- let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
+ }
+}
+
+fn select_debuginfo(
+ matches: &getopts::Matches,
+ cg: &CodegenOptions,
+ error_format: ErrorOutputType,
+) -> DebugInfo {
let max_g = matches.opt_positions("g").into_iter().max();
let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
if let Some("debuginfo") = s.splitn(2, '=').next() {
@@ -2307,7 +2348,7 @@
None
}
}).max();
- let debuginfo = if max_g > max_c {
+ if max_g > max_c {
DebugInfo::Full
} else {
match cg.debuginfo {
@@ -2325,14 +2366,14 @@
);
}
}
- };
-
- let mut search_paths = vec![];
- for s in &matches.opt_strs("L") {
- search_paths.push(SearchPath::from_cli_opt(&s[..], error_format));
}
+}
- let libs = matches
+fn parse_libs(
+ matches: &getopts::Matches,
+ error_format: ErrorOutputType,
+) -> Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> {
+ matches
.opt_strs("l")
.into_iter()
.map(|s| {
@@ -2371,52 +2412,23 @@
let new_name = name_parts.next();
(name.to_owned(), new_name.map(|n| n.to_owned()), kind)
})
- .collect();
+ .collect()
+}
- let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
- let test = matches.opt_present("test");
-
- let is_unstable_enabled = nightly_options::is_unstable_enabled(matches);
-
- prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s {
- "crate-name" => PrintRequest::CrateName,
- "file-names" => PrintRequest::FileNames,
- "sysroot" => PrintRequest::Sysroot,
- "cfg" => PrintRequest::Cfg,
- "target-list" => PrintRequest::TargetList,
- "target-cpus" => PrintRequest::TargetCPUs,
- "target-features" => PrintRequest::TargetFeatures,
- "relocation-models" => PrintRequest::RelocationModels,
- "code-models" => PrintRequest::CodeModels,
- "tls-models" => PrintRequest::TlsModels,
- "native-static-libs" => PrintRequest::NativeStaticLibs,
- "target-spec-json" => {
- if is_unstable_enabled {
- PrintRequest::TargetSpec
- } else {
- early_error(
- error_format,
- "the `-Z unstable-options` flag must also be passed to \
- enable the target-spec-json print option",
- );
- }
- }
- req => early_error(error_format, &format!("unknown print request `{}`", req)),
- }));
-
- let borrowck_mode = match debugging_opts.borrowck.as_ref().map(|s| &s[..]) {
+fn parse_borrowck_mode(dopts: &DebuggingOptions, error_format: ErrorOutputType) -> BorrowckMode {
+ match dopts.borrowck.as_ref().map(|s| &s[..]) {
None | Some("migrate") => BorrowckMode::Migrate,
Some("mir") => BorrowckMode::Mir,
Some(m) => early_error(error_format, &format!("unknown borrowck mode `{}`", m)),
- };
-
- if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
- early_warn(
- error_format,
- "-C remark requires \"-C debuginfo=n\" to show source locations",
- );
}
+}
+fn parse_externs(
+ matches: &getopts::Matches,
+ debugging_opts: &DebuggingOptions,
+ error_format: ErrorOutputType,
+ is_unstable_enabled: bool,
+) -> Externs {
if matches.opt_present("extern-private") && !debugging_opts.unstable_options {
early_error(
ErrorOutputType::default(),
@@ -2457,10 +2469,14 @@
// flag
entry.is_private_dep |= private;
}
+ Externs(externs)
+}
- let crate_name = matches.opt_str("crate-name");
-
- let remap_path_prefix = matches
+fn parse_remap_path_prefix(
+ matches: &getopts::Matches,
+ error_format: ErrorOutputType
+) -> Vec<(PathBuf, PathBuf)> {
+ matches
.opt_strs("remap-path-prefix")
.into_iter()
.map(|remap| {
@@ -2475,42 +2491,130 @@
),
}
})
- .collect();
+ .collect()
+}
- (
- Options {
- crate_types,
- optimize: opt_level,
- debuginfo,
- lint_opts,
- lint_cap,
- describe_lints,
- output_types: OutputTypes(output_types),
- search_paths,
- maybe_sysroot: sysroot_opt,
- target_triple,
- test,
- incremental,
- debugging_opts,
- prints,
- borrowck_mode,
- cg,
+pub fn build_session_options(matches: &getopts::Matches) -> Options {
+ let color = parse_color(matches);
+
+ let edition = parse_crate_edition(matches);
+
+ let (json_rendered, json_artifact_notifications) = parse_json(matches);
+
+ let error_format = parse_error_format(matches, color, json_rendered);
+
+ let unparsed_crate_types = matches.opt_strs("crate-type");
+ let crate_types = parse_crate_types_from_list(unparsed_crate_types)
+ .unwrap_or_else(|e| early_error(error_format, &e[..]));
+
+ let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
+
+ let mut debugging_opts = build_debugging_options(matches, error_format);
+ check_debug_option_stability(&debugging_opts, error_format, json_rendered);
+
+ let output_types = parse_output_types(&debugging_opts, matches, error_format);
+
+ let mut cg = build_codegen_options(matches, error_format);
+ let (disable_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
+ &output_types,
+ matches,
+ error_format,
+ cg.codegen_units,
+ );
+
+ check_thread_count(&debugging_opts, error_format);
+
+ let incremental = select_incremental_path(&debugging_opts, &cg, error_format);
+
+ if debugging_opts.profile && incremental.is_some() {
+ early_error(
error_format,
- externs: Externs(externs),
- crate_name,
- alt_std_name: None,
- libs,
- unstable_features: UnstableFeatures::from_environment(),
- debug_assertions,
- actually_rustdoc: false,
- cli_forced_codegen_units: codegen_units,
- cli_forced_thinlto_off: disable_thinlto,
- remap_path_prefix,
- edition,
- json_artifact_notifications,
- },
- cfg,
- )
+ "can't instrument with gcov profiling when compiling incrementally",
+ );
+ }
+
+ if cg.profile_generate.enabled() && cg.profile_use.is_some() {
+ early_error(
+ error_format,
+ "options `-C profile-generate` and `-C profile-use` are exclusive",
+ );
+ }
+
+ let is_unstable_enabled = nightly_options::is_unstable_enabled(matches);
+ let prints = collect_print_requests(
+ &mut cg,
+ &mut debugging_opts,
+ matches,
+ is_unstable_enabled,
+ error_format,
+ );
+
+ let cg = cg;
+
+ let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
+ let target_triple = parse_target_triple(matches, error_format);
+ let opt_level = parse_opt_level(matches, &cg, error_format);
+ // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
+ // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
+ // for more details.
+ let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
+ let debuginfo = select_debuginfo(matches, &cg, error_format);
+
+ let mut search_paths = vec![];
+ for s in &matches.opt_strs("L") {
+ search_paths.push(SearchPath::from_cli_opt(&s[..], error_format));
+ }
+
+ let libs = parse_libs(matches, error_format);
+
+ let test = matches.opt_present("test");
+
+ let borrowck_mode = parse_borrowck_mode(&debugging_opts, error_format);
+
+ if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
+ early_warn(
+ error_format,
+ "-C remark requires \"-C debuginfo=n\" to show source locations",
+ );
+ }
+
+ let externs = parse_externs(matches, &debugging_opts, error_format, is_unstable_enabled);
+
+ let crate_name = matches.opt_str("crate-name");
+
+ let remap_path_prefix = parse_remap_path_prefix(matches, error_format);
+
+ Options {
+ crate_types,
+ optimize: opt_level,
+ debuginfo,
+ lint_opts,
+ lint_cap,
+ describe_lints,
+ output_types,
+ search_paths,
+ maybe_sysroot: sysroot_opt,
+ target_triple,
+ test,
+ incremental,
+ debugging_opts,
+ prints,
+ borrowck_mode,
+ cg,
+ error_format,
+ externs,
+ crate_name,
+ alt_std_name: None,
+ libs,
+ unstable_features: UnstableFeatures::from_environment(),
+ debug_assertions,
+ actually_rustdoc: false,
+ cli_forced_codegen_units: codegen_units,
+ cli_forced_thinlto_off: disable_thinlto,
+ remap_path_prefix,
+ edition,
+ json_artifact_notifications,
+ }
}
pub fn make_crate_type_option() -> RustcOptGroup {
diff --git a/src/librustc/session/config/tests.rs b/src/librustc/session/config/tests.rs
index c117418..061bbdc 100644
--- a/src/librustc/session/config/tests.rs
+++ b/src/librustc/session/config/tests.rs
@@ -3,8 +3,9 @@
use crate::middle::cstore;
use crate::session::config::{
build_configuration,
- build_session_options_and_crate_config,
- to_crate_config
+ build_session_options,
+ to_crate_config,
+ parse_cfgspecs,
};
use crate::session::config::{LtoCli, LinkerPluginLto, SwitchWithOptPath, ExternEntry};
use crate::session::build_session;
@@ -18,6 +19,16 @@
use syntax::edition::{Edition, DEFAULT_EDITION};
use syntax;
use super::Options;
+use rustc_data_structures::fx::FxHashSet;
+
+pub fn build_session_options_and_crate_config(
+ matches: &getopts::Matches,
+) -> (Options, FxHashSet<(String, Option<String>)>) {
+ (
+ build_session_options(matches),
+ parse_cfgspecs(matches.opt_strs("cfg")),
+ )
+}
impl ExternEntry {
fn new_public<S: Into<String>,
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index fa2902e..c59df14 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -28,7 +28,7 @@
use syntax::feature_gate::{self, AttributeType};
use syntax::json::JsonEmitter;
use syntax::source_map;
-use syntax::parse::{self, ParseSess};
+use syntax::sess::ParseSess;
use syntax::symbol::Symbol;
use syntax_pos::{MultiSpan, Span};
use crate::util::profiling::{SelfProfiler, SelfProfilerRef};
@@ -1159,7 +1159,7 @@
);
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
- let parse_sess = parse::ParseSess::with_span_handler(
+ let parse_sess = ParseSess::with_span_handler(
span_diagnostic,
source_map,
);
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index cd52f8f..256194c 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -43,7 +43,7 @@
use crate::ty::{BoundVar, BindingMode};
use crate::ty::CanonicalPolyFnSig;
use crate::util::common::ErrorReported;
-use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet};
+use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet, NodeMap};
use crate::util::nodemap::{FxHashMap, FxHashSet};
use crate::util::profiling::SelfProfilerRef;
@@ -1051,6 +1051,9 @@
/// Common consts, pre-interned for your convenience.
pub consts: CommonConsts<'tcx>,
+ /// Resolutions of `extern crate` items produced by resolver.
+ extern_crate_map: NodeMap<CrateNum>,
+
/// Map indicating what traits are in scope for places where this
/// is relevant; generated by resolve.
trait_map: FxHashMap<DefIndex,
@@ -1274,6 +1277,7 @@
types: common_types,
lifetimes: common_lifetimes,
consts: common_consts,
+ extern_crate_map: resolutions.extern_crate_map,
trait_map,
export_map: resolutions.export_map.into_iter().map(|(k, v)| {
let exports: Vec<_> = v.into_iter().map(|e| {
@@ -2951,7 +2955,7 @@
};
providers.extern_mod_stmt_cnum = |tcx, id| {
let id = tcx.hir().as_local_node_id(id).unwrap();
- tcx.cstore.extern_mod_stmt_cnum_untracked(id)
+ tcx.extern_crate_map.get(&id).cloned()
};
providers.all_crate_nums = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index ce7e182..aed9e87 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -824,10 +824,14 @@
});
(present_variants.next(), present_variants.next())
};
- if present_first.is_none() {
+ let present_first = match present_first {
+ present_first @ Some(_) => present_first,
// Uninhabited because it has no variants, or only absent ones.
- return tcx.layout_raw(param_env.and(tcx.types.never));
- }
+ None if def.is_enum() => return tcx.layout_raw(param_env.and(tcx.types.never)),
+ // if it's a struct, still compute a layout so that we can still compute the
+ // field offsets
+ None => Some(VariantIdx::new(0)),
+ };
let is_struct = !def.is_enum() ||
// Only one variant is present.
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 3692caa..00b5fa2 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -28,7 +28,7 @@
use crate::ty::util::{IntTypeExt, Discr};
use crate::ty::walk::TypeWalker;
use crate::util::captures::Captures;
-use crate::util::nodemap::{NodeSet, DefIdMap, FxHashMap};
+use crate::util::nodemap::{NodeMap, NodeSet, DefIdMap, FxHashMap};
use arena::SyncDroplessArena;
use crate::session::DataTypeKind;
@@ -121,6 +121,7 @@
#[derive(Clone)]
pub struct Resolutions {
+ pub extern_crate_map: NodeMap<CrateNum>,
pub trait_map: TraitMap,
pub maybe_unused_trait_imports: NodeSet,
pub maybe_unused_extern_crates: Vec<(NodeId, Span)>,
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index c4967f8..363109a 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -1483,7 +1483,7 @@
}
// Replace any anonymous late-bound regions with named
- // variants, using gensym'd identifiers, so that we can
+ // variants, using new unique identifiers, so that we can
// clearly differentiate between named and unnamed regions in
// the output. We'll probably want to tweak this over time to
// decide just how much information to give.
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 5ddf153..e1eab2c 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -697,6 +697,9 @@
// that type, and when we finish expanding that type we remove the
// its DefId.
seen_opaque_tys: FxHashSet<DefId>,
+ // Cache of all expansions we've seen so far. This is a critical
+ // optimization for some large types produced by async fn trees.
+ expanded_cache: FxHashMap<(DefId, SubstsRef<'tcx>), Ty<'tcx>>,
primary_def_id: DefId,
found_recursion: bool,
tcx: TyCtxt<'tcx>,
@@ -713,9 +716,16 @@
}
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);
+ let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) {
+ Some(expanded_ty) => expanded_ty,
+ None => {
+ 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);
+ self.expanded_cache.insert((def_id, substs), expanded_ty);
+ expanded_ty
+ }
+ };
self.seen_opaque_tys.remove(&def_id);
Some(expanded_ty)
} else {
@@ -735,14 +745,17 @@
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Opaque(def_id, substs) = t.kind {
self.expand_opaque_ty(def_id, substs).unwrap_or(t)
- } else {
+ } else if t.has_projections() {
t.super_fold_with(self)
+ } else {
+ t
}
}
}
let mut visitor = OpaqueTypeExpander {
seen_opaque_tys: FxHashSet::default(),
+ expanded_cache: FxHashMap::default(),
primary_def_id: def_id,
found_recursion: false,
tcx: self,
@@ -1096,6 +1109,9 @@
ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
+ // Zero-length arrays never contain anything to drop.
+ ty::Array(_, len) if len.try_eval_usize(tcx, param_env) == Some(0) => false,
+
// Structural recursion.
ty::Array(ty, _) | ty::Slice(ty) => needs_drop(ty),
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index 71a6067..98be0ae 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -52,6 +52,7 @@
impl BackendTypes for Builder<'_, 'll, 'tcx> {
type Value = <CodegenCx<'ll, 'tcx> as BackendTypes>::Value;
+ type Function = <CodegenCx<'ll, 'tcx> as BackendTypes>::Function;
type BasicBlock = <CodegenCx<'ll, 'tcx> as BackendTypes>::BasicBlock;
type Type = <CodegenCx<'ll, 'tcx> as BackendTypes>::Type;
type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet;
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index 35d5107..08fa23f 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -33,7 +33,7 @@
assert!(!instance.substs.has_param_types());
let sig = instance.fn_sig(cx.tcx());
- if let Some(&llfn) = cx.instances().borrow().get(&instance) {
+ if let Some(&llfn) = cx.instances.borrow().get(&instance) {
return llfn;
}
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index 6fbea96..a1a5232 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -2,7 +2,7 @@
//! Code that is useful in various codegen modules.
-use crate::llvm::{self, True, False, Bool, BasicBlock, OperandBundleDef};
+use crate::llvm::{self, True, False, Bool, BasicBlock, OperandBundleDef, ConstantInt};
use crate::abi;
use crate::consts;
use crate::type_::Type;
@@ -86,6 +86,8 @@
impl BackendTypes for CodegenCx<'ll, 'tcx> {
type Value = &'ll Value;
+ type Function = &'ll Value;
+
type BasicBlock = &'ll BasicBlock;
type Type = &'ll Type;
type Funclet = Funclet<'ll>;
@@ -243,33 +245,23 @@
struct_in_context(self.llcx, elts, packed)
}
- fn const_to_uint(&self, v: &'ll Value) -> u64 {
- unsafe {
+ fn const_to_opt_uint(&self, v: &'ll Value) -> Option<u64> {
+ try_as_const_integral(v).map(|v| unsafe {
llvm::LLVMConstIntGetZExtValue(v)
- }
- }
-
- fn is_const_integral(&self, v: &'ll Value) -> bool {
- unsafe {
- llvm::LLVMIsAConstantInt(v).is_some()
- }
+ })
}
fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option<u128> {
- unsafe {
- if self.is_const_integral(v) {
- let (mut lo, mut hi) = (0u64, 0u64);
- let success = llvm::LLVMRustConstInt128Get(v, sign_ext,
- &mut hi, &mut lo);
- if success {
- Some(hi_lo_to_u128(lo, hi))
- } else {
- None
- }
+ try_as_const_integral(v).and_then(|v| unsafe {
+ let (mut lo, mut hi) = (0u64, 0u64);
+ let success = llvm::LLVMRustConstInt128Get(v, sign_ext,
+ &mut hi, &mut lo);
+ if success {
+ Some(hi_lo_to_u128(lo, hi))
} else {
None
}
- }
+ })
}
fn scalar_to_backend(
@@ -305,7 +297,7 @@
}
}
Some(GlobalAlloc::Function(fn_instance)) => {
- self.get_fn(fn_instance)
+ self.get_fn_addr(fn_instance)
}
Some(GlobalAlloc::Static(def_id)) => {
assert!(self.tcx.is_static(def_id));
@@ -386,3 +378,9 @@
fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 {
((hi as u128) << 64) | (lo as u128)
}
+
+fn try_as_const_integral(v: &'ll Value) -> Option<&'ll ConstantInt> {
+ unsafe {
+ llvm::LLVMIsAConstantInt(v)
+ }
+}
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 7ca2269..2da9387 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -20,7 +20,6 @@
use rustc::ty::{self, Ty, TyCtxt, Instance};
use rustc::util::nodemap::FxHashMap;
use rustc_target::spec::{HasTargetSpec, Target};
-use rustc_codegen_ssa::callee::resolve_and_get_fn;
use rustc_codegen_ssa::base::wants_msvc_seh;
use crate::callee::get_fn;
@@ -327,11 +326,11 @@
&self.vtables
}
- fn instances(&self) -> &RefCell<FxHashMap<Instance<'tcx>, &'ll Value>> {
- &self.instances
+ fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value {
+ get_fn(self, instance)
}
- fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value {
+ fn get_fn_addr(&self, instance: Instance<'tcx>) -> &'ll Value {
get_fn(self, instance)
}
@@ -362,7 +361,14 @@
let tcx = self.tcx;
let llfn = match tcx.lang_items().eh_personality() {
Some(def_id) if !wants_msvc_seh(self.sess()) => {
- resolve_and_get_fn(self, def_id, tcx.intern_substs(&[]))
+ self.get_fn_addr(
+ ty::Instance::resolve(
+ tcx,
+ ty::ParamEnv::reveal_all(),
+ def_id,
+ tcx.intern_substs(&[]),
+ ).unwrap()
+ )
}
_ => {
let name = if wants_msvc_seh(self.sess()) {
@@ -390,7 +396,14 @@
let tcx = self.tcx;
assert!(self.sess().target.target.options.custom_unwind_resume);
if let Some(def_id) = tcx.lang_items().eh_unwind_resume() {
- let llfn = resolve_and_get_fn(self, def_id, tcx.intern_substs(&[]));
+ let llfn = self.get_fn_addr(
+ ty::Instance::resolve(
+ tcx,
+ ty::ParamEnv::reveal_all(),
+ def_id,
+ tcx.intern_substs(&[]),
+ ).unwrap()
+ );
unwresume.set(Some(llfn));
return llfn;
}
diff --git a/src/librustc_codegen_llvm/error_codes.rs b/src/librustc_codegen_llvm/error_codes.rs
deleted file mode 100644
index 042e51e..0000000
--- a/src/librustc_codegen_llvm/error_codes.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-register_diagnostics! {
-
-E0511: r##"
-Invalid monomorphization of an intrinsic function was used. Erroneous code
-example:
-
-```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
-#![feature(platform_intrinsics)]
-
-extern "platform-intrinsic" {
- fn simd_add<T>(a: T, b: T) -> T;
-}
-
-fn main() {
- unsafe { simd_add(0, 1); }
- // error: invalid monomorphization of `simd_add` intrinsic
-}
-```
-
-The generic type has to be a SIMD type. Example:
-
-```
-#![feature(repr_simd)]
-#![feature(platform_intrinsics)]
-
-#[repr(simd)]
-#[derive(Copy, Clone)]
-struct i32x2(i32, i32);
-
-extern "platform-intrinsic" {
- fn simd_add<T>(a: T, b: T) -> T;
-}
-
-unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok!
-```
-"##,
-
-}
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 68d9af0..3df8d4c 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -20,9 +20,9 @@
use rustc::hir;
use syntax::ast::{self, FloatTy};
+use rustc_codegen_ssa::common::span_invalid_monomorphization_error;
use rustc_codegen_ssa::traits::*;
-use rustc::session::Session;
use syntax_pos::Span;
use std::cmp::Ordering;
@@ -1026,10 +1026,6 @@
rust_try
}
-fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
- span_err!(a, b, E0511, "{}", c);
-}
-
fn generic_simd_intrinsic(
bx: &mut Builder<'a, 'll, 'tcx>,
name: &str,
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 52797e6..fde04a6 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -38,7 +38,7 @@
extern crate rustc_driver as _;
#[macro_use] extern crate log;
-#[macro_use] extern crate syntax;
+extern crate syntax;
extern crate syntax_pos;
extern crate rustc_errors as errors;
@@ -64,8 +64,6 @@
use rustc_codegen_ssa::ModuleCodegen;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
-mod error_codes;
-
mod back {
pub mod archive;
pub mod bytecode;
@@ -258,10 +256,6 @@
llvm_util::print_version();
}
- fn diagnostics(&self) -> &[(&'static str, &'static str)] {
- &error_codes::DIAGNOSTICS
- }
-
fn target_features(&self, sess: &Session) -> Vec<Symbol> {
target_features(sess)
}
@@ -271,15 +265,10 @@
}
fn provide(&self, providers: &mut ty::query::Providers<'_>) {
- rustc_codegen_utils::symbol_names::provide(providers);
- rustc_codegen_ssa::back::symbol_export::provide(providers);
- rustc_codegen_ssa::base::provide_both(providers);
attributes::provide(providers);
}
fn provide_extern(&self, providers: &mut ty::query::Providers<'_>) {
- rustc_codegen_ssa::back::symbol_export::provide_extern(providers);
- rustc_codegen_ssa::base::provide_both(providers);
attributes::provide_extern(providers);
}
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index b07214f..a2313b9 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -510,6 +510,7 @@
extern { pub type Context; }
extern { pub type Type; }
extern { pub type Value; }
+extern { pub type ConstantInt; }
extern { pub type Metadata; }
extern { pub type BasicBlock; }
#[repr(C)]
@@ -719,8 +720,8 @@
pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value;
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value;
pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value;
- pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong;
- pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool,
+ pub fn LLVMConstIntGetZExtValue(ConstantVal: &ConstantInt) -> c_ulonglong;
+ pub fn LLVMRustConstInt128Get(ConstantVal: &ConstantInt, SExt: bool,
high: &mut u64, low: &mut u64) -> bool;
@@ -1666,7 +1667,7 @@
#[allow(improper_ctypes)]
pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString);
- pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>;
+ pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&ConstantInt>;
pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind;
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>;
diff --git a/src/librustc_codegen_ssa/README.md b/src/librustc_codegen_ssa/README.md
index c8bb2e7..a09a0c2 100644
--- a/src/librustc_codegen_ssa/README.md
+++ b/src/librustc_codegen_ssa/README.md
@@ -84,7 +84,7 @@
{
fn new_block<'b>(
cx: &'a Self::CodegenCx,
- llfn: Self::Value,
+ llfn: Self::Function,
name: &'b str
) -> Self;
/* ... */
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 481db26..5339134 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -22,7 +22,8 @@
use rustc::util::profiling::SelfProfilerRef;
use rustc_fs_util::link_or_copy;
use rustc_data_structures::svh::Svh;
-use rustc_errors::{Handler, Level, FatalError, DiagnosticId};
+use rustc_data_structures::sync::Lrc;
+use rustc_errors::{Handler, Level, FatalError, DiagnosticId, SourceMapperDyn};
use rustc_errors::emitter::{Emitter};
use rustc_target::spec::MergeFunctions;
use syntax::attr;
@@ -1666,13 +1667,13 @@
}
impl Emitter for SharedEmitter {
- fn emit_diagnostic(&mut self, db: &rustc_errors::Diagnostic) {
+ fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) {
drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
- msg: db.message(),
- code: db.code.clone(),
- lvl: db.level,
+ msg: diag.message(),
+ code: diag.code.clone(),
+ lvl: diag.level,
})));
- for child in &db.children {
+ for child in &diag.children {
drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
msg: child.message(),
code: None,
@@ -1681,6 +1682,9 @@
}
drop(self.sender.send(SharedEmitterMessage::AbortIfErrors));
}
+ fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>> {
+ None
+ }
}
impl SharedEmitterMain {
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index 9350877..1c441ca 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -36,7 +36,6 @@
use crate::back::write::{OngoingCodegen, start_async_codegen, submit_pre_lto_module_to_llvm,
submit_post_lto_module_to_llvm};
use crate::{MemFlags, CrateInfo};
-use crate::callee;
use crate::common::{RealPredicate, TypeKind, IntPredicate};
use crate::meth;
use crate::mir;
@@ -377,8 +376,7 @@
let sig = instance.fn_sig(cx.tcx());
let sig = cx.tcx().normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
- let lldecl = cx.instances().borrow().get(&instance).cloned().unwrap_or_else(||
- bug!("Instance `{:?}` not already declared", instance));
+ let lldecl = cx.get_fn(instance);
let mir = cx.tcx().instance_mir(instance.def);
mir::codegen_mir::<Bx>(cx, lldecl, &mir, instance, sig);
@@ -400,7 +398,7 @@
return;
}
- let main_llfn = cx.get_fn(instance);
+ let main_llfn = cx.get_fn_addr(instance);
let et = cx.tcx().entry_fn(LOCAL_CRATE).map(|e| e.1);
match et {
@@ -455,10 +453,13 @@
let (start_fn, args) = if use_start_lang_item {
let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None);
- let start_fn = callee::resolve_and_get_fn(
- cx,
- start_def_id,
- cx.tcx().intern_substs(&[main_ret_ty.into()]),
+ let start_fn = cx.get_fn_addr(
+ ty::Instance::resolve(
+ cx.tcx(),
+ ty::ParamEnv::reveal_all(),
+ start_def_id,
+ cx.tcx().intern_substs(&[main_ret_ty.into()]),
+ ).unwrap()
);
(start_fn, vec![bx.pointercast(rust_main, cx.type_ptr_to(cx.type_i8p())),
arg_argc, arg_argv])
diff --git a/src/librustc_codegen_ssa/callee.rs b/src/librustc_codegen_ssa/callee.rs
deleted file mode 100644
index 6ba6774..0000000
--- a/src/librustc_codegen_ssa/callee.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-use crate::traits::*;
-use rustc::ty;
-use rustc::ty::subst::SubstsRef;
-use rustc::hir::def_id::DefId;
-
-pub fn resolve_and_get_fn<'tcx, Cx: CodegenMethods<'tcx>>(
- cx: &Cx,
- def_id: DefId,
- substs: SubstsRef<'tcx>,
-) -> Cx::Value {
- cx.get_fn(
- ty::Instance::resolve(
- cx.tcx(),
- ty::ParamEnv::reveal_all(),
- def_id,
- substs
- ).unwrap()
- )
-}
-
-pub fn resolve_and_get_fn_for_ptr<'tcx,
- Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
->(
- cx: &Cx,
- def_id: DefId,
- substs: SubstsRef<'tcx>,
-) -> Cx::Value {
- cx.get_fn(
- ty::Instance::resolve_for_fn_ptr(
- cx.tcx(),
- ty::ParamEnv::reveal_all(),
- def_id,
- substs
- ).unwrap()
- )
-}
-
-pub fn resolve_and_get_fn_for_vtable<'tcx,
- Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx>
->(
- cx: &Cx,
- def_id: DefId,
- substs: SubstsRef<'tcx>,
-) -> Cx::Value {
- cx.get_fn(
- ty::Instance::resolve_for_vtable(
- cx.tcx(),
- ty::ParamEnv::reveal_all(),
- def_id,
- substs
- ).unwrap()
- )
-}
diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs
index e3aa35e..ac39ca9 100644
--- a/src/librustc_codegen_ssa/common.rs
+++ b/src/librustc_codegen_ssa/common.rs
@@ -1,6 +1,7 @@
#![allow(non_camel_case_types, non_snake_case)]
use rustc::ty::{Ty, TyCtxt};
+use rustc::session::Session;
use syntax_pos::Span;
use rustc::hir::def_id::DefId;
@@ -200,3 +201,7 @@
_ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
}
}
+
+pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
+ span_err!(a, b, E0511, "{}", c);
+}
diff --git a/src/librustc_codegen_ssa/error_codes.rs b/src/librustc_codegen_ssa/error_codes.rs
index 8ff41c2..02e26d8 100644
--- a/src/librustc_codegen_ssa/error_codes.rs
+++ b/src/librustc_codegen_ssa/error_codes.rs
@@ -1,5 +1,40 @@
syntax::register_diagnostics! {
+E0511: r##"
+Invalid monomorphization of an intrinsic function was used. Erroneous code
+example:
+
+```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
+#![feature(platform_intrinsics)]
+
+extern "platform-intrinsic" {
+ fn simd_add<T>(a: T, b: T) -> T;
+}
+
+fn main() {
+ unsafe { simd_add(0, 1); }
+ // error: invalid monomorphization of `simd_add` intrinsic
+}
+```
+
+The generic type has to be a SIMD type. Example:
+
+```
+#![feature(repr_simd)]
+#![feature(platform_intrinsics)]
+
+#[repr(simd)]
+#[derive(Copy, Clone)]
+struct i32x2(i32, i32);
+
+extern "platform-intrinsic" {
+ fn simd_add<T>(a: T, b: T) -> T;
+}
+
+unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok!
+```
+"##,
+
E0668: r##"
Malformed inline assembly rejected by LLVM.
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index d700001..0221a04 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -27,6 +27,7 @@
use rustc::session::config::{OutputFilenames, OutputType};
use rustc::middle::lang_items::LangItem;
use rustc::hir::def_id::CrateNum;
+use rustc::ty::query::Providers;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::svh::Svh;
@@ -41,7 +42,6 @@
pub mod mir;
pub mod debuginfo;
pub mod base;
-pub mod callee;
pub mod glue;
pub mod meth;
pub mod mono_item;
@@ -156,3 +156,13 @@
pub linker_info: back::linker::LinkerInfo,
pub crate_info: CrateInfo,
}
+
+pub fn provide(providers: &mut Providers<'_>) {
+ crate::back::symbol_export::provide(providers);
+ crate::base::provide_both(providers);
+}
+
+pub fn provide_extern(providers: &mut Providers<'_>) {
+ crate::back::symbol_export::provide_extern(providers);
+ crate::base::provide_both(providers);
+}
diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs
index 7fe9f5f..266d2e5 100644
--- a/src/librustc_codegen_ssa/meth.rs
+++ b/src/librustc_codegen_ssa/meth.rs
@@ -1,6 +1,5 @@
use rustc_target::abi::call::FnType;
-use crate::callee;
use crate::traits::*;
use rustc::ty::{self, Ty, Instance};
@@ -92,7 +91,14 @@
let methods = methods.cloned().map(|opt_mth| {
opt_mth.map_or(nullptr, |(def_id, substs)| {
- callee::resolve_and_get_fn_for_vtable(cx, def_id, substs)
+ cx.get_fn_addr(
+ ty::Instance::resolve_for_vtable(
+ cx.tcx(),
+ ty::ParamEnv::reveal_all(),
+ def_id,
+ substs,
+ ).unwrap()
+ )
})
});
@@ -102,7 +108,7 @@
// `get_vtable` in rust_mir/interpret/traits.rs
// /////////////////////////////////////////////////////////////////////////////////////////////
let components: Vec<_> = [
- cx.get_fn(Instance::resolve_drop_in_place(cx.tcx(), ty)),
+ cx.get_fn_addr(Instance::resolve_drop_in_place(cx.tcx(), ty)),
cx.const_usize(layout.size.bytes()),
cx.const_usize(layout.align.abi.bytes())
].iter().cloned().chain(methods).collect();
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index b0df81b..dc77d02 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -358,7 +358,7 @@
(meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_ty), fn_ty)
}
_ => {
- (bx.get_fn(drop_fn),
+ (bx.get_fn_addr(drop_fn),
FnType::of_instance(&bx, drop_fn))
}
};
@@ -460,7 +460,7 @@
let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item);
let instance = ty::Instance::mono(bx.tcx(), def_id);
let fn_ty = FnType::of_instance(&bx, instance);
- let llfn = bx.get_fn(instance);
+ let llfn = bx.get_fn_addr(instance);
// Codegen the actual panic invoke/call.
helper.do_call(self, &mut bx, fn_ty, llfn, &args, None, cleanup);
@@ -576,7 +576,7 @@
common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem);
let instance = ty::Instance::mono(bx.tcx(), def_id);
let fn_ty = FnType::of_instance(&bx, instance);
- let llfn = bx.get_fn(instance);
+ let llfn = bx.get_fn_addr(instance);
if let Some((_, target)) = destination.as_ref() {
helper.maybe_sideeffect(self.mir, &mut bx, &[*target]);
@@ -793,7 +793,7 @@
let fn_ptr = match (llfn, instance) {
(Some(llfn), _) => llfn,
- (None, Some(instance)) => bx.get_fn(instance),
+ (None, Some(instance)) => bx.get_fn_addr(instance),
_ => span_bug!(span, "no llfn for call"),
};
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index d5612d7..1a2e796 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -30,7 +30,7 @@
debug_context: FunctionDebugContext<Bx::DIScope>,
- llfn: Bx::Value,
+ llfn: Bx::Function,
cx: &'a Bx::CodegenCx,
@@ -183,7 +183,7 @@
pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx,
- llfn: Bx::Value,
+ llfn: Bx::Function,
mir: &'a Body<'tcx>,
instance: Instance<'tcx>,
sig: ty::FnSig<'tcx>,
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index 2d97f82..1d1bc2a 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -394,8 +394,8 @@
// Statically compute the offset if we can, otherwise just use the element size,
// as this will yield the lowest alignment.
let layout = self.layout.field(bx, 0);
- let offset = if bx.is_const_integral(llindex) {
- layout.size.checked_mul(bx.const_to_uint(llindex), bx).unwrap_or(layout.size)
+ let offset = if let Some(llindex) = bx.const_to_opt_uint(llindex) {
+ layout.size.checked_mul(llindex, bx).unwrap_or(layout.size)
} else {
layout.size
};
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index 978e721..27442bb 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -10,7 +10,6 @@
use crate::base;
use crate::MemFlags;
-use crate::callee;
use crate::common::{self, RealPredicate, IntPredicate};
use crate::traits::*;
@@ -95,7 +94,7 @@
let size = bx.const_usize(dest.layout.size.bytes());
// Use llvm.memset.p0i8.* to initialize all zero arrays
- if bx.cx().is_const_integral(v) && bx.cx().const_to_uint(v) == 0 {
+ if bx.cx().const_to_opt_uint(v) == Some(0) {
let fill = bx.cx().const_u8(0);
bx.memset(start, fill, size, dest.align, MemFlags::empty());
return bx;
@@ -190,7 +189,15 @@
bug!("reifying a fn ptr that requires const arguments");
}
OperandValue::Immediate(
- callee::resolve_and_get_fn_for_ptr(bx.cx(), def_id, substs))
+ bx.get_fn_addr(
+ ty::Instance::resolve_for_fn_ptr(
+ bx.tcx(),
+ ty::ParamEnv::reveal_all(),
+ def_id,
+ substs
+ ).unwrap()
+ )
+ )
}
_ => {
bug!("{} cannot be reified to a fn ptr", operand.layout.ty)
@@ -205,7 +212,7 @@
def_id,
substs,
ty::ClosureKind::FnOnce);
- OperandValue::Immediate(bx.cx().get_fn(instance))
+ OperandValue::Immediate(bx.cx().get_fn_addr(instance))
}
_ => {
bug!("{} cannot be cast to a fn ptr", operand.layout.ty)
@@ -488,7 +495,7 @@
}
};
let instance = ty::Instance::mono(bx.tcx(), def_id);
- let r = bx.cx().get_fn(instance);
+ let r = bx.cx().get_fn_addr(instance);
let call = bx.call(r, &[llsize, llalign], None);
let val = bx.pointercast(call, llty_ptr);
diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs
index cb197f5..a7faf4e 100644
--- a/src/librustc_codegen_ssa/traits/backend.rs
+++ b/src/librustc_codegen_ssa/traits/backend.rs
@@ -14,6 +14,8 @@
pub trait BackendTypes {
type Value: CodegenObject;
+ type Function: CodegenObject;
+
type BasicBlock: Copy;
type Type: CodegenObject;
type Funclet;
diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs
index 1886701..62b5bcb 100644
--- a/src/librustc_codegen_ssa/traits/builder.rs
+++ b/src/librustc_codegen_ssa/traits/builder.rs
@@ -34,7 +34,7 @@
+ HasTargetSpec
{
- fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self;
+ fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &'b str) -> Self;
fn with_cx(cx: &'a Self::CodegenCx) -> Self;
fn build_sibling_block(&self, name: &str) -> Self;
fn cx(&self) -> &Self::CodegenCx;
diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs
index e7ce03f..95ada60 100644
--- a/src/librustc_codegen_ssa/traits/consts.rs
+++ b/src/librustc_codegen_ssa/traits/consts.rs
@@ -21,11 +21,9 @@
fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
- fn const_to_uint(&self, v: Self::Value) -> u64;
+ fn const_to_opt_uint(&self, v: Self::Value) -> Option<u64>;
fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option<u128>;
- fn is_const_integral(&self, v: Self::Value) -> bool;
-
fn scalar_to_backend(
&self,
cv: Scalar,
diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs
index e75f247..989e6cf 100644
--- a/src/librustc_codegen_ssa/traits/debuginfo.rs
+++ b/src/librustc_codegen_ssa/traits/debuginfo.rs
@@ -20,7 +20,7 @@
&self,
instance: Instance<'tcx>,
sig: ty::FnSig<'tcx>,
- llfn: Self::Value,
+ llfn: Self::Function,
mir: &mir::Body<'_>,
) -> FunctionDebugContext<Self::DIScope>;
diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/src/librustc_codegen_ssa/traits/declare.rs
index 624a982..cd42044 100644
--- a/src/librustc_codegen_ssa/traits/declare.rs
+++ b/src/librustc_codegen_ssa/traits/declare.rs
@@ -17,13 +17,13 @@
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
- fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Value;
+ fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Function;
/// Declare a Rust function.
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
- fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::Value;
+ fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::Function;
/// Declare a global with an intention to define it.
///
diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs
index 46c88a6..658ddd0 100644
--- a/src/librustc_codegen_ssa/traits/misc.rs
+++ b/src/librustc_codegen_ssa/traits/misc.rs
@@ -11,14 +11,14 @@
&self,
) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>;
fn check_overflow(&self) -> bool;
- fn instances(&self) -> &RefCell<FxHashMap<Instance<'tcx>, Self::Value>>;
- fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value;
+ fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function;
+ fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value;
fn eh_personality(&self) -> Self::Value;
fn eh_unwind_resume(&self) -> Self::Value;
fn sess(&self) -> &Session;
fn codegen_unit(&self) -> &Arc<CodegenUnit<'tcx>>;
fn used_statics(&self) -> &RefCell<Vec<Self::Value>>;
- fn set_frame_pointer_elimination(&self, llfn: Self::Value);
- fn apply_target_cpu_attr(&self, llfn: Self::Value);
+ fn set_frame_pointer_elimination(&self, llfn: Self::Function);
+ fn apply_target_cpu_attr(&self, llfn: Self::Function);
fn create_used_variable(&self);
}
diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs
index efe4a25..4318ef1 100644
--- a/src/librustc_codegen_ssa/traits/mod.rs
+++ b/src/librustc_codegen_ssa/traits/mod.rs
@@ -88,6 +88,7 @@
type CodegenCx: CodegenMethods<'tcx>
+ BackendTypes<
Value = Self::Value,
+ Function = Self::Function,
BasicBlock = Self::BasicBlock,
Type = Self::Type,
Funclet = Self::Funclet,
diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs
index 2e3af84..1077c1f 100644
--- a/src/librustc_codegen_utils/codegen_backend.rs
+++ b/src/librustc_codegen_utils/codegen_backend.rs
@@ -25,7 +25,6 @@
fn target_features(&self, _sess: &Session) -> Vec<Symbol> { vec![] }
fn print_passes(&self) {}
fn print_version(&self) {}
- fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] }
fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync>;
fn provide(&self, _providers: &mut Providers<'_>);
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index 1201446..6692034 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -18,6 +18,7 @@
extern crate rustc;
use rustc::ty::TyCtxt;
+use rustc::ty::query::Providers;
use rustc::hir::def_id::LOCAL_CRATE;
use syntax::symbol::sym;
@@ -37,3 +38,7 @@
}
}
}
+
+pub fn provide(providers: &mut Providers<'_>) {
+ crate::symbol_names::provide(providers);
+}
diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs
index 3277b85..9622c29 100644
--- a/src/librustc_data_structures/sync.rs
+++ b/src/librustc_data_structures/sync.rs
@@ -1,6 +1,6 @@
//! This module defines types which are thread safe if cfg!(parallel_compiler) is true.
//!
-//! `Lrc` is an alias of either Rc or Arc.
+//! `Lrc` is an alias of `Arc` if cfg!(parallel_compiler) is true, `Rc` otherwise.
//!
//! `Lock` is a mutex.
//! It internally uses `parking_lot::Mutex` if cfg!(parallel_compiler) is true,
@@ -12,7 +12,7 @@
//!
//! `MTLock` is a mutex which disappears if cfg!(parallel_compiler) is false.
//!
-//! `MTRef` is a immutable reference if cfg!(parallel_compiler), and an mutable reference otherwise.
+//! `MTRef` is an immutable reference if cfg!(parallel_compiler), and a mutable reference otherwise.
//!
//! `rustc_erase_owner!` erases a OwningRef owner into Erased or Erased + Send + Sync
//! depending on the value of cfg!(parallel_compiler).
@@ -23,29 +23,6 @@
use std::ops::{Deref, DerefMut};
use crate::owning_ref::{Erased, OwningRef};
-pub fn serial_join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
- where A: FnOnce() -> RA,
- B: FnOnce() -> RB
-{
- (oper_a(), oper_b())
-}
-
-pub struct SerialScope;
-
-impl SerialScope {
- pub fn spawn<F>(&self, f: F)
- where F: FnOnce(&SerialScope)
- {
- f(self)
- }
-}
-
-pub fn serial_scope<F, R>(f: F) -> R
- where F: FnOnce(&SerialScope) -> R
-{
- f(&SerialScope)
-}
-
pub use std::sync::atomic::Ordering::SeqCst;
pub use std::sync::atomic::Ordering;
@@ -176,8 +153,28 @@
pub type AtomicU32 = Atomic<u32>;
pub type AtomicU64 = Atomic<u64>;
- pub use self::serial_join as join;
- pub use self::serial_scope as scope;
+ pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
+ where A: FnOnce() -> RA,
+ B: FnOnce() -> RB
+ {
+ (oper_a(), oper_b())
+ }
+
+ pub struct SerialScope;
+
+ impl SerialScope {
+ pub fn spawn<F>(&self, f: F)
+ where F: FnOnce(&SerialScope)
+ {
+ f(self)
+ }
+ }
+
+ pub fn scope<F, R>(f: F) -> R
+ where F: FnOnce(&SerialScope) -> R
+ {
+ f(&SerialScope)
+ }
#[macro_export]
macro_rules! parallel {
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index dd088b6..f33cb4e 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -166,7 +166,8 @@
None => return Ok(()),
};
- let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
+ let sopts = config::build_session_options(&matches);
+ let cfg = config::parse_cfgspecs(matches.opt_strs("cfg"));
let mut dummy_config = |sopts, cfg, diagnostic_output| {
let mut config = interface::Config {
@@ -615,7 +616,7 @@
let mut v = Vec::new();
locator::list_file_metadata(&sess.target.target,
path,
- &*cstore.metadata_loader,
+ cstore,
&mut v)
.unwrap();
println!("{}", String::from_utf8(v).unwrap());
diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index 0281d10..491bc2a 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -31,24 +31,28 @@
impl Emitter for AnnotateSnippetEmitterWriter {
/// The entry point for the diagnostics generation
- fn emit_diagnostic(&mut self, db: &Diagnostic) {
- let mut children = db.children.clone();
- let (mut primary_span, suggestions) = self.primary_span_formatted(&db);
+ fn emit_diagnostic(&mut self, diag: &Diagnostic) {
+ let mut children = diag.children.clone();
+ let (mut primary_span, suggestions) = self.primary_span_formatted(&diag);
self.fix_multispans_in_std_macros(&self.source_map,
&mut primary_span,
&mut children,
- &db.level,
+ &diag.level,
self.external_macro_backtrace);
- self.emit_messages_default(&db.level,
- db.message(),
- &db.code,
+ self.emit_messages_default(&diag.level,
+ diag.message(),
+ &diag.code,
&primary_span,
&children,
&suggestions);
}
+ fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>> {
+ self.source_map.as_ref()
+ }
+
fn should_show_explain(&self) -> bool {
!self.short_message
}
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 68f9333..1e48678 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -13,7 +13,7 @@
use crate::{
Level, CodeSuggestion, Diagnostic, SubDiagnostic,
- SuggestionStyle, SourceMapperDyn, DiagnosticId,
+ SuggestionStyle, SourceMapper, SourceMapperDyn, DiagnosticId,
};
use crate::Level::Error;
use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, StyledString, Style};
@@ -180,7 +180,7 @@
/// Emitter trait for emitting errors.
pub trait Emitter {
/// Emit a structured diagnostic.
- fn emit_diagnostic(&mut self, db: &Diagnostic);
+ fn emit_diagnostic(&mut self, diag: &Diagnostic);
/// Emit a notification that an artifact has been output.
/// This is currently only supported for the JSON format,
@@ -192,6 +192,8 @@
true
}
+ fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>>;
+
/// Formats the substitutions of the primary_span
///
/// The are a lot of conditions to this method, but in short:
@@ -204,10 +206,10 @@
/// we return the original `primary_span` and the original suggestions.
fn primary_span_formatted<'a>(
&mut self,
- db: &'a Diagnostic
+ diag: &'a Diagnostic,
) -> (MultiSpan, &'a [CodeSuggestion]) {
- let mut primary_span = db.span.clone();
- if let Some((sugg, rest)) = db.suggestions.split_first() {
+ let mut primary_span = diag.span.clone();
+ if let Some((sugg, rest)) = diag.suggestions.split_first() {
if rest.is_empty() &&
// ^ if there is only one suggestion
// don't display multi-suggestions as labels
@@ -234,7 +236,20 @@
format!("help: {}", sugg.msg)
} else {
// Show the default suggestion text with the substitution
- format!("help: {}: `{}`", sugg.msg, substitution)
+ format!(
+ "help: {}{}: `{}`",
+ sugg.msg,
+ if self.source_map().map(|sm| is_case_difference(
+ &**sm,
+ substitution,
+ sugg.substitutions[0].parts[0].span,
+ )).unwrap_or(false) {
+ " (notice the capitalization)"
+ } else {
+ ""
+ },
+ substitution,
+ )
};
primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg);
@@ -245,10 +260,10 @@
// to be consistent. We could try to figure out if we can
// make one (or the first one) inline, but that would give
// undue importance to a semi-random suggestion
- (primary_span, &db.suggestions)
+ (primary_span, &diag.suggestions)
}
} else {
- (primary_span, &db.suggestions)
+ (primary_span, &diag.suggestions)
}
}
@@ -382,19 +397,23 @@
}
impl Emitter for EmitterWriter {
- fn emit_diagnostic(&mut self, db: &Diagnostic) {
- let mut children = db.children.clone();
- let (mut primary_span, suggestions) = self.primary_span_formatted(&db);
+ fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>> {
+ self.sm.as_ref()
+ }
+
+ fn emit_diagnostic(&mut self, diag: &Diagnostic) {
+ let mut children = diag.children.clone();
+ let (mut primary_span, suggestions) = self.primary_span_formatted(&diag);
self.fix_multispans_in_std_macros(&self.sm,
&mut primary_span,
&mut children,
- &db.level,
+ &diag.level,
self.external_macro_backtrace);
- self.emit_messages_default(&db.level,
- &db.styled_message(),
- &db.code,
+ self.emit_messages_default(&diag.level,
+ &diag.styled_message(),
+ &diag.code,
&primary_span,
&children,
&suggestions);
@@ -1461,7 +1480,9 @@
let suggestions = suggestion.splice_lines(&**sm);
let mut row_num = 2;
- for &(ref complete, ref parts) in suggestions.iter().take(MAX_SUGGESTIONS) {
+ let mut notice_capitalization = false;
+ for (complete, parts, only_capitalization) in suggestions.iter().take(MAX_SUGGESTIONS) {
+ notice_capitalization |= only_capitalization;
// Only show underline if the suggestion spans a single line and doesn't cover the
// entirety of the code output. If you have multiple replacements in the same line
// of code, show the underline.
@@ -1552,7 +1573,10 @@
}
if suggestions.len() > MAX_SUGGESTIONS {
let msg = format!("and {} other candidates", suggestions.len() - MAX_SUGGESTIONS);
- buffer.puts(row_num, 0, &msg, Style::NoStyle);
+ buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
+ } else if notice_capitalization {
+ let msg = "notice the capitalization difference";
+ buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
}
emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
Ok(())
@@ -2034,3 +2058,18 @@
}
}
}
+
+/// Whether the original and suggested code are visually similar enough to warrant extra wording.
+pub fn is_case_difference(sm: &dyn SourceMapper, suggested: &str, sp: Span) -> bool {
+ // FIXME: this should probably be extended to also account for `FO0` → `FOO` and unicode.
+ let found = sm.span_to_snippet(sp).unwrap();
+ let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z'];
+ // All the chars that differ in capitalization are confusable (above):
+ let confusable = found.chars().zip(suggested.chars()).filter(|(f, s)| f != s).all(|(f, s)| {
+ (ascii_confusables.contains(&f) || ascii_confusables.contains(&s))
+ });
+ confusable && found.to_lowercase() == suggested.to_lowercase()
+ // FIXME: We sometimes suggest the same thing we already have, which is a
+ // bug, but be defensive against that here.
+ && found != suggested
+}
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 2fae584..63df052 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -13,7 +13,7 @@
use Level::*;
-use emitter::{Emitter, EmitterWriter};
+use emitter::{Emitter, EmitterWriter, is_case_difference};
use registry::Registry;
use rustc_data_structures::sync::{self, Lrc, Lock};
@@ -37,13 +37,16 @@
mod styled_buffer;
mod lock;
-use syntax_pos::{BytePos,
- Loc,
- FileLinesResult,
- SourceFile,
- FileName,
- MultiSpan,
- Span};
+use syntax_pos::{
+ BytePos,
+ FileLinesResult,
+ FileName,
+ Loc,
+ MultiSpan,
+ SourceFile,
+ Span,
+ SpanSnippetError,
+};
/// Indicates the confidence in the correctness of a suggestion.
///
@@ -147,6 +150,7 @@
fn lookup_char_pos(&self, pos: BytePos) -> Loc;
fn span_to_lines(&self, sp: Span) -> FileLinesResult;
fn span_to_string(&self, sp: Span) -> String;
+ fn span_to_snippet(&self, sp: Span) -> Result<String, SpanSnippetError>;
fn span_to_filename(&self, sp: Span) -> FileName;
fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span>;
fn call_span_if_macro(&self, sp: Span) -> Span;
@@ -155,9 +159,12 @@
}
impl CodeSuggestion {
- /// Returns the assembled code suggestions and whether they should be shown with an underline.
- pub fn splice_lines(&self, cm: &SourceMapperDyn)
- -> Vec<(String, Vec<SubstitutionPart>)> {
+ /// Returns the assembled code suggestions, whether they should be shown with an underline
+ /// and whether the substitution only differs in capitalization.
+ pub fn splice_lines(
+ &self,
+ cm: &SourceMapperDyn,
+ ) -> Vec<(String, Vec<SubstitutionPart>, bool)> {
use syntax_pos::{CharPos, Pos};
fn push_trailing(buf: &mut String,
@@ -232,6 +239,7 @@
prev_hi = cm.lookup_char_pos(part.span.hi());
prev_line = fm.get_line(prev_hi.line - 1);
}
+ let only_capitalization = is_case_difference(cm, &buf, bounding_span);
// if the replacement already ends with a newline, don't print the next line
if !buf.ends_with('\n') {
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
@@ -240,7 +248,7 @@
while buf.ends_with('\n') {
buf.pop();
}
- (buf, substitution.parts)
+ (buf, substitution.parts, only_capitalization)
}).collect()
}
}
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index a1dc5b0..396c561 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -130,7 +130,7 @@
let crate_name = crate_name.to_string();
let (result, resolver) = BoxedResolver::new(static move || {
let sess = &*sess;
- let mut crate_loader = CrateLoader::new(sess, &*cstore, &crate_name);
+ let crate_loader = CrateLoader::new(sess, &*cstore, &crate_name);
let resolver_arenas = Resolver::arenas();
let res = configure_and_expand_inner(
sess,
@@ -138,7 +138,7 @@
krate,
&crate_name,
&resolver_arenas,
- &mut crate_loader,
+ &crate_loader,
plugin_info,
);
let mut resolver = match res {
@@ -169,6 +169,7 @@
ExpansionResult {
defs: Steal::new(resolver.definitions),
resolutions: Steal::new(Resolutions {
+ extern_crate_map: resolver.extern_crate_map,
export_map: resolver.export_map,
trait_map: resolver.trait_map,
glob_map: resolver.glob_map,
@@ -187,6 +188,7 @@
ExpansionResult {
defs: Steal::new(resolver.definitions.clone()),
resolutions: Steal::new(Resolutions {
+ extern_crate_map: resolver.extern_crate_map.clone(),
export_map: resolver.export_map.clone(),
trait_map: resolver.trait_map.clone(),
glob_map: resolver.glob_map.clone(),
@@ -319,7 +321,7 @@
mut krate: ast::Crate,
crate_name: &str,
resolver_arenas: &'a ResolverArenas<'a>,
- crate_loader: &'a mut CrateLoader<'a>,
+ crate_loader: &'a CrateLoader<'a>,
plugin_info: PluginInfo,
) -> Result<(ast::Crate, Resolver<'a>)> {
time(sess, "pre-AST-expansion lint checks", || {
@@ -541,7 +543,8 @@
) -> Result<hir::map::Forest> {
// Lower AST to HIR.
let hir_forest = time(sess, "lowering AST -> HIR", || {
- let hir_crate = lower_crate(sess, cstore, &dep_graph, &krate, resolver);
+ let nt_to_tokenstream = syntax::parse::nt_to_tokenstream;
+ let hir_crate = lower_crate(sess, cstore, &dep_graph, &krate, resolver, nt_to_tokenstream);
if sess.opts.debugging_opts.hir_stats {
hir_stats::print_hir_stats(&hir_crate);
@@ -662,16 +665,15 @@
if sess.binary_dep_depinfo() {
for cnum in compiler.cstore.crates_untracked() {
- let metadata = compiler.cstore.crate_data_as_rc_any(cnum);
- let metadata = metadata.downcast_ref::<cstore::CrateMetadata>().unwrap();
- if let Some((path, _)) = &metadata.source.dylib {
- files.push(escape_dep_filename(&FileName::Real(path.clone())));
+ let source = compiler.cstore.crate_source_untracked(cnum);
+ if let Some((path, _)) = source.dylib {
+ files.push(escape_dep_filename(&FileName::Real(path)));
}
- if let Some((path, _)) = &metadata.source.rlib {
- files.push(escape_dep_filename(&FileName::Real(path.clone())));
+ if let Some((path, _)) = source.rlib {
+ files.push(escape_dep_filename(&FileName::Real(path)));
}
- if let Some((path, _)) = &metadata.source.rmeta {
- files.push(escape_dep_filename(&FileName::Real(path.clone())));
+ if let Some((path, _)) = source.rmeta {
+ files.push(escape_dep_filename(&FileName::Real(path)));
}
}
}
@@ -789,10 +791,13 @@
cstore::provide(providers);
lint::provide(providers);
rustc_lint::provide(providers);
+ rustc_codegen_utils::provide(providers);
+ rustc_codegen_ssa::provide(providers);
}
pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) {
cstore::provide_extern(providers);
+ rustc_codegen_ssa::provide_extern(providers);
}
declare_box_region_type!(
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index d0a7eab..9a16d0a 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -45,7 +45,7 @@
use syntax_pos::{BytePos, Span};
use syntax::symbol::{Symbol, kw, sym};
use syntax::errors::{Applicability, DiagnosticBuilder};
-use syntax::print::pprust::expr_to_string;
+use syntax::print::pprust::{self, expr_to_string};
use syntax::visit::FnKind;
use rustc::hir::{self, GenericParamKind, PatKind};
@@ -701,7 +701,8 @@
}
}
if attr.check_name(sym::no_start) || attr.check_name(sym::crate_id) {
- let msg = format!("use of deprecated attribute `{}`: no longer used.", attr.path);
+ let path_str = pprust::path_to_string(&attr.path);
+ let msg = format!("use of deprecated attribute `{}`: no longer used.", path_str);
lint_deprecated_attr(cx, attr, &msg, None);
}
}
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 50a2187..9850121 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -1,6 +1,6 @@
//! Validates all used crates and extern libraries and loads their metadata
-use crate::cstore::{self, CStore, CrateSource, MetadataBlob};
+use crate::cstore::{self, CStore, MetadataBlob};
use crate::locator::{self, CratePaths};
use crate::schema::{CrateRoot, CrateDep};
use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell};
@@ -14,7 +14,7 @@
use rustc::session::config::{Sanitizer, self};
use rustc_target::spec::{PanicStrategy, TargetTriple};
use rustc::session::search_paths::PathKind;
-use rustc::middle::cstore::{ExternCrate, ExternCrateSource};
+use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource};
use rustc::util::common::record_time;
use rustc::util::nodemap::FxHashSet;
use rustc::hir::map::Definitions;
@@ -33,15 +33,13 @@
use log::{debug, info, log_enabled};
use proc_macro::bridge::client::ProcMacro;
-pub struct Library {
- pub dylib: Option<(PathBuf, PathKind)>,
- pub rlib: Option<(PathBuf, PathKind)>,
- pub rmeta: Option<(PathBuf, PathKind)>,
+crate struct Library {
+ pub source: CrateSource,
pub metadata: MetadataBlob,
}
pub struct CrateLoader<'a> {
- pub sess: &'a Session,
+ sess: &'a Session,
cstore: &'a CStore,
local_crate_name: Symbol,
}
@@ -189,7 +187,7 @@
}
fn register_crate(
- &mut self,
+ &self,
host_lib: Option<Library>,
root: Option<&CratePaths>,
span: Span,
@@ -197,10 +195,10 @@
dep_kind: DepKind,
name: Symbol
) -> (CrateNum, Lrc<cstore::CrateMetadata>) {
- let _prof_timer =
- self.sess.prof.generic_activity("metadata_register_crate");
+ let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
- let crate_root = lib.metadata.get_root();
+ let Library { source, metadata } = lib;
+ let crate_root = metadata.get_root();
self.verify_no_symbol_conflicts(span, &crate_root);
let private_dep = self.sess.opts.externs.get(&name.as_str())
@@ -218,28 +216,22 @@
let root = if let Some(root) = root {
root
} else {
- crate_paths = CratePaths {
- ident: crate_root.name.to_string(),
- dylib: lib.dylib.clone().map(|p| p.0),
- rlib: lib.rlib.clone().map(|p| p.0),
- rmeta: lib.rmeta.clone().map(|p| p.0),
- };
+ crate_paths = CratePaths { name: crate_root.name, source: source.clone() };
&crate_paths
};
- let Library { dylib, rlib, rmeta, metadata } = lib;
let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind);
let dependencies: Vec<CrateNum> = cnum_map.iter().cloned().collect();
let raw_proc_macros = crate_root.proc_macro_data.map(|_| {
let temp_root;
- let (dlsym_dylib, dlsym_root) = match &host_lib {
+ let (dlsym_source, dlsym_root) = match &host_lib {
Some(host_lib) =>
- (&host_lib.dylib, { temp_root = host_lib.metadata.get_root(); &temp_root }),
- None => (&dylib, &crate_root),
+ (&host_lib.source, { temp_root = host_lib.metadata.get_root(); &temp_root }),
+ None => (&source, &crate_root),
};
- let dlsym_dylib = dlsym_dylib.as_ref().expect("no dylib for a proc-macro crate");
+ let dlsym_dylib = dlsym_source.dylib.as_ref().expect("no dylib for a proc-macro crate");
self.dlsym_proc_macros(&dlsym_dylib.0, dlsym_root.disambiguator, span)
});
@@ -268,13 +260,8 @@
source_map_import_info: RwLock::new(vec![]),
alloc_decoding_state: AllocDecodingState::new(interpret_alloc_index),
dep_kind: Lock::new(dep_kind),
- source: cstore::CrateSource {
- dylib,
- rlib,
- rmeta,
- },
+ source,
private_dep,
- span,
raw_proc_macros,
dep_node_index: AtomicCell::new(DepNodeIndex::INVALID),
};
@@ -285,7 +272,7 @@
}
fn load_proc_macro<'b>(
- &mut self,
+ &self,
locate_ctxt: &mut locator::Context<'b>,
path_kind: PathKind,
) -> Option<(LoadResult, Option<Library>)>
@@ -340,7 +327,7 @@
}
fn resolve_crate<'b>(
- &'b mut self,
+ &'b self,
name: Symbol,
span: Span,
dep_kind: DepKind,
@@ -350,7 +337,7 @@
}
fn maybe_resolve_crate<'b>(
- &'b mut self,
+ &'b self,
name: Symbol,
span: Span,
mut dep_kind: DepKind,
@@ -410,7 +397,7 @@
}
}
- fn load(&mut self, locate_ctxt: &mut locator::Context<'_>) -> Option<LoadResult> {
+ fn load(&self, locate_ctxt: &mut locator::Context<'_>) -> Option<LoadResult> {
let library = locate_ctxt.maybe_load_library_crate()?;
// In the case that we're loading a crate, but not matching
@@ -437,7 +424,7 @@
}
}
- fn update_extern_crate(&mut self,
+ fn update_extern_crate(&self,
cnum: CrateNum,
mut extern_crate: ExternCrate,
visited: &mut FxHashSet<(CrateNum, bool)>)
@@ -479,7 +466,7 @@
}
// Go through the crate metadata and load any crates that it references
- fn resolve_crate_deps(&mut self,
+ fn resolve_crate_deps(&self,
root: &CratePaths,
crate_root: &CrateRoot<'_>,
metadata: &MetadataBlob,
@@ -509,7 +496,7 @@
})).collect()
}
- fn read_extension_crate(&mut self, name: Symbol, span: Span) -> ExtensionCrate {
+ fn read_extension_crate(&self, name: Symbol, span: Span) -> ExtensionCrate {
info!("read extension crate `{}`", name);
let target_triple = self.sess.opts.target_triple.clone();
let host_triple = TargetTriple::from_triple(config::host_triple());
@@ -559,7 +546,7 @@
(data.source.dylib.clone(), PMDSource::Registered(data))
}
LoadResult::Loaded(library) => {
- let dylib = library.dylib.clone();
+ let dylib = library.source.dylib.clone();
let metadata = PMDSource::Owned(library);
(dylib, metadata)
}
@@ -605,7 +592,7 @@
/// Look for a plugin registrar. Returns library path, crate
/// SVH and DefIndex of the registrar function.
- pub fn find_plugin_registrar(&mut self,
+ pub fn find_plugin_registrar(&self,
span: Span,
name: Symbol)
-> Option<(PathBuf, CrateDisambiguator)> {
@@ -638,7 +625,7 @@
}
}
- fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
+ fn inject_panic_runtime(&self, krate: &ast::Crate) {
// If we're only compiling an rlib, then there's no need to select a
// panic runtime, so we just skip this section entirely.
let any_non_rlib = self.sess.crate_types.borrow().iter().any(|ct| {
@@ -719,7 +706,7 @@
&|data| data.root.needs_panic_runtime);
}
- fn inject_sanitizer_runtime(&mut self) {
+ fn inject_sanitizer_runtime(&self) {
if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer {
// Sanitizers can only be used on some tested platforms with
// executables linked to `std`
@@ -817,7 +804,7 @@
}
}
- fn inject_profiler_runtime(&mut self) {
+ fn inject_profiler_runtime(&self) {
if self.sess.opts.debugging_opts.profile ||
self.sess.opts.cg.profile_generate.enabled()
{
@@ -834,7 +821,7 @@
}
}
- fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
+ fn inject_allocator_crate(&self, krate: &ast::Crate) {
let has_global_allocator = match &*global_allocator_spans(krate) {
[span1, span2, ..] => {
self.sess.struct_span_err(*span2, "cannot define multiple global allocators")
@@ -973,7 +960,7 @@
}
impl<'a> CrateLoader<'a> {
- pub fn postprocess(&mut self, krate: &ast::Crate) {
+ pub fn postprocess(&self, krate: &ast::Crate) {
self.inject_sanitizer_runtime();
self.inject_profiler_runtime();
self.inject_allocator_crate(krate);
@@ -984,9 +971,7 @@
}
}
- pub fn process_extern_crate(
- &mut self, item: &ast::Item, definitions: &Definitions,
- ) -> CrateNum {
+ pub fn process_extern_crate(&self, item: &ast::Item, definitions: &Definitions) -> CrateNum {
match item.kind {
ast::ItemKind::ExternCrate(orig_name) => {
debug!("resolving extern crate stmt. ident: {} orig_name: {:?}",
@@ -1019,18 +1004,13 @@
},
&mut FxHashSet::default(),
);
- self.cstore.add_extern_mod_stmt_cnum(item.id, cnum);
cnum
}
_ => bug!(),
}
}
- pub fn process_path_extern(
- &mut self,
- name: Symbol,
- span: Span,
- ) -> CrateNum {
+ pub fn process_path_extern(&self, name: Symbol, span: Span) -> CrateNum {
let cnum = self.resolve_crate(name, span, DepKind::Explicit, None).0;
self.update_extern_crate(
@@ -1048,11 +1028,7 @@
cnum
}
- pub fn maybe_process_path_extern(
- &mut self,
- name: Symbol,
- span: Span,
- ) -> Option<CrateNum> {
+ pub fn maybe_process_path_extern(&self, name: Symbol, span: Span) -> Option<CrateNum> {
let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?.0;
self.update_extern_crate(
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 98a08e5..a5a458e 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -5,19 +5,15 @@
use rustc::dep_graph::DepNodeIndex;
use rustc::hir::def_id::{CrateNum, DefIndex};
use rustc::hir::map::definitions::DefPathTable;
-use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader};
+use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate, MetadataLoader};
use rustc::mir::interpret::AllocDecodingState;
use rustc_index::vec::IndexVec;
-use rustc::util::nodemap::{FxHashMap, NodeMap};
-
-use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell};
+use rustc::util::nodemap::FxHashMap;
+use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell};
use syntax::ast;
use syntax::ext::base::SyntaxExtension;
use syntax_pos;
-
-pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference};
-pub use rustc::middle::cstore::NativeLibraryKind::*;
-pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule};
+use proc_macro::bridge::client::ProcMacro;
pub use crate::cstore_impl::{provide, provide_extern};
@@ -25,17 +21,13 @@
// local crate numbers (as generated during this session). Each external
// crate may refer to types in other external crates, and each has their
// own crate numbers.
-pub type CrateNumMap = IndexVec<CrateNum, CrateNum>;
+crate type CrateNumMap = IndexVec<CrateNum, CrateNum>;
-pub use rustc_data_structures::sync::MetadataRef;
-use syntax_pos::Span;
-use proc_macro::bridge::client::ProcMacro;
-
-pub struct MetadataBlob(pub MetadataRef);
+crate struct MetadataBlob(pub MetadataRef);
/// Holds information about a syntax_pos::SourceFile imported from another crate.
/// See `imported_source_files()` for more information.
-pub struct ImportedSourceFile {
+crate struct ImportedSourceFile {
/// This SourceFile's byte-offset within the source_map of its original crate
pub original_start_pos: syntax_pos::BytePos,
/// The end of this SourceFile within the source_map of its original crate
@@ -45,59 +37,66 @@
}
pub struct CrateMetadata {
- /// Information about the extern crate that caused this crate to
- /// be loaded. If this is `None`, then the crate was injected
- /// (e.g., by the allocator)
- pub extern_crate: Lock<Option<ExternCrate>>,
+ /// The primary crate data - binary metadata blob.
+ crate blob: MetadataBlob,
- pub blob: MetadataBlob,
- pub cnum_map: CrateNumMap,
- pub cnum: CrateNum,
- pub dependencies: Lock<Vec<CrateNum>>,
- pub source_map_import_info: RwLock<Vec<ImportedSourceFile>>,
+ // --- Some data pre-decoded from the metadata blob, usually for performance ---
- /// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
- pub alloc_decoding_state: AllocDecodingState,
-
- // NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
- // lifetime is only used behind `Lazy`, and therefore acts like an
- // universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
- // is being used to decode those values.
- pub root: schema::CrateRoot<'static>,
-
+ /// Properties of the whole crate.
+ /// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
+ /// lifetime is only used behind `Lazy`, and therefore acts like an
+ /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
+ /// is being used to decode those values.
+ crate root: schema::CrateRoot<'static>,
/// For each definition in this crate, we encode a key. When the
/// crate is loaded, we read all the keys and put them in this
/// hashmap, which gives the reverse mapping. This allows us to
/// quickly retrace a `DefPath`, which is needed for incremental
/// compilation support.
- pub def_path_table: Lrc<DefPathTable>,
-
- pub trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>,
-
- pub dep_kind: Lock<DepKind>,
- pub source: CrateSource,
-
- /// Whether or not this crate should be consider a private dependency
- /// for purposes of the 'exported_private_dependencies' lint
- pub private_dep: bool,
-
- pub span: Span,
-
- pub raw_proc_macros: Option<&'static [ProcMacro]>,
-
+ crate def_path_table: Lrc<DefPathTable>,
+ /// Trait impl data.
+ /// FIXME: Used only from queries and can use query cache,
+ /// so pre-decoding can probably be avoided.
+ crate trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>,
+ /// Proc macro descriptions for this crate, if it's a proc macro crate.
+ crate raw_proc_macros: Option<&'static [ProcMacro]>,
+ /// Source maps for code from the crate.
+ crate source_map_import_info: RwLock<Vec<ImportedSourceFile>>,
+ /// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
+ crate alloc_decoding_state: AllocDecodingState,
/// The `DepNodeIndex` of the `DepNode` representing this upstream crate.
/// It is initialized on the first access in `get_crate_dep_node_index()`.
- /// Do not access the value directly, as it might not have been initialized
- /// yet.
+ /// Do not access the value directly, as it might not have been initialized yet.
/// The field must always be initialized to `DepNodeIndex::INVALID`.
- pub(super) dep_node_index: AtomicCell<DepNodeIndex>,
+ crate dep_node_index: AtomicCell<DepNodeIndex>,
+
+ // --- Other significant crate properties ---
+
+ /// ID of this crate, from the current compilation session's point of view.
+ crate cnum: CrateNum,
+ /// Maps crate IDs as they are were seen from this crate's compilation sessions into
+ /// IDs as they are seen from the current compilation session.
+ crate cnum_map: CrateNumMap,
+ /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime.
+ crate dependencies: Lock<Vec<CrateNum>>,
+ /// How to link (or not link) this crate to the currently compiled crate.
+ crate dep_kind: Lock<DepKind>,
+ /// Filesystem location of this crate.
+ crate source: CrateSource,
+ /// Whether or not this crate should be consider a private dependency
+ /// for purposes of the 'exported_private_dependencies' lint
+ crate private_dep: bool,
+
+ // --- Data used only for improving diagnostics ---
+
+ /// Information about the `extern crate` item or path that caused this crate to be loaded.
+ /// If this is `None`, then the crate was injected (e.g., by the allocator).
+ crate extern_crate: Lock<Option<ExternCrate>>,
}
pub struct CStore {
metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
- /// Map from NodeId's of local extern crate statements to crate numbers
- extern_mod_crate_map: Lock<NodeMap<CrateNum>>,
- pub metadata_loader: Box<dyn MetadataLoader + Sync>,
+ crate metadata_loader: Box<dyn MetadataLoader + Sync>,
}
pub enum LoadedMacro {
@@ -113,30 +112,29 @@
// corresponding `CrateNum`. This first entry will always remain
// `None`.
metas: RwLock::new(IndexVec::from_elem_n(None, 1)),
- extern_mod_crate_map: Default::default(),
metadata_loader,
}
}
- pub(super) fn alloc_new_crate_num(&self) -> CrateNum {
+ crate fn alloc_new_crate_num(&self) -> CrateNum {
let mut metas = self.metas.borrow_mut();
let cnum = CrateNum::new(metas.len());
metas.push(None);
cnum
}
- pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
+ crate fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
self.metas.borrow()[cnum].clone()
.unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum))
}
- pub(super) fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
+ crate fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
let mut metas = self.metas.borrow_mut();
assert!(metas[cnum].is_none(), "Overwriting crate metadata entry");
metas[cnum] = Some(data);
}
- pub(super) fn iter_crate_data<I>(&self, mut i: I)
+ crate fn iter_crate_data<I>(&self, mut i: I)
where I: FnMut(CrateNum, &Lrc<CrateMetadata>)
{
for (k, v) in self.metas.borrow().iter_enumerated() {
@@ -146,16 +144,14 @@
}
}
- pub(super) fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
+ crate fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
let mut ordering = Vec::new();
self.push_dependencies_in_postorder(&mut ordering, krate);
ordering.reverse();
ordering
}
- pub(super) fn push_dependencies_in_postorder(&self,
- ordering: &mut Vec<CrateNum>,
- krate: CrateNum) {
+ crate fn push_dependencies_in_postorder(&self, ordering: &mut Vec<CrateNum>, krate: CrateNum) {
if ordering.contains(&krate) {
return;
}
@@ -170,7 +166,7 @@
ordering.push(krate);
}
- pub(super) fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
+ crate fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
let mut ordering = Vec::new();
for (num, v) in self.metas.borrow().iter_enumerated() {
if let &Some(_) = v {
@@ -179,12 +175,4 @@
}
return ordering
}
-
- pub(super) fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
- self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
- }
-
- pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
- self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
- }
}
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 642a763..fd01126 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -6,8 +6,7 @@
use crate::schema;
use rustc::ty::query::QueryConfig;
-use rustc::middle::cstore::{CrateStore, DepKind,
- EncodedMetadata, NativeLibraryKind};
+use rustc::middle::cstore::{CrateSource, CrateStore, DepKind, EncodedMetadata, NativeLibraryKind};
use rustc::middle::exported_symbols::ExportedSymbol;
use rustc::middle::stability::DeprecationEntry;
use rustc::middle::dependency_format::Linkage;
@@ -414,12 +413,6 @@
}
}
- pub fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind {
- let data = self.get_crate_data(cnum);
- let r = *data.dep_kind.lock();
- r
- }
-
pub fn crate_edition_untracked(&self, cnum: CrateNum) -> Edition {
self.get_crate_data(cnum).root.edition
}
@@ -428,14 +421,6 @@
self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
}
- pub fn ctor_kind_untracked(&self, def: DefId) -> def::CtorKind {
- self.get_crate_data(def.krate).get_ctor_kind(def.index)
- }
-
- pub fn item_attrs_untracked(&self, def: DefId, sess: &Session) -> Lrc<[ast::Attribute]> {
- self.get_crate_data(def.krate).get_item_attrs(def.index, sess)
- }
-
pub fn item_children_untracked(
&self,
def_id: DefId,
@@ -493,6 +478,10 @@
pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem {
self.get_crate_data(def.krate).get_associated_item(def.index)
}
+
+ pub fn crate_source_untracked(&self, cnum: CrateNum) -> CrateSource {
+ self.get_crate_data(cnum).source.clone()
+ }
}
impl CrateStore for cstore::CStore {
@@ -549,11 +538,6 @@
result
}
- fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option<CrateNum>
- {
- self.do_extern_mod_stmt_cnum(emod_id)
- }
-
fn postorder_cnums_untracked(&self) -> Vec<CrateNum> {
self.do_postorder_cnums_untracked()
}
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 132ef7d..6969d60 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1,13 +1,13 @@
// Decoding metadata from a single crate's metadata
-use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule};
+use crate::cstore::{self, CrateMetadata, MetadataBlob};
use crate::schema::*;
use rustc_index::vec::IndexVec;
use rustc_data_structures::sync::{Lrc, ReadGuard};
use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc::hir;
-use rustc::middle::cstore::LinkagePreference;
+use rustc::middle::cstore::{LinkagePreference, NativeLibrary, ForeignModule};
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
@@ -38,7 +38,7 @@
use proc_macro::bridge::client::ProcMacro;
use syntax::ext::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro};
-pub struct DecodeContext<'a, 'tcx> {
+crate struct DecodeContext<'a, 'tcx> {
opaque: opaque::Decoder<'a>,
cdata: Option<&'a CrateMetadata>,
sess: Option<&'tcx Session>,
@@ -54,7 +54,7 @@
}
/// Abstract over the various ways one can create metadata decoders.
-pub trait Metadata<'a, 'tcx>: Copy {
+crate trait Metadata<'a, 'tcx>: Copy {
fn raw_bytes(self) -> &'a [u8];
fn cdata(self) -> Option<&'a CrateMetadata> { None }
fn sess(self) -> Option<&'tcx Session> { None }
@@ -130,7 +130,7 @@
}
impl<'a, 'tcx, T: Decodable> Lazy<T> {
- pub fn decode<M: Metadata<'a, 'tcx>>(self, meta: M) -> T {
+ crate fn decode<M: Metadata<'a, 'tcx>>(self, meta: M) -> T {
let mut dcx = meta.decoder(self.position);
dcx.lazy_state = LazyState::NodeStart(self.position);
T::decode(&mut dcx).unwrap()
@@ -138,7 +138,7 @@
}
impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> {
- pub fn decode<M: Metadata<'a, 'tcx>>(
+ crate fn decode<M: Metadata<'a, 'tcx>>(
self,
meta: M,
) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
@@ -149,11 +149,11 @@
}
impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
- pub fn tcx(&self) -> TyCtxt<'tcx> {
+ fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx.expect("missing TyCtxt in DecodeContext")
}
- pub fn cdata(&self) -> &'a CrateMetadata {
+ fn cdata(&self) -> &'a CrateMetadata {
self.cdata.expect("missing CrateMetadata in DecodeContext")
}
@@ -379,15 +379,15 @@
implement_ty_decoder!( DecodeContext<'a, 'tcx> );
impl<'tcx> MetadataBlob {
- pub fn is_compatible(&self) -> bool {
+ crate fn is_compatible(&self) -> bool {
self.raw_bytes().starts_with(METADATA_HEADER)
}
- pub fn get_rustc_version(&self) -> String {
+ crate fn get_rustc_version(&self) -> String {
Lazy::<String>::from_position(METADATA_HEADER.len() + 4).decode(self)
}
- pub fn get_root(&self) -> CrateRoot<'tcx> {
+ crate fn get_root(&self) -> CrateRoot<'tcx> {
let slice = self.raw_bytes();
let offset = METADATA_HEADER.len();
let pos = (((slice[offset + 0] as u32) << 24) | ((slice[offset + 1] as u32) << 16) |
@@ -396,7 +396,7 @@
Lazy::<CrateRoot<'tcx>>::from_position(pos).decode(self)
}
- pub fn list_crate_metadata(&self,
+ crate fn list_crate_metadata(&self,
out: &mut dyn io::Write) -> io::Result<()> {
write!(out, "=External Dependencies=\n")?;
let root = self.get_root();
@@ -449,7 +449,7 @@
}
impl<'a, 'tcx> CrateMetadata {
- pub fn is_proc_macro_crate(&self) -> bool {
+ crate fn is_proc_macro_crate(&self) -> bool {
self.root.proc_macro_decls_static.is_some()
}
@@ -499,7 +499,7 @@
&self.raw_proc_macros.unwrap()[pos]
}
- pub fn item_name(&self, item_index: DefIndex) -> Symbol {
+ crate fn item_name(&self, item_index: DefIndex) -> Symbol {
if !self.is_proc_macro(item_index) {
self.def_key(item_index)
.disambiguated_data
@@ -512,7 +512,7 @@
}
}
- pub fn def_kind(&self, index: DefIndex) -> Option<DefKind> {
+ crate fn def_kind(&self, index: DefIndex) -> Option<DefKind> {
if !self.is_proc_macro(index) {
self.entry(index).kind.def_kind()
} else {
@@ -522,7 +522,7 @@
}
}
- pub fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
+ crate fn get_span(&self, index: DefIndex, sess: &Session) -> Span {
self.entry(index).span.decode((self, sess))
}
@@ -556,7 +556,7 @@
)
}
- pub fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
+ crate fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
match self.entry(item_id).kind {
EntryKind::Trait(data) => {
let data = data.decode((self, sess));
@@ -622,7 +622,7 @@
)
}
- pub fn get_adt_def(&self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef {
+ crate fn get_adt_def(&self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef {
let item = self.entry(item_id);
let did = self.local_def_id(item_id);
@@ -647,7 +647,7 @@
tcx.alloc_adt_def(did, kind, variants, repr)
}
- pub fn get_predicates(
+ crate fn get_predicates(
&self,
item_id: DefIndex,
tcx: TyCtxt<'tcx>,
@@ -655,7 +655,7 @@
self.entry(item_id).predicates.unwrap().decode((self, tcx))
}
- pub fn get_predicates_defined_on(
+ crate fn get_predicates_defined_on(
&self,
item_id: DefIndex,
tcx: TyCtxt<'tcx>,
@@ -663,7 +663,7 @@
self.entry(item_id).predicates_defined_on.unwrap().decode((self, tcx))
}
- pub fn get_super_predicates(
+ crate fn get_super_predicates(
&self,
item_id: DefIndex,
tcx: TyCtxt<'tcx>,
@@ -677,30 +677,27 @@
super_predicates.decode((self, tcx))
}
- pub fn get_generics(&self,
- item_id: DefIndex,
- sess: &Session)
- -> ty::Generics {
+ crate fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics {
self.entry(item_id).generics.unwrap().decode((self, sess))
}
- pub fn get_type(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+ crate fn get_type(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
self.entry(id).ty.unwrap().decode((self, tcx))
}
- pub fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
+ crate fn get_stability(&self, id: DefIndex) -> Option<attr::Stability> {
match self.is_proc_macro(id) {
true => self.root.proc_macro_stability.clone(),
false => self.entry(id).stability.map(|stab| stab.decode(self)),
}
}
- pub fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
+ crate fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
self.entry_unless_proc_macro(id)
.and_then(|entry| entry.deprecation.map(|depr| depr.decode(self)))
}
- pub fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
+ crate fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
match self.is_proc_macro(id) {
true => ty::Visibility::Public,
false => self.entry(id).visibility.decode(self),
@@ -714,30 +711,31 @@
}
}
- pub fn get_parent_impl(&self, id: DefIndex) -> Option<DefId> {
+ crate fn get_parent_impl(&self, id: DefIndex) -> Option<DefId> {
self.get_impl_data(id).parent_impl
}
- pub fn get_impl_polarity(&self, id: DefIndex) -> ty::ImplPolarity {
+ crate fn get_impl_polarity(&self, id: DefIndex) -> ty::ImplPolarity {
self.get_impl_data(id).polarity
}
- pub fn get_impl_defaultness(&self, id: DefIndex) -> hir::Defaultness {
+ crate fn get_impl_defaultness(&self, id: DefIndex) -> hir::Defaultness {
self.get_impl_data(id).defaultness
}
- pub fn get_coerce_unsized_info(&self,
- id: DefIndex)
- -> Option<ty::adjustment::CoerceUnsizedInfo> {
+ crate fn get_coerce_unsized_info(
+ &self,
+ id: DefIndex,
+ ) -> Option<ty::adjustment::CoerceUnsizedInfo> {
self.get_impl_data(id).coerce_unsized_info
}
- pub fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option<ty::TraitRef<'tcx>> {
+ crate fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option<ty::TraitRef<'tcx>> {
self.get_impl_data(id).trait_ref.map(|tr| tr.decode((self, tcx)))
}
/// Iterates over all the stability attributes in the given crate.
- pub fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(ast::Name, Option<ast::Name>)] {
+ crate fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(ast::Name, Option<ast::Name>)] {
// FIXME: For a proc macro crate, not sure whether we should return the "host"
// features or an empty Vec. Both don't cause ICEs.
tcx.arena.alloc_from_iter(self.root
@@ -746,7 +744,7 @@
}
/// Iterates over the language items in the given crate.
- pub fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
+ crate fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] {
if self.is_proc_macro_crate() {
// Proc macro crates do not export any lang-items to the target.
&[]
@@ -759,7 +757,7 @@
}
/// Iterates over the diagnostic items in the given crate.
- pub fn get_diagnostic_items(
+ crate fn get_diagnostic_items(
&self,
tcx: TyCtxt<'tcx>,
) -> &'tcx FxHashMap<Symbol, DefId> {
@@ -776,7 +774,7 @@
}
/// Iterates over each child of the given item.
- pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
+ crate fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
where F: FnMut(def::Export<hir::HirId>)
{
if let Some(proc_macros_ids) = self.root.proc_macro_data.map(|d| d.decode(self)) {
@@ -911,12 +909,12 @@
}
}
- pub fn is_item_mir_available(&self, id: DefIndex) -> bool {
+ crate fn is_item_mir_available(&self, id: DefIndex) -> bool {
!self.is_proc_macro(id) &&
self.maybe_entry(id).and_then(|item| item.decode(self).mir).is_some()
}
- pub fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
+ crate fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
self.entry_unless_proc_macro(id)
.and_then(|entry| entry.mir.map(|mir| mir.decode((self, tcx))))
.unwrap_or_else(|| {
@@ -924,7 +922,7 @@
})
}
- pub fn get_promoted_mir(
+ crate fn get_promoted_mir(
&self,
tcx: TyCtxt<'tcx>,
id: DefIndex,
@@ -936,7 +934,7 @@
})
}
- pub fn mir_const_qualif(&self, id: DefIndex) -> u8 {
+ crate fn mir_const_qualif(&self, id: DefIndex) -> u8 {
match self.entry(id).kind {
EntryKind::Const(qualif, _) |
EntryKind::AssocConst(AssocContainer::ImplDefault, qualif, _) |
@@ -947,7 +945,7 @@
}
}
- pub fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem {
+ crate fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem {
let item = self.entry(id);
let def_key = self.def_key(id);
let parent = self.local_def_id(def_key.parent.unwrap());
@@ -981,11 +979,11 @@
}
}
- pub fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
+ crate fn get_item_variances(&self, id: DefIndex) -> Vec<ty::Variance> {
self.entry(id).variances.decode(self).collect()
}
- pub fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
+ crate fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
match self.entry(node_id).kind {
EntryKind::Struct(data, _) |
EntryKind::Union(data, _) |
@@ -994,7 +992,7 @@
}
}
- pub fn get_ctor_def_id(&self, node_id: DefIndex) -> Option<DefId> {
+ crate fn get_ctor_def_id(&self, node_id: DefIndex) -> Option<DefId> {
match self.entry(node_id).kind {
EntryKind::Struct(data, _) => {
data.decode(self).ctor.map(|index| self.local_def_id(index))
@@ -1006,8 +1004,7 @@
}
}
-
- pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> {
+ crate fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> {
// The attributes for a tuple struct/variant are attached to the definition, not the ctor;
// we assume that someone passing in a tuple struct ctor is actually wanting to
// look at the definition
@@ -1022,7 +1019,11 @@
Lrc::from(self.get_attributes(&item, sess))
}
- pub fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec<Spanned<ast::Name>> {
+ crate fn get_struct_field_names(
+ &self,
+ id: DefIndex,
+ sess: &Session,
+ ) -> Vec<Spanned<ast::Name>> {
self.entry(id)
.children
.decode(self)
@@ -1049,7 +1050,7 @@
None
}
- pub fn get_inherent_implementations_for_type(
+ crate fn get_inherent_implementations_for_type(
&self,
tcx: TyCtxt<'tcx>,
id: DefIndex,
@@ -1060,7 +1061,7 @@
.map(|index| self.local_def_id(index)))
}
- pub fn get_implementations_for_trait(
+ crate fn get_implementations_for_trait(
&self,
tcx: TyCtxt<'tcx>,
filter: Option<DefId>,
@@ -1091,7 +1092,7 @@
}
}
- pub fn get_trait_of_item(&self, id: DefIndex) -> Option<DefId> {
+ crate fn get_trait_of_item(&self, id: DefIndex) -> Option<DefId> {
let def_key = self.def_key(id);
match def_key.disambiguated_data.data {
DefPathData::TypeNs(..) | DefPathData::ValueNs(..) => (),
@@ -1108,7 +1109,7 @@
}
- pub fn get_native_libraries(&self, sess: &Session) -> Vec<NativeLibrary> {
+ crate fn get_native_libraries(&self, sess: &Session) -> Vec<NativeLibrary> {
if self.is_proc_macro_crate() {
// Proc macro crates do not have any *target* native libraries.
vec![]
@@ -1117,7 +1118,7 @@
}
}
- pub fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] {
+ crate fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] {
if self.is_proc_macro_crate() {
// Proc macro crates do not have any *target* foreign modules.
&[]
@@ -1126,7 +1127,7 @@
}
}
- pub fn get_dylib_dependency_formats(
+ crate fn get_dylib_dependency_formats(
&self,
tcx: TyCtxt<'tcx>,
) -> &'tcx [(CrateNum, LinkagePreference)] {
@@ -1140,7 +1141,7 @@
}))
}
- pub fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
+ crate fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
if self.is_proc_macro_crate() {
// Proc macro crates do not depend on any target weak lang-items.
&[]
@@ -1151,7 +1152,7 @@
}
}
- pub fn get_fn_param_names(&self, id: DefIndex) -> Vec<ast::Name> {
+ crate fn get_fn_param_names(&self, id: DefIndex) -> Vec<ast::Name> {
let param_names = match self.entry(id).kind {
EntryKind::Fn(data) |
EntryKind::ForeignFn(data) => data.decode(self).param_names,
@@ -1161,7 +1162,7 @@
param_names.decode(self).collect()
}
- pub fn exported_symbols(
+ crate fn exported_symbols(
&self,
tcx: TyCtxt<'tcx>,
) -> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> {
@@ -1174,7 +1175,7 @@
}
}
- pub fn get_rendered_const(&self, id: DefIndex) -> String {
+ crate fn get_rendered_const(&self, id: DefIndex) -> String {
match self.entry(id).kind {
EntryKind::Const(_, data) |
EntryKind::AssocConst(_, _, data) => data.decode(self).0,
@@ -1182,7 +1183,7 @@
}
}
- pub fn get_macro(&self, id: DefIndex) -> MacroDef {
+ crate fn get_macro(&self, id: DefIndex) -> MacroDef {
let entry = self.entry(id);
match entry.kind {
EntryKind::MacroDef(macro_def) => macro_def.decode(self),
@@ -1200,7 +1201,7 @@
constness == hir::Constness::Const
}
- pub fn asyncness(&self, id: DefIndex) -> hir::IsAsync {
+ crate fn asyncness(&self, id: DefIndex) -> hir::IsAsync {
match self.entry(id).kind {
EntryKind::Fn(data) => data.decode(self).asyncness,
EntryKind::Method(data) => data.decode(self).fn_data.asyncness,
@@ -1209,7 +1210,7 @@
}
}
- pub fn is_foreign_item(&self, id: DefIndex) -> bool {
+ crate fn is_foreign_item(&self, id: DefIndex) -> bool {
match self.entry(id).kind {
EntryKind::ForeignImmStatic |
EntryKind::ForeignMutStatic |
@@ -1228,7 +1229,7 @@
}
}
- pub fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
+ crate fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
let sig = match self.entry(id).kind {
EntryKind::Fn(data) |
EntryKind::ForeignFn(data) => data.decode(self).sig,
@@ -1242,7 +1243,7 @@
}
#[inline]
- pub fn def_key(&self, index: DefIndex) -> DefKey {
+ crate fn def_key(&self, index: DefIndex) -> DefKey {
let mut key = self.def_path_table.def_key(index);
if self.is_proc_macro(index) {
let name = self.raw_proc_macro(index).name();
@@ -1252,13 +1253,13 @@
}
// Returns the path leading to the thing with this `id`.
- pub fn def_path(&self, id: DefIndex) -> DefPath {
+ crate fn def_path(&self, id: DefIndex) -> DefPath {
debug!("def_path(cnum={:?}, id={:?})", self.cnum, id);
DefPath::make(self.cnum, id, |parent| self.def_key(parent))
}
#[inline]
- pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
+ crate fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
self.def_path_table.def_path_hash(index)
}
@@ -1287,9 +1288,10 @@
///
/// Proc macro crates don't currently export spans, so this function does not have
/// to work for them.
- pub fn imported_source_files(&'a self,
- local_source_map: &source_map::SourceMap)
- -> ReadGuard<'a, Vec<cstore::ImportedSourceFile>> {
+ fn imported_source_files(
+ &'a self,
+ local_source_map: &source_map::SourceMap,
+ ) -> ReadGuard<'a, Vec<cstore::ImportedSourceFile>> {
{
let source_files = self.source_map_import_info.borrow();
if !source_files.is_empty() {
diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs
index 9a30623..7f76a97 100644
--- a/src/librustc_metadata/dependency_format.rs
+++ b/src/librustc_metadata/dependency_format.rs
@@ -60,7 +60,7 @@
use rustc::util::nodemap::FxHashMap;
use rustc_target::spec::PanicStrategy;
-pub fn calculate(tcx: TyCtxt<'_>) -> Dependencies {
+crate fn calculate(tcx: TyCtxt<'_>) -> Dependencies {
tcx.sess.crate_types.borrow().iter().map(|&ty| {
let linkage = calculate_type(tcx, ty);
verify_ok(tcx, &linkage);
diff --git a/src/librustc_metadata/dynamic_lib.rs b/src/librustc_metadata/dynamic_lib.rs
index 4c27936..3871eb8 100644
--- a/src/librustc_metadata/dynamic_lib.rs
+++ b/src/librustc_metadata/dynamic_lib.rs
@@ -32,30 +32,6 @@
}
}
- /// Loads a dynamic library into the global namespace (RTLD_GLOBAL on Unix)
- /// and do it now (don't use RTLD_LAZY on Unix).
- pub fn open_global_now(filename: &Path) -> Result<DynamicLibrary, String> {
- let maybe_library = dl::open_global_now(filename.as_os_str());
- match maybe_library {
- Err(err) => Err(err),
- Ok(handle) => Ok(DynamicLibrary { handle })
- }
- }
-
- /// Returns the environment variable for this process's dynamic library
- /// search path
- pub fn envvar() -> &'static str {
- if cfg!(windows) {
- "PATH"
- } else if cfg!(target_os = "macos") {
- "DYLD_LIBRARY_PATH"
- } else if cfg!(target_os = "haiku") {
- "LIBRARY_PATH"
- } else {
- "LD_LIBRARY_PATH"
- }
- }
-
/// Accesses the value at the symbol of the dynamic library.
pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
// This function should have a lifetime constraint of 'a on
@@ -83,7 +59,7 @@
use std::ptr;
use std::str;
- pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
+ pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
check_for_errors_in(|| {
unsafe {
match filename {
@@ -94,13 +70,6 @@
})
}
- pub fn open_global_now(filename: &OsStr) -> Result<*mut u8, String> {
- check_for_errors_in(|| unsafe {
- let s = CString::new(filename.as_bytes()).unwrap();
- libc::dlopen(s.as_ptr(), libc::RTLD_GLOBAL | libc::RTLD_NOW) as *mut u8
- })
- }
-
unsafe fn open_external(filename: &OsStr) -> *mut u8 {
let s = CString::new(filename.as_bytes()).unwrap();
libc::dlopen(s.as_ptr(), libc::RTLD_LAZY) as *mut u8
@@ -110,8 +79,8 @@
libc::dlopen(ptr::null(), libc::RTLD_LAZY) as *mut u8
}
- pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
- F: FnOnce() -> T,
+ fn check_for_errors_in<T, F>(f: F) -> Result<T, String>
+ where F: FnOnce() -> T,
{
use std::sync::{Mutex, Once};
static INIT: Once = Once::new();
@@ -139,14 +108,15 @@
}
}
- pub unsafe fn symbol(handle: *mut u8,
- symbol: *const libc::c_char)
- -> Result<*mut u8, String> {
+ pub(super) unsafe fn symbol(
+ handle: *mut u8,
+ symbol: *const libc::c_char,
+ ) -> Result<*mut u8, String> {
check_for_errors_in(|| {
libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8
})
}
- pub unsafe fn close(handle: *mut u8) {
+ pub(super) unsafe fn close(handle: *mut u8) {
libc::dlclose(handle as *mut libc::c_void); ()
}
}
@@ -178,11 +148,7 @@
fn FreeLibrary(handle: HMODULE) -> BOOL;
}
- pub fn open_global_now(filename: &OsStr) -> Result<*mut u8, String> {
- open(Some(filename))
- }
-
- pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
+ pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
// disable "dll load failed" error dialog.
let prev_error_mode = unsafe {
// SEM_FAILCRITICALERRORS 0x01
@@ -225,14 +191,15 @@
result
}
- pub unsafe fn symbol(handle: *mut u8,
- symbol: *const c_char)
- -> Result<*mut u8, String> {
+ pub(super) unsafe fn symbol(
+ handle: *mut u8,
+ symbol: *const c_char,
+ ) -> Result<*mut u8, String> {
let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8;
ptr_result(ptr)
}
- pub unsafe fn close(handle: *mut u8) {
+ pub(super) unsafe fn close(handle: *mut u8) {
FreeLibrary(handle as HMODULE);
}
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index bbfbba2..03a14f8 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -5,7 +5,7 @@
EncodedMetadata, ForeignModule};
use rustc::hir::def::CtorKind;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, LOCAL_CRATE};
-use rustc::hir::GenericParamKind;
+use rustc::hir::{GenericParamKind, AnonConst};
use rustc::hir::map::definitions::DefPathTable;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_index::vec::IndexVec;
@@ -42,9 +42,9 @@
use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
use rustc::hir::intravisit;
-pub struct EncodeContext<'tcx> {
+struct EncodeContext<'tcx> {
opaque: opaque::Encoder,
- pub tcx: TyCtxt<'tcx>,
+ tcx: TyCtxt<'tcx>,
entries_index: Index<'tcx>,
@@ -313,11 +313,12 @@
/// the `Entry` (which may point to other encoded information)
/// and will then record the `Lazy<Entry>` for use in the index.
// FIXME(eddyb) remove this.
- pub fn record<DATA>(&mut self,
- id: DefId,
- op: impl FnOnce(&mut Self, DATA) -> Entry<'tcx>,
- data: DATA)
- {
+ fn record<DATA>(
+ &mut self,
+ id: DefId,
+ op: impl FnOnce(&mut Self, DATA) -> Entry<'tcx>,
+ data: DATA,
+ ) {
assert!(id.is_local());
let entry = op(self, data);
@@ -1711,6 +1712,11 @@
intravisit::walk_expr(self, ex);
self.encode_info_for_expr(ex);
}
+ fn visit_anon_const(&mut self, c: &'tcx AnonConst) {
+ intravisit::walk_anon_const(self, c);
+ let def_id = self.tcx.hir().local_def_id(c.hir_id);
+ self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id);
+ }
fn visit_item(&mut self, item: &'tcx hir::Item) {
intravisit::walk_item(self, item);
let def_id = self.tcx.hir().local_def_id(item.hir_id);
@@ -1728,25 +1734,10 @@
EncodeContext::encode_info_for_foreign_item,
(def_id, ni));
}
- fn visit_variant(&mut self,
- v: &'tcx hir::Variant,
- g: &'tcx hir::Generics,
- id: hir::HirId) {
- intravisit::walk_variant(self, v, g, id);
-
- if let Some(ref discr) = v.disr_expr {
- let def_id = self.tcx.hir().local_def_id(discr.hir_id);
- self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id);
- }
- }
fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
intravisit::walk_generics(self, generics);
self.encode_info_for_generics(generics);
}
- fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
- intravisit::walk_ty(self, ty);
- self.encode_info_for_ty(ty);
- }
fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef) {
let def_id = self.tcx.hir().local_def_id(macro_def.hir_id);
self.record(def_id, EncodeContext::encode_info_for_macro_def, macro_def);
@@ -1784,16 +1775,6 @@
}
}
- fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
- match ty.kind {
- hir::TyKind::Array(_, ref length) => {
- let def_id = self.tcx.hir().local_def_id(length.hir_id);
- self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id);
- }
- _ => {}
- }
- }
-
fn encode_info_for_expr(&mut self, expr: &hir::Expr) {
match expr.kind {
hir::ExprKind::Closure(..) => {
@@ -1920,7 +1901,7 @@
// will allow us to slice the metadata to the precise length that we just
// generated regardless of trailing bytes that end up in it.
-pub fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
+crate fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
let mut encoder = opaque::Encoder::new(vec![]);
encoder.emit_raw_bytes(METADATA_HEADER);
@@ -1962,7 +1943,7 @@
EncodedMetadata { raw_data: result }
}
-pub fn get_repr_options(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions {
+fn get_repr_options(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions {
let ty = tcx.type_of(did);
match ty.kind {
ty::Adt(ref def, _) => return def.repr,
diff --git a/src/librustc_metadata/foreign_modules.rs b/src/librustc_metadata/foreign_modules.rs
index 8a4f6e6..fa14025 100644
--- a/src/librustc_metadata/foreign_modules.rs
+++ b/src/librustc_metadata/foreign_modules.rs
@@ -3,7 +3,7 @@
use rustc::middle::cstore::ForeignModule;
use rustc::ty::TyCtxt;
-pub fn collect(tcx: TyCtxt<'_>) -> Vec<ForeignModule> {
+crate fn collect(tcx: TyCtxt<'_>) -> Vec<ForeignModule> {
let mut collector = Collector {
tcx,
modules: Vec::new(),
diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs
index 6f248f2..037f9d3 100644
--- a/src/librustc_metadata/index.rs
+++ b/src/librustc_metadata/index.rs
@@ -7,7 +7,7 @@
use log::debug;
/// Helper trait, for encoding to, and decoding from, a fixed number of bytes.
-pub trait FixedSizeEncoding {
+trait FixedSizeEncoding {
const BYTE_LEN: usize;
// FIXME(eddyb) convert to and from `[u8; Self::BYTE_LEN]` instead,
@@ -75,25 +75,25 @@
/// `u32::MAX`. Whenever an index is visited, we fill in the
/// appropriate spot by calling `record_position`. We should never
/// visit the same index twice.
-pub struct Index<'tcx> {
+crate struct Index<'tcx> {
positions: Vec<u8>,
_marker: PhantomData<&'tcx ()>,
}
impl Index<'tcx> {
- pub fn new(max_index: usize) -> Self {
+ crate fn new(max_index: usize) -> Self {
Index {
positions: vec![0xff; max_index * 4],
_marker: PhantomData,
}
}
- pub fn record(&mut self, def_id: DefId, entry: Lazy<Entry<'tcx>>) {
+ crate fn record(&mut self, def_id: DefId, entry: Lazy<Entry<'tcx>>) {
assert!(def_id.is_local());
self.record_index(def_id.index, entry);
}
- pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry<'tcx>>) {
+ fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry<'tcx>>) {
assert!(entry.position < (u32::MAX as usize));
let position = entry.position as u32;
let array_index = item.index();
@@ -108,7 +108,7 @@
position.write_to_bytes_at(positions, array_index)
}
- pub fn write_index(&self, buf: &mut Encoder) -> Lazy<[Self]> {
+ crate fn write_index(&self, buf: &mut Encoder) -> Lazy<[Self]> {
let pos = buf.position();
// First we write the length of the lower range ...
@@ -123,7 +123,7 @@
/// Given the metadata, extract out the offset of a particular
/// DefIndex (if any).
#[inline(never)]
- pub fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
+ crate fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
let bytes = &bytes[self.position..];
debug!("Index::lookup: index={:?} len={:?}",
def_index,
diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs
index 527d442..4291f3a 100644
--- a/src/librustc_metadata/link_args.rs
+++ b/src/librustc_metadata/link_args.rs
@@ -4,7 +4,7 @@
use rustc_target::spec::abi::Abi;
use syntax::symbol::sym;
-pub fn collect(tcx: TyCtxt<'_>) -> Vec<String> {
+crate fn collect(tcx: TyCtxt<'_>) -> Vec<String> {
let mut collector = Collector {
args: Vec::new(),
};
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 8df236c..05676da 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -212,13 +212,14 @@
//! no means all of the necessary details. Take a look at the rest of
//! metadata::locator or metadata::creader for all the juicy details!
-use crate::cstore::{MetadataRef, MetadataBlob};
+use crate::cstore::{MetadataBlob, CStore};
use crate::creader::Library;
use crate::schema::{METADATA_HEADER, rustc_version};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::svh::Svh;
-use rustc::middle::cstore::MetadataLoader;
+use rustc_data_structures::sync::MetadataRef;
+use rustc::middle::cstore::{CrateSource, MetadataLoader};
use rustc::session::{config, Session};
use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
use rustc::session::search_paths::PathKind;
@@ -245,13 +246,13 @@
use log::{debug, info, warn};
#[derive(Clone)]
-pub struct CrateMismatch {
+crate struct CrateMismatch {
path: PathBuf,
got: String,
}
#[derive(Clone)]
-pub struct Context<'a> {
+crate struct Context<'a> {
pub sess: &'a Session,
pub span: Span,
pub crate_name: Symbol,
@@ -272,11 +273,9 @@
pub metadata_loader: &'a dyn MetadataLoader,
}
-pub struct CratePaths {
- pub ident: String,
- pub dylib: Option<PathBuf>,
- pub rlib: Option<PathBuf>,
- pub rmeta: Option<PathBuf>,
+crate struct CratePaths {
+ pub name: Symbol,
+ pub source: CrateSource,
}
#[derive(Copy, Clone, PartialEq)]
@@ -296,14 +295,8 @@
}
}
-impl CratePaths {
- fn paths(&self) -> Vec<PathBuf> {
- self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).cloned().collect()
- }
-}
-
impl<'a> Context<'a> {
- pub fn reset(&mut self) {
+ crate fn reset(&mut self) {
self.rejected_via_hash.clear();
self.rejected_via_triple.clear();
self.rejected_via_kind.clear();
@@ -311,7 +304,7 @@
self.rejected_via_filename.clear();
}
- pub fn maybe_load_library_crate(&mut self) -> Option<Library> {
+ crate fn maybe_load_library_crate(&mut self) -> Option<Library> {
let mut seen_paths = FxHashSet::default();
match self.extra_filename {
Some(s) => self.find_library_crate(s, &mut seen_paths)
@@ -320,10 +313,10 @@
}
}
- pub fn report_errs(self) -> ! {
+ crate fn report_errs(self) -> ! {
let add = match self.root {
None => String::new(),
- Some(r) => format!(" which `{}` depends on", r.ident),
+ Some(r) => format!(" which `{}` depends on", r.name),
};
let mut msg = "the following crate versions were found:".to_string();
let mut err = if !self.rejected_via_hash.is_empty() {
@@ -341,8 +334,8 @@
match self.root {
None => {}
Some(r) => {
- for path in r.paths().iter() {
- msg.push_str(&format!("\ncrate `{}`: {}", r.ident, path.display()));
+ for path in r.source.paths() {
+ msg.push_str(&format!("\ncrate `{}`: {}", r.name, path.display()));
}
}
}
@@ -534,18 +527,8 @@
// search is being performed for.
let mut libraries = FxHashMap::default();
for (_hash, (rlibs, rmetas, dylibs)) in candidates {
- let mut slot = None;
- let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot);
- let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot);
- let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot);
- if let Some((h, m)) = slot {
- libraries.insert(h,
- Library {
- dylib,
- rlib,
- rmeta,
- metadata: m,
- });
+ if let Some((svh, lib)) = self.extract_lib(rlibs, rmetas, dylibs) {
+ libraries.insert(svh, lib);
}
}
@@ -563,7 +546,7 @@
self.crate_name);
let candidates = libraries.iter().filter_map(|(_, lib)| {
let crate_name = &lib.metadata.get_root().name.as_str();
- match &(&lib.dylib, &lib.rlib) {
+ match &(&lib.source.dylib, &lib.source.rlib) {
&(&Some((ref pd, _)), &Some((ref pr, _))) => {
Some(format!("\ncrate `{}`: {}\n{:>padding$}",
crate_name,
@@ -584,6 +567,21 @@
}
}
+ fn extract_lib(
+ &mut self,
+ rlibs: FxHashMap<PathBuf, PathKind>,
+ rmetas: FxHashMap<PathBuf, PathKind>,
+ dylibs: FxHashMap<PathBuf, PathKind>,
+ ) -> Option<(Svh, Library)> {
+ let mut slot = None;
+ let source = CrateSource {
+ rlib: self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot),
+ rmeta: self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot),
+ dylib: self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot),
+ };
+ slot.map(|(svh, metadata)| (svh, Library { source, metadata }))
+ }
+
// Attempts to extract *one* library from the set `m`. If the set has no
// elements, `None` is returned. If the set has more than one element, then
// the errors and notes are emitted about the set of libraries.
@@ -828,23 +826,8 @@
}
};
- // Extract the rlib/dylib pair.
- let mut slot = None;
- let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot);
- let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot);
- let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot);
-
- if rlib.is_none() && rmeta.is_none() && dylib.is_none() {
- return None;
- }
- slot.map(|(_, metadata)|
- Library {
- dylib,
- rlib,
- rmeta,
- metadata,
- }
- )
+ // Extract the dylib/rlib/rmeta triple.
+ self.extract_lib(rlibs, rmetas, dylibs).map(|(_, lib)| lib)
}
}
@@ -931,7 +914,7 @@
/// A diagnostic function for dumping crate metadata to an output stream.
pub fn list_file_metadata(target: &Target,
path: &Path,
- loader: &dyn MetadataLoader,
+ cstore: &CStore,
out: &mut dyn io::Write)
-> io::Result<()> {
let filename = path.file_name().unwrap().to_str().unwrap();
@@ -942,7 +925,7 @@
} else {
CrateFlavor::Dylib
};
- match get_metadata_section(target, flavor, path, loader) {
+ match get_metadata_section(target, flavor, path, &*cstore.metadata_loader) {
Ok(metadata) => metadata.list_crate_metadata(out),
Err(msg) => write!(out, "{}\n", msg),
}
diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index 24ed8fc..9e4c268 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -11,7 +11,7 @@
use syntax::symbol::{kw, sym, Symbol};
use syntax::{span_err, struct_span_err};
-pub fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLibrary> {
+crate fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLibrary> {
let mut collector = Collector {
tcx,
libs: Vec::new(),
@@ -21,7 +21,7 @@
return collector.libs;
}
-pub fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool {
+crate fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool {
match lib.cfg {
Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, None),
None => true,
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 4fe9c46..d3539e7 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -21,7 +21,7 @@
use std::marker::PhantomData;
-pub fn rustc_version() -> String {
+crate fn rustc_version() -> String {
format!("rustc {}",
option_env!("CFG_VERSION").unwrap_or("unknown version"))
}
@@ -29,7 +29,7 @@
/// Metadata encoding version.
/// N.B., increment this if you change the format of metadata such that
/// the rustc version can't be found to compare with `rustc_version()`.
-pub const METADATA_VERSION: u8 = 4;
+const METADATA_VERSION: u8 = 4;
/// Metadata header which includes `METADATA_VERSION`.
/// To get older versions of rustc to ignore this metadata,
@@ -39,12 +39,12 @@
/// This header is followed by the position of the `CrateRoot`,
/// which is encoded as a 32-bit big-endian unsigned integer,
/// and further followed by the rustc version string.
-pub const METADATA_HEADER: &[u8; 12] =
+crate const METADATA_HEADER: &[u8; 12] =
&[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
/// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
/// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
-pub trait LazyMeta {
+crate trait LazyMeta {
type Meta: Copy + 'static;
/// Returns the minimum encoded size.
@@ -98,7 +98,7 @@
#[must_use]
// FIXME(#59875) the `Meta` parameter only exists to dodge
// invariance wrt `T` (coming from the `meta: T::Meta` field).
-pub struct Lazy<T, Meta = <T as LazyMeta>::Meta>
+crate struct Lazy<T, Meta = <T as LazyMeta>::Meta>
where T: ?Sized + LazyMeta<Meta = Meta>,
Meta: 'static + Copy,
{
@@ -108,7 +108,7 @@
}
impl<T: ?Sized + LazyMeta> Lazy<T> {
- pub fn from_position_and_meta(position: usize, meta: T::Meta) -> Lazy<T> {
+ crate fn from_position_and_meta(position: usize, meta: T::Meta) -> Lazy<T> {
Lazy {
position,
meta,
@@ -118,13 +118,13 @@
}
impl<T> Lazy<T> {
- pub fn from_position(position: usize) -> Lazy<T> {
+ crate fn from_position(position: usize) -> Lazy<T> {
Lazy::from_position_and_meta(position, ())
}
}
impl<T> Lazy<[T]> {
- pub fn empty() -> Lazy<[T]> {
+ crate fn empty() -> Lazy<[T]> {
Lazy::from_position_and_meta(0, 0)
}
}
@@ -141,7 +141,7 @@
/// Encoding / decoding state for `Lazy`.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub enum LazyState {
+crate enum LazyState {
/// Outside of a metadata node.
NoNode,
@@ -156,7 +156,7 @@
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct CrateRoot<'tcx> {
+crate struct CrateRoot<'tcx> {
pub name: Symbol,
pub triple: TargetTriple,
pub extra_filename: String,
@@ -202,7 +202,7 @@
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct CrateDep {
+crate struct CrateDep {
pub name: ast::Name,
pub hash: Svh,
pub kind: DepKind,
@@ -210,13 +210,13 @@
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct TraitImpls {
+crate struct TraitImpls {
pub trait_id: (u32, DefIndex),
pub impls: Lazy<[DefIndex]>,
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct Entry<'tcx> {
+crate struct Entry<'tcx> {
pub kind: EntryKind<'tcx>,
pub visibility: Lazy<ty::Visibility>,
pub span: Lazy<Span>,
@@ -237,7 +237,7 @@
}
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
-pub enum EntryKind<'tcx> {
+crate enum EntryKind<'tcx> {
Const(ConstQualif, Lazy<RenderedConst>),
ImmStatic,
MutStatic,
@@ -272,28 +272,28 @@
/// Additional data for EntryKind::Const and EntryKind::AssocConst
#[derive(Clone, Copy, RustcEncodable, RustcDecodable)]
-pub struct ConstQualif {
+crate struct ConstQualif {
pub mir: u8,
}
/// Contains a constant which has been rendered to a String.
/// Used by rustdoc.
#[derive(RustcEncodable, RustcDecodable)]
-pub struct RenderedConst(pub String);
+crate struct RenderedConst(pub String);
#[derive(RustcEncodable, RustcDecodable)]
-pub struct ModData {
+crate struct ModData {
pub reexports: Lazy<[def::Export<hir::HirId>]>,
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct MacroDef {
+crate struct MacroDef {
pub body: String,
pub legacy: bool,
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct FnData<'tcx> {
+crate struct FnData<'tcx> {
pub asyncness: hir::IsAsync,
pub constness: hir::Constness,
pub param_names: Lazy<[ast::Name]>,
@@ -301,7 +301,7 @@
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct VariantData<'tcx> {
+crate struct VariantData<'tcx> {
pub ctor_kind: CtorKind,
pub discr: ty::VariantDiscr,
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
@@ -312,7 +312,7 @@
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct TraitData<'tcx> {
+crate struct TraitData<'tcx> {
pub unsafety: hir::Unsafety,
pub paren_sugar: bool,
pub has_auto_impl: bool,
@@ -321,12 +321,12 @@
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct TraitAliasData<'tcx> {
+crate struct TraitAliasData<'tcx> {
pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct ImplData<'tcx> {
+crate struct ImplData<'tcx> {
pub polarity: ty::ImplPolarity,
pub defaultness: hir::Defaultness,
pub parent_impl: Option<DefId>,
@@ -341,7 +341,7 @@
/// is a trait or an impl and whether, in a trait, it has
/// a default, or an in impl, whether it's marked "default".
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
-pub enum AssocContainer {
+crate enum AssocContainer {
TraitRequired,
TraitWithDefault,
ImplDefault,
@@ -349,7 +349,7 @@
}
impl AssocContainer {
- pub fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer {
+ crate fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer {
match *self {
AssocContainer::TraitRequired |
AssocContainer::TraitWithDefault => ty::TraitContainer(def_id),
@@ -359,7 +359,7 @@
}
}
- pub fn defaultness(&self) -> hir::Defaultness {
+ crate fn defaultness(&self) -> hir::Defaultness {
match *self {
AssocContainer::TraitRequired => hir::Defaultness::Default {
has_value: false,
@@ -376,22 +376,22 @@
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct MethodData<'tcx> {
+crate struct MethodData<'tcx> {
pub fn_data: FnData<'tcx>,
pub container: AssocContainer,
pub has_self: bool,
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct ClosureData<'tcx> {
+crate struct ClosureData<'tcx> {
pub sig: Lazy<ty::PolyFnSig<'tcx>>,
}
#[derive(RustcEncodable, RustcDecodable)]
-pub struct GeneratorData<'tcx> {
+crate struct GeneratorData<'tcx> {
pub layout: mir::GeneratorLayout<'tcx>,
}
// Tags used for encoding Spans:
-pub const TAG_VALID_SPAN: u8 = 0;
-pub const TAG_INVALID_SPAN: u8 = 1;
+crate const TAG_VALID_SPAN: u8 = 0;
+crate const TAG_INVALID_SPAN: u8 = 1;
diff --git a/src/librustc_mir/dataflow/impls/indirect_mutation.rs b/src/librustc_mir/dataflow/impls/indirect_mutation.rs
index 990425c..bc09e32 100644
--- a/src/librustc_mir/dataflow/impls/indirect_mutation.rs
+++ b/src/librustc_mir/dataflow/impls/indirect_mutation.rs
@@ -104,25 +104,16 @@
kind: mir::BorrowKind,
borrowed_place: &mir::Place<'tcx>,
) -> bool {
- let borrowed_ty = borrowed_place.ty(self.body, self.tcx).ty;
-
- // Zero-sized types cannot be mutated, since there is nothing inside to mutate.
- //
- // FIXME: For now, we only exempt arrays of length zero. We need to carefully
- // consider the effects before extending this to all ZSTs.
- if let ty::Array(_, len) = borrowed_ty.kind {
- if len.try_eval_usize(self.tcx, self.param_env) == Some(0) {
- return false;
- }
- }
-
match kind {
mir::BorrowKind::Mut { .. } => true,
| mir::BorrowKind::Shared
| mir::BorrowKind::Shallow
| mir::BorrowKind::Unique
- => !borrowed_ty.is_freeze(self.tcx, self.param_env, DUMMY_SP),
+ => !borrowed_place
+ .ty(self.body, self.tcx)
+ .ty
+ .is_freeze(self.tcx, self.param_env, DUMMY_SP),
}
}
}
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 06999ab..ad0f75d 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -1,4 +1,5 @@
use syntax::ast::{self, MetaItem};
+use syntax::print::pprust;
use syntax::symbol::{Symbol, sym};
use rustc_index::bit_set::{BitSet, HybridBitSet};
@@ -159,9 +160,8 @@
if let Some(s) = item.value_str() {
return Some(s.to_string())
} else {
- sess.span_err(
- item.span,
- &format!("{} attribute requires a path", item.path));
+ let path = pprust::path_to_string(&item.path);
+ sess.span_err(item.span, &format!("{} attribute requires a path", path));
return None;
}
}
diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs
index 77853ff..419c905 100644
--- a/src/librustc_mir/error_codes.rs
+++ b/src/librustc_mir/error_codes.rs
@@ -64,7 +64,9 @@
This error indicates that the compiler cannot guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
-determine the flow of execution. Erroneous code example:
+determine the flow of execution.
+
+Erroneous code example:
```compile_fail,E0004
enum Terminator {
@@ -109,7 +111,9 @@
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee
-that a name will be extracted in all cases. Erroneous code example:
+that a name will be extracted in all cases.
+
+Erroneous code example:
```compile_fail,E0005
let x = Some(1);
@@ -145,6 +149,8 @@
moved into a variable called `op_string` while simultaneously requiring the
inner `String` to be moved into a variable called `s`.
+Erroneous code example:
+
```compile_fail,E0007
let x = Some("s".to_string());
@@ -208,15 +214,130 @@
```
"##,
+E0010: r##"
+The value of statics and constants must be known at compile time, and they live
+for the entire lifetime of a program. Creating a boxed value allocates memory on
+the heap at runtime, and therefore cannot be done at compile time.
+
+Erroneous code example:
+
+```compile_fail,E0010
+#![feature(box_syntax)]
+
+const CON : Box<i32> = box 0;
+```
+"##,
+
+E0013: r##"
+Static and const variables can refer to other const variables. But a const
+variable cannot refer to a static variable.
+
+Erroneous code example:
+
+```compile_fail,E0013
+static X: i32 = 42;
+const Y: i32 = X;
+```
+
+In this example, `Y` cannot refer to `X` here. To fix this, the value can be
+extracted as a const and then used:
+
+```
+const A: i32 = 42;
+static X: i32 = A;
+const Y: i32 = A;
+```
+"##,
+
+// FIXME(#57563) Change the language here when const fn stabilizes
+E0015: r##"
+The only functions that can be called in static or constant expressions are
+`const` functions, and struct/enum constructors. `const` functions are only
+available on a nightly compiler. Rust currently does not support more general
+compile-time function execution.
+
+```
+const FOO: Option<u8> = Some(1); // enum constructor
+struct Bar {x: u8}
+const BAR: Bar = Bar {x: 1}; // struct constructor
+```
+
+See [RFC 911] for more details on the design of `const fn`s.
+
+[RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md
+"##,
+
+E0017: r##"
+References in statics and constants may only refer to immutable values.
+
+Erroneous code example:
+
+```compile_fail,E0017
+static X: i32 = 1;
+const C: i32 = 2;
+
+// these three are not allowed:
+const CR: &mut i32 = &mut C;
+static STATIC_REF: &'static mut i32 = &mut X;
+static CONST_REF: &'static mut i32 = &mut C;
+```
+
+Statics are shared everywhere, and if they refer to mutable data one might
+violate memory safety since holding multiple mutable references to shared data
+is not allowed.
+
+If you really want global mutable state, try using `static mut` or a global
+`UnsafeCell`.
+"##,
+
+E0019: r##"
+A function call isn't allowed in the const's initialization expression
+because the expression's value must be known at compile-time.
+
+Erroneous code example:
+
+```compile_fail,E0019
+#![feature(box_syntax)]
+
+fn main() {
+ struct MyOwned;
+
+ static STATIC11: Box<MyOwned> = box MyOwned; // error!
+}
+```
+
+Remember: you can't use a function call inside a const's initialization
+expression! However, you can totally use it anywhere else:
+
+```
+enum Test {
+ V1
+}
+
+impl Test {
+ fn func(&self) -> i32 {
+ 12
+ }
+}
+
+fn main() {
+ const FOO: Test = Test::V1;
+
+ FOO.func(); // here is good
+ let x = FOO.func(); // or even here!
+}
+```
+"##,
+
E0030: r##"
When matching against a range, the compiler verifies that the range is
-non-empty. Range patterns include both end-points, so this is equivalent to
+non-empty. Range patterns include both end-points, so this is equivalent to
requiring the start of the range to be less than or equal to the end of the
range.
-For example:
+Erroneous code example:
-```compile_fail
+```compile_fail,E0030
match 5u32 {
// This range is ok, albeit pointless.
1 ..= 1 => {}
@@ -226,7 +347,61 @@
```
"##,
+E0133: r##"
+Unsafe code was used outside of an unsafe function or block.
+
+Erroneous code example:
+
+```compile_fail,E0133
+unsafe fn f() { return; } // This is the unsafe code
+
+fn main() {
+ f(); // error: call to unsafe function requires unsafe function or block
+}
+```
+
+Using unsafe functionality is potentially dangerous and disallowed by safety
+checks. Examples:
+
+* Dereferencing raw pointers
+* Calling functions via FFI
+* Calling functions marked unsafe
+
+These safety checks can be relaxed for a section of the code by wrapping the
+unsafe instructions with an `unsafe` block. For instance:
+
+```
+unsafe fn f() { return; }
+
+fn main() {
+ unsafe { f(); } // ok!
+}
+```
+
+See also https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html
+"##,
+
E0158: r##"
+An associated const has been referenced in a pattern.
+
+Erroneous code example:
+
+```compile_fail,E0158
+enum EFoo { A, B, C, D }
+
+trait Foo {
+ const X: EFoo;
+}
+
+fn test<A: Foo>(arg: EFoo) {
+ match arg {
+ A::X => { // error!
+ println!("A::X");
+ }
+ }
+}
+```
+
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.
@@ -247,6 +422,39 @@
```
"##,
+E0161: r##"
+A value was moved. However, its size was not known at compile time, and only
+values of a known size can be moved.
+
+Erroneous code example:
+
+```compile_fail,E0161
+#![feature(box_syntax)]
+
+fn main() {
+ let array: &[isize] = &[1, 2, 3];
+ let _x: Box<[isize]> = box *array;
+ // error: cannot move a value of type [isize]: the size of [isize] cannot
+ // be statically determined
+}
+```
+
+In Rust, you can only move a value when its size is known at compile time.
+
+To work around this restriction, consider "hiding" the value behind a reference:
+either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
+it around as usual. Example:
+
+```
+#![feature(box_syntax)]
+
+fn main() {
+ let array: &[isize] = &[1, 2, 3];
+ let _x: Box<&[isize]> = box array; // ok!
+}
+```
+"##,
+
E0162: r##"
#### Note: this error code is no longer emitted by the compiler.
@@ -468,158 +676,6 @@
See also https://github.com/rust-lang/rust/issues/14587
"##,
-E0010: r##"
-The value of statics and constants must be known at compile time, and they live
-for the entire lifetime of a program. Creating a boxed value allocates memory on
-the heap at runtime, and therefore cannot be done at compile time. Erroneous
-code example:
-
-```compile_fail,E0010
-#![feature(box_syntax)]
-
-const CON : Box<i32> = box 0;
-```
-"##,
-
-E0013: r##"
-Static and const variables can refer to other const variables. But a const
-variable cannot refer to a static variable. For example, `Y` cannot refer to
-`X` here:
-
-```compile_fail,E0013
-static X: i32 = 42;
-const Y: i32 = X;
-```
-
-To fix this, the value can be extracted as a const and then used:
-
-```
-const A: i32 = 42;
-static X: i32 = A;
-const Y: i32 = A;
-```
-"##,
-
-// FIXME(#57563) Change the language here when const fn stabilizes
-E0015: r##"
-The only functions that can be called in static or constant expressions are
-`const` functions, and struct/enum constructors. `const` functions are only
-available on a nightly compiler. Rust currently does not support more general
-compile-time function execution.
-
-```
-const FOO: Option<u8> = Some(1); // enum constructor
-struct Bar {x: u8}
-const BAR: Bar = Bar {x: 1}; // struct constructor
-```
-
-See [RFC 911] for more details on the design of `const fn`s.
-
-[RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md
-"##,
-
-E0017: r##"
-References in statics and constants may only refer to immutable values.
-Erroneous code example:
-
-```compile_fail,E0017
-static X: i32 = 1;
-const C: i32 = 2;
-
-// these three are not allowed:
-const CR: &mut i32 = &mut C;
-static STATIC_REF: &'static mut i32 = &mut X;
-static CONST_REF: &'static mut i32 = &mut C;
-```
-
-Statics are shared everywhere, and if they refer to mutable data one might
-violate memory safety since holding multiple mutable references to shared data
-is not allowed.
-
-If you really want global mutable state, try using `static mut` or a global
-`UnsafeCell`.
-"##,
-
-E0019: r##"
-A function call isn't allowed in the const's initialization expression
-because the expression's value must be known at compile-time. Erroneous code
-example:
-
-```compile_fail
-enum Test {
- V1
-}
-
-impl Test {
- fn test(&self) -> i32 {
- 12
- }
-}
-
-fn main() {
- const FOO: Test = Test::V1;
-
- const A: i32 = FOO.test(); // You can't call Test::func() here!
-}
-```
-
-Remember: you can't use a function call inside a const's initialization
-expression! However, you can totally use it anywhere else:
-
-```
-enum Test {
- V1
-}
-
-impl Test {
- fn func(&self) -> i32 {
- 12
- }
-}
-
-fn main() {
- const FOO: Test = Test::V1;
-
- FOO.func(); // here is good
- let x = FOO.func(); // or even here!
-}
-```
-"##,
-
-E0133: r##"
-Unsafe code was used outside of an unsafe function or block.
-
-Erroneous code example:
-
-```compile_fail,E0133
-unsafe fn f() { return; } // This is the unsafe code
-
-fn main() {
- f(); // error: call to unsafe function requires unsafe function or block
-}
-```
-
-Using unsafe functionality is potentially dangerous and disallowed by safety
-checks. Examples:
-
-* Dereferencing raw pointers
-* Calling functions via FFI
-* Calling functions marked unsafe
-
-These safety checks can be relaxed for a section of the code by wrapping the
-unsafe instructions with an `unsafe` block. For instance:
-
-```
-unsafe fn f() { return; }
-
-fn main() {
- unsafe { f(); } // ok!
-}
-```
-
-See also https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html
-"##,
-
E0373: r##"
This error occurs when an attempt is made to use data captured by a closure,
when that data may no longer exist. It's most commonly seen when attempting to
@@ -672,7 +728,9 @@
"##,
E0381: r##"
-It is not allowed to use or capture an uninitialized variable. For example:
+It is not allowed to use or capture an uninitialized variable.
+
+Erroneous code example:
```compile_fail,E0381
fn main() {
@@ -694,7 +752,9 @@
E0382: r##"
This error occurs when an attempt is made to use a variable after its contents
-have been moved elsewhere. For example:
+have been moved elsewhere.
+
+Erroneous code example:
```compile_fail,E0382
struct MyStruct { s: u32 }
@@ -842,7 +902,8 @@
E0384: r##"
This error occurs when an attempt is made to reassign an immutable variable.
-For example:
+
+Erroneous code example:
```compile_fail,E0384
fn main() {
@@ -862,13 +923,15 @@
```
"##,
-/*E0386: r##"
+E0386: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
This error occurs when an attempt is made to mutate the target of a mutable
reference stored inside an immutable container.
For example, this can happen when storing a `&mut` inside an immutable `Box`:
-```compile_fail,E0386
+```
let mut x: i64 = 1;
let y: Box<_> = Box::new(&mut x);
**y = 2; // error, cannot assign to data in an immutable container
@@ -892,13 +955,15 @@
let y: Box<Cell<_>> = Box::new(Cell::new(x));
y.set(2);
```
-"##,*/
+"##,
E0387: r##"
#### Note: this error code is no longer emitted by the compiler.
This error occurs when an attempt is made to mutate or mutably reference data
-that a closure has captured immutably. Examples of this error are shown below:
+that a closure has captured immutably.
+
+Erroneous code example:
```compile_fail
// Accepts a function or a closure that captures its environment immutably.
@@ -963,7 +1028,7 @@
commonly occurs when attempting to assign to a non-mutable reference of a
mutable reference (`&(&mut T)`).
-Example of erroneous code:
+Erroneous code example:
```compile_fail
struct FancyNum {
@@ -1022,43 +1087,11 @@
```
"##,
-E0161: r##"
-A value was moved. However, its size was not known at compile time, and only
-values of a known size can be moved.
+E0492: r##"
+A borrow of a constant containing interior mutability was attempted.
Erroneous code example:
-```compile_fail
-#![feature(box_syntax)]
-
-fn main() {
- let array: &[isize] = &[1, 2, 3];
- let _x: Box<[isize]> = box *array;
- // error: cannot move a value of type [isize]: the size of [isize] cannot
- // be statically determined
-}
-```
-
-In Rust, you can only move a value when its size is known at compile time.
-
-To work around this restriction, consider "hiding" the value behind a reference:
-either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
-it around as usual. Example:
-
-```
-#![feature(box_syntax)]
-
-fn main() {
- let array: &[isize] = &[1, 2, 3];
- let _x: Box<&[isize]> = box array; // ok!
-}
-```
-"##,
-
-E0492: r##"
-A borrow of a constant containing interior mutability was attempted. Erroneous
-code example:
-
```compile_fail,E0492
use std::sync::atomic::AtomicUsize;
@@ -1174,7 +1207,9 @@
"##,
E0499: r##"
-A variable was borrowed as mutable more than once. Erroneous code example:
+A variable was borrowed as mutable more than once.
+
+Erroneous code example:
```compile_fail,E0499
let mut i = 0;
@@ -1205,7 +1240,9 @@
"##,
E0500: r##"
-A borrowed variable was used by a closure. Example of erroneous code:
+A borrowed variable was used by a closure.
+
+Erroneous code example:
```compile_fail,E0500
fn you_know_nothing(jon_snow: &mut i32) {
@@ -1256,7 +1293,7 @@
http://rustbyexample.com/fn/closures/capture.html for more information about
capturing.
-Example of erroneous code:
+Erroneous code example:
```compile_fail,E0501
fn inside_closure(x: &mut i32) {
@@ -1329,7 +1366,7 @@
This error indicates that you are trying to borrow a variable as mutable when it
has already been borrowed as immutable.
-Example of erroneous code:
+Erroneous code example:
```compile_fail,E0502
fn bar(x: &mut i32) {}
@@ -1360,7 +1397,7 @@
E0503: r##"
A value was used after it was mutably borrowed.
-Example of erroneous code:
+Erroneous code example:
```compile_fail,E0503
fn main() {
@@ -1418,7 +1455,7 @@
This error occurs when an attempt is made to move a borrowed variable into a
closure.
-Example of erroneous code:
+Erroneous code example:
```compile_fail
struct FancyNum {
@@ -1609,7 +1646,7 @@
E0506: r##"
This error occurs when an attempt is made to assign to a borrowed value.
-Example of erroneous code:
+Erroneous code example:
```compile_fail,E0506
struct FancyNum {
@@ -1827,7 +1864,7 @@
E0508: r##"
A value was moved out of a non-copy fixed-size array.
-Example of erroneous code:
+Erroneous code example:
```compile_fail,E0508
struct NonCopy;
@@ -1872,7 +1909,7 @@
This error occurs when an attempt is made to move out of a value whose type
implements the `Drop` trait.
-Example of erroneous code:
+Erroneous code example:
```compile_fail,E0509
struct FancyNum {
@@ -1982,30 +2019,14 @@
to go "back in time" to the `None` arm.
"##,
-E0579: r##"
-When matching against an exclusive range, the compiler verifies that the range
-is non-empty. Exclusive range patterns include the start point but not the end
-point, so this is equivalent to requiring the start of the range to be less
-than the end of the range.
-
-For example:
-
-```compile_fail
-match 5u32 {
- // This range is ok, albeit pointless.
- 1 .. 2 => {}
- // This range is empty, and the compiler can tell.
- 5 .. 5 => {}
-}
-```
-"##,
-
E0515: r##"
Cannot return value that references local variable
Local variables, function parameters and temporaries are all dropped before the
end of the function body. So a reference to them cannot be returned.
+Erroneous code example:
+
```compile_fail,E0515
fn get_dangling_reference() -> &'static i32 {
let x = 0;
@@ -2101,6 +2122,28 @@
```
"##,
+E0579: r##"
+When matching against an exclusive range, the compiler verifies that the range
+is non-empty. Exclusive range patterns include the start point but not the end
+point, so this is equivalent to requiring the start of the range to be less
+than the end of the range.
+
+Erroneous code example:
+
+```compile_fail,E0579
+#![feature(exclusive_range_pattern)]
+
+fn main() {
+ match 5u32 {
+ // This range is ok, albeit pointless.
+ 1 .. 2 => {}
+ // This range is empty, and the compiler can tell.
+ 5 .. 5 => {} // error!
+ }
+}
+```
+"##,
+
E0595: r##"
#### Note: this error code is no longer emitted by the compiler.
@@ -2124,7 +2167,7 @@
E0596: r##"
This error occurs because you tried to mutably borrow a non-mutable variable.
-Example of erroneous code:
+Erroneous code example:
```compile_fail,E0596
let x = 1;
@@ -2143,7 +2186,7 @@
E0597: r##"
This error occurs because a value was dropped while it was still borrowed
-Example of erroneous code:
+Erroneous code example:
```compile_fail,E0597
struct Foo<'a> {
@@ -2180,6 +2223,8 @@
This error occurs because a borrow in a generator persists across a
yield point.
+Erroneous code example:
+
```compile_fail,E0626
# #![feature(generators, generator_trait, pin)]
# use std::ops::Generator;
@@ -2271,7 +2316,7 @@
This error occurs because a borrow of a thread-local variable was made inside a
function which outlived the lifetime of the function.
-Example of erroneous code:
+Erroneous code example:
```compile_fail,E0712
#![feature(thread_local)]
@@ -2293,7 +2338,7 @@
This error occurs when an attempt is made to borrow state past the end of the
lifetime of a type that implements the `Drop` trait.
-Example of erroneous code:
+Erroneous code example:
```compile_fail,E0713
#![feature(nll)]
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 3ba9895..903eb3c 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -9,7 +9,7 @@
use rustc::mir::interpret::truncate;
use rustc::ty::{self, Ty};
use rustc::ty::layout::{
- self, Size, Abi, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, PrimitiveExt
+ self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, PrimitiveExt
};
use rustc::ty::TypeFoldable;
@@ -377,20 +377,17 @@
layout::FieldPlacement::Array { stride, .. } => {
let len = base.len(self)?;
if field >= len {
- // This can be violated because this runs during promotion on code where the
- // type system has not yet ensured that such things don't happen.
+ // This can be violated because the index (field) can be a runtime value
+ // provided by the user.
debug!("tried to access element {} of array/slice with length {}", field, len);
throw_panic!(BoundsCheck { len, index: field });
}
stride * field
}
layout::FieldPlacement::Union(count) => {
- // FIXME(#64506) `UninhabitedValue` can be removed when this issue is resolved
- if base.layout.abi == Abi::Uninhabited {
- throw_unsup!(UninhabitedValue);
- }
assert!(field < count as u64,
- "Tried to access field {} of union with {} fields", field, count);
+ "Tried to access field {} of union {:#?} with {} fields",
+ field, base.layout, count);
// Offset is always 0
Size::from_bytes(0)
}
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 0339b85..43c4f72 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -263,7 +263,8 @@
let mut err = self.err_handler().struct_span_err(poly.span,
&format!("`?Trait` is not permitted in {}", where_));
if is_trait {
- err.note(&format!("traits are `?{}` by default", poly.trait_ref.path));
+ let path_str = pprust::path_to_string(&poly.trait_ref.path);
+ err.note(&format!("traits are `?{}` by default", path_str));
}
err.emit();
}
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 030f9b9..0d5361f 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -37,6 +37,7 @@
use syntax::ext::hygiene::ExpnId;
use syntax::feature_gate::is_builtin_attr;
use syntax::parse::token::{self, Token};
+use syntax::print::pprust;
use syntax::{span_err, struct_span_err};
use syntax::source_map::{respan, Spanned};
use syntax::symbol::{kw, sym};
@@ -93,7 +94,8 @@
where T: ToNameBinding<'a>,
{
let binding = def.to_name_binding(self.arenas);
- if let Err(old_binding) = self.try_define(parent, ident, ns, binding) {
+ let key = self.new_key(ident, ns);
+ if let Err(old_binding) = self.try_define(parent, key, binding) {
self.report_conflict(parent, ident, ns, old_binding, &binding);
}
}
@@ -103,8 +105,7 @@
return self.module_map[&def_id]
}
- let macros_only = self.cstore.dep_kind_untracked(def_id.krate).macros_only();
- if let Some(&module) = self.extern_module_map.get(&(def_id, macros_only)) {
+ if let Some(&module) = self.extern_module_map.get(&def_id) {
return module;
}
@@ -120,7 +121,7 @@
let module = self.arenas.alloc_module(ModuleData::new(
parent, kind, def_id, ExpnId::root(), DUMMY_SP
));
- self.extern_module_map.insert((def_id, macros_only), module);
+ self.extern_module_map.insert(def_id, module);
module
}
@@ -228,7 +229,7 @@
.span_suggestion(
path.span,
"try",
- format!("crate::{}", path),
+ format!("crate::{}", pprust::path_to_string(&path)),
Applicability::MaybeIncorrect,
)
.emit();
@@ -349,9 +350,12 @@
self.r.indeterminate_imports.push(directive);
match directive.subclass {
+ // Don't add unresolved underscore imports to modules
+ SingleImport { target: Ident { name: kw::Underscore, .. }, .. } => {}
SingleImport { target, type_ns_only, .. } => {
self.r.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
- let mut resolution = this.resolution(current_module, target, ns).borrow_mut();
+ let key = this.new_key(target, ns);
+ let mut resolution = this.resolution(current_module, key).borrow_mut();
resolution.add_single_import(directive);
});
}
@@ -407,7 +411,7 @@
};
match use_tree.kind {
ast::UseTreeKind::Simple(rename, ..) => {
- let mut ident = use_tree.ident().gensym_if_underscore();
+ let mut ident = use_tree.ident();
let mut module_path = prefix;
let mut source = module_path.pop().unwrap();
let mut type_ns_only = false;
@@ -585,7 +589,7 @@
let parent_scope = &self.parent_scope;
let parent = parent_scope.module;
let expansion = parent_scope.expansion;
- let ident = item.ident.gensym_if_underscore();
+ let ident = item.ident;
let sp = item.span;
let vis = self.resolve_visibility(&item.vis);
@@ -617,6 +621,7 @@
let crate_id = self.r.crate_loader.process_extern_crate(
item, &self.r.definitions
);
+ self.r.extern_crate_map.insert(item.id, crate_id);
self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
};
@@ -850,10 +855,6 @@
fn build_reduced_graph_for_external_crate_res(&mut self, child: Export<NodeId>) {
let parent = self.parent_scope.module;
let Export { ident, res, vis, span } = child;
- // FIXME: We shouldn't create the gensym here, it should come from metadata,
- // but metadata cannot encode gensyms currently, so we create it here.
- // This is only a guess, two equivalent idents may incorrectly get different gensyms here.
- let ident = ident.gensym_if_underscore();
let expansion = ExpnId::root(); // FIXME(jseyfried) intercrate hygiene
// Record primary definitions.
match res {
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index d713315d..de87580 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -80,11 +80,11 @@
names: &mut Vec<TypoSuggestion>,
filter_fn: &impl Fn(Res) -> bool,
) {
- for (&(ident, _), resolution) in self.resolutions(module).borrow().iter() {
+ for (key, resolution) in self.resolutions(module).borrow().iter() {
if let Some(binding) = resolution.borrow().binding {
let res = binding.res();
if filter_fn(res) {
- names.push(TypoSuggestion::from_res(ident.name, res));
+ names.push(TypoSuggestion::from_res(key.ident.name, res));
}
}
}
@@ -849,7 +849,7 @@
}
let resolutions = self.r.resolutions(crate_module).borrow();
- let resolution = resolutions.get(&(ident, MacroNS))?;
+ let resolution = resolutions.get(&self.r.new_key(ident, MacroNS))?;
let binding = resolution.borrow().binding()?;
if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() {
let module_name = crate_module.kind.name().unwrap();
diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs
index 4734677..1e65cba 100644
--- a/src/librustc_resolve/error_codes.rs
+++ b/src/librustc_resolve/error_codes.rs
@@ -1611,6 +1611,56 @@
```
"##,
+E0574: r##"
+Something other than a struct, variant or union has been used when one was
+expected.
+
+Erroneous code example:
+
+```compile_fail,E0574
+mod Mordor {}
+
+let sauron = Mordor { x: () }; // error!
+
+enum Jak {
+ Daxter { i: isize },
+}
+
+let eco = Jak::Daxter { i: 1 };
+match eco {
+ Jak { i } => {} // error!
+}
+```
+
+In all these errors, a type was expected. For example, in the first error,
+we tried to instantiate the `Mordor` module, which is impossible. If you want
+to instantiate a type inside a module, you can do it as follow:
+
+```
+mod Mordor {
+ pub struct TheRing {
+ pub x: usize,
+ }
+}
+
+let sauron = Mordor::TheRing { x: 1 }; // ok!
+```
+
+In the second error, we tried to bind the `Jak` enum directly, which is not
+possible: you can only bind one of its variants. To do so:
+
+```
+enum Jak {
+ Daxter { i: isize },
+}
+
+let eco = Jak::Daxter { i: 1 };
+match eco {
+ Jak::Daxter { i } => {} // ok!
+}
+```
+"##,
+
E0603: r##"
A private item was used outside its scope.
@@ -1739,7 +1789,6 @@
// E0467, removed
// E0470, removed
E0573,
- E0574,
E0575,
E0576,
E0577,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index e0ff153..e5b0ef8 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -26,7 +26,7 @@
use rustc::lint;
use rustc::hir::def::{self, DefKind, PartialRes, CtorKind, CtorOf, NonMacroAttrKind, ExportMap};
use rustc::hir::def::Namespace::*;
-use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
+use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
use rustc::hir::{TraitMap, GlobMap};
use rustc::ty::{self, DefIdTree};
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
@@ -38,6 +38,7 @@
use syntax::ext::hygiene::{ExpnId, Transparency, SyntaxContext};
use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
use syntax::ext::base::{SyntaxExtension, MacroKind, SpecialDerives};
+use syntax::print::pprust;
use syntax::symbol::{kw, sym};
use syntax::visit::{self, Visitor};
@@ -431,7 +432,22 @@
}
}
-type Resolutions<'a> = RefCell<FxIndexMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>;
+/// A key that identifies a binding in a given `Module`.
+///
+/// Multiple bindings in the same module can have the same key (in a valid
+/// program) if all but one of them come from glob imports.
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+struct BindingKey {
+ /// The identifier for the binding, aways the `modern` version of the
+ /// identifier.
+ ident: Ident,
+ ns: Namespace,
+ /// 0 if ident is not `_`, otherwise a value that's unique to the specific
+ /// `_` in the expanded AST that introduced this binding.
+ disambiguator: u32,
+}
+
+type Resolutions<'a> = RefCell<FxIndexMap<BindingKey, &'a RefCell<NameResolution<'a>>>>;
/// One node in the tree of modules.
pub struct ModuleData<'a> {
@@ -491,8 +507,8 @@
fn for_each_child<R, F>(&'a self, resolver: &mut R, mut f: F)
where R: AsMut<Resolver<'a>>, F: FnMut(&mut R, Ident, Namespace, &'a NameBinding<'a>)
{
- for (&(ident, ns), name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
- name_resolution.borrow().binding.map(|binding| f(resolver, ident, ns, binding));
+ for (key, name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
+ name_resolution.borrow().binding.map(|binding| f(resolver, key.ident, key.ns, binding));
}
}
@@ -854,6 +870,8 @@
/// Resolutions for labels (node IDs of their corresponding blocks or loops).
label_res_map: NodeMap<NodeId>,
+ /// `CrateNum` resolutions of `extern crate` items.
+ pub extern_crate_map: NodeMap<CrateNum>,
pub export_map: ExportMap<NodeId>,
pub trait_map: TraitMap,
@@ -877,8 +895,9 @@
/// language items.
empty_module: Module<'a>,
module_map: FxHashMap<DefId, Module<'a>>,
- extern_module_map: FxHashMap<(DefId, bool /* MacrosOnly? */), Module<'a>>,
+ extern_module_map: FxHashMap<DefId, Module<'a>>,
binding_parent_modules: FxHashMap<PtrKey<'a, NameBinding<'a>>, Module<'a>>,
+ underscore_disambiguator: u32,
/// Maps glob imports to the names of items actually imported.
pub glob_map: GlobMap,
@@ -899,7 +918,7 @@
arenas: &'a ResolverArenas<'a>,
dummy_binding: &'a NameBinding<'a>,
- crate_loader: &'a mut CrateLoader<'a>,
+ crate_loader: &'a CrateLoader<'a>,
macro_names: FxHashSet<Ident>,
builtin_macros: FxHashMap<Name, SyntaxExtension>,
macro_use_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
@@ -1069,7 +1088,7 @@
cstore: &'a CStore,
krate: &Crate,
crate_name: &str,
- crate_loader: &'a mut CrateLoader<'a>,
+ crate_loader: &'a CrateLoader<'a>,
arenas: &'a ResolverArenas<'a>)
-> Resolver<'a> {
let root_def_id = DefId::local(CRATE_DEF_INDEX);
@@ -1154,8 +1173,10 @@
partial_res_map: Default::default(),
import_res_map: Default::default(),
label_res_map: Default::default(),
+ extern_crate_map: Default::default(),
export_map: FxHashMap::default(),
trait_map: Default::default(),
+ underscore_disambiguator: 0,
empty_module,
module_map,
block_map: Default::default(),
@@ -1280,6 +1301,17 @@
self.arenas.alloc_module(module)
}
+ fn new_key(&mut self, ident: Ident, ns: Namespace) -> BindingKey {
+ let ident = ident.modern();
+ let disambiguator = if ident.name == kw::Underscore {
+ self.underscore_disambiguator += 1;
+ self.underscore_disambiguator
+ } else {
+ 0
+ };
+ BindingKey { ident, ns, disambiguator }
+ }
+
fn resolutions(&mut self, module: Module<'a>) -> &'a Resolutions<'a> {
if module.populate_on_access.get() {
module.populate_on_access.set(false);
@@ -1288,9 +1320,9 @@
&module.lazy_resolutions
}
- fn resolution(&mut self, module: Module<'a>, ident: Ident, ns: Namespace)
+ fn resolution(&mut self, module: Module<'a>, key: BindingKey)
-> &'a RefCell<NameResolution<'a>> {
- *self.resolutions(module).borrow_mut().entry((ident.modern(), ns))
+ *self.resolutions(module).borrow_mut().entry(key)
.or_insert_with(|| self.arenas.alloc_name_resolution())
}
@@ -2011,13 +2043,13 @@
let mut candidates =
self.lookup_import_candidates(ident, TypeNS, is_mod);
candidates.sort_by_cached_key(|c| {
- (c.path.segments.len(), c.path.to_string())
+ (c.path.segments.len(), pprust::path_to_string(&c.path))
});
if let Some(candidate) = candidates.get(0) {
(
String::from("unresolved import"),
Some((
- vec![(ident.span, candidate.path.to_string())],
+ vec![(ident.span, pprust::path_to_string(&candidate.path))],
String::from("a similar path exists"),
Applicability::MaybeIncorrect,
)),
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 2b87bba..4918608 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -21,6 +21,7 @@
use syntax::ext::compile_declarative_macro;
use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
use syntax::feature_gate::GateIssue;
+use syntax::print::pprust;
use syntax::symbol::{Symbol, kw, sym};
use syntax_pos::{Span, DUMMY_SP};
@@ -324,7 +325,8 @@
Ok(if ext.macro_kind() != kind {
let expected = kind.descr_expected();
- let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path);
+ let path_str = pprust::path_to_string(path);
+ let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path_str);
self.session.struct_span_err(path.span, &msg)
.span_label(path.span, format!("not {} {}", kind.article(), expected))
.emit();
@@ -805,14 +807,16 @@
}
}
if let Some(depr) = &stability.rustc_depr {
- let (message, lint) = stability::rustc_deprecation_message(depr, &path.to_string());
+ let path = pprust::path_to_string(path);
+ let (message, lint) = stability::rustc_deprecation_message(depr, &path);
stability::early_report_deprecation(
self.session, &message, depr.suggestion, lint, span
);
}
}
if let Some(depr) = &ext.deprecation {
- let (message, lint) = stability::deprecation_message(depr, &path.to_string());
+ let path = pprust::path_to_string(&path);
+ let (message, lint) = stability::deprecation_message(depr, &path);
stability::early_report_deprecation(self.session, &message, None, lint, span);
}
}
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 3603431..56fd2da 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -7,7 +7,7 @@
use crate::Determinacy::{self, *};
use crate::Namespace::{self, TypeNS, MacroNS};
use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
-use crate::{Resolver, ResolutionError, Segment, ModuleKind};
+use crate::{Resolver, ResolutionError, BindingKey, Segment, ModuleKind};
use crate::{names_to_string, module_to_string};
use crate::diagnostics::Suggestion;
@@ -235,7 +235,8 @@
}
};
- let resolution = self.resolution(module, ident, ns)
+ let key = self.new_key(ident, ns);
+ let resolution = self.resolution(module, key)
.try_borrow_mut()
.map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
@@ -447,17 +448,16 @@
}
// Define the name or return the existing binding if there is a collision.
- pub fn try_define(
+ crate fn try_define(
&mut self,
module: Module<'a>,
- ident: Ident,
- ns: Namespace,
+ key: BindingKey,
binding: &'a NameBinding<'a>,
) -> Result<(), &'a NameBinding<'a>> {
let res = binding.res();
- self.check_reserved_macro_name(ident, res);
+ self.check_reserved_macro_name(key.ident, res);
self.set_binding_parent_module(binding, module);
- self.update_resolution(module, ident, ns, |this, resolution| {
+ self.update_resolution(module, key, |this, resolution| {
if let Some(old_binding) = resolution.binding {
if res == Res::Err {
// Do not override real bindings with `Res::Err`s from error recovery.
@@ -479,8 +479,9 @@
} else {
(binding, old_binding)
};
- if glob_binding.res() != nonglob_binding.res() &&
- ns == MacroNS && nonglob_binding.expansion != ExpnId::root() {
+ if glob_binding.res() != nonglob_binding.res()
+ && key.ns == MacroNS && nonglob_binding.expansion != ExpnId::root()
+ {
resolution.binding = Some(this.ambiguity(
AmbiguityKind::GlobVsExpanded,
nonglob_binding,
@@ -499,9 +500,9 @@
DUPLICATE_MACRO_EXPORTS,
CRATE_NODE_ID,
binding.span,
- &format!("a macro named `{}` has already been exported", ident),
+ &format!("a macro named `{}` has already been exported", key.ident),
BuiltinLintDiagnostics::DuplicatedMacroExports(
- ident, old_binding.span, binding.span));
+ key.ident, old_binding.span, binding.span));
resolution.binding = Some(binding);
} else {
@@ -531,9 +532,9 @@
// Use `f` to mutate the resolution of the name in the module.
// If the resolution becomes a success, define it in the module's glob importers.
fn update_resolution<T, F>(
- &mut self, module: Module<'a>,
- ident: Ident,
- ns: Namespace,
+ &mut self,
+ module: Module<'a>,
+ key: BindingKey,
f: F,
) -> T
where F: FnOnce(&mut Resolver<'a>, &mut NameResolution<'a>) -> T
@@ -541,7 +542,7 @@
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
// during which the resolution might end up getting re-defined via a glob cycle.
let (binding, t) = {
- let resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
+ let resolution = &mut *self.resolution(module, key).borrow_mut();
let old_binding = resolution.binding();
let t = f(self, resolution);
@@ -558,7 +559,7 @@
// Define `binding` in `module`s glob importers.
for directive in module.glob_importers.borrow_mut().iter() {
- let mut ident = ident.modern();
+ let mut ident = key.ident;
let scope = match ident.span.reverse_glob_adjust(module.expansion, directive.span) {
Some(Some(def)) => self.macro_def_scope(def),
Some(None) => directive.parent_scope.module,
@@ -566,7 +567,8 @@
};
if self.is_accessible_from(binding.vis, scope) {
let imported_binding = self.import(binding, directive);
- let _ = self.try_define(directive.parent_scope.module, ident, ns, imported_binding);
+ let key = BindingKey { ident, ..key };
+ let _ = self.try_define(directive.parent_scope.module, key, imported_binding);
}
}
@@ -580,7 +582,8 @@
let dummy_binding = self.dummy_binding;
let dummy_binding = self.import(dummy_binding, directive);
self.per_ns(|this, ns| {
- let _ = this.try_define(directive.parent_scope.module, target, ns, dummy_binding);
+ let key = this.new_key(target, ns);
+ let _ = this.try_define(directive.parent_scope.module, key, dummy_binding);
// Consider erroneous imports used to avoid duplicate diagnostics.
this.record_use(target, ns, dummy_binding, false);
});
@@ -820,8 +823,11 @@
let parent = directive.parent_scope.module;
match source_bindings[ns].get() {
Err(Undetermined) => indeterminate = true,
+ // Don't update the resolution, because it was never added.
+ Err(Determined) if target.name == kw::Underscore => {}
Err(Determined) => {
- this.update_resolution(parent, target, ns, |_, resolution| {
+ let key = this.new_key(target, ns);
+ this.update_resolution(parent, key, |_, resolution| {
resolution.single_imports.remove(&PtrKey(directive));
});
}
@@ -1052,7 +1058,7 @@
_ => None,
};
let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
- let names = resolutions.filter_map(|(&(ref i, _), resolution)| {
+ let names = resolutions.filter_map(|(BindingKey { ident: i, .. }, resolution)| {
if *i == ident { return None; } // Never suggest the same name
match *resolution.borrow() {
NameResolution { binding: Some(name_binding), .. } => {
@@ -1301,19 +1307,18 @@
// Ensure that `resolutions` isn't borrowed during `try_define`,
// since it might get updated via a glob cycle.
- let bindings = self.r.resolutions(module).borrow().iter().filter_map(|(ident, resolution)| {
- resolution.borrow().binding().map(|binding| (*ident, binding))
+ let bindings = self.r.resolutions(module).borrow().iter().filter_map(|(key, resolution)| {
+ resolution.borrow().binding().map(|binding| (*key, binding))
}).collect::<Vec<_>>();
- for ((mut ident, ns), binding) in bindings {
- let scope = match ident.span.reverse_glob_adjust(module.expansion, directive.span) {
+ for (mut key, binding) in bindings {
+ let scope = match key.ident.span.reverse_glob_adjust(module.expansion, directive.span) {
Some(Some(def)) => self.r.macro_def_scope(def),
Some(None) => directive.parent_scope.module,
None => continue,
};
if self.r.is_accessible_from(binding.pseudo_vis(), scope) {
let imported_binding = self.r.import(binding, directive);
- let _ =
- self.r.try_define(directive.parent_scope.module, ident, ns, imported_binding);
+ let _ = self.r.try_define(directive.parent_scope.module, key, imported_binding);
}
}
@@ -1329,29 +1334,23 @@
let mut reexports = Vec::new();
- for (&(ident, ns), resolution) in self.r.resolutions(module).borrow().iter() {
- let resolution = &mut *resolution.borrow_mut();
- let binding = match resolution.binding {
- Some(binding) => binding,
- None => continue,
- };
-
+ module.for_each_child(self.r, |this, ident, ns, binding| {
// Filter away ambiguous imports and anything that has def-site
// hygiene.
// FIXME: Implement actual cross-crate hygiene.
let is_good_import = binding.is_import() && !binding.is_ambiguity()
- && !ident.span.modern().from_expansion();
+ && !ident.span.from_expansion();
if is_good_import || binding.is_macro_def() {
let res = binding.res();
if res != Res::Err {
if let Some(def_id) = res.opt_def_id() {
if !def_id.is_local() {
- self.r.cstore.export_macros_untracked(def_id.krate);
+ this.cstore.export_macros_untracked(def_id.krate);
}
}
reexports.push(Export {
- ident: ident.modern(),
- res: res,
+ ident,
+ res,
span: binding.span,
vis: binding.vis,
});
@@ -1360,7 +1359,7 @@
if let NameBindingKind::Import { binding: orig_binding, directive, .. } = binding.kind {
if ns == TypeNS && orig_binding.is_variant() &&
- !orig_binding.vis.is_at_least(binding.vis, &*self) {
+ !orig_binding.vis.is_at_least(binding.vis, &*this) {
let msg = match directive.subclass {
ImportDirectiveSubclass::SingleImport { .. } => {
format!("variant `{}` is private and cannot be re-exported",
@@ -1372,33 +1371,34 @@
let error_id = (DiagnosticMessageId::ErrorId(0), // no code?!
Some(binding.span),
msg.clone());
- let fresh = self.r.session.one_time_diagnostics
+ let fresh = this.session.one_time_diagnostics
.borrow_mut().insert(error_id);
if !fresh {
- continue;
+ return;
}
msg
},
ref s @ _ => bug!("unexpected import subclass {:?}", s)
};
- let mut err = self.r.session.struct_span_err(binding.span, &msg);
+ let mut err = this.session.struct_span_err(binding.span, &msg);
let imported_module = match directive.imported_module.get() {
Some(ModuleOrUniformRoot::Module(module)) => module,
_ => bug!("module should exist"),
};
let parent_module = imported_module.parent.expect("parent should exist");
- let resolutions = self.r.resolutions(parent_module).borrow();
+ let resolutions = this.resolutions(parent_module).borrow();
let enum_path_segment_index = directive.module_path.len() - 1;
let enum_ident = directive.module_path[enum_path_segment_index].ident;
- let enum_resolution = resolutions.get(&(enum_ident, TypeNS))
+ let key = this.new_key(enum_ident, TypeNS);
+ let enum_resolution = resolutions.get(&key)
.expect("resolution should exist");
let enum_span = enum_resolution.borrow()
.binding.expect("binding should exist")
.span;
- let enum_def_span = self.r.session.source_map().def_span(enum_span);
- let enum_def_snippet = self.r.session.source_map()
+ let enum_def_span = this.session.source_map().def_span(enum_span);
+ let enum_def_snippet = this.session.source_map()
.span_to_snippet(enum_def_span).expect("snippet should exist");
// potentially need to strip extant `crate`/`pub(path)` for suggestion
let after_vis_index = enum_def_snippet.find("enum")
@@ -1406,7 +1406,7 @@
let suggestion = format!("pub {}",
&enum_def_snippet[after_vis_index..]);
- self.r.session
+ this.session
.diag_span_suggestion_once(&mut err,
DiagnosticMessageId::ErrorId(0),
enum_def_span,
@@ -1415,7 +1415,7 @@
err.emit();
}
}
- }
+ });
if reexports.len() > 0 {
if let Some(def_id) = module.def_id() {
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index edd2db3..502ae33 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -115,15 +115,17 @@
F: FnOnce(&mut Self),
{
let item_def_id = self.tcx.hir().local_def_id_from_node_id(item_id);
- if self.tcx.has_typeck_tables(item_def_id) {
- let tables = self.tcx.typeck_tables_of(item_def_id);
- let old_tables = self.save_ctxt.tables;
- self.save_ctxt.tables = tables;
- f(self);
- self.save_ctxt.tables = old_tables;
+
+ let tables = if self.tcx.has_typeck_tables(item_def_id) {
+ self.tcx.typeck_tables_of(item_def_id)
} else {
- f(self);
- }
+ self.save_ctxt.empty_tables
+ };
+
+ let old_tables = self.save_ctxt.tables;
+ self.save_ctxt.tables = tables;
+ f(self);
+ self.save_ctxt.tables = old_tables;
}
fn span_from_span(&self, span: Span) -> SpanData {
@@ -530,12 +532,14 @@
);
}
- for field in def.fields() {
- self.process_struct_field_def(field, item.id);
- self.visit_ty(&field.ty);
- }
+ self.nest_tables(item.id, |v| {
+ for field in def.fields() {
+ v.process_struct_field_def(field, item.id);
+ v.visit_ty(&field.ty);
+ }
- self.process_generic_params(ty_params, &qualname, item.id);
+ v.process_generic_params(ty_params, &qualname, item.id);
+ });
}
fn process_enum(
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 70b508d..1cfb84b 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -48,6 +48,9 @@
pub struct SaveContext<'l, 'tcx> {
tcx: TyCtxt<'tcx>,
tables: &'l ty::TypeckTables<'tcx>,
+ /// Used as a fallback when nesting the typeck tables during item processing
+ /// (if these are not available for that item, e.g. don't own a body)
+ empty_tables: &'l ty::TypeckTables<'tcx>,
access_levels: &'l AccessLevels,
span_utils: SpanUtils<'tcx>,
config: Config,
@@ -1114,6 +1117,7 @@
let save_ctxt = SaveContext {
tcx,
tables: &ty::TypeckTables::empty(None),
+ empty_tables: &ty::TypeckTables::empty(None),
access_levels: &access_levels,
span_utils: SpanUtils::new(&tcx.sess),
config: find_config(config),
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index 26d37f1..fde5c5b 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -738,7 +738,11 @@
pub fn offset(&self, i: usize) -> Size {
match *self {
- FieldPlacement::Union(_) => Size::ZERO,
+ FieldPlacement::Union(count) => {
+ assert!(i < count,
+ "Tried to access field {} of union with {} fields", i, count);
+ Size::ZERO
+ },
FieldPlacement::Array { stride, count } => {
let i = i as u64;
assert!(i < count);
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 8b97bf6..4f41339 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -611,6 +611,16 @@
Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn)) => {
debug!("supplied_sig_of_closure: closure is async fn body");
self.deduce_future_output_from_obligations(expr_def_id)
+ .unwrap_or_else(|| {
+ // AFAIK, deducing the future output
+ // always succeeds *except* in error cases
+ // like #65159. I'd like to return Error
+ // here, but I can't because I can't
+ // easily (and locally) prove that we
+ // *have* reported an
+ // error. --nikomatsakis
+ astconv.ty_infer(None, decl.output.span())
+ })
}
_ => astconv.ty_infer(None, decl.output.span()),
@@ -645,7 +655,7 @@
fn deduce_future_output_from_obligations(
&self,
expr_def_id: DefId,
- ) -> Ty<'tcx> {
+ ) -> Option<Ty<'tcx>> {
debug!("deduce_future_output_from_obligations(expr_def_id={:?})", expr_def_id);
let ret_coercion =
@@ -688,8 +698,7 @@
} else {
None
}
- })
- .unwrap();
+ });
debug!("deduce_future_output_from_obligations: output_ty={:?}", output_ty);
output_ty
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 96cc5aa..f2d001e 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -777,7 +777,7 @@
} else {
"items from traits can only be used if the trait is implemented and in scope"
});
- let mut msg = format!(
+ let message = |action| format!(
"the following {traits_define} an item `{name}`, perhaps you need to {action} \
{one_of_them}:",
traits_define = if candidates.len() == 1 {
@@ -785,11 +785,7 @@
} else {
"traits define"
},
- action = if let Some(param) = param_type {
- format!("restrict type parameter `{}` with", param)
- } else {
- "implement".to_string()
- },
+ action = action,
one_of_them = if candidates.len() == 1 {
"it"
} else {
@@ -809,50 +805,81 @@
// Get the `hir::Param` to verify whether it already has any bounds.
// We do this to avoid suggesting code that ends up as `T: FooBar`,
// instead we suggest `T: Foo + Bar` in that case.
- let mut has_bounds = None;
- let mut impl_trait = false;
- if let Node::GenericParam(ref param) = hir.get(id) {
- let kind = ¶m.kind;
- if let hir::GenericParamKind::Type { synthetic: Some(_), .. } = kind {
- // We've found `fn foo(x: impl Trait)` instead of
- // `fn foo<T>(x: T)`. We want to suggest the correct
- // `fn foo(x: impl Trait + TraitBound)` instead of
- // `fn foo<T: TraitBound>(x: T)`. (See #63706.)
- impl_trait = true;
- has_bounds = param.bounds.get(1);
- } else {
- has_bounds = param.bounds.get(0);
+ match hir.get(id) {
+ Node::GenericParam(ref param) => {
+ let mut impl_trait = false;
+ let has_bounds = if let hir::GenericParamKind::Type {
+ synthetic: Some(_), ..
+ } = ¶m.kind {
+ // We've found `fn foo(x: impl Trait)` instead of
+ // `fn foo<T>(x: T)`. We want to suggest the correct
+ // `fn foo(x: impl Trait + TraitBound)` instead of
+ // `fn foo<T: TraitBound>(x: T)`. (#63706)
+ impl_trait = true;
+ param.bounds.get(1)
+ } else {
+ param.bounds.get(0)
+ };
+ let sp = hir.span(id);
+ let sp = if let Some(first_bound) = has_bounds {
+ // `sp` only covers `T`, change it so that it covers
+ // `T:` when appropriate
+ sp.until(first_bound.span())
+ } else {
+ sp
+ };
+ // FIXME: contrast `t.def_id` against `param.bounds` to not suggest
+ // traits already there. That can happen when the cause is that
+ // we're in a const scope or associated function used as a method.
+ err.span_suggestions(
+ sp,
+ &message(format!(
+ "restrict type parameter `{}` with",
+ param.name.ident().as_str(),
+ )),
+ candidates.iter().map(|t| format!(
+ "{}{} {}{}",
+ param.name.ident().as_str(),
+ if impl_trait { " +" } else { ":" },
+ self.tcx.def_path_str(t.def_id),
+ if has_bounds.is_some() { " + "} else { "" },
+ )),
+ Applicability::MaybeIncorrect,
+ );
+ suggested = true;
}
+ Node::Item(hir::Item {
+ kind: hir::ItemKind::Trait(.., bounds, _), ident, ..
+ }) => {
+ let (sp, sep, article) = if bounds.is_empty() {
+ (ident.span.shrink_to_hi(), ":", "a")
+ } else {
+ (bounds.last().unwrap().span().shrink_to_hi(), " +", "another")
+ };
+ err.span_suggestions(
+ sp,
+ &message(format!("add {} supertrait for", article)),
+ candidates.iter().map(|t| format!(
+ "{} {}",
+ sep,
+ self.tcx.def_path_str(t.def_id),
+ )),
+ Applicability::MaybeIncorrect,
+ );
+ suggested = true;
+ }
+ _ => {}
}
- let sp = hir.span(id);
- // `sp` only covers `T`, change it so that it covers `T:` when appropriate.
- let sp = if let Some(first_bound) = has_bounds {
- sp.until(first_bound.span())
- } else {
- sp
- };
-
- // FIXME: contrast `t.def_id` against `param.bounds` to not suggest traits
- // already there. That can happen when the cause is that we're in a const
- // scope or associated function used as a method.
- err.span_suggestions(
- sp,
- &msg[..],
- candidates.iter().map(|t| format!(
- "{}{} {}{}",
- param,
- if impl_trait { " +" } else { ":" },
- self.tcx.def_path_str(t.def_id),
- if has_bounds.is_some() { " + " } else { "" },
- )),
- Applicability::MaybeIncorrect,
- );
- suggested = true;
}
};
}
if !suggested {
+ let mut msg = message(if let Some(param) = param_type {
+ format!("restrict type parameter `{}` with", param)
+ } else {
+ "implement".to_string()
+ });
for (i, trait_info) in candidates.iter().enumerate() {
msg.push_str(&format!(
"\ncandidate #{}: `{}`",
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index da3b52a..706f52d 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -9,7 +9,7 @@
use syntax::symbol::{Symbol, sym};
use syntax::ast::{MetaItem, MetaItemKind, NestedMetaItem, LitKind};
-use syntax::parse::ParseSess;
+use syntax::sess::ParseSess;
use syntax::feature_gate::Features;
use syntax_pos::Span;
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 5d86ee9..30c9453 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -14,7 +14,7 @@
use syntax::source_map::{SourceMap, FilePathMapping};
use syntax::parse::lexer;
use syntax::parse::token::{self, Token};
-use syntax::parse;
+use syntax::sess::ParseSess;
use syntax::symbol::{kw, sym};
use syntax_pos::{Span, FileName};
@@ -33,7 +33,7 @@
class, tooltip).unwrap();
}
- let sess = parse::ParseSess::new(FilePathMapping::empty());
+ let sess = ParseSess::new(FilePathMapping::empty());
let fm = sess.source_map().new_source_file(
FileName::Custom(String::from("rustdoc-highlighting")),
src.to_owned(),
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 1ff71a0..b726ad1 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -46,6 +46,7 @@
use syntax::ast;
use syntax::edition::Edition;
use syntax::ext::base::MacroKind;
+use syntax::print::pprust;
use syntax::source_map::FileName;
use syntax::feature_gate::UnstableFeatures;
use syntax::symbol::{Symbol, sym};
@@ -2957,7 +2958,7 @@
}
fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
- let path = attr.path.to_string();
+ let path = pprust::path_to_string(&attr.path);
if attr.is_word() {
Some(path)
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 32044e4..10e15ab 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -1,6 +1,7 @@
use errors::Applicability;
use syntax::parse::lexer::{StringReader as Lexer};
-use syntax::parse::{ParseSess, token};
+use syntax::parse::token;
+use syntax::sess::ParseSess;
use syntax::source_map::FilePathMapping;
use syntax_pos::{InnerSpan, FileName};
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 05e6f36..0be6340 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -394,7 +394,7 @@
// Uses libsyntax to parse the doctest and find if there's a main fn and the extern
// crate already is included.
let (already_has_main, already_has_extern_crate, found_macro) = with_globals(edition, || {
- use crate::syntax::{parse::{self, ParseSess}, source_map::FilePathMapping};
+ use crate::syntax::{parse, sess::ParseSess, source_map::FilePathMapping};
use errors::emitter::EmitterWriter;
use errors::Handler;
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 0239520..79d9112 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -7,7 +7,6 @@
use crate::ext::hygiene::ExpnId;
use crate::parse::token::{self, DelimToken};
-use crate::print::pprust;
use crate::ptr::P;
use crate::source_map::{dummy_spanned, respan, Spanned};
use crate::symbol::{kw, sym, Symbol};
@@ -70,7 +69,7 @@
/// along with a bunch of supporting information.
///
/// E.g., `std::cmp::PartialEq`.
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Path {
pub span: Span,
/// The segments in the path: the things separated by `::`.
@@ -86,18 +85,6 @@
}
}
-impl fmt::Debug for Path {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "path({})", pprust::path_to_string(self))
- }
-}
-
-impl fmt::Display for Path {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", pprust::path_to_string(self))
- }
-}
-
impl Path {
// Convert a span and an identifier to the corresponding
// one-segment path.
@@ -507,19 +494,13 @@
pub span: Span,
}
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Pat {
pub id: NodeId,
pub kind: PatKind,
pub span: Span,
}
-impl fmt::Debug for Pat {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self))
- }
-}
-
impl Pat {
/// Attempt reparsing the pattern as a type.
/// This is intended for use by diagnostics.
@@ -831,7 +812,7 @@
}
/// A statement
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Stmt {
pub id: NodeId,
pub kind: StmtKind,
@@ -865,18 +846,7 @@
}
}
-impl fmt::Debug for Stmt {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "stmt({}: {})",
- self.id.to_string(),
- pprust::stmt_to_string(self)
- )
- }
-}
-
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum StmtKind {
/// A local (let) binding.
Local(P<Local>),
@@ -973,7 +943,7 @@
}
/// An expression.
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Expr {
pub id: NodeId,
pub kind: ExprKind,
@@ -1100,12 +1070,6 @@
}
}
-impl fmt::Debug for Expr {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self))
- }
-}
-
/// Limit types of a range (inclusive or exclusive)
#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug)]
pub enum RangeLimits {
@@ -1660,19 +1624,13 @@
},
}
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Ty {
pub id: NodeId,
pub kind: TyKind,
pub span: Span,
}
-impl fmt::Debug for Ty {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "type({})", pprust::ty_to_string(self))
- }
-}
-
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct BareFnTy {
pub unsafety: Unsafety,
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 2a8e6b2..1fe698c 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -4,7 +4,8 @@
use crate::early_buffered_lints::BufferedEarlyLintId;
use crate::ext::base::ExtCtxt;
use crate::feature_gate::{Features, GatedCfg};
-use crate::parse::ParseSess;
+use crate::print::pprust;
+use crate::sess::ParseSess;
use errors::{Applicability, Handler};
use syntax_pos::hygiene::Transparency;
@@ -243,7 +244,11 @@
let meta = meta.as_ref().unwrap();
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
- handle_errors(sess, meta.span, AttrError::MultipleItem(meta.path.to_string()));
+ handle_errors(
+ sess,
+ meta.span,
+ AttrError::MultipleItem(pprust::path_to_string(&meta.path)),
+ );
return false
}
if let Some(v) = meta.value_str() {
@@ -271,7 +276,10 @@
handle_errors(
sess,
mi.span,
- AttrError::UnknownMetaItem(mi.path.to_string(), expected),
+ AttrError::UnknownMetaItem(
+ pprust::path_to_string(&mi.path),
+ expected,
+ ),
);
continue 'outer
}
@@ -362,7 +370,7 @@
sess,
meta.span(),
AttrError::UnknownMetaItem(
- mi.path.to_string(),
+ pprust::path_to_string(&mi.path),
&["feature", "reason", "issue", "soft"]
),
);
@@ -434,7 +442,8 @@
sess,
meta.span(),
AttrError::UnknownMetaItem(
- mi.path.to_string(), &["since", "note"],
+ pprust::path_to_string(&mi.path),
+ &["since", "note"],
),
);
continue 'outer
@@ -597,8 +606,11 @@
!eval_condition(mis[0].meta_item().unwrap(), sess, eval)
},
_ => {
- span_err!(sess.span_diagnostic, cfg.span, E0537,
- "invalid predicate `{}`", cfg.path);
+ span_err!(
+ sess.span_diagnostic, cfg.span, E0537,
+ "invalid predicate `{}`",
+ pprust::path_to_string(&cfg.path)
+ );
false
}
}
@@ -653,7 +665,9 @@
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
handle_errors(
- sess, meta.span, AttrError::MultipleItem(meta.path.to_string())
+ sess,
+ meta.span,
+ AttrError::MultipleItem(pprust::path_to_string(&meta.path)),
);
return false
}
@@ -691,8 +705,10 @@
handle_errors(
sess,
meta.span(),
- AttrError::UnknownMetaItem(mi.path.to_string(),
- &["since", "note"]),
+ AttrError::UnknownMetaItem(
+ pprust::path_to_string(&mi.path),
+ &["since", "note"],
+ ),
);
continue 'outer
}
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 7bef693..d291e50 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -16,9 +16,10 @@
use crate::source_map::{BytePos, Spanned, DUMMY_SP};
use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
use crate::parse::parser::Parser;
-use crate::parse::{ParseSess, PResult};
+use crate::parse::PResult;
use crate::parse::token::{self, Token};
use crate::ptr::P;
+use crate::sess::ParseSess;
use crate::symbol::{sym, Symbol};
use crate::ThinVec;
use crate::tokenstream::{TokenStream, TokenTree, DelimSpan};
@@ -551,7 +552,7 @@
impl MetaItemKind {
pub fn tokens(&self, span: Span) -> TokenStream {
match *self {
- MetaItemKind::Word => TokenStream::empty(),
+ MetaItemKind::Word => TokenStream::default(),
MetaItemKind::NameValue(ref lit) => {
let mut vec = vec![TokenTree::token(token::Eq, span).into()];
lit.tokens().append_to_tree_and_joint_vec(&mut vec);
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 2923cc8..2099d01 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -10,8 +10,9 @@
use crate::ast;
use crate::edition::Edition;
use crate::mut_visit::*;
-use crate::parse::{token, ParseSess};
+use crate::parse::token;
use crate::ptr::P;
+use crate::sess::ParseSess;
use crate::symbol::sym;
use crate::util::map_in_place::MapInPlace;
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 583fb3f..01be564 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -5,9 +5,10 @@
use crate::ext::expand::{self, AstFragment, Invocation};
use crate::ext::hygiene::ExpnId;
use crate::mut_visit::{self, MutVisitor};
-use crate::parse::{self, parser, ParseSess, DirectoryOwnership};
+use crate::parse::{self, parser, DirectoryOwnership};
use crate::parse::token;
use crate::ptr::P;
+use crate::sess::ParseSess;
use crate::symbol::{kw, sym, Ident, Symbol};
use crate::{ThinVec, MACRO_ARGUMENTS};
use crate::tokenstream::{self, TokenStream};
@@ -892,7 +893,7 @@
/// when a macro expansion occurs, the resulting nodes have the `backtrace()
/// -> expn_data` of their expansion context stored into their span.
pub struct ExtCtxt<'a> {
- pub parse_sess: &'a parse::ParseSess,
+ pub parse_sess: &'a ParseSess,
pub ecfg: expand::ExpansionConfig<'a>,
pub root_path: PathBuf,
pub resolver: &'a mut dyn Resolver,
@@ -901,7 +902,7 @@
}
impl<'a> ExtCtxt<'a> {
- pub fn new(parse_sess: &'a parse::ParseSess,
+ pub fn new(parse_sess: &'a ParseSess,
ecfg: expand::ExpansionConfig<'a>,
resolver: &'a mut dyn Resolver)
-> ExtCtxt<'a> {
@@ -935,7 +936,7 @@
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 }
+ pub fn parse_sess(&self) -> &'a ParseSess { self.parse_sess }
pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config }
pub fn call_site(&self) -> Span {
self.current_expansion.id.expn_data().call_site
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index bbd8da2..2559e87 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -10,13 +10,14 @@
use crate::ext::placeholders::{placeholder, PlaceholderExpander};
use crate::feature_gate::{self, Features, GateIssue, is_builtin_attr, emit_feature_err};
use crate::mut_visit::*;
-use crate::parse::{DirectoryOwnership, PResult, ParseSess};
+use crate::parse::{DirectoryOwnership, PResult};
use crate::parse::token;
use crate::parse::parser::Parser;
+use crate::print::pprust;
use crate::ptr::P;
use crate::symbol::{sym, Symbol};
use crate::tokenstream::{TokenStream, TokenTree};
-use crate::visit::{self, Visitor};
+use crate::visit::Visitor;
use crate::util::map_in_place::MapInPlace;
use errors::{Applicability, FatalError};
@@ -388,7 +389,8 @@
"`derive` may only be applied to structs, enums and unions");
if let ast::AttrStyle::Inner = attr.style {
let trait_list = derives.iter()
- .map(|t| t.to_string()).collect::<Vec<_>>();
+ .map(|t| pprust::path_to_string(t))
+ .collect::<Vec<_>>();
let suggestion = format!("#[derive({})]", trait_list.join(", "));
err.span_suggestion(
span, "try an outer attribute", suggestion,
@@ -575,10 +577,7 @@
SyntaxExtensionKind::Bang(expander) => {
self.gate_proc_macro_expansion_kind(span, fragment_kind);
let tok_result = expander.expand(self.cx, span, mac.stream());
- let result =
- self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span);
- self.gate_proc_macro_expansion(span, &result);
- result
+ self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
}
SyntaxExtensionKind::LegacyBang(expander) => {
let prev = self.cx.current_expansion.prior_type_ascription;
@@ -587,8 +586,11 @@
let result = if let Some(result) = fragment_kind.make_from(tok_result) {
result
} else {
- let msg = format!("non-{kind} macro in {kind} position: {path}",
- kind = fragment_kind.name(), path = mac.path);
+ let msg = format!(
+ "non-{kind} macro in {kind} position: {path}",
+ kind = fragment_kind.name(),
+ path = pprust::path_to_string(&mac.path),
+ );
self.cx.span_err(span, &msg);
self.cx.trace_macros_diag();
fragment_kind.dummy(span)
@@ -619,10 +621,7 @@
})), DUMMY_SP).into();
let input = self.extract_proc_macro_attr_input(attr.item.tokens, span);
let tok_result = expander.expand(self.cx, span, input, item_tok);
- let res =
- self.parse_ast_fragment(tok_result, fragment_kind, &attr.item.path, span);
- self.gate_proc_macro_expansion(span, &res);
- res
+ self.parse_ast_fragment(tok_result, fragment_kind, &attr.item.path, span)
}
SyntaxExtensionKind::LegacyAttr(expander) => {
match attr.parse_meta(self.cx.parse_sess) {
@@ -671,12 +670,12 @@
}
}
Some(TokenTree::Token(..)) => {}
- None => return TokenStream::empty(),
+ None => return TokenStream::default(),
}
self.cx.span_err(span, "custom attribute invocations must be \
of the form `#[foo]` or `#[foo(..)]`, the macro name must only be \
followed by a delimiter token");
- TokenStream::empty()
+ TokenStream::default()
}
fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
@@ -713,41 +712,6 @@
);
}
- fn gate_proc_macro_expansion(&self, span: Span, fragment: &AstFragment) {
- if self.cx.ecfg.proc_macro_hygiene() {
- return
- }
-
- fragment.visit_with(&mut DisallowMacros {
- span,
- parse_sess: self.cx.parse_sess,
- });
-
- struct DisallowMacros<'a> {
- span: Span,
- parse_sess: &'a ParseSess,
- }
-
- impl<'ast, 'a> Visitor<'ast> for DisallowMacros<'a> {
- fn visit_item(&mut self, i: &'ast ast::Item) {
- if let ast::ItemKind::MacroDef(_) = i.kind {
- emit_feature_err(
- self.parse_sess,
- sym::proc_macro_hygiene,
- self.span,
- GateIssue::Language,
- "procedural macros cannot expand to macro definitions",
- );
- }
- visit::walk_item(self, i);
- }
-
- fn visit_mac(&mut self, _mac: &'ast ast::Mac) {
- // ...
- }
- }
- }
-
fn gate_proc_macro_expansion_kind(&self, span: Span, kind: AstFragmentKind) {
let kind = match kind {
AstFragmentKind::Expr |
@@ -878,7 +842,7 @@
err.span_label(span, "caused by the macro expansion here");
let msg = format!(
"the usage of `{}!` is likely invalid in {} context",
- macro_path,
+ pprust::path_to_string(¯o_path),
kind_name,
);
err.note(&msg);
diff --git a/src/libsyntax/ext/mbe/macro_check.rs b/src/libsyntax/ext/mbe/macro_check.rs
index 97074f5..aabaff4 100644
--- a/src/libsyntax/ext/mbe/macro_check.rs
+++ b/src/libsyntax/ext/mbe/macro_check.rs
@@ -109,7 +109,7 @@
use crate::ext::mbe::{KleeneToken, TokenTree};
use crate::parse::token::TokenKind;
use crate::parse::token::{DelimToken, Token};
-use crate::parse::ParseSess;
+use crate::sess::ParseSess;
use crate::symbol::{kw, sym};
use rustc_data_structures::fx::FxHashMap;
diff --git a/src/libsyntax/ext/mbe/macro_parser.rs b/src/libsyntax/ext/mbe/macro_parser.rs
index 0cb5eff..ff382c3 100644
--- a/src/libsyntax/ext/mbe/macro_parser.rs
+++ b/src/libsyntax/ext/mbe/macro_parser.rs
@@ -76,10 +76,11 @@
use crate::ast::{Ident, Name};
use crate::ext::mbe::{self, TokenTree};
-use crate::parse::{Directory, ParseSess, PResult};
+use crate::parse::{Directory, PResult};
use crate::parse::parser::{Parser, PathStyle};
use crate::parse::token::{self, DocComment, Nonterminal, Token};
use crate::print::pprust;
+use crate::sess::ParseSess;
use crate::symbol::{kw, sym, Symbol};
use crate::tokenstream::{DelimSpan, TokenStream};
diff --git a/src/libsyntax/ext/mbe/macro_rules.rs b/src/libsyntax/ext/mbe/macro_rules.rs
index aec4a68..b422329 100644
--- a/src/libsyntax/ext/mbe/macro_rules.rs
+++ b/src/libsyntax/ext/mbe/macro_rules.rs
@@ -14,8 +14,9 @@
use crate::parse::parser::Parser;
use crate::parse::token::TokenKind::*;
use crate::parse::token::{self, NtTT, Token};
-use crate::parse::{Directory, ParseSess};
+use crate::parse::Directory;
use crate::print::pprust;
+use crate::sess::ParseSess;
use crate::symbol::{kw, sym, Symbol};
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
@@ -174,7 +175,8 @@
rhses: &[mbe::TokenTree],
) -> Box<dyn MacResult + 'cx> {
if cx.trace_macros() {
- trace_macros_note(cx, sp, format!("expanding `{}! {{ {} }}`", name, arg));
+ let msg = format!("expanding `{}! {{ {} }}`", name, pprust::tts_to_string(arg.clone()));
+ trace_macros_note(cx, sp, msg);
}
// Which arm's failure should we report? (the one furthest along)
@@ -212,7 +214,8 @@
}
if cx.trace_macros() {
- trace_macros_note(cx, sp, format!("to `{}`", tts));
+ let msg = format!("to `{}`", pprust::tts_to_string(tts.clone()));
+ trace_macros_note(cx, sp, msg);
}
let directory = Directory {
diff --git a/src/libsyntax/ext/mbe/quoted.rs b/src/libsyntax/ext/mbe/quoted.rs
index 8cb85bd..3cec4bc 100644
--- a/src/libsyntax/ext/mbe/quoted.rs
+++ b/src/libsyntax/ext/mbe/quoted.rs
@@ -2,8 +2,8 @@
use crate::ext::mbe::macro_parser;
use crate::ext::mbe::{TokenTree, KleeneOp, KleeneToken, SequenceRepetition, Delimited};
use crate::parse::token::{self, Token};
-use crate::parse::ParseSess;
use crate::print::pprust;
+use crate::sess::ParseSess;
use crate::symbol::kw;
use crate::tokenstream;
diff --git a/src/libsyntax/ext/mbe/transcribe.rs b/src/libsyntax/ext/mbe/transcribe.rs
index ba818eb..da93043 100644
--- a/src/libsyntax/ext/mbe/transcribe.rs
+++ b/src/libsyntax/ext/mbe/transcribe.rs
@@ -95,7 +95,7 @@
) -> TokenStream {
// Nothing for us to transcribe...
if src.is_empty() {
- return TokenStream::empty();
+ return TokenStream::default();
}
// We descend into the RHS (`src`), expanding things as we go. This stack contains the things
diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs
index 8eecef1..4fae25b 100644
--- a/src/libsyntax/ext/placeholders.rs
+++ b/src/libsyntax/ext/placeholders.rs
@@ -15,7 +15,7 @@
fn mac_placeholder() -> ast::Mac {
ast::Mac {
path: ast::Path { span: DUMMY_SP, segments: Vec::new() },
- tts: TokenStream::empty().into(),
+ tts: TokenStream::default().into(),
delim: ast::MacDelimiter::Brace,
span: DUMMY_SP,
prior_type_ascription: None,
@@ -32,12 +32,12 @@
attrs: ThinVec::new(),
kind: ast::ExprKind::Mac(mac_placeholder()),
});
- let ty = P(ast::Ty {
+ let ty = || P(ast::Ty {
id,
kind: ast::TyKind::Mac(mac_placeholder()),
span,
});
- let pat = P(ast::Pat {
+ let pat = || P(ast::Pat {
id,
kind: ast::PatKind::Mac(mac_placeholder()),
span,
@@ -83,7 +83,7 @@
body: expr_placeholder(),
guard: None,
id,
- pat,
+ pat: pat(),
span,
is_placeholder: true,
}
@@ -105,7 +105,7 @@
id,
ident,
is_shorthand: false,
- pat,
+ pat: pat(),
span,
is_placeholder: true,
}
@@ -124,9 +124,9 @@
ast::Param {
attrs: Default::default(),
id,
- pat,
+ pat: pat(),
span,
- ty,
+ ty: ty(),
is_placeholder: true,
}
]),
@@ -136,7 +136,7 @@
id,
ident: None,
span,
- ty,
+ ty: ty(),
vis,
is_placeholder: true,
}
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index 021ec46..e0e1a1c 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -1,7 +1,9 @@
use crate::ast;
use crate::ext::base::ExtCtxt;
-use crate::parse::{self, token, ParseSess};
+use crate::parse::{self, token};
use crate::parse::lexer::comments;
+use crate::print::pprust;
+use crate::sess::ParseSess;
use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
use errors::Diagnostic;
@@ -174,7 +176,7 @@
}
Interpolated(nt) => {
- let stream = nt.to_tokenstream(sess, span);
+ let stream = parse::nt_to_tokenstream(&nt, sess, span);
TokenTree::Group(Group {
delimiter: Delimiter::None,
stream,
@@ -332,8 +334,7 @@
if !Self::is_valid(&string) {
panic!("`{:?}` is not a valid identifier", string)
}
- // Get rid of gensyms to conservatively check rawness on the string contents only.
- if is_raw && !sym.as_interned_str().as_symbol().can_be_raw() {
+ if is_raw && !sym.can_be_raw() {
panic!("`{}` cannot be a raw identifier", string);
}
Ident { sym, is_raw, span }
@@ -393,7 +394,7 @@
impl server::TokenStream for Rustc<'_> {
fn new(&mut self) -> Self::TokenStream {
- TokenStream::empty()
+ TokenStream::default()
}
fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
stream.is_empty()
@@ -407,7 +408,7 @@
)
}
fn to_string(&mut self, stream: &Self::TokenStream) -> String {
- stream.to_string()
+ pprust::tts_to_string(stream.clone())
}
fn from_token_tree(
&mut self,
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index ab1620b..043a2ff 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -9,8 +9,8 @@
use crate::ast;
use crate::attr::AttributeTemplate;
+use crate::sess::ParseSess;
use crate::symbol::{Symbol, sym};
-use crate::parse::ParseSess;
use syntax_pos::Span;
use rustc_data_structures::fx::FxHashMap;
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 6008f8f..c07b605 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -5,14 +5,14 @@
use crate::ast::{
self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
- PatKind, RangeEnd,
+ PatKind, RangeEnd, VariantData,
};
use crate::attr::{self, check_builtin_attribute};
use crate::source_map::Spanned;
use crate::edition::{ALL_EDITIONS, Edition};
use crate::visit::{self, FnKind, Visitor};
-use crate::parse::{token, ParseSess};
-use crate::parse::parser::Parser;
+use crate::parse::token;
+use crate::sess::ParseSess;
use crate::symbol::{Symbol, sym};
use crate::tokenstream::TokenTree;
@@ -246,6 +246,51 @@
Abi::System => {}
}
}
+
+ fn maybe_report_invalid_custom_discriminants(&self, variants: &[ast::Variant]) {
+ let has_fields = variants.iter().any(|variant| match variant.data {
+ VariantData::Tuple(..) | VariantData::Struct(..) => true,
+ VariantData::Unit(..) => false,
+ });
+
+ let discriminant_spans = variants.iter().filter(|variant| match variant.data {
+ VariantData::Tuple(..) | VariantData::Struct(..) => false,
+ VariantData::Unit(..) => true,
+ })
+ .filter_map(|variant| variant.disr_expr.as_ref().map(|c| c.value.span))
+ .collect::<Vec<_>>();
+
+ if !discriminant_spans.is_empty() && has_fields {
+ let mut err = feature_err(
+ self.parse_sess,
+ sym::arbitrary_enum_discriminant,
+ discriminant_spans.clone(),
+ crate::feature_gate::GateIssue::Language,
+ "custom discriminant values are not allowed in enums with tuple or struct variants",
+ );
+ for sp in discriminant_spans {
+ err.span_label(sp, "disallowed custom discriminant");
+ }
+ for variant in variants.iter() {
+ match &variant.data {
+ VariantData::Struct(..) => {
+ err.span_label(
+ variant.span,
+ "struct variant defined here",
+ );
+ }
+ VariantData::Tuple(..) => {
+ err.span_label(
+ variant.span,
+ "tuple variant defined here",
+ );
+ }
+ VariantData::Unit(..) => {}
+ }
+ }
+ err.emit();
+ }
+ }
}
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
@@ -353,7 +398,7 @@
let has_feature = self.features.arbitrary_enum_discriminant;
if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) {
- Parser::maybe_report_invalid_custom_discriminants(self.parse_sess, &variants);
+ self.maybe_report_invalid_custom_discriminants(&variants);
}
}
@@ -769,7 +814,7 @@
}
if let Some(allowed) = allow_features.as_ref() {
- if allowed.iter().find(|f| *f == name.as_str()).is_none() {
+ if allowed.iter().find(|&f| f == &name.as_str() as &str).is_none() {
span_err!(span_handler, mi.span(), E0725,
"the feature `{}` is not in the list of allowed features",
name);
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index 2423e10..e329678 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -12,7 +12,7 @@
use crate::source_map::{SourceMap, FilePathMapping};
use errors::registry::Registry;
-use errors::{SubDiagnostic, CodeSuggestion, SourceMapper};
+use errors::{SubDiagnostic, CodeSuggestion, SourceMapper, SourceMapperDyn};
use errors::{DiagnosticId, Applicability};
use errors::emitter::{Emitter, HumanReadableErrorType};
@@ -89,8 +89,8 @@
}
impl Emitter for JsonEmitter {
- fn emit_diagnostic(&mut self, db: &errors::Diagnostic) {
- let data = Diagnostic::from_errors_diagnostic(db, self);
+ fn emit_diagnostic(&mut self, diag: &errors::Diagnostic) {
+ let data = Diagnostic::from_errors_diagnostic(diag, self);
let result = if self.pretty {
writeln!(&mut self.dst, "{}", as_pretty_json(&data))
} else {
@@ -113,6 +113,10 @@
}
}
+ fn source_map(&self) -> Option<&Lrc<SourceMapperDyn>> {
+ Some(&self.sm)
+ }
+
fn should_show_explain(&self) -> bool {
match self.json_rendered {
HumanReadableErrorType::Short(_) => false,
@@ -205,10 +209,10 @@
}
impl Diagnostic {
- fn from_errors_diagnostic(db: &errors::Diagnostic,
+ fn from_errors_diagnostic(diag: &errors::Diagnostic,
je: &JsonEmitter)
-> Diagnostic {
- let sugg = db.suggestions.iter().map(|sugg| {
+ let sugg = diag.suggestions.iter().map(|sugg| {
Diagnostic {
message: sugg.msg.clone(),
code: None,
@@ -237,30 +241,30 @@
let output = buf.clone();
je.json_rendered.new_emitter(
Box::new(buf), Some(je.sm.clone()), false, None, je.external_macro_backtrace
- ).ui_testing(je.ui_testing).emit_diagnostic(db);
+ ).ui_testing(je.ui_testing).emit_diagnostic(diag);
let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap();
let output = String::from_utf8(output).unwrap();
Diagnostic {
- message: db.message(),
- code: DiagnosticCode::map_opt_string(db.code.clone(), je),
- level: db.level.to_str(),
- spans: DiagnosticSpan::from_multispan(&db.span, je),
- children: db.children.iter().map(|c| {
+ message: diag.message(),
+ code: DiagnosticCode::map_opt_string(diag.code.clone(), je),
+ level: diag.level.to_str(),
+ spans: DiagnosticSpan::from_multispan(&diag.span, je),
+ children: diag.children.iter().map(|c| {
Diagnostic::from_sub_diagnostic(c, je)
}).chain(sugg).collect(),
rendered: Some(output),
}
}
- fn from_sub_diagnostic(db: &SubDiagnostic, je: &JsonEmitter) -> Diagnostic {
+ fn from_sub_diagnostic(diag: &SubDiagnostic, je: &JsonEmitter) -> Diagnostic {
Diagnostic {
- message: db.message(),
+ message: diag.message(),
code: None,
- level: db.level.to_str(),
- spans: db.render_span.as_ref()
+ level: diag.level.to_str(),
+ spans: diag.render_span.as_ref()
.map(|sp| DiagnosticSpan::from_multispan(sp, je))
- .unwrap_or_else(|| DiagnosticSpan::from_multispan(&db.span, je)),
+ .unwrap_or_else(|| DiagnosticSpan::from_multispan(&diag.span, je)),
children: vec![],
rendered: None,
}
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 09a4779..fa75f56 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -147,6 +147,7 @@
pub mod show_span;
pub use syntax_pos::edition;
pub use syntax_pos::symbol;
+pub mod sess;
pub mod tokenstream;
pub mod visit;
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 3923b9f..60ee17d 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -610,10 +610,8 @@
}
pub fn noop_visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T) {
- visit_opt(tts, |tts| {
- let tts = Lrc::make_mut(tts);
- visit_vec(tts, |(tree, _is_joint)| vis.visit_tt(tree));
- })
+ let tts = Lrc::make_mut(tts);
+ visit_vec(tts, |(tree, _is_joint)| vis.visit_tt(tree));
}
// Applies ident visitor if it's an ident; applies other visits to interpolated nodes.
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index e74f304..0963efc 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -203,7 +203,7 @@
};
TokenStream::from_streams(smallvec![eq.into(), tokens])
} else {
- TokenStream::empty()
+ TokenStream::default()
};
ast::AttrItem { path, tokens }
})
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index 42cbe28..943838d 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -1,9 +1,8 @@
use crate::ast::{
self, Param, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind,
- Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, VariantData,
+ Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind,
};
-use crate::feature_gate::feature_err;
-use crate::parse::{SeqSep, PResult, Parser, ParseSess};
+use crate::parse::{SeqSep, PResult, Parser};
use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType};
use crate::parse::token::{self, TokenKind};
use crate::print::pprust;
@@ -715,55 +714,7 @@
}
}
- crate fn maybe_report_invalid_custom_discriminants(
- sess: &ParseSess,
- variants: &[ast::Variant],
- ) {
- let has_fields = variants.iter().any(|variant| match variant.data {
- VariantData::Tuple(..) | VariantData::Struct(..) => true,
- VariantData::Unit(..) => false,
- });
-
- let discriminant_spans = variants.iter().filter(|variant| match variant.data {
- VariantData::Tuple(..) | VariantData::Struct(..) => false,
- VariantData::Unit(..) => true,
- })
- .filter_map(|variant| variant.disr_expr.as_ref().map(|c| c.value.span))
- .collect::<Vec<_>>();
-
- if !discriminant_spans.is_empty() && has_fields {
- let mut err = feature_err(
- sess,
- sym::arbitrary_enum_discriminant,
- discriminant_spans.clone(),
- crate::feature_gate::GateIssue::Language,
- "custom discriminant values are not allowed in enums with tuple or struct variants",
- );
- for sp in discriminant_spans {
- err.span_label(sp, "disallowed custom discriminant");
- }
- for variant in variants.iter() {
- match &variant.data {
- VariantData::Struct(..) => {
- err.span_label(
- variant.span,
- "struct variant defined here",
- );
- }
- VariantData::Tuple(..) => {
- err.span_label(
- variant.span,
- "tuple variant defined here",
- );
- }
- VariantData::Unit(..) => {}
- }
- }
- err.emit();
- }
- }
-
- crate fn maybe_recover_from_bad_type_plus(
+ pub(super) fn maybe_recover_from_bad_type_plus(
&mut self,
allow_plus: bool,
ty: &Ty,
@@ -856,7 +807,7 @@
// This is a best-effort recovery.
path.span,
"try",
- format!("<{}>::{}", ty_str, path),
+ format!("<{}>::{}", ty_str, pprust::path_to_string(&path)),
Applicability::MaybeIncorrect,
)
.emit();
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index ac3fead..e6dc9a4 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1,5 +1,5 @@
-use crate::parse::ParseSess;
use crate::parse::token::{self, Token, TokenKind};
+use crate::sess::ParseSess;
use crate::symbol::{sym, Symbol};
use crate::parse::unescape_error_reporting::{emit_unescape_error, push_escaped_char};
diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/parse/literal.rs
index 56a79bf..14e1696 100644
--- a/src/libsyntax/parse/literal.rs
+++ b/src/libsyntax/parse/literal.rs
@@ -1,14 +1,10 @@
//! Code related to parsing literals.
use crate::ast::{self, Lit, LitKind};
-use crate::parse::parser::Parser;
-use crate::parse::PResult;
-use crate::parse::token::{self, Token, TokenKind};
-use crate::print::pprust;
+use crate::parse::token::{self, Token};
use crate::symbol::{kw, sym, Symbol};
use crate::tokenstream::{TokenStream, TokenTree};
-use errors::{Applicability, Handler};
use log::debug;
use rustc_data_structures::sync::Lrc;
use syntax_pos::Span;
@@ -28,72 +24,6 @@
IntTooLarge,
}
-impl LitError {
- fn report(&self, diag: &Handler, lit: token::Lit, span: Span) {
- let token::Lit { kind, suffix, .. } = lit;
- match *self {
- // `NotLiteral` is not an error by itself, so we don't report
- // it and give the parser opportunity to try something else.
- LitError::NotLiteral => {}
- // `LexerError` *is* an error, but it was already reported
- // by lexer, so here we don't report it the second time.
- LitError::LexerError => {}
- LitError::InvalidSuffix => {
- expect_no_suffix(
- diag, span, &format!("{} {} literal", kind.article(), kind.descr()), suffix
- );
- }
- LitError::InvalidIntSuffix => {
- let suf = suffix.expect("suffix error with no suffix").as_str();
- if looks_like_width_suffix(&['i', 'u'], &suf) {
- // If it looks like a width, try to be helpful.
- let msg = format!("invalid width `{}` for integer literal", &suf[1..]);
- diag.struct_span_err(span, &msg)
- .help("valid widths are 8, 16, 32, 64 and 128")
- .emit();
- } else {
- let msg = format!("invalid suffix `{}` for integer literal", suf);
- diag.struct_span_err(span, &msg)
- .span_label(span, format!("invalid suffix `{}`", suf))
- .help("the suffix must be one of the integral types (`u32`, `isize`, etc)")
- .emit();
- }
- }
- LitError::InvalidFloatSuffix => {
- let suf = suffix.expect("suffix error with no suffix").as_str();
- if looks_like_width_suffix(&['f'], &suf) {
- // If it looks like a width, try to be helpful.
- let msg = format!("invalid width `{}` for float literal", &suf[1..]);
- diag.struct_span_err(span, &msg)
- .help("valid widths are 32 and 64")
- .emit();
- } else {
- let msg = format!("invalid suffix `{}` for float literal", suf);
- diag.struct_span_err(span, &msg)
- .span_label(span, format!("invalid suffix `{}`", suf))
- .help("valid suffixes are `f32` and `f64`")
- .emit();
- }
- }
- LitError::NonDecimalFloat(base) => {
- let descr = match base {
- 16 => "hexadecimal",
- 8 => "octal",
- 2 => "binary",
- _ => unreachable!(),
- };
- diag.struct_span_err(span, &format!("{} float literal is not supported", descr))
- .span_label(span, "not supported")
- .emit();
- }
- LitError::IntTooLarge => {
- diag.struct_span_err(span, "integer literal is too large")
- .emit();
- }
- }
- }
-}
-
impl LitKind {
/// Converts literal token into a semantic literal.
fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> {
@@ -204,7 +134,7 @@
let (kind, symbol, suffix) = match *self {
LitKind::Str(symbol, ast::StrStyle::Cooked) => {
// Don't re-intern unless the escaped string is different.
- let s = &symbol.as_str();
+ let s: &str = &symbol.as_str();
let escaped = s.escape_default().to_string();
let symbol = if escaped == *s { symbol } else { Symbol::intern(&escaped) };
(token::Str, symbol, None)
@@ -254,7 +184,7 @@
impl Lit {
/// Converts literal token into an AST literal.
- fn from_lit_token(token: token::Lit, span: Span) -> Result<Lit, LitError> {
+ crate fn from_lit_token(token: token::Lit, span: Span) -> Result<Lit, LitError> {
Ok(Lit { token, kind: LitKind::from_lit_token(token)?, span })
}
@@ -296,99 +226,6 @@
}
}
-impl<'a> Parser<'a> {
- /// Matches `lit = true | false | token_lit`.
- crate fn parse_lit(&mut self) -> PResult<'a, Lit> {
- let mut recovered = None;
- if self.token == token::Dot {
- // Attempt to recover `.4` as `0.4`.
- recovered = self.look_ahead(1, |next_token| {
- if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix })
- = next_token.kind {
- if self.token.span.hi() == next_token.span.lo() {
- let s = String::from("0.") + &symbol.as_str();
- let kind = TokenKind::lit(token::Float, Symbol::intern(&s), suffix);
- return Some(Token::new(kind, self.token.span.to(next_token.span)));
- }
- }
- None
- });
- if let Some(token) = &recovered {
- self.bump();
- self.diagnostic()
- .struct_span_err(token.span, "float literals must have an integer part")
- .span_suggestion(
- token.span,
- "must have an integer part",
- pprust::token_to_string(token),
- Applicability::MachineApplicable,
- )
- .emit();
- }
- }
-
- let token = recovered.as_ref().unwrap_or(&self.token);
- match Lit::from_token(token) {
- Ok(lit) => {
- self.bump();
- Ok(lit)
- }
- Err(LitError::NotLiteral) => {
- let msg = format!("unexpected token: {}", self.this_token_descr());
- Err(self.span_fatal(token.span, &msg))
- }
- Err(err) => {
- let (lit, span) = (token.expect_lit(), token.span);
- self.bump();
- err.report(&self.sess.span_diagnostic, lit, span);
- // Pack possible quotes and prefixes from the original literal into
- // the error literal's symbol so they can be pretty-printed faithfully.
- let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
- let symbol = Symbol::intern(&suffixless_lit.to_string());
- let lit = token::Lit::new(token::Err, symbol, lit.suffix);
- Lit::from_lit_token(lit, span).map_err(|_| unreachable!())
- }
- }
- }
-}
-
-crate fn expect_no_suffix(diag: &Handler, sp: Span, kind: &str, suffix: Option<Symbol>) {
- if let Some(suf) = suffix {
- let mut err = if kind == "a tuple index" &&
- [sym::i32, sym::u32, sym::isize, sym::usize].contains(&suf) {
- // #59553: warn instead of reject out of hand to allow the fix to percolate
- // through the ecosystem when people fix their macros
- let mut err = diag.struct_span_warn(
- sp,
- &format!("suffixes on {} are invalid", kind),
- );
- err.note(&format!(
- "`{}` is *temporarily* accepted on tuple index fields as it was \
- incorrectly accepted on stable for a few releases",
- suf,
- ));
- err.help(
- "on proc macros, you'll want to use `syn::Index::from` or \
- `proc_macro::Literal::*_unsuffixed` for code that will desugar \
- to tuple field access",
- );
- err.note(
- "for more context, see https://github.com/rust-lang/rust/issues/60210",
- );
- err
- } else {
- diag.struct_span_err(sp, &format!("suffixes on {} are invalid", kind))
- };
- err.span_label(sp, format!("invalid suffix `{}`", suf));
- err.emit();
- }
-}
-
-// Checks if `s` looks like i32 or u1234 etc.
-fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
- s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
-}
-
fn strip_underscores(symbol: Symbol) -> Symbol {
// Do not allocate a new string unless necessary.
let s = symbol.as_str();
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 1518da2..cb90caab 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -1,29 +1,24 @@
//! The main parser interface.
-use crate::ast::{self, CrateConfig, NodeId};
-use crate::early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
-use crate::source_map::{SourceMap, FilePathMapping};
-use crate::feature_gate::UnstableFeatures;
-use crate::parse::parser::Parser;
-use crate::parse::parser::emit_unclosed_delims;
-use crate::parse::token::TokenKind;
-use crate::tokenstream::{TokenStream, TokenTree};
+use crate::ast;
+use crate::parse::parser::{Parser, emit_unclosed_delims};
+use crate::parse::token::{Nonterminal, TokenKind};
+use crate::tokenstream::{self, TokenStream, TokenTree};
use crate::print::pprust;
-use crate::symbol::Symbol;
+use crate::sess::ParseSess;
-use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
-use rustc_data_structures::fx::{FxHashSet, FxHashMap};
+use errors::{FatalError, Level, Diagnostic, DiagnosticBuilder};
#[cfg(target_arch = "x86_64")]
use rustc_data_structures::static_assert_size;
-use rustc_data_structures::sync::{Lrc, Lock, Once};
-use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
-use syntax_pos::edition::Edition;
-use syntax_pos::hygiene::ExpnId;
+use rustc_data_structures::sync::Lrc;
+use syntax_pos::{Span, SourceFile, FileName};
use std::borrow::Cow;
-use std::path::{Path, PathBuf};
+use std::path::Path;
use std::str;
+use log::info;
+
#[cfg(test)]
mod tests;
@@ -45,112 +40,6 @@
#[cfg(target_arch = "x86_64")]
static_assert_size!(PResult<'_, bool>, 16);
-/// Collected spans during parsing for places where a certain feature was
-/// used and should be feature gated accordingly in `check_crate`.
-#[derive(Default)]
-pub struct GatedSpans {
- /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`.
- pub let_chains: Lock<Vec<Span>>,
- /// Spans collected for gating `async_closure`, e.g. `async || ..`.
- pub async_closure: Lock<Vec<Span>>,
- /// Spans collected for gating `yield e?` expressions (`generators` gate).
- pub yields: Lock<Vec<Span>>,
- /// Spans collected for gating `or_patterns`, e.g. `Some(Foo | Bar)`.
- pub or_patterns: Lock<Vec<Span>>,
- /// Spans collected for gating `const_extern_fn`, e.g. `const extern fn foo`.
- pub const_extern_fn: Lock<Vec<Span>>,
-}
-
-/// Info about a parsing session.
-pub struct ParseSess {
- pub span_diagnostic: Handler,
- pub unstable_features: UnstableFeatures,
- pub config: CrateConfig,
- pub edition: Edition,
- pub missing_fragment_specifiers: Lock<FxHashSet<Span>>,
- /// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
- pub raw_identifier_spans: Lock<Vec<Span>>,
- /// Used to determine and report recursive module inclusions.
- included_mod_stack: Lock<Vec<PathBuf>>,
- source_map: Lrc<SourceMap>,
- pub buffered_lints: Lock<Vec<BufferedEarlyLint>>,
- /// Contains the spans of block expressions that could have been incomplete based on the
- /// operation token that followed it, but that the parser cannot identify without further
- /// analysis.
- pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
- pub injected_crate_name: Once<Symbol>,
- pub gated_spans: GatedSpans,
-}
-
-impl ParseSess {
- pub fn new(file_path_mapping: FilePathMapping) -> Self {
- let cm = Lrc::new(SourceMap::new(file_path_mapping));
- let handler = Handler::with_tty_emitter(
- ColorConfig::Auto,
- true,
- None,
- Some(cm.clone()),
- );
- ParseSess::with_span_handler(handler, cm)
- }
-
- pub fn with_span_handler(handler: Handler, source_map: Lrc<SourceMap>) -> Self {
- Self {
- span_diagnostic: handler,
- unstable_features: UnstableFeatures::from_environment(),
- config: FxHashSet::default(),
- edition: ExpnId::root().expn_data().edition,
- missing_fragment_specifiers: Lock::new(FxHashSet::default()),
- raw_identifier_spans: Lock::new(Vec::new()),
- included_mod_stack: Lock::new(vec![]),
- source_map,
- buffered_lints: Lock::new(vec![]),
- ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
- injected_crate_name: Once::new(),
- gated_spans: GatedSpans::default(),
- }
- }
-
- #[inline]
- pub fn source_map(&self) -> &SourceMap {
- &self.source_map
- }
-
- pub fn buffer_lint<S: Into<MultiSpan>>(&self,
- lint_id: BufferedEarlyLintId,
- span: S,
- id: NodeId,
- msg: &str,
- ) {
- self.buffered_lints.with_lock(|buffered_lints| {
- buffered_lints.push(BufferedEarlyLint{
- span: span.into(),
- id,
- msg: msg.into(),
- lint_id,
- });
- });
- }
-
- /// Extend an error with a suggestion to wrap an expression with parentheses to allow the
- /// parser to continue parsing the following operation as part of the same expression.
- pub fn expr_parentheses_needed(
- &self,
- err: &mut DiagnosticBuilder<'_>,
- span: Span,
- alt_snippet: Option<String>,
- ) {
- if let Some(snippet) = self.source_map().span_to_snippet(span).ok().or(alt_snippet) {
- err.span_suggestion(
- span,
- "parentheses are required to parse this as an expression",
- format!("({})", snippet),
- Applicability::MachineApplicable,
- );
- }
- }
-}
-
#[derive(Clone)]
pub struct Directory<'a> {
pub path: Cow<'a, Path>,
@@ -407,3 +296,132 @@
}
}
}
+
+// NOTE(Centril): The following probably shouldn't be here but it acknowledges the
+// fact that architecturally, we are using parsing (read on below to understand why).
+
+pub fn nt_to_tokenstream(nt: &Nonterminal, sess: &ParseSess, span: Span) -> TokenStream {
+ // A `Nonterminal` is often a parsed AST item. At this point we now
+ // need to convert the parsed AST to an actual token stream, e.g.
+ // un-parse it basically.
+ //
+ // Unfortunately there's not really a great way to do that in a
+ // guaranteed lossless fashion right now. The fallback here is to just
+ // stringify the AST node and reparse it, but this loses all span
+ // information.
+ //
+ // As a result, some AST nodes are annotated with the token stream they
+ // came from. Here we attempt to extract these lossless token streams
+ // before we fall back to the stringification.
+ let tokens = match *nt {
+ Nonterminal::NtItem(ref item) => {
+ prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
+ }
+ Nonterminal::NtTraitItem(ref item) => {
+ prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
+ }
+ Nonterminal::NtImplItem(ref item) => {
+ prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
+ }
+ Nonterminal::NtIdent(ident, is_raw) => {
+ Some(tokenstream::TokenTree::token(token::Ident(ident.name, is_raw), ident.span).into())
+ }
+ Nonterminal::NtLifetime(ident) => {
+ Some(tokenstream::TokenTree::token(token::Lifetime(ident.name), ident.span).into())
+ }
+ Nonterminal::NtTT(ref tt) => {
+ Some(tt.clone().into())
+ }
+ _ => None,
+ };
+
+ // FIXME(#43081): Avoid this pretty-print + reparse hack
+ let source = pprust::nonterminal_to_string(nt);
+ let filename = FileName::macro_expansion_source_code(&source);
+ let tokens_for_real = parse_stream_from_source_str(filename, source, sess, Some(span));
+
+ // During early phases of the compiler the AST could get modified
+ // directly (e.g., attributes added or removed) and the internal cache
+ // of tokens my not be invalidated or updated. Consequently if the
+ // "lossless" token stream disagrees with our actual stringification
+ // (which has historically been much more battle-tested) then we go
+ // with the lossy stream anyway (losing span information).
+ //
+ // Note that the comparison isn't `==` here to avoid comparing spans,
+ // but it *also* is a "probable" equality which is a pretty weird
+ // definition. We mostly want to catch actual changes to the AST
+ // like a `#[cfg]` being processed or some weird `macro_rules!`
+ // expansion.
+ //
+ // What we *don't* want to catch is the fact that a user-defined
+ // literal like `0xf` is stringified as `15`, causing the cached token
+ // stream to not be literal `==` token-wise (ignoring spans) to the
+ // token stream we got from stringification.
+ //
+ // Instead the "probably equal" check here is "does each token
+ // recursively have the same discriminant?" We basically don't look at
+ // the token values here and assume that such fine grained token stream
+ // modifications, including adding/removing typically non-semantic
+ // tokens such as extra braces and commas, don't happen.
+ if let Some(tokens) = tokens {
+ if tokens.probably_equal_for_proc_macro(&tokens_for_real) {
+ return tokens
+ }
+ info!("cached tokens found, but they're not \"probably equal\", \
+ going with stringified version");
+ }
+ return tokens_for_real
+}
+
+fn prepend_attrs(
+ sess: &ParseSess,
+ attrs: &[ast::Attribute],
+ tokens: Option<&tokenstream::TokenStream>,
+ span: syntax_pos::Span
+) -> Option<tokenstream::TokenStream> {
+ let tokens = tokens?;
+ if attrs.len() == 0 {
+ return Some(tokens.clone())
+ }
+ let mut builder = tokenstream::TokenStreamBuilder::new();
+ for attr in attrs {
+ assert_eq!(attr.style, ast::AttrStyle::Outer,
+ "inner attributes should prevent cached tokens from existing");
+
+ let source = pprust::attribute_to_string(attr);
+ let macro_filename = FileName::macro_expansion_source_code(&source);
+ if attr.is_sugared_doc {
+ let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
+ builder.push(stream);
+ continue
+ }
+
+ // synthesize # [ $path $tokens ] manually here
+ let mut brackets = tokenstream::TokenStreamBuilder::new();
+
+ // For simple paths, push the identifier directly
+ if attr.path.segments.len() == 1 && attr.path.segments[0].args.is_none() {
+ let ident = attr.path.segments[0].ident;
+ let token = token::Ident(ident.name, ident.as_str().starts_with("r#"));
+ brackets.push(tokenstream::TokenTree::token(token, ident.span));
+
+ // ... and for more complicated paths, fall back to a reparse hack that
+ // should eventually be removed.
+ } else {
+ let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
+ brackets.push(stream);
+ }
+
+ brackets.push(attr.tokens.clone());
+
+ // The span we list here for `#` and for `[ ... ]` are both wrong in
+ // that it encompasses more than each token, but it hopefully is "good
+ // enough" for now at least.
+ builder.push(tokenstream::TokenTree::token(token::Pound, attr.span));
+ let delim_span = tokenstream::DelimSpan::from_single(attr.span);
+ builder.push(tokenstream::TokenTree::Delimited(
+ delim_span, token::DelimToken::Bracket, brackets.build().into()));
+ }
+ builder.push(tokens.clone());
+ Some(builder.build())
+}
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 4a457f5..8638376 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -9,20 +9,20 @@
pub use path::PathStyle;
mod stmt;
mod generics;
+use super::diagnostics::Error;
use crate::ast::{
- self, DUMMY_NODE_ID, AttrStyle, Attribute, BindingMode, CrateSugar, Ident,
- IsAsync, MacDelimiter, Mutability, Param, StrStyle, SelfKind, TyKind, Visibility,
- VisibilityKind, Unsafety,
+ self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident,
+ IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety,
};
-use crate::parse::{ParseSess, PResult, Directory, DirectoryOwnership, SeqSep, literal, token};
-use crate::parse::diagnostics::{Error, dummy_arg};
+use crate::parse::{PResult, Directory, DirectoryOwnership, SeqSep};
use crate::parse::lexer::UnmatchedBrace;
use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
-use crate::parse::token::{Token, TokenKind, DelimToken};
+use crate::parse::token::{self, Token, TokenKind, DelimToken};
use crate::print::pprust;
use crate::ptr::P;
-use crate::source_map::{self, respan};
+use crate::sess::ParseSess;
+use crate::source_map::respan;
use crate::symbol::{kw, sym, Symbol};
use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
use crate::ThinVec;
@@ -56,17 +56,6 @@
Ignore,
}
-/// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
-struct ParamCfg {
- /// Is `self` is allowed as the first parameter?
- is_self_allowed: bool,
- /// Is `...` allowed as the tail of the parameter list?
- allow_c_variadic: bool,
- /// `is_name_required` decides if, per-parameter,
- /// the parameter must have a pattern or just a type.
- is_name_required: fn(&token::Token) -> bool,
-}
-
/// Like `maybe_whole_expr`, but for things other than expressions.
#[macro_export]
macro_rules! maybe_whole {
@@ -649,10 +638,6 @@
}
}
- fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<ast::Name>) {
- literal::expect_no_suffix(&self.sess.span_diagnostic, sp, kind, suffix)
- }
-
/// Attempts to consume a `<`. If `<<` is seen, replaces it with a single
/// `<` and continue. If `<-` is seen, replaces it with a single `<`
/// and continue. If a `<` is not seen, returns false.
@@ -1105,271 +1090,6 @@
res
}
- /// Parses the parameter list of a function, including the `(` and `)` delimiters.
- fn parse_fn_params(&mut self, mut cfg: ParamCfg) -> PResult<'a, Vec<Param>> {
- let sp = self.token.span;
- let is_trait_item = cfg.is_self_allowed;
- let mut c_variadic = false;
- // Parse the arguments, starting out with `self` being possibly allowed...
- let (params, _) = self.parse_paren_comma_seq(|p| {
- let param = p.parse_param_general(&cfg, is_trait_item);
- // ...now that we've parsed the first argument, `self` is no longer allowed.
- cfg.is_self_allowed = false;
-
- match param {
- Ok(param) => Ok(
- if let TyKind::CVarArgs = param.ty.kind {
- c_variadic = true;
- if p.token != token::CloseDelim(token::Paren) {
- p.span_err(
- p.token.span,
- "`...` must be the last argument of a C-variadic function",
- );
- // FIXME(eddyb) this should probably still push `CVarArgs`.
- // Maybe AST validation/HIR lowering should emit the above error?
- None
- } else {
- Some(param)
- }
- } else {
- Some(param)
- }
- ),
- Err(mut e) => {
- e.emit();
- let lo = p.prev_span;
- // Skip every token until next possible arg or end.
- p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
- // Create a placeholder argument for proper arg count (issue #34264).
- let span = lo.to(p.prev_span);
- Ok(Some(dummy_arg(Ident::new(kw::Invalid, span))))
- }
- }
- })?;
-
- let mut params: Vec<_> = params.into_iter().filter_map(|x| x).collect();
-
- // Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
- self.deduplicate_recovered_params_names(&mut params);
-
- if c_variadic && params.len() <= 1 {
- self.span_err(
- sp,
- "C-variadic function must be declared with at least one named argument",
- );
- }
-
- Ok(params)
- }
-
- /// Skips unexpected attributes and doc comments in this position and emits an appropriate
- /// error.
- /// This version of parse param doesn't necessarily require identifier names.
- fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> {
- let lo = self.token.span;
- let attrs = self.parse_outer_attributes()?;
-
- // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
- if let Some(mut param) = self.parse_self_param()? {
- param.attrs = attrs.into();
- return if cfg.is_self_allowed {
- Ok(param)
- } else {
- self.recover_bad_self_param(param, is_trait_item)
- };
- }
-
- let is_name_required = match self.token.kind {
- token::DotDotDot => false,
- _ => (cfg.is_name_required)(&self.token),
- };
- let (pat, ty) = if is_name_required || self.is_named_param() {
- debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
-
- let pat = self.parse_fn_param_pat()?;
- if let Err(mut err) = self.expect(&token::Colon) {
- return if let Some(ident) = self.parameter_without_type(
- &mut err,
- pat,
- is_name_required,
- cfg.is_self_allowed,
- is_trait_item,
- ) {
- err.emit();
- Ok(dummy_arg(ident))
- } else {
- Err(err)
- };
- }
-
- self.eat_incorrect_doc_comment_for_param_type();
- (pat, self.parse_ty_common(true, true, cfg.allow_c_variadic)?)
- } else {
- debug!("parse_param_general ident_to_pat");
- let parser_snapshot_before_ty = self.clone();
- self.eat_incorrect_doc_comment_for_param_type();
- let mut ty = self.parse_ty_common(true, true, cfg.allow_c_variadic);
- if ty.is_ok() && self.token != token::Comma &&
- self.token != token::CloseDelim(token::Paren) {
- // This wasn't actually a type, but a pattern looking like a type,
- // so we are going to rollback and re-parse for recovery.
- ty = self.unexpected();
- }
- match ty {
- Ok(ty) => {
- let ident = Ident::new(kw::Invalid, self.prev_span);
- let bm = BindingMode::ByValue(Mutability::Immutable);
- let pat = self.mk_pat_ident(ty.span, bm, ident);
- (pat, ty)
- }
- // If this is a C-variadic argument and we hit an error, return the error.
- Err(err) if self.token == token::DotDotDot => return Err(err),
- // Recover from attempting to parse the argument as a type without pattern.
- Err(mut err) => {
- err.cancel();
- mem::replace(self, parser_snapshot_before_ty);
- self.recover_arg_parse()?
- }
- }
- };
-
- let span = lo.to(self.token.span);
-
- Ok(Param {
- attrs: attrs.into(),
- id: ast::DUMMY_NODE_ID,
- is_placeholder: false,
- pat,
- span,
- ty,
- })
- }
-
- /// Returns the parsed optional self parameter and whether a self shortcut was used.
- ///
- /// See `parse_self_param_with_attrs` to collect attributes.
- fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
- // Extract an identifier *after* having confirmed that the token is one.
- let expect_self_ident = |this: &mut Self| {
- match this.token.kind {
- // Preserve hygienic context.
- token::Ident(name, _) => {
- let span = this.token.span;
- this.bump();
- Ident::new(name, span)
- }
- _ => unreachable!(),
- }
- };
- // Is `self` `n` tokens ahead?
- let is_isolated_self = |this: &Self, n| {
- this.is_keyword_ahead(n, &[kw::SelfLower])
- && this.look_ahead(n + 1, |t| t != &token::ModSep)
- };
- // Is `mut self` `n` tokens ahead?
- let is_isolated_mut_self = |this: &Self, n| {
- this.is_keyword_ahead(n, &[kw::Mut])
- && is_isolated_self(this, n + 1)
- };
- // Parse `self` or `self: TYPE`. We already know the current token is `self`.
- let parse_self_possibly_typed = |this: &mut Self, m| {
- let eself_ident = expect_self_ident(this);
- let eself_hi = this.prev_span;
- let eself = if this.eat(&token::Colon) {
- SelfKind::Explicit(this.parse_ty()?, m)
- } else {
- SelfKind::Value(m)
- };
- Ok((eself, eself_ident, eself_hi))
- };
- // Recover for the grammar `*self`, `*const self`, and `*mut self`.
- let recover_self_ptr = |this: &mut Self| {
- let msg = "cannot pass `self` by raw pointer";
- let span = this.token.span;
- this.struct_span_err(span, msg)
- .span_label(span, msg)
- .emit();
-
- Ok((SelfKind::Value(Mutability::Immutable), expect_self_ident(this), this.prev_span))
- };
-
- // Parse optional `self` parameter of a method.
- // Only a limited set of initial token sequences is considered `self` parameters; anything
- // else is parsed as a normal function parameter list, so some lookahead is required.
- let eself_lo = self.token.span;
- let (eself, eself_ident, eself_hi) = match self.token.kind {
- token::BinOp(token::And) => {
- let eself = if is_isolated_self(self, 1) {
- // `&self`
- self.bump();
- SelfKind::Region(None, Mutability::Immutable)
- } else if is_isolated_mut_self(self, 1) {
- // `&mut self`
- self.bump();
- self.bump();
- SelfKind::Region(None, Mutability::Mutable)
- } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
- // `&'lt self`
- self.bump();
- let lt = self.expect_lifetime();
- SelfKind::Region(Some(lt), Mutability::Immutable)
- } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
- // `&'lt mut self`
- self.bump();
- let lt = self.expect_lifetime();
- self.bump();
- SelfKind::Region(Some(lt), Mutability::Mutable)
- } else {
- // `¬_self`
- return Ok(None);
- };
- (eself, expect_self_ident(self), self.prev_span)
- }
- // `*self`
- token::BinOp(token::Star) if is_isolated_self(self, 1) => {
- self.bump();
- recover_self_ptr(self)?
- }
- // `*mut self` and `*const self`
- token::BinOp(token::Star) if
- self.look_ahead(1, |t| t.is_mutability())
- && is_isolated_self(self, 2) =>
- {
- self.bump();
- self.bump();
- recover_self_ptr(self)?
- }
- // `self` and `self: TYPE`
- token::Ident(..) if is_isolated_self(self, 0) => {
- parse_self_possibly_typed(self, Mutability::Immutable)?
- }
- // `mut self` and `mut self: TYPE`
- token::Ident(..) if is_isolated_mut_self(self, 0) => {
- self.bump();
- parse_self_possibly_typed(self, Mutability::Mutable)?
- }
- _ => return Ok(None),
- };
-
- let eself = source_map::respan(eself_lo.to(eself_hi), eself);
- Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident)))
- }
-
- fn is_named_param(&self) -> bool {
- let offset = match self.token.kind {
- token::Interpolated(ref nt) => match **nt {
- token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
- _ => 0,
- }
- token::BinOp(token::And) | token::AndAnd => 1,
- _ if self.token.is_keyword(kw::Mut) => 1,
- _ => 0,
- };
-
- self.look_ahead(offset, |t| t.is_ident()) &&
- self.look_ahead(offset + 1, |t| t == &token::Colon)
- }
-
fn is_crate_vis(&self) -> bool {
self.token.is_keyword(kw::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
}
@@ -1454,12 +1174,14 @@
`pub(super)`: visible only in the current module's parent
`pub(in path::to::module)`: visible only on the specified path"##;
+ let path_str = pprust::path_to_string(&path);
+
struct_span_err!(self.sess.span_diagnostic, path.span, E0704, "{}", msg)
.help(suggestion)
.span_suggestion(
path.span,
- &format!("make this visible only to module `{}` with `in`", path),
- format!("in {}", path),
+ &format!("make this visible only to module `{}` with `in`", path_str),
+ format!("in {}", path_str),
Applicability::MachineApplicable,
)
.emit();
@@ -1548,7 +1270,7 @@
// This can happen due to a bad interaction of two unrelated recovery mechanisms with
// mismatched delimiters *and* recovery lookahead on the likely typo `pub ident(`
// (#62881).
- return Ok((ret?, TokenStream::new(vec![])));
+ return Ok((ret?, TokenStream::default()));
} else {
&mut self.token_cursor.stack[prev].last_token
};
@@ -1563,7 +1285,7 @@
// This can happen due to a bad interaction of two unrelated recovery mechanisms
// with mismatched delimiters *and* recovery lookahead on the likely typo
// `pub ident(` (#62895, different but similar to the case above).
- return Ok((ret?, TokenStream::new(vec![])));
+ return Ok((ret?, TokenStream::default()));
}
};
@@ -1641,7 +1363,7 @@
],
Applicability::MaybeIncorrect,
).span_suggestion(
- self.sess.source_map.next_point(self.prev_span),
+ self.sess.source_map().next_point(self.prev_span),
"add a semicolon",
';'.to_string(),
Applicability::MaybeIncorrect,
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index b459782..dd0fd83 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -1,17 +1,17 @@
-use super::{
- Parser, PResult, Restrictions, PrevTokenKind, TokenType, PathStyle, BlockMode, SemiColonMode,
- SeqSep, TokenExpectType,
-};
+use super::{Parser, PResult, Restrictions, PrevTokenKind, TokenType, PathStyle, BlockMode};
+use super::{SemiColonMode, SeqSep, TokenExpectType};
use super::pat::{GateOr, PARAM_EXPECTED};
+use crate::parse::literal::LitError;
+
use crate::ast::{
self, DUMMY_NODE_ID, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode,
Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm, Ty, TyKind,
- FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst, Field,
+ FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst, Field, Lit,
};
use crate::maybe_recover_from_interpolated_ty_qpath;
use crate::parse::classify;
-use crate::parse::token::{self, Token};
+use crate::parse::token::{self, Token, TokenKind};
use crate::parse::diagnostics::Error;
use crate::print::pprust;
use crate::ptr::P;
@@ -20,6 +20,7 @@
use crate::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par};
use errors::Applicability;
+use syntax_pos::Symbol;
use std::mem;
use rustc_data_structures::thin_vec::ThinVec;
@@ -552,8 +553,11 @@
// Report non-fatal diagnostics, keep `x as usize` as an expression
// in AST and continue parsing.
- let msg = format!("`<` is interpreted as a start of generic \
- arguments for `{}`, not a {}", path, op_noun);
+ let msg = format!(
+ "`<` is interpreted as a start of generic arguments for `{}`, not a {}",
+ pprust::path_to_string(&path),
+ op_noun,
+ );
let span_after_type = parser_snapshot_after_type.token.span;
let expr = mk_expr(self, P(Ty {
span: path.span,
@@ -1069,6 +1073,165 @@
self.maybe_recover_from_bad_qpath(expr, true)
}
+ /// Matches `lit = true | false | token_lit`.
+ crate fn parse_lit(&mut self) -> PResult<'a, Lit> {
+ let mut recovered = None;
+ if self.token == token::Dot {
+ // Attempt to recover `.4` as `0.4`.
+ recovered = self.look_ahead(1, |next_token| {
+ if let token::Literal(token::Lit { kind: token::Integer, symbol, suffix })
+ = next_token.kind {
+ if self.token.span.hi() == next_token.span.lo() {
+ let s = String::from("0.") + &symbol.as_str();
+ let kind = TokenKind::lit(token::Float, Symbol::intern(&s), suffix);
+ return Some(Token::new(kind, self.token.span.to(next_token.span)));
+ }
+ }
+ None
+ });
+ if let Some(token) = &recovered {
+ self.bump();
+ self.struct_span_err(token.span, "float literals must have an integer part")
+ .span_suggestion(
+ token.span,
+ "must have an integer part",
+ pprust::token_to_string(token),
+ Applicability::MachineApplicable,
+ )
+ .emit();
+ }
+ }
+
+ let token = recovered.as_ref().unwrap_or(&self.token);
+ match Lit::from_token(token) {
+ Ok(lit) => {
+ self.bump();
+ Ok(lit)
+ }
+ Err(LitError::NotLiteral) => {
+ let msg = format!("unexpected token: {}", self.this_token_descr());
+ Err(self.span_fatal(token.span, &msg))
+ }
+ Err(err) => {
+ let (lit, span) = (token.expect_lit(), token.span);
+ self.bump();
+ self.error_literal_from_token(err, lit, span);
+ // Pack possible quotes and prefixes from the original literal into
+ // the error literal's symbol so they can be pretty-printed faithfully.
+ let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
+ let symbol = Symbol::intern(&suffixless_lit.to_string());
+ let lit = token::Lit::new(token::Err, symbol, lit.suffix);
+ Lit::from_lit_token(lit, span).map_err(|_| unreachable!())
+ }
+ }
+ }
+
+ fn error_literal_from_token(&self, err: LitError, lit: token::Lit, span: Span) {
+ // Checks if `s` looks like i32 or u1234 etc.
+ fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
+ s.len() > 1
+ && s.starts_with(first_chars)
+ && s[1..].chars().all(|c| c.is_ascii_digit())
+ }
+
+ let token::Lit { kind, suffix, .. } = lit;
+ match err {
+ // `NotLiteral` is not an error by itself, so we don't report
+ // it and give the parser opportunity to try something else.
+ LitError::NotLiteral => {}
+ // `LexerError` *is* an error, but it was already reported
+ // by lexer, so here we don't report it the second time.
+ LitError::LexerError => {}
+ LitError::InvalidSuffix => {
+ self.expect_no_suffix(
+ span,
+ &format!("{} {} literal", kind.article(), kind.descr()),
+ suffix,
+ );
+ }
+ LitError::InvalidIntSuffix => {
+ let suf = suffix.expect("suffix error with no suffix").as_str();
+ if looks_like_width_suffix(&['i', 'u'], &suf) {
+ // If it looks like a width, try to be helpful.
+ let msg = format!("invalid width `{}` for integer literal", &suf[1..]);
+ self.struct_span_err(span, &msg)
+ .help("valid widths are 8, 16, 32, 64 and 128")
+ .emit();
+ } else {
+ let msg = format!("invalid suffix `{}` for integer literal", suf);
+ self.struct_span_err(span, &msg)
+ .span_label(span, format!("invalid suffix `{}`", suf))
+ .help("the suffix must be one of the integral types (`u32`, `isize`, etc)")
+ .emit();
+ }
+ }
+ LitError::InvalidFloatSuffix => {
+ let suf = suffix.expect("suffix error with no suffix").as_str();
+ if looks_like_width_suffix(&['f'], &suf) {
+ // If it looks like a width, try to be helpful.
+ let msg = format!("invalid width `{}` for float literal", &suf[1..]);
+ self.struct_span_err(span, &msg)
+ .help("valid widths are 32 and 64")
+ .emit();
+ } else {
+ let msg = format!("invalid suffix `{}` for float literal", suf);
+ self.struct_span_err(span, &msg)
+ .span_label(span, format!("invalid suffix `{}`", suf))
+ .help("valid suffixes are `f32` and `f64`")
+ .emit();
+ }
+ }
+ LitError::NonDecimalFloat(base) => {
+ let descr = match base {
+ 16 => "hexadecimal",
+ 8 => "octal",
+ 2 => "binary",
+ _ => unreachable!(),
+ };
+ self.struct_span_err(span, &format!("{} float literal is not supported", descr))
+ .span_label(span, "not supported")
+ .emit();
+ }
+ LitError::IntTooLarge => {
+ self.struct_span_err(span, "integer literal is too large")
+ .emit();
+ }
+ }
+ }
+
+ pub(super) fn expect_no_suffix(&self, sp: Span, kind: &str, suffix: Option<Symbol>) {
+ if let Some(suf) = suffix {
+ let mut err = if kind == "a tuple index"
+ && [sym::i32, sym::u32, sym::isize, sym::usize].contains(&suf)
+ {
+ // #59553: warn instead of reject out of hand to allow the fix to percolate
+ // through the ecosystem when people fix their macros
+ let mut err = self.sess.span_diagnostic.struct_span_warn(
+ sp,
+ &format!("suffixes on {} are invalid", kind),
+ );
+ err.note(&format!(
+ "`{}` is *temporarily* accepted on tuple index fields as it was \
+ incorrectly accepted on stable for a few releases",
+ suf,
+ ));
+ err.help(
+ "on proc macros, you'll want to use `syn::Index::from` or \
+ `proc_macro::Literal::*_unsuffixed` for code that will desugar \
+ to tuple field access",
+ );
+ err.note(
+ "for more context, see https://github.com/rust-lang/rust/issues/60210",
+ );
+ err
+ } else {
+ self.struct_span_err(sp, &format!("suffixes on {} are invalid", kind))
+ };
+ err.span_label(sp, format!("invalid suffix `{}`", suf));
+ err.emit();
+ }
+ }
+
/// Matches `'-' lit | lit` (cf. `ast_validation::AstValidator::check_expr_within_pat`).
crate fn parse_literal_maybe_minus(&mut self) -> PResult<'a, P<Expr>> {
maybe_whole_expr!(self);
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index 3c60c88..08c624b 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -1,28 +1,23 @@
-use super::{Parser, PResult, PathStyle, SemiColonMode, BlockMode, ParamCfg};
-
+use super::{Parser, PResult, PathStyle, SemiColonMode, BlockMode};
use crate::maybe_whole;
use crate::ptr::P;
-use crate::ast::{
- self, DUMMY_NODE_ID, Ident, Attribute, AttrStyle,
- Item, ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind,
- UseTree, UseTreeKind, PathSegment,
- IsAuto, Constness, IsAsync, Unsafety, Defaultness,
- Visibility, VisibilityKind, Mutability, FnDecl, FnHeader, MethodSig, Block,
- ForeignItem, ForeignItemKind,
- Ty, TyKind, Generics, GenericBounds, TraitRef,
- EnumDef, VariantData, StructField, AnonConst,
- Mac, MacDelimiter,
-};
+use crate::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrStyle, AnonConst, Item, ItemKind};
+use crate::ast::{ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
+use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
+use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
+use crate::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField};
+use crate::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, MethodSig, SelfKind, Param};
use crate::ext::base::DummyResult;
use crate::parse::token;
use crate::parse::parser::maybe_append;
-use crate::parse::diagnostics::Error;
+use crate::parse::diagnostics::{Error, dummy_arg};
use crate::tokenstream::{TokenTree, TokenStream};
-use crate::source_map::{respan, Span};
use crate::symbol::{kw, sym};
+use crate::source_map::{self, respan, Span};
+use crate::ThinVec;
-use std::mem;
use log::debug;
+use std::mem;
use rustc_target::spec::abi::Abi;
use errors::{Applicability, DiagnosticBuilder, DiagnosticId, StashKey};
@@ -412,7 +407,7 @@
self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, vis)
}
- fn mk_item_with_info(
+ pub(super) fn mk_item_with_info(
&self,
attrs: Vec<Attribute>,
lo: Span,
@@ -425,16 +420,6 @@
Ok(Some(self.mk_item(span, ident, item, vis, attrs)))
}
- fn recover_first_param(&mut self) -> &'static str {
- match self.parse_outer_attributes()
- .and_then(|_| self.parse_self_param())
- .map_err(|mut e| e.cancel())
- {
- Ok(Some(_)) => "method",
- _ => "function",
- }
- }
-
/// This is the fall-through for parsing items.
fn parse_macro_use_or_failure(
&mut self,
@@ -707,9 +692,11 @@
Ok(item)
}
- fn parse_impl_item_(&mut self,
- at_end: &mut bool,
- mut attrs: Vec<Attribute>) -> PResult<'a, ImplItem> {
+ fn parse_impl_item_(
+ &mut self,
+ at_end: &mut bool,
+ mut attrs: Vec<Attribute>,
+ ) -> PResult<'a, ImplItem> {
let lo = self.token.span;
let vis = self.parse_visibility(false)?;
let defaultness = self.parse_defaultness();
@@ -722,8 +709,11 @@
(name, kind, generics)
} else if self.is_const_item() {
self.parse_impl_const()?
+ } else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
+ // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
+ (Ident::invalid(), ast::ImplItemKind::Macro(mac), Generics::default())
} else {
- let (name, inner_attrs, generics, kind) = self.parse_impl_method(&vis, at_end)?;
+ let (name, inner_attrs, generics, kind) = self.parse_impl_method(at_end)?;
attrs.extend(inner_attrs);
(name, kind, generics)
};
@@ -783,71 +773,6 @@
Ok((name, ImplItemKind::Const(typ, expr), Generics::default()))
}
- /// Parses a method or a macro invocation in a trait impl.
- fn parse_impl_method(
- &mut self,
- vis: &Visibility,
- at_end: &mut bool
- ) -> PResult<'a, (Ident, Vec<Attribute>, Generics, ImplItemKind)> {
- // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
- if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? {
- // method macro
- Ok((Ident::invalid(), vec![], Generics::default(), ast::ImplItemKind::Macro(mac)))
- } else {
- let (ident, sig, generics) = self.parse_method_sig(|_| true)?;
- *at_end = true;
- let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
- Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(sig, body)))
- }
- }
-
- /// Parse the "signature", including the identifier, parameters, and generics
- /// of a method. The body is not parsed as that differs between `trait`s and `impl`s.
- fn parse_method_sig(
- &mut self,
- is_name_required: fn(&token::Token) -> bool,
- ) -> PResult<'a, (Ident, MethodSig, Generics)> {
- let header = self.parse_fn_front_matter()?;
- let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
- is_self_allowed: true,
- allow_c_variadic: false,
- is_name_required,
- })?;
- Ok((ident, MethodSig { header, decl }, generics))
- }
-
- /// Parses all the "front matter" for a `fn` declaration, up to
- /// and including the `fn` keyword:
- ///
- /// - `const fn`
- /// - `unsafe fn`
- /// - `const unsafe fn`
- /// - `extern fn`
- /// - etc.
- fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
- let is_const_fn = self.eat_keyword(kw::Const);
- let const_span = self.prev_span;
- let asyncness = self.parse_asyncness();
- if let IsAsync::Async { .. } = asyncness {
- self.ban_async_in_2015(self.prev_span);
- }
- let asyncness = respan(self.prev_span, asyncness);
- let unsafety = self.parse_unsafety();
- let (constness, unsafety, abi) = if is_const_fn {
- (respan(const_span, Constness::Const), unsafety, Abi::Rust)
- } else {
- let abi = self.parse_extern_abi()?;
- (respan(self.prev_span, Constness::NotConst), unsafety, abi)
- };
- if !self.eat_keyword(kw::Fn) {
- // It is possible for `expect_one_of` to recover given the contents of
- // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
- // account for this.
- if !self.expect_one_of(&[], &[])? { unreachable!() }
- }
- Ok(FnHeader { constness, unsafety, asyncness, abi })
- }
-
/// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`.
fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> {
// Parse optional `auto` prefix.
@@ -957,13 +882,7 @@
// trait item macro.
(Ident::invalid(), TraitItemKind::Macro(mac), Generics::default())
} else {
- // This is somewhat dubious; We don't want to allow
- // argument names to be left off if there is a definition...
- //
- // We don't allow argument names to be left off in edition 2018.
- let (ident, sig, generics) = self.parse_method_sig(|t| t.span.rust_2018())?;
- let body = self.parse_trait_method_body(at_end, &mut attrs)?;
- (ident, TraitItemKind::Method(sig, body), generics)
+ self.parse_trait_item_method(at_end, &mut attrs)?
};
Ok(TraitItem {
@@ -991,43 +910,6 @@
Ok((ident, TraitItemKind::Const(ty, default), Generics::default()))
}
- /// Parse the "body" of a method in a trait item definition.
- /// This can either be `;` when there's no body,
- /// or e.g. a block when the method is a provided one.
- fn parse_trait_method_body(
- &mut self,
- at_end: &mut bool,
- attrs: &mut Vec<Attribute>,
- ) -> PResult<'a, Option<P<Block>>> {
- Ok(match self.token.kind {
- token::Semi => {
- debug!("parse_trait_method_body(): parsing required method");
- self.bump();
- *at_end = true;
- None
- }
- token::OpenDelim(token::Brace) => {
- debug!("parse_trait_method_body(): parsing provided method");
- *at_end = true;
- let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
- attrs.extend(inner_attrs.iter().cloned());
- Some(body)
- }
- token::Interpolated(ref nt) => {
- match **nt {
- token::NtBlock(..) => {
- *at_end = true;
- let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
- attrs.extend(inner_attrs.iter().cloned());
- Some(body)
- }
- _ => return self.expected_semi_or_open_brace(),
- }
- }
- _ => return self.expected_semi_or_open_brace(),
- })
- }
-
/// Parses the following grammar:
///
/// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
@@ -1194,45 +1076,6 @@
Ok(ident)
}
- /// Parses an item-position function declaration.
- fn parse_item_fn(
- &mut self,
- lo: Span,
- vis: Visibility,
- attrs: Vec<Attribute>,
- header: FnHeader,
- ) -> PResult<'a, Option<P<Item>>> {
- let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
- is_self_allowed: false,
- allow_c_variadic: header.abi == Abi::C && header.unsafety == Unsafety::Unsafe,
- is_name_required: |_| true,
- })?;
- let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
- let kind = ItemKind::Fn(decl, header, generics, body);
- self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs)))
- }
-
- /// Parse the "signature", including the identifier, parameters, and generics of a function.
- fn parse_fn_sig(&mut self, cfg: ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
- let ident = self.parse_ident()?;
- let mut generics = self.parse_generics()?;
- let decl = self.parse_fn_decl(cfg, true)?;
- generics.where_clause = self.parse_where_clause()?;
- Ok((ident, decl, generics))
- }
-
- /// Parses the parameter list and result type of a function declaration.
- pub(super) fn parse_fn_decl(
- &mut self,
- cfg: ParamCfg,
- ret_allow_plus: bool,
- ) -> PResult<'a, P<FnDecl>> {
- Ok(P(FnDecl {
- inputs: self.parse_fn_params(cfg)?,
- output: self.parse_ret_ty(ret_allow_plus)?,
- }))
- }
-
/// Parses `extern` for foreign ABIs modules.
///
/// `extern` is expected to have been
@@ -1344,32 +1187,6 @@
}
}
- /// Parses a function declaration from a foreign module.
- fn parse_item_foreign_fn(
- &mut self,
- vis: ast::Visibility,
- lo: Span,
- attrs: Vec<Attribute>,
- extern_sp: Span,
- ) -> PResult<'a, ForeignItem> {
- self.expect_keyword(kw::Fn)?;
- let (ident, decl, generics) = self.parse_fn_sig(super::ParamCfg {
- is_self_allowed: false,
- allow_c_variadic: true,
- is_name_required: |_| true,
- })?;
- let span = lo.to(self.token.span);
- self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?;
- Ok(ast::ForeignItem {
- ident,
- attrs,
- kind: ForeignItemKind::Fn(decl, generics),
- id: DUMMY_NODE_ID,
- span,
- vis,
- })
- }
-
/// Parses a static item from a foreign module.
/// Assumes that the `static` keyword is already parsed.
fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
@@ -1910,3 +1727,466 @@
})
}
}
+
+/// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
+pub(super) struct ParamCfg {
+ /// Is `self` is allowed as the first parameter?
+ pub is_self_allowed: bool,
+ /// Is `...` allowed as the tail of the parameter list?
+ pub allow_c_variadic: bool,
+ /// `is_name_required` decides if, per-parameter,
+ /// the parameter must have a pattern or just a type.
+ pub is_name_required: fn(&token::Token) -> bool,
+}
+
+/// Parsing of functions and methods.
+impl<'a> Parser<'a> {
+ /// Parses an item-position function declaration.
+ fn parse_item_fn(
+ &mut self,
+ lo: Span,
+ vis: Visibility,
+ attrs: Vec<Attribute>,
+ header: FnHeader,
+ ) -> PResult<'a, Option<P<Item>>> {
+ let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
+ is_self_allowed: false,
+ allow_c_variadic: header.abi == Abi::C && header.unsafety == Unsafety::Unsafe,
+ is_name_required: |_| true,
+ })?;
+ let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
+ let kind = ItemKind::Fn(decl, header, generics, body);
+ self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs)))
+ }
+
+ /// Parses a function declaration from a foreign module.
+ fn parse_item_foreign_fn(
+ &mut self,
+ vis: ast::Visibility,
+ lo: Span,
+ attrs: Vec<Attribute>,
+ extern_sp: Span,
+ ) -> PResult<'a, ForeignItem> {
+ self.expect_keyword(kw::Fn)?;
+ let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
+ is_self_allowed: false,
+ allow_c_variadic: true,
+ is_name_required: |_| true,
+ })?;
+ let span = lo.to(self.token.span);
+ self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?;
+ Ok(ast::ForeignItem {
+ ident,
+ attrs,
+ kind: ForeignItemKind::Fn(decl, generics),
+ id: DUMMY_NODE_ID,
+ span,
+ vis,
+ })
+ }
+
+ /// Parses a method or a macro invocation in a trait impl.
+ fn parse_impl_method(
+ &mut self,
+ at_end: &mut bool,
+ ) -> PResult<'a, (Ident, Vec<Attribute>, Generics, ImplItemKind)> {
+ let (ident, sig, generics) = self.parse_method_sig(|_| true)?;
+ *at_end = true;
+ let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
+ Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(sig, body)))
+ }
+
+ fn parse_trait_item_method(
+ &mut self,
+ at_end: &mut bool,
+ attrs: &mut Vec<Attribute>,
+ ) -> PResult<'a, (Ident, TraitItemKind, Generics)> {
+ // This is somewhat dubious; We don't want to allow
+ // argument names to be left off if there is a definition...
+ //
+ // We don't allow argument names to be left off in edition 2018.
+ let (ident, sig, generics) = self.parse_method_sig(|t| t.span.rust_2018())?;
+ let body = self.parse_trait_method_body(at_end, attrs)?;
+ Ok((ident, TraitItemKind::Method(sig, body), generics))
+ }
+
+ /// Parse the "body" of a method in a trait item definition.
+ /// This can either be `;` when there's no body,
+ /// or e.g. a block when the method is a provided one.
+ fn parse_trait_method_body(
+ &mut self,
+ at_end: &mut bool,
+ attrs: &mut Vec<Attribute>,
+ ) -> PResult<'a, Option<P<Block>>> {
+ Ok(match self.token.kind {
+ token::Semi => {
+ debug!("parse_trait_method_body(): parsing required method");
+ self.bump();
+ *at_end = true;
+ None
+ }
+ token::OpenDelim(token::Brace) => {
+ debug!("parse_trait_method_body(): parsing provided method");
+ *at_end = true;
+ let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
+ attrs.extend(inner_attrs.iter().cloned());
+ Some(body)
+ }
+ token::Interpolated(ref nt) => {
+ match **nt {
+ token::NtBlock(..) => {
+ *at_end = true;
+ let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
+ attrs.extend(inner_attrs.iter().cloned());
+ Some(body)
+ }
+ _ => return self.expected_semi_or_open_brace(),
+ }
+ }
+ _ => return self.expected_semi_or_open_brace(),
+ })
+ }
+
+ /// Parse the "signature", including the identifier, parameters, and generics
+ /// of a method. The body is not parsed as that differs between `trait`s and `impl`s.
+ fn parse_method_sig(
+ &mut self,
+ is_name_required: fn(&token::Token) -> bool,
+ ) -> PResult<'a, (Ident, MethodSig, Generics)> {
+ let header = self.parse_fn_front_matter()?;
+ let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
+ is_self_allowed: true,
+ allow_c_variadic: false,
+ is_name_required,
+ })?;
+ Ok((ident, MethodSig { header, decl }, generics))
+ }
+
+ /// Parses all the "front matter" for a `fn` declaration, up to
+ /// and including the `fn` keyword:
+ ///
+ /// - `const fn`
+ /// - `unsafe fn`
+ /// - `const unsafe fn`
+ /// - `extern fn`
+ /// - etc.
+ fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> {
+ let is_const_fn = self.eat_keyword(kw::Const);
+ let const_span = self.prev_span;
+ let asyncness = self.parse_asyncness();
+ if let IsAsync::Async { .. } = asyncness {
+ self.ban_async_in_2015(self.prev_span);
+ }
+ let asyncness = respan(self.prev_span, asyncness);
+ let unsafety = self.parse_unsafety();
+ let (constness, unsafety, abi) = if is_const_fn {
+ (respan(const_span, Constness::Const), unsafety, Abi::Rust)
+ } else {
+ let abi = self.parse_extern_abi()?;
+ (respan(self.prev_span, Constness::NotConst), unsafety, abi)
+ };
+ if !self.eat_keyword(kw::Fn) {
+ // It is possible for `expect_one_of` to recover given the contents of
+ // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't
+ // account for this.
+ if !self.expect_one_of(&[], &[])? { unreachable!() }
+ }
+ Ok(FnHeader { constness, unsafety, asyncness, abi })
+ }
+
+ /// Parse the "signature", including the identifier, parameters, and generics of a function.
+ fn parse_fn_sig(&mut self, cfg: ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
+ let ident = self.parse_ident()?;
+ let mut generics = self.parse_generics()?;
+ let decl = self.parse_fn_decl(cfg, true)?;
+ generics.where_clause = self.parse_where_clause()?;
+ Ok((ident, decl, generics))
+ }
+
+ /// Parses the parameter list and result type of a function declaration.
+ pub(super) fn parse_fn_decl(
+ &mut self,
+ cfg: ParamCfg,
+ ret_allow_plus: bool,
+ ) -> PResult<'a, P<FnDecl>> {
+ Ok(P(FnDecl {
+ inputs: self.parse_fn_params(cfg)?,
+ output: self.parse_ret_ty(ret_allow_plus)?,
+ }))
+ }
+
+ /// Parses the parameter list of a function, including the `(` and `)` delimiters.
+ fn parse_fn_params(&mut self, mut cfg: ParamCfg) -> PResult<'a, Vec<Param>> {
+ let sp = self.token.span;
+ let is_trait_item = cfg.is_self_allowed;
+ let mut c_variadic = false;
+ // Parse the arguments, starting out with `self` being possibly allowed...
+ let (params, _) = self.parse_paren_comma_seq(|p| {
+ let param = p.parse_param_general(&cfg, is_trait_item);
+ // ...now that we've parsed the first argument, `self` is no longer allowed.
+ cfg.is_self_allowed = false;
+
+ match param {
+ Ok(param) => Ok(
+ if let TyKind::CVarArgs = param.ty.kind {
+ c_variadic = true;
+ if p.token != token::CloseDelim(token::Paren) {
+ p.span_err(
+ p.token.span,
+ "`...` must be the last argument of a C-variadic function",
+ );
+ // FIXME(eddyb) this should probably still push `CVarArgs`.
+ // Maybe AST validation/HIR lowering should emit the above error?
+ None
+ } else {
+ Some(param)
+ }
+ } else {
+ Some(param)
+ }
+ ),
+ Err(mut e) => {
+ e.emit();
+ let lo = p.prev_span;
+ // Skip every token until next possible arg or end.
+ p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]);
+ // Create a placeholder argument for proper arg count (issue #34264).
+ let span = lo.to(p.prev_span);
+ Ok(Some(dummy_arg(Ident::new(kw::Invalid, span))))
+ }
+ }
+ })?;
+
+ let mut params: Vec<_> = params.into_iter().filter_map(|x| x).collect();
+
+ // Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
+ self.deduplicate_recovered_params_names(&mut params);
+
+ if c_variadic && params.len() <= 1 {
+ self.span_err(
+ sp,
+ "C-variadic function must be declared with at least one named argument",
+ );
+ }
+
+ Ok(params)
+ }
+
+ /// Skips unexpected attributes and doc comments in this position and emits an appropriate
+ /// error.
+ /// This version of parse param doesn't necessarily require identifier names.
+ fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> {
+ let lo = self.token.span;
+ let attrs = self.parse_outer_attributes()?;
+
+ // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
+ if let Some(mut param) = self.parse_self_param()? {
+ param.attrs = attrs.into();
+ return if cfg.is_self_allowed {
+ Ok(param)
+ } else {
+ self.recover_bad_self_param(param, is_trait_item)
+ };
+ }
+
+ let is_name_required = match self.token.kind {
+ token::DotDotDot => false,
+ _ => (cfg.is_name_required)(&self.token),
+ };
+ let (pat, ty) = if is_name_required || self.is_named_param() {
+ debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
+
+ let pat = self.parse_fn_param_pat()?;
+ if let Err(mut err) = self.expect(&token::Colon) {
+ return if let Some(ident) = self.parameter_without_type(
+ &mut err,
+ pat,
+ is_name_required,
+ cfg.is_self_allowed,
+ is_trait_item,
+ ) {
+ err.emit();
+ Ok(dummy_arg(ident))
+ } else {
+ Err(err)
+ };
+ }
+
+ self.eat_incorrect_doc_comment_for_param_type();
+ (pat, self.parse_ty_common(true, true, cfg.allow_c_variadic)?)
+ } else {
+ debug!("parse_param_general ident_to_pat");
+ let parser_snapshot_before_ty = self.clone();
+ self.eat_incorrect_doc_comment_for_param_type();
+ let mut ty = self.parse_ty_common(true, true, cfg.allow_c_variadic);
+ if ty.is_ok() && self.token != token::Comma &&
+ self.token != token::CloseDelim(token::Paren) {
+ // This wasn't actually a type, but a pattern looking like a type,
+ // so we are going to rollback and re-parse for recovery.
+ ty = self.unexpected();
+ }
+ match ty {
+ Ok(ty) => {
+ let ident = Ident::new(kw::Invalid, self.prev_span);
+ let bm = BindingMode::ByValue(Mutability::Immutable);
+ let pat = self.mk_pat_ident(ty.span, bm, ident);
+ (pat, ty)
+ }
+ // If this is a C-variadic argument and we hit an error, return the error.
+ Err(err) if self.token == token::DotDotDot => return Err(err),
+ // Recover from attempting to parse the argument as a type without pattern.
+ Err(mut err) => {
+ err.cancel();
+ mem::replace(self, parser_snapshot_before_ty);
+ self.recover_arg_parse()?
+ }
+ }
+ };
+
+ let span = lo.to(self.token.span);
+
+ Ok(Param {
+ attrs: attrs.into(),
+ id: ast::DUMMY_NODE_ID,
+ is_placeholder: false,
+ pat,
+ span,
+ ty,
+ })
+ }
+
+ /// Returns the parsed optional self parameter and whether a self shortcut was used.
+ ///
+ /// See `parse_self_param_with_attrs` to collect attributes.
+ fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
+ // Extract an identifier *after* having confirmed that the token is one.
+ let expect_self_ident = |this: &mut Self| {
+ match this.token.kind {
+ // Preserve hygienic context.
+ token::Ident(name, _) => {
+ let span = this.token.span;
+ this.bump();
+ Ident::new(name, span)
+ }
+ _ => unreachable!(),
+ }
+ };
+ // Is `self` `n` tokens ahead?
+ let is_isolated_self = |this: &Self, n| {
+ this.is_keyword_ahead(n, &[kw::SelfLower])
+ && this.look_ahead(n + 1, |t| t != &token::ModSep)
+ };
+ // Is `mut self` `n` tokens ahead?
+ let is_isolated_mut_self = |this: &Self, n| {
+ this.is_keyword_ahead(n, &[kw::Mut])
+ && is_isolated_self(this, n + 1)
+ };
+ // Parse `self` or `self: TYPE`. We already know the current token is `self`.
+ let parse_self_possibly_typed = |this: &mut Self, m| {
+ let eself_ident = expect_self_ident(this);
+ let eself_hi = this.prev_span;
+ let eself = if this.eat(&token::Colon) {
+ SelfKind::Explicit(this.parse_ty()?, m)
+ } else {
+ SelfKind::Value(m)
+ };
+ Ok((eself, eself_ident, eself_hi))
+ };
+ // Recover for the grammar `*self`, `*const self`, and `*mut self`.
+ let recover_self_ptr = |this: &mut Self| {
+ let msg = "cannot pass `self` by raw pointer";
+ let span = this.token.span;
+ this.struct_span_err(span, msg)
+ .span_label(span, msg)
+ .emit();
+
+ Ok((SelfKind::Value(Mutability::Immutable), expect_self_ident(this), this.prev_span))
+ };
+
+ // Parse optional `self` parameter of a method.
+ // Only a limited set of initial token sequences is considered `self` parameters; anything
+ // else is parsed as a normal function parameter list, so some lookahead is required.
+ let eself_lo = self.token.span;
+ let (eself, eself_ident, eself_hi) = match self.token.kind {
+ token::BinOp(token::And) => {
+ let eself = if is_isolated_self(self, 1) {
+ // `&self`
+ self.bump();
+ SelfKind::Region(None, Mutability::Immutable)
+ } else if is_isolated_mut_self(self, 1) {
+ // `&mut self`
+ self.bump();
+ self.bump();
+ SelfKind::Region(None, Mutability::Mutable)
+ } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
+ // `&'lt self`
+ self.bump();
+ let lt = self.expect_lifetime();
+ SelfKind::Region(Some(lt), Mutability::Immutable)
+ } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
+ // `&'lt mut self`
+ self.bump();
+ let lt = self.expect_lifetime();
+ self.bump();
+ SelfKind::Region(Some(lt), Mutability::Mutable)
+ } else {
+ // `¬_self`
+ return Ok(None);
+ };
+ (eself, expect_self_ident(self), self.prev_span)
+ }
+ // `*self`
+ token::BinOp(token::Star) if is_isolated_self(self, 1) => {
+ self.bump();
+ recover_self_ptr(self)?
+ }
+ // `*mut self` and `*const self`
+ token::BinOp(token::Star) if
+ self.look_ahead(1, |t| t.is_mutability())
+ && is_isolated_self(self, 2) =>
+ {
+ self.bump();
+ self.bump();
+ recover_self_ptr(self)?
+ }
+ // `self` and `self: TYPE`
+ token::Ident(..) if is_isolated_self(self, 0) => {
+ parse_self_possibly_typed(self, Mutability::Immutable)?
+ }
+ // `mut self` and `mut self: TYPE`
+ token::Ident(..) if is_isolated_mut_self(self, 0) => {
+ self.bump();
+ parse_self_possibly_typed(self, Mutability::Mutable)?
+ }
+ _ => return Ok(None),
+ };
+
+ let eself = source_map::respan(eself_lo.to(eself_hi), eself);
+ Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident)))
+ }
+
+ fn is_named_param(&self) -> bool {
+ let offset = match self.token.kind {
+ token::Interpolated(ref nt) => match **nt {
+ token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
+ _ => 0,
+ }
+ token::BinOp(token::And) | token::AndAnd => 1,
+ _ if self.token.is_keyword(kw::Mut) => 1,
+ _ => 0,
+ };
+
+ self.look_ahead(offset, |t| t.is_ident()) &&
+ self.look_ahead(offset + 1, |t| t == &token::Colon)
+ }
+
+ fn recover_first_param(&mut self) -> &'static str {
+ match self.parse_outer_attributes()
+ .and_then(|_| self.parse_self_param())
+ .map_err(|mut e| e.cancel())
+ {
+ Ok(Some(_)) => "method",
+ _ => "function",
+ }
+ }
+}
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 48f9e30..e288346 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -367,6 +367,7 @@
let pat = self.mk_pat(lo.to(self.prev_span), pat);
let pat = self.maybe_recover_from_bad_qpath(pat, true)?;
+ let pat = self.recover_intersection_pat(pat)?;
if !allow_range_pat {
self.ban_pat_range_if_ambiguous(&pat)?
@@ -375,6 +376,65 @@
Ok(pat)
}
+ /// Try to recover the more general form `intersect ::= $pat_lhs @ $pat_rhs`.
+ ///
+ /// Allowed binding patterns generated by `binding ::= ref? mut? $ident @ $pat_rhs`
+ /// should already have been parsed by now at this point,
+ /// if the next token is `@` then we can try to parse the more general form.
+ ///
+ /// Consult `parse_pat_ident` for the `binding` grammar.
+ ///
+ /// The notion of intersection patterns are found in
+ /// e.g. [F#][and] where they are called AND-patterns.
+ ///
+ /// [and]: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching
+ fn recover_intersection_pat(&mut self, lhs: P<Pat>) -> PResult<'a, P<Pat>> {
+ if self.token.kind != token::At {
+ // Next token is not `@` so it's not going to be an intersection pattern.
+ return Ok(lhs);
+ }
+
+ // At this point we attempt to parse `@ $pat_rhs` and emit an error.
+ self.bump(); // `@`
+ let mut rhs = self.parse_pat(None)?;
+ let sp = lhs.span.to(rhs.span);
+
+ if let PatKind::Ident(_, _, ref mut sub @ None) = rhs.kind {
+ // The user inverted the order, so help them fix that.
+ let mut applicability = Applicability::MachineApplicable;
+ lhs.walk(&mut |p| match p.kind {
+ // `check_match` is unhappy if the subpattern has a binding anywhere.
+ PatKind::Ident(..) => {
+ applicability = Applicability::MaybeIncorrect;
+ false // Short-circuit.
+ },
+ _ => true,
+ });
+
+ let lhs_span = lhs.span;
+ // Move the LHS into the RHS as a subpattern.
+ // The RHS is now the full pattern.
+ *sub = Some(lhs);
+
+ self.struct_span_err(sp, "pattern on wrong side of `@`")
+ .span_label(lhs_span, "pattern on the left, should be on the right")
+ .span_label(rhs.span, "binding on the right, should be on the left")
+ .span_suggestion(sp, "switch the order", pprust::pat_to_string(&rhs), applicability)
+ .emit();
+ } else {
+ // The special case above doesn't apply so we may have e.g. `A(x) @ B(y)`.
+ rhs.kind = PatKind::Wild;
+ self.struct_span_err(sp, "left-hand side of `@` must be a binding")
+ .span_label(lhs.span, "interpreted as a pattern, not a binding")
+ .span_label(rhs.span, "also a pattern")
+ .note("bindings are `x`, `mut x`, `ref x`, and `ref mut x`")
+ .emit();
+ }
+
+ rhs.span = sp;
+ Ok(rhs)
+ }
+
/// Ban a range pattern if it has an ambiguous interpretation.
fn ban_pat_range_if_ambiguous(&self, pat: &Pat) -> PResult<'a, ()> {
match pat.kind {
diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs
index 018b595..e696ab0 100644
--- a/src/libsyntax/parse/parser/ty.rs
+++ b/src/libsyntax/parse/parser/ty.rs
@@ -1,4 +1,5 @@
use super::{Parser, PResult, PathStyle, PrevTokenKind, TokenType};
+use super::item::ParamCfg;
use crate::{maybe_whole, maybe_recover_from_interpolated_ty_qpath};
use crate::ptr::P;
@@ -281,7 +282,7 @@
let unsafety = self.parse_unsafety();
let abi = self.parse_extern_abi()?;
self.expect_keyword(kw::Fn)?;
- let cfg = super::ParamCfg {
+ let cfg = ParamCfg {
is_self_allowed: false,
allow_c_variadic: true,
is_name_required: |_| false,
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index fd78a2b..eb74ab2 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -4,16 +4,13 @@
pub use LitKind::*;
pub use TokenKind::*;
-use crate::ast::{self};
-use crate::parse::{parse_stream_from_source_str, ParseSess};
-use crate::print::pprust;
+use crate::ast;
use crate::ptr::P;
use crate::symbol::kw;
-use crate::tokenstream::{self, DelimSpan, TokenStream, TokenTree};
+use crate::tokenstream::TokenTree;
use syntax_pos::symbol::Symbol;
-use syntax_pos::{self, Span, FileName, DUMMY_SP};
-use log::info;
+use syntax_pos::{self, Span, DUMMY_SP};
use std::fmt;
use std::mem;
@@ -737,131 +734,3 @@
}
}
}
-
-impl Nonterminal {
- pub fn to_tokenstream(&self, sess: &ParseSess, span: Span) -> TokenStream {
- // A `Nonterminal` is often a parsed AST item. At this point we now
- // need to convert the parsed AST to an actual token stream, e.g.
- // un-parse it basically.
- //
- // Unfortunately there's not really a great way to do that in a
- // guaranteed lossless fashion right now. The fallback here is to just
- // stringify the AST node and reparse it, but this loses all span
- // information.
- //
- // As a result, some AST nodes are annotated with the token stream they
- // came from. Here we attempt to extract these lossless token streams
- // before we fall back to the stringification.
- let tokens = match *self {
- Nonterminal::NtItem(ref item) => {
- prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
- }
- Nonterminal::NtTraitItem(ref item) => {
- prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
- }
- Nonterminal::NtImplItem(ref item) => {
- prepend_attrs(sess, &item.attrs, item.tokens.as_ref(), span)
- }
- Nonterminal::NtIdent(ident, is_raw) => {
- Some(TokenTree::token(Ident(ident.name, is_raw), ident.span).into())
- }
- Nonterminal::NtLifetime(ident) => {
- Some(TokenTree::token(Lifetime(ident.name), ident.span).into())
- }
- Nonterminal::NtTT(ref tt) => {
- Some(tt.clone().into())
- }
- _ => None,
- };
-
- // FIXME(#43081): Avoid this pretty-print + reparse hack
- let source = pprust::nonterminal_to_string(self);
- let filename = FileName::macro_expansion_source_code(&source);
- let tokens_for_real = parse_stream_from_source_str(filename, source, sess, Some(span));
-
- // During early phases of the compiler the AST could get modified
- // directly (e.g., attributes added or removed) and the internal cache
- // of tokens my not be invalidated or updated. Consequently if the
- // "lossless" token stream disagrees with our actual stringification
- // (which has historically been much more battle-tested) then we go
- // with the lossy stream anyway (losing span information).
- //
- // Note that the comparison isn't `==` here to avoid comparing spans,
- // but it *also* is a "probable" equality which is a pretty weird
- // definition. We mostly want to catch actual changes to the AST
- // like a `#[cfg]` being processed or some weird `macro_rules!`
- // expansion.
- //
- // What we *don't* want to catch is the fact that a user-defined
- // literal like `0xf` is stringified as `15`, causing the cached token
- // stream to not be literal `==` token-wise (ignoring spans) to the
- // token stream we got from stringification.
- //
- // Instead the "probably equal" check here is "does each token
- // recursively have the same discriminant?" We basically don't look at
- // the token values here and assume that such fine grained token stream
- // modifications, including adding/removing typically non-semantic
- // tokens such as extra braces and commas, don't happen.
- if let Some(tokens) = tokens {
- if tokens.probably_equal_for_proc_macro(&tokens_for_real) {
- return tokens
- }
- info!("cached tokens found, but they're not \"probably equal\", \
- going with stringified version");
- }
- return tokens_for_real
- }
-}
-
-fn prepend_attrs(sess: &ParseSess,
- attrs: &[ast::Attribute],
- tokens: Option<&tokenstream::TokenStream>,
- span: syntax_pos::Span)
- -> Option<tokenstream::TokenStream>
-{
- let tokens = tokens?;
- if attrs.len() == 0 {
- return Some(tokens.clone())
- }
- let mut builder = tokenstream::TokenStreamBuilder::new();
- for attr in attrs {
- assert_eq!(attr.style, ast::AttrStyle::Outer,
- "inner attributes should prevent cached tokens from existing");
-
- let source = pprust::attribute_to_string(attr);
- let macro_filename = FileName::macro_expansion_source_code(&source);
- if attr.is_sugared_doc {
- let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
- builder.push(stream);
- continue
- }
-
- // synthesize # [ $path $tokens ] manually here
- let mut brackets = tokenstream::TokenStreamBuilder::new();
-
- // For simple paths, push the identifier directly
- if attr.path.segments.len() == 1 && attr.path.segments[0].args.is_none() {
- let ident = attr.path.segments[0].ident;
- let token = Ident(ident.name, ident.as_str().starts_with("r#"));
- brackets.push(tokenstream::TokenTree::token(token, ident.span));
-
- // ... and for more complicated paths, fall back to a reparse hack that
- // should eventually be removed.
- } else {
- let stream = parse_stream_from_source_str(macro_filename, source, sess, Some(span));
- brackets.push(stream);
- }
-
- brackets.push(attr.tokens.clone());
-
- // The span we list here for `#` and for `[ ... ]` are both wrong in
- // that it encompasses more than each token, but it hopefully is "good
- // enough" for now at least.
- builder.push(tokenstream::TokenTree::token(Pound, attr.span));
- let delim_span = DelimSpan::from_single(attr.span);
- builder.push(tokenstream::TokenTree::Delimited(
- delim_span, DelimToken::Bracket, brackets.build().into()));
- }
- builder.push(tokens.clone());
- Some(builder.build())
-}
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 7d4ffe4..136fc35 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -6,10 +6,11 @@
use crate::source_map::{self, SourceMap, Spanned};
use crate::parse::token::{self, BinOpToken, DelimToken, Nonterminal, Token, TokenKind};
use crate::parse::lexer::comments;
-use crate::parse::{self, ParseSess};
+use crate::parse;
use crate::print::pp::{self, Breaks};
use crate::print::pp::Breaks::{Consistent, Inconsistent};
use crate::ptr::P;
+use crate::sess::ParseSess;
use crate::symbol::{kw, sym};
use crate::tokenstream::{self, TokenStream, TokenTree};
@@ -2381,7 +2382,8 @@
}
self.print_ident(ident);
if let Some(ref p) = *sub {
- self.s.word("@");
+ self.s.space();
+ self.s.word_space("@");
self.print_pat(p);
}
}
diff --git a/src/libsyntax/sess.rs b/src/libsyntax/sess.rs
new file mode 100644
index 0000000..e49d395
--- /dev/null
+++ b/src/libsyntax/sess.rs
@@ -0,0 +1,124 @@
+//! Contains `ParseSess` which holds state living beyond what one `Parser` might.
+//! It also serves as an input to the parser itself.
+
+use crate::ast::{CrateConfig, NodeId};
+use crate::early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId};
+use crate::source_map::{SourceMap, FilePathMapping};
+use crate::feature_gate::UnstableFeatures;
+
+use errors::{Applicability, Handler, ColorConfig, DiagnosticBuilder};
+use rustc_data_structures::fx::{FxHashSet, FxHashMap};
+use rustc_data_structures::sync::{Lrc, Lock, Once};
+use syntax_pos::{Symbol, Span, MultiSpan};
+use syntax_pos::edition::Edition;
+use syntax_pos::hygiene::ExpnId;
+
+use std::path::PathBuf;
+use std::str;
+
+/// Collected spans during parsing for places where a certain feature was
+/// used and should be feature gated accordingly in `check_crate`.
+#[derive(Default)]
+crate struct GatedSpans {
+ /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`.
+ crate let_chains: Lock<Vec<Span>>,
+ /// Spans collected for gating `async_closure`, e.g. `async || ..`.
+ crate async_closure: Lock<Vec<Span>>,
+ /// Spans collected for gating `yield e?` expressions (`generators` gate).
+ crate yields: Lock<Vec<Span>>,
+ /// Spans collected for gating `or_patterns`, e.g. `Some(Foo | Bar)`.
+ crate or_patterns: Lock<Vec<Span>>,
+ /// Spans collected for gating `const_extern_fn`, e.g. `const extern fn foo`.
+ crate const_extern_fn: Lock<Vec<Span>>,
+}
+
+/// Info about a parsing session.
+pub struct ParseSess {
+ pub span_diagnostic: Handler,
+ crate unstable_features: UnstableFeatures,
+ pub config: CrateConfig,
+ pub edition: Edition,
+ pub missing_fragment_specifiers: Lock<FxHashSet<Span>>,
+ /// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
+ pub raw_identifier_spans: Lock<Vec<Span>>,
+ /// Used to determine and report recursive module inclusions.
+ pub(super) included_mod_stack: Lock<Vec<PathBuf>>,
+ source_map: Lrc<SourceMap>,
+ pub buffered_lints: Lock<Vec<BufferedEarlyLint>>,
+ /// Contains the spans of block expressions that could have been incomplete based on the
+ /// operation token that followed it, but that the parser cannot identify without further
+ /// analysis.
+ pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
+ pub injected_crate_name: Once<Symbol>,
+ crate gated_spans: GatedSpans,
+}
+
+impl ParseSess {
+ pub fn new(file_path_mapping: FilePathMapping) -> Self {
+ let cm = Lrc::new(SourceMap::new(file_path_mapping));
+ let handler = Handler::with_tty_emitter(
+ ColorConfig::Auto,
+ true,
+ None,
+ Some(cm.clone()),
+ );
+ ParseSess::with_span_handler(handler, cm)
+ }
+
+ pub fn with_span_handler(handler: Handler, source_map: Lrc<SourceMap>) -> Self {
+ Self {
+ span_diagnostic: handler,
+ unstable_features: UnstableFeatures::from_environment(),
+ config: FxHashSet::default(),
+ edition: ExpnId::root().expn_data().edition,
+ missing_fragment_specifiers: Lock::new(FxHashSet::default()),
+ raw_identifier_spans: Lock::new(Vec::new()),
+ included_mod_stack: Lock::new(vec![]),
+ source_map,
+ buffered_lints: Lock::new(vec![]),
+ ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
+ injected_crate_name: Once::new(),
+ gated_spans: GatedSpans::default(),
+ }
+ }
+
+ #[inline]
+ pub fn source_map(&self) -> &SourceMap {
+ &self.source_map
+ }
+
+ pub fn buffer_lint(
+ &self,
+ lint_id: BufferedEarlyLintId,
+ span: impl Into<MultiSpan>,
+ id: NodeId,
+ msg: &str,
+ ) {
+ self.buffered_lints.with_lock(|buffered_lints| {
+ buffered_lints.push(BufferedEarlyLint{
+ span: span.into(),
+ id,
+ msg: msg.into(),
+ lint_id,
+ });
+ });
+ }
+
+ /// Extend an error with a suggestion to wrap an expression with parentheses to allow the
+ /// parser to continue parsing the following operation as part of the same expression.
+ pub fn expr_parentheses_needed(
+ &self,
+ err: &mut DiagnosticBuilder<'_>,
+ span: Span,
+ alt_snippet: Option<String>,
+ ) {
+ if let Some(snippet) = self.source_map().span_to_snippet(span).ok().or(alt_snippet) {
+ err.span_suggestion(
+ span,
+ "parentheses are required to parse this as an expression",
+ format!("({})", snippet),
+ Applicability::MachineApplicable,
+ );
+ }
+ }
+}
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index 5e569f9..1501adc 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -970,6 +970,9 @@
fn span_to_string(&self, sp: Span) -> String {
self.span_to_string(sp)
}
+ fn span_to_snippet(&self, sp: Span) -> Result<String, SpanSnippetError> {
+ self.span_to_snippet(sp)
+ }
fn span_to_filename(&self, sp: Span) -> FileName {
self.span_to_filename(sp)
}
diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs
index f510ac9..fbcf368 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax/tests.rs
@@ -1,7 +1,8 @@
use crate::{ast, panictry};
-use crate::parse::{ParseSess, PResult, source_file_to_stream};
+use crate::parse::{PResult, source_file_to_stream};
use crate::parse::new_parser_from_source_str;
use crate::parse::parser::Parser;
+use crate::sess::ParseSess;
use crate::source_map::{SourceMap, FilePathMapping};
use crate::tokenstream::TokenStream;
use crate::with_default_globals;
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index bef12ed..0ff1c26 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -14,7 +14,6 @@
//! ownership of the original.
use crate::parse::token::{self, DelimToken, Token, TokenKind};
-use crate::print::pprust;
use syntax_pos::{BytePos, Span, DUMMY_SP};
#[cfg(target_arch = "x86_64")]
@@ -23,7 +22,7 @@
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
use smallvec::{SmallVec, smallvec};
-use std::{fmt, iter, mem};
+use std::{iter, mem};
#[cfg(test)]
mod tests;
@@ -137,13 +136,8 @@
/// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s
/// instead of a representation of the abstract syntax tree.
/// Today's `TokenTree`s can still contain AST via `token::Interpolated` for back-compat.
-///
-/// The use of `Option` is an optimization that avoids the need for an
-/// allocation when the stream is empty. However, it is not guaranteed that an
-/// empty stream is represented with `None`; it may be represented as a `Some`
-/// around an empty `Vec`.
-#[derive(Clone, Debug)]
-pub struct TokenStream(pub Option<Lrc<Vec<TreeAndJoint>>>);
+#[derive(Clone, Debug, Default)]
+pub struct TokenStream(pub Lrc<Vec<TreeAndJoint>>);
pub type TreeAndJoint = (TokenTree, IsJoint);
@@ -164,35 +158,33 @@
/// separating the two arguments with a comma for diagnostic suggestions.
pub(crate) fn add_comma(&self) -> Option<(TokenStream, Span)> {
// Used to suggest if a user writes `foo!(a b);`
- if let Some(ref stream) = self.0 {
- let mut suggestion = None;
- let mut iter = stream.iter().enumerate().peekable();
- while let Some((pos, ts)) = iter.next() {
- if let Some((_, next)) = iter.peek() {
- let sp = match (&ts, &next) {
- (_, (TokenTree::Token(Token { kind: token::Comma, .. }), _)) => continue,
- ((TokenTree::Token(token_left), NonJoint),
- (TokenTree::Token(token_right), _))
- if ((token_left.is_ident() && !token_left.is_reserved_ident())
- || token_left.is_lit()) &&
- ((token_right.is_ident() && !token_right.is_reserved_ident())
- || token_right.is_lit()) => token_left.span,
- ((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(),
- _ => continue,
- };
- let sp = sp.shrink_to_hi();
- let comma = (TokenTree::token(token::Comma, sp), NonJoint);
- suggestion = Some((pos, comma, sp));
- }
+ let mut suggestion = None;
+ let mut iter = self.0.iter().enumerate().peekable();
+ while let Some((pos, ts)) = iter.next() {
+ if let Some((_, next)) = iter.peek() {
+ let sp = match (&ts, &next) {
+ (_, (TokenTree::Token(Token { kind: token::Comma, .. }), _)) => continue,
+ ((TokenTree::Token(token_left), NonJoint),
+ (TokenTree::Token(token_right), _))
+ if ((token_left.is_ident() && !token_left.is_reserved_ident())
+ || token_left.is_lit()) &&
+ ((token_right.is_ident() && !token_right.is_reserved_ident())
+ || token_right.is_lit()) => token_left.span,
+ ((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(),
+ _ => continue,
+ };
+ let sp = sp.shrink_to_hi();
+ let comma = (TokenTree::token(token::Comma, sp), NonJoint);
+ suggestion = Some((pos, comma, sp));
}
- if let Some((pos, comma, sp)) = suggestion {
- let mut new_stream = vec![];
- let parts = stream.split_at(pos + 1);
- new_stream.extend_from_slice(parts.0);
- new_stream.push(comma);
- new_stream.extend_from_slice(parts.1);
- return Some((TokenStream::new(new_stream), sp));
- }
+ }
+ if let Some((pos, comma, sp)) = suggestion {
+ let mut new_stream = vec![];
+ let parts = self.0.split_at(pos + 1);
+ new_stream.extend_from_slice(parts.0);
+ new_stream.push(comma);
+ new_stream.extend_from_slice(parts.1);
+ return Some((TokenStream::new(new_stream), sp));
}
None
}
@@ -225,28 +217,21 @@
}
impl TokenStream {
- pub fn len(&self) -> usize {
- if let Some(ref slice) = self.0 {
- slice.len()
- } else {
- 0
- }
- }
-
- pub fn empty() -> TokenStream {
- TokenStream(None)
+ pub fn new(streams: Vec<TreeAndJoint>) -> TokenStream {
+ TokenStream(Lrc::new(streams))
}
pub fn is_empty(&self) -> bool {
- match self.0 {
- None => true,
- Some(ref stream) => stream.is_empty(),
- }
+ self.0.is_empty()
+ }
+
+ pub fn len(&self) -> usize {
+ self.0.len()
}
pub(crate) fn from_streams(mut streams: SmallVec<[TokenStream; 2]>) -> TokenStream {
match streams.len() {
- 0 => TokenStream::empty(),
+ 0 => TokenStream::default(),
1 => streams.pop().unwrap(),
_ => {
// We are going to extend the first stream in `streams` with
@@ -270,41 +255,24 @@
// Get the first stream. If it's `None`, create an empty
// stream.
let mut iter = streams.drain();
- let mut first_stream_lrc = match iter.next().unwrap().0 {
- Some(first_stream_lrc) => first_stream_lrc,
- None => Lrc::new(vec![]),
- };
+ let mut first_stream_lrc = iter.next().unwrap().0;
// Append the elements to the first stream, after reserving
// space for them.
let first_vec_mut = Lrc::make_mut(&mut first_stream_lrc);
first_vec_mut.reserve(num_appends);
for stream in iter {
- if let Some(stream) = stream.0 {
- first_vec_mut.extend(stream.iter().cloned());
- }
+ first_vec_mut.extend(stream.0.iter().cloned());
}
// Create the final `TokenStream`.
- match first_vec_mut.len() {
- 0 => TokenStream(None),
- _ => TokenStream(Some(first_stream_lrc)),
- }
+ TokenStream(first_stream_lrc)
}
}
}
- pub fn new(streams: Vec<TreeAndJoint>) -> TokenStream {
- match streams.len() {
- 0 => TokenStream(None),
- _ => TokenStream(Some(Lrc::new(streams))),
- }
- }
-
pub fn append_to_tree_and_joint_vec(self, vec: &mut Vec<TreeAndJoint>) {
- if let Some(stream) = self.0 {
- vec.extend(stream.iter().cloned());
- }
+ vec.extend(self.0.iter().cloned());
}
pub fn trees(&self) -> Cursor {
@@ -371,24 +339,22 @@
}
pub fn map_enumerated<F: FnMut(usize, TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream {
- TokenStream(self.0.map(|stream| {
- Lrc::new(
- stream
- .iter()
- .enumerate()
- .map(|(i, (tree, is_joint))| (f(i, tree.clone()), *is_joint))
- .collect())
- }))
+ TokenStream(Lrc::new(
+ self.0
+ .iter()
+ .enumerate()
+ .map(|(i, (tree, is_joint))| (f(i, tree.clone()), *is_joint))
+ .collect()
+ ))
}
pub fn map<F: FnMut(TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream {
- TokenStream(self.0.map(|stream| {
- Lrc::new(
- stream
- .iter()
- .map(|(tree, is_joint)| (f(tree.clone()), *is_joint))
- .collect())
- }))
+ TokenStream(Lrc::new(
+ self.0
+ .iter()
+ .map(|(tree, is_joint)| (f(tree.clone()), *is_joint))
+ .collect()
+ ))
}
}
@@ -406,44 +372,43 @@
// If `self` is not empty and the last tree within the last stream is a
// token tree marked with `Joint`...
- if let Some(TokenStream(Some(ref mut last_stream_lrc))) = self.0.last_mut() {
+ if let Some(TokenStream(ref mut last_stream_lrc)) = self.0.last_mut() {
if let Some((TokenTree::Token(last_token), Joint)) = last_stream_lrc.last() {
// ...and `stream` is not empty and the first tree within it is
// a token tree...
- if let TokenStream(Some(ref mut stream_lrc)) = stream {
- if let Some((TokenTree::Token(token), is_joint)) = stream_lrc.first() {
+ let TokenStream(ref mut stream_lrc) = stream;
+ if let Some((TokenTree::Token(token), is_joint)) = stream_lrc.first() {
- // ...and the two tokens can be glued together...
- if let Some(glued_tok) = last_token.glue(&token) {
+ // ...and the two tokens can be glued together...
+ if let Some(glued_tok) = last_token.glue(&token) {
- // ...then do so, by overwriting the last token
- // tree in `self` and removing the first token tree
- // from `stream`. This requires using `make_mut()`
- // on the last stream in `self` and on `stream`,
- // and in practice this doesn't cause cloning 99.9%
- // of the time.
+ // ...then do so, by overwriting the last token
+ // tree in `self` and removing the first token tree
+ // from `stream`. This requires using `make_mut()`
+ // on the last stream in `self` and on `stream`,
+ // and in practice this doesn't cause cloning 99.9%
+ // of the time.
- // Overwrite the last token tree with the merged
- // token.
- let last_vec_mut = Lrc::make_mut(last_stream_lrc);
- *last_vec_mut.last_mut().unwrap() =
- (TokenTree::Token(glued_tok), *is_joint);
+ // Overwrite the last token tree with the merged
+ // token.
+ let last_vec_mut = Lrc::make_mut(last_stream_lrc);
+ *last_vec_mut.last_mut().unwrap() =
+ (TokenTree::Token(glued_tok), *is_joint);
- // Remove the first token tree from `stream`. (This
- // is almost always the only tree in `stream`.)
- let stream_vec_mut = Lrc::make_mut(stream_lrc);
- stream_vec_mut.remove(0);
+ // Remove the first token tree from `stream`. (This
+ // is almost always the only tree in `stream`.)
+ let stream_vec_mut = Lrc::make_mut(stream_lrc);
+ stream_vec_mut.remove(0);
- // Don't push `stream` if it's empty -- that could
- // block subsequent token gluing, by getting
- // between two token trees that should be glued
- // together.
- if !stream.is_empty() {
- self.0.push(stream);
- }
- return;
+ // Don't push `stream` if it's empty -- that could
+ // block subsequent token gluing, by getting
+ // between two token trees that should be glued
+ // together.
+ if !stream.is_empty() {
+ self.0.push(stream);
}
+ return;
}
}
}
@@ -476,16 +441,11 @@
}
pub fn next_with_joint(&mut self) -> Option<TreeAndJoint> {
- match self.stream.0 {
- None => None,
- Some(ref stream) => {
- if self.index < stream.len() {
- self.index += 1;
- Some(stream[self.index - 1].clone())
- } else {
- None
- }
- }
+ if self.index < self.stream.len() {
+ self.index += 1;
+ Some(self.stream.0[self.index - 1].clone())
+ } else {
+ None
}
}
@@ -494,22 +454,13 @@
return;
}
let index = self.index;
- let stream = mem::replace(&mut self.stream, TokenStream(None));
+ let stream = mem::take(&mut self.stream);
*self = TokenStream::from_streams(smallvec![stream, new_stream]).into_trees();
self.index = index;
}
pub fn look_ahead(&self, n: usize) -> Option<TokenTree> {
- match self.stream.0 {
- None => None,
- Some(ref stream) => stream[self.index ..].get(n).map(|(tree, _)| tree.clone()),
- }
- }
-}
-
-impl fmt::Display for TokenStream {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- f.write_str(&pprust::tts_to_string(self.clone()))
+ self.stream.0[self.index ..].get(n).map(|(tree, _)| tree.clone())
}
}
diff --git a/src/libsyntax_ext/cmdline_attrs.rs b/src/libsyntax_ext/cmdline_attrs.rs
index 203c4a8..2c31597 100644
--- a/src/libsyntax_ext/cmdline_attrs.rs
+++ b/src/libsyntax_ext/cmdline_attrs.rs
@@ -3,7 +3,8 @@
use syntax::ast::{self, AttrItem, AttrStyle};
use syntax::attr::mk_attr;
use syntax::panictry;
-use syntax::parse::{self, token, ParseSess};
+use syntax::parse::{self, token};
+use syntax::sess::ParseSess;
use syntax_pos::FileName;
pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate {
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index abdcb6c..9c3ec06 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -190,8 +190,8 @@
use syntax::source_map::respan;
use syntax::util::map_in_place::MapInPlace;
use syntax::ptr::P;
+use syntax::sess::ParseSess;
use syntax::symbol::{Symbol, kw, sym};
-use syntax::parse::ParseSess;
use syntax_pos::{Span};
use ty::{LifetimeBounds, Path, Ptr, PtrTy, Self_, Ty};
diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs
index 315babc..62c7e18 100644
--- a/src/libsyntax_ext/plugin_macro_defs.rs
+++ b/src/libsyntax_ext/plugin_macro_defs.rs
@@ -20,7 +20,7 @@
attr::mk_word_item(Ident::new(sym::rustc_builtin_macro, span)));
let parens: TreeAndJoint = TokenTree::Delimited(
- DelimSpan::from_single(span), token::Paren, TokenStream::empty()
+ DelimSpan::from_single(span), token::Paren, TokenStream::default()
).into();
let trees = vec![parens.clone(), TokenTree::token(token::FatArrow, span).into(), parens];
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index 9b53bcb..1b70688 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -6,8 +6,9 @@
use syntax::ext::base::ExtCtxt;
use syntax::ext::expand::{AstFragment, ExpansionConfig};
use syntax::ext::proc_macro::is_proc_macro_attr;
-use syntax::parse::ParseSess;
+use syntax::print::pprust;
use syntax::ptr::P;
+use syntax::sess::ParseSess;
use syntax::symbol::{kw, sym};
use syntax::visit::{self, Visitor};
use syntax_pos::{Span, DUMMY_SP};
@@ -248,13 +249,20 @@
for attr in &item.attrs {
if is_proc_macro_attr(&attr) {
if let Some(prev_attr) = found_attr {
+ let path_str = pprust::path_to_string(&attr.path);
let msg = if attr.path.segments[0].ident.name ==
prev_attr.path.segments[0].ident.name {
- format!("only one `#[{}]` attribute is allowed on any given function",
- attr.path)
+ format!(
+ "only one `#[{}]` attribute is allowed on any given function",
+ path_str,
+ )
} else {
- format!("`#[{}]` and `#[{}]` attributes cannot both be applied \
- to the same function", attr.path, prev_attr.path)
+ format!(
+ "`#[{}]` and `#[{}]` attributes cannot both be applied
+ to the same function",
+ path_str,
+ pprust::path_to_string(&prev_attr.path),
+ )
};
self.handler.struct_span_err(attr.span, &msg)
@@ -280,8 +288,10 @@
};
if !is_fn {
- let msg = format!("the `#[{}]` attribute may only be used on bare functions",
- attr.path);
+ let msg = format!(
+ "the `#[{}]` attribute may only be used on bare functions",
+ pprust::path_to_string(&attr.path),
+ );
self.handler.span_err(attr.span, &msg);
return;
@@ -292,8 +302,10 @@
}
if !self.is_proc_macro_crate {
- let msg = format!("the `#[{}]` attribute is only usable with crates of the \
- `proc-macro` crate type", attr.path);
+ let msg = format!(
+ "the `#[{}]` attribute is only usable with crates of the `proc-macro` crate type",
+ pprust::path_to_string(&attr.path),
+ );
self.handler.span_err(attr.span, &msg);
return;
diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs
index c577b1e..4f17acf 100644
--- a/src/libsyntax_ext/standard_library_imports.rs
+++ b/src/libsyntax_ext/standard_library_imports.rs
@@ -3,8 +3,8 @@
use syntax::ext::expand::ExpansionConfig;
use syntax::ext::hygiene::AstPass;
use syntax::ext::base::{ExtCtxt, Resolver};
-use syntax::parse::ParseSess;
use syntax::ptr::P;
+use syntax::sess::ParseSess;
use syntax::symbol::{Ident, Symbol, kw, sym};
use syntax_pos::DUMMY_SP;
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index f79ad14..0bb279c 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -10,8 +10,8 @@
use syntax::ext::expand::{AstFragment, ExpansionConfig};
use syntax::feature_gate::Features;
use syntax::mut_visit::{*, ExpectOne};
-use syntax::parse::ParseSess;
use syntax::ptr::P;
+use syntax::sess::ParseSess;
use syntax::source_map::respan;
use syntax::symbol::{sym, Symbol};
use syntax_pos::{Span, DUMMY_SP};
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 30ee9b9..7f7c5cb 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -12,7 +12,7 @@
#![feature(non_exhaustive)]
#![feature(optin_builtin_traits)]
#![feature(rustc_attrs)]
-#![feature(proc_macro_hygiene)]
+#![cfg_attr(bootstrap, feature(proc_macro_hygiene))]
#![feature(specialization)]
#![feature(step_trait)]
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index c37efde..8845b66 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -808,25 +808,13 @@
Ident::new(self.name, self.span.modern_and_legacy())
}
- /// Transforms an underscore identifier into one with the same name, but
- /// gensymed. Leaves non-underscore identifiers unchanged.
- pub fn gensym_if_underscore(self) -> Ident {
- if self.name == kw::Underscore {
- let name = with_interner(|interner| interner.gensymed(self.name));
- Ident::new(name, self.span)
- } else {
- self
- }
- }
-
/// Convert the name to a `LocalInternedString`. This is a slowish
/// operation because it requires locking the symbol interner.
pub fn as_str(self) -> LocalInternedString {
self.name.as_str()
}
- /// Convert the name to an `InternedString`. This is a slowish operation
- /// because it requires locking the symbol interner.
+ /// Convert the name to an `InternedString`.
pub fn as_interned_str(self) -> InternedString {
self.name.as_interned_str()
}
@@ -881,26 +869,9 @@
}
}
-/// A symbol is an interned or gensymed string. A gensym is a symbol that is
-/// never equal to any other symbol.
+/// An interned string.
///
-/// Conceptually, a gensym can be thought of as a normal symbol with an
-/// invisible unique suffix. Gensyms are useful when creating new identifiers
-/// that must not match any existing identifiers, e.g. during macro expansion
-/// and syntax desugaring. Because gensyms should always be identifiers, all
-/// gensym operations are on `Ident` rather than `Symbol`. (Indeed, in the
-/// future the gensym-ness may be moved from `Symbol` to hygiene data.)
-///
-/// Examples:
-/// ```
-/// assert_eq!(Ident::from_str("_"), Ident::from_str("_"))
-/// assert_ne!(Ident::from_str("_").gensym_if_underscore(), Ident::from_str("_"))
-/// assert_ne!(
-/// Ident::from_str("_").gensym_if_underscore(),
-/// Ident::from_str("_").gensym_if_underscore(),
-/// )
-/// ```
-/// Internally, a symbol is implemented as an index, and all operations
+/// Internally, a `Symbol` is implemented as an index, and all operations
/// (including hashing, equality, and ordering) operate on that index. The use
/// of `rustc_index::newtype_index!` means that `Option<Symbol>` only takes up 4 bytes,
/// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes.
@@ -951,12 +922,9 @@
})
}
- /// Convert to an `InternedString`. This is a slowish operation because it
- /// requires locking the symbol interner.
+ /// Convert to an `InternedString`.
pub fn as_interned_str(self) -> InternedString {
- with_interner(|interner| InternedString {
- symbol: interner.interned(self)
- })
+ InternedString { symbol: self }
}
pub fn as_u32(self) -> u32 {
@@ -966,12 +934,7 @@
impl fmt::Debug for Symbol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let is_gensymed = with_interner(|interner| interner.is_gensymed(*self));
- if is_gensymed {
- write!(f, "{}({:?})", self, self.0)
- } else {
- write!(f, "{}", self)
- }
+ fmt::Display::fmt(self, f)
}
}
@@ -994,15 +957,11 @@
}
// The `&'static str`s in this type actually point into the arena.
-//
-// Note that normal symbols are indexed upward from 0, and gensyms are indexed
-// downward from SymbolIndex::MAX_AS_U32.
#[derive(Default)]
pub struct Interner {
arena: DroplessArena,
names: FxHashMap<&'static str, Symbol>,
strings: Vec<&'static str>,
- gensyms: Vec<Symbol>,
}
impl Interner {
@@ -1035,34 +994,10 @@
self.names.insert(string, name);
name
}
-
- fn interned(&self, symbol: Symbol) -> Symbol {
- if (symbol.0.as_usize()) < self.strings.len() {
- symbol
- } else {
- self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize]
- }
- }
-
- fn gensymed(&mut self, symbol: Symbol) -> Symbol {
- self.gensyms.push(symbol);
- Symbol::new(SymbolIndex::MAX_AS_U32 - self.gensyms.len() as u32 + 1)
- }
-
- fn is_gensymed(&mut self, symbol: Symbol) -> bool {
- symbol.0.as_usize() >= self.strings.len()
- }
-
// Get the symbol as a string. `Symbol::as_str()` should be used in
// preference to this function.
pub fn get(&self, symbol: Symbol) -> &str {
- match self.strings.get(symbol.0.as_usize()) {
- Some(string) => string,
- None => {
- let symbol = self.gensyms[(SymbolIndex::MAX_AS_U32 - symbol.0.as_u32()) as usize];
- self.strings[symbol.0.as_usize()]
- }
- }
+ self.strings[symbol.0.as_usize()]
}
}
@@ -1202,30 +1137,6 @@
}
}
-impl std::cmp::PartialEq<LocalInternedString> for str {
- fn eq(&self, other: &LocalInternedString) -> bool {
- self == other.string
- }
-}
-
-impl<'a> std::cmp::PartialEq<LocalInternedString> for &'a str {
- fn eq(&self, other: &LocalInternedString) -> bool {
- *self == other.string
- }
-}
-
-impl std::cmp::PartialEq<LocalInternedString> for String {
- fn eq(&self, other: &LocalInternedString) -> bool {
- self == other.string
- }
-}
-
-impl<'a> std::cmp::PartialEq<LocalInternedString> for &'a String {
- fn eq(&self, other: &LocalInternedString) -> bool {
- *self == other.string
- }
-}
-
impl !Send for LocalInternedString {}
impl !Sync for LocalInternedString {}
@@ -1247,19 +1158,12 @@
}
}
-/// An alternative to `Symbol` that is focused on string contents. It has two
-/// main differences to `Symbol`.
+/// An alternative to `Symbol` that is focused on string contents.
///
-/// First, its implementations of `Hash`, `PartialOrd` and `Ord` work with the
+/// Its implementations of `Hash`, `PartialOrd` and `Ord` work with the
/// string chars rather than the symbol integer. This is useful when hash
/// stability is required across compile sessions, or a guaranteed sort
/// ordering is required.
-///
-/// Second, gensym-ness is irrelevant. E.g.:
-/// ```
-/// assert_ne!(Symbol::gensym("x"), Symbol::gensym("x"))
-/// assert_eq!(Symbol::gensym("x").as_interned_str(), Symbol::gensym("x").as_interned_str())
-/// ```
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct InternedString {
symbol: Symbol,
diff --git a/src/libsyntax_pos/symbol/tests.rs b/src/libsyntax_pos/symbol/tests.rs
index 1b91c9b..f74b9a0 100644
--- a/src/libsyntax_pos/symbol/tests.rs
+++ b/src/libsyntax_pos/symbol/tests.rs
@@ -14,13 +14,6 @@
assert_eq!(i.intern("cat"), Symbol::new(1));
// dog is still at zero
assert_eq!(i.intern("dog"), Symbol::new(0));
- let z = i.intern("zebra");
- assert_eq!(i.gensymed(z), Symbol::new(SymbolIndex::MAX_AS_U32));
- // gensym of same string gets new number:
- assert_eq!(i.gensymed(z), Symbol::new(SymbolIndex::MAX_AS_U32 - 1));
- // gensym of *existing* string gets new number:
- let d = i.intern("dog");
- assert_eq!(i.gensymed(d), Symbol::new(SymbolIndex::MAX_AS_U32 - 2));
}
#[test]
diff --git a/src/test/ui-fulldeps/ast_stmt_expr_attr.rs b/src/test/ui-fulldeps/ast_stmt_expr_attr.rs
index 6c5f539..5479119 100644
--- a/src/test/ui-fulldeps/ast_stmt_expr_attr.rs
+++ b/src/test/ui-fulldeps/ast_stmt_expr_attr.rs
@@ -10,9 +10,10 @@
use syntax::ast::*;
use syntax::attr::*;
use syntax::ast;
+use syntax::sess::ParseSess;
use syntax::source_map::{FilePathMapping, FileName};
use syntax::parse;
-use syntax::parse::{ParseSess, PResult};
+use syntax::parse::PResult;
use syntax::parse::new_parser_from_source_str;
use syntax::parse::parser::Parser;
use syntax::parse::token;
diff --git a/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs b/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs
index 8631bcc..ac97ec7 100644
--- a/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs
+++ b/src/test/ui-fulldeps/mod_dir_path_canonicalized.rs
@@ -7,8 +7,9 @@
extern crate syntax;
use std::path::Path;
+use syntax::sess::ParseSess;
use syntax::source_map::FilePathMapping;
-use syntax::parse::{self, ParseSess};
+use syntax::parse;
#[path = "mod_dir_simple/test.rs"]
mod gravy;
diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index d4aff73..932a173 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -24,14 +24,14 @@
use rustc_data_structures::thin_vec::ThinVec;
use syntax::ast::*;
+use syntax::sess::ParseSess;
use syntax::source_map::{Spanned, DUMMY_SP, FileName};
use syntax::source_map::FilePathMapping;
use syntax::mut_visit::{self, MutVisitor, visit_clobber};
-use syntax::parse::{self, ParseSess};
+use syntax::parse;
use syntax::print::pprust;
use syntax::ptr::P;
-
fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
let src_as_string = src.to_string();
diff --git a/src/test/ui/associated-const/associated-const-impl-wrong-lifetime.stderr b/src/test/ui/associated-const/associated-const-impl-wrong-lifetime.stderr
index c213cfe..2ceab39 100644
--- a/src/test/ui/associated-const/associated-const-impl-wrong-lifetime.stderr
+++ b/src/test/ui/associated-const/associated-const-impl-wrong-lifetime.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `&'static str`
found type `&'a str`
-note: the lifetime 'a as defined on the impl at 6:6...
+note: the lifetime `'a` as defined on the impl at 6:6...
--> $DIR/associated-const-impl-wrong-lifetime.rs:6:6
|
LL | impl<'a> Foo for &'a () {
diff --git a/src/test/ui/associated-item/issue-48027.rs b/src/test/ui/associated-item/issue-48027.rs
new file mode 100644
index 0000000..c9b4ccd
--- /dev/null
+++ b/src/test/ui/associated-item/issue-48027.rs
@@ -0,0 +1,8 @@
+trait Bar {
+ const X: usize;
+ fn return_n(&self) -> [u8; Bar::X]; //~ ERROR: type annotations needed
+}
+
+impl dyn Bar {} //~ ERROR: the trait `Bar` cannot be made into an object
+
+fn main() {}
diff --git a/src/test/ui/associated-item/issue-48027.stderr b/src/test/ui/associated-item/issue-48027.stderr
new file mode 100644
index 0000000..562146a
--- /dev/null
+++ b/src/test/ui/associated-item/issue-48027.stderr
@@ -0,0 +1,21 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/issue-48027.rs:6:6
+ |
+LL | const X: usize;
+ | - the trait cannot contain associated consts like `X`
+...
+LL | impl dyn Bar {}
+ | ^^^^^^^ the trait `Bar` cannot be made into an object
+
+error[E0283]: type annotations needed: cannot resolve `_: Bar`
+ --> $DIR/issue-48027.rs:3:32
+ |
+LL | const X: usize;
+ | --------------- required by `Bar::X`
+LL | fn return_n(&self) -> [u8; Bar::X];
+ | ^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0038, E0283.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
index 4309373..5ea98dc 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr
@@ -4,7 +4,7 @@
LL | bar(foo, x)
| ^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 37:8...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 37:8...
--> $DIR/project-fn-ret-contravariant.rs:37:8
|
LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
index b8b1a97..627609c 100644
--- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
+++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr
@@ -4,7 +4,7 @@
LL | bar(foo, x)
| ^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 44:8...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 44:8...
--> $DIR/project-fn-ret-invariant.rs:44:8
|
LL | fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {
diff --git a/src/test/ui/associated-types/issue-44153.rs b/src/test/ui/associated-types/issue-44153.rs
new file mode 100644
index 0000000..2101cb6
--- /dev/null
+++ b/src/test/ui/associated-types/issue-44153.rs
@@ -0,0 +1,19 @@
+pub trait Array {
+ type Element;
+}
+
+pub trait Visit {
+ fn visit() {}
+}
+
+impl Array for () {
+ type Element = ();
+}
+
+impl<'a> Visit for () where
+ (): Array<Element=&'a ()>,
+{}
+
+fn main() {
+ <() as Visit>::visit(); //~ ERROR: type mismatch resolving
+}
diff --git a/src/test/ui/associated-types/issue-44153.stderr b/src/test/ui/associated-types/issue-44153.stderr
new file mode 100644
index 0000000..b62a866
--- /dev/null
+++ b/src/test/ui/associated-types/issue-44153.stderr
@@ -0,0 +1,16 @@
+error[E0271]: type mismatch resolving `<() as Array>::Element == &()`
+ --> $DIR/issue-44153.rs:18:5
+ |
+LL | fn visit() {}
+ | ---------- required by `Visit::visit`
+...
+LL | <() as Visit>::visit();
+ | ^^^^^^^^^^^^^^^^^^^^ expected (), found &()
+ |
+ = note: expected type `()`
+ found type `&()`
+ = note: required because of the requirements on the impl of `Visit` for `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0271`.
diff --git a/src/test/ui/associated-types/issue-48010.rs b/src/test/ui/associated-types/issue-48010.rs
new file mode 100644
index 0000000..70e30c1
--- /dev/null
+++ b/src/test/ui/associated-types/issue-48010.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+#![crate_type = "lib"]
+
+pub struct Foo;
+
+pub struct Path<T: Bar> {
+ _inner: T::Slice,
+}
+
+pub trait Bar: Sized {
+ type Slice: ?Sized;
+
+ fn open(_: &Path<Self>);
+}
+
+impl Bar for Foo {
+ type Slice = [u8];
+
+ fn open(_: &Path<Self>) {
+ unimplemented!()
+ }
+}
diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr
index 5099297..efec160 100644
--- a/src/test/ui/async-await/issues/issue-63388-2.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-2.stderr
@@ -15,12 +15,12 @@
LL | foo
| --- this return type evaluates to the `'static` lifetime...
|
-note: ...can't outlive the lifetime '_ as defined on the method body at 11:14
+note: ...can't outlive the lifetime `'_` as defined on the method body at 11:14
--> $DIR/issue-63388-2.rs:11:14
|
LL | foo: &dyn Foo, bar: &'a dyn Foo
| ^
-help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 11:14
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'_` as defined on the method body at 11:14
|
LL | foo + '_
|
diff --git a/src/test/ui/async-await/issues/issue-65159.rs b/src/test/ui/async-await/issues/issue-65159.rs
new file mode 100644
index 0000000..b5fee06
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-65159.rs
@@ -0,0 +1,10 @@
+// Regression test for #65159. We used to ICE.
+//
+// edition:2018
+
+async fn copy() -> Result<()> //~ ERROR wrong number of type arguments
+{
+ Ok(())
+}
+
+fn main() { }
diff --git a/src/test/ui/async-await/issues/issue-65159.stderr b/src/test/ui/async-await/issues/issue-65159.stderr
new file mode 100644
index 0000000..56d2c38
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-65159.stderr
@@ -0,0 +1,9 @@
+error[E0107]: wrong number of type arguments: expected 2, found 1
+ --> $DIR/issue-65159.rs:5:20
+ |
+LL | async fn copy() -> Result<()>
+ | ^^^^^^^^^^ expected 2 type arguments
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/async-await/unused-lifetime.rs b/src/test/ui/async-await/unused-lifetime.rs
new file mode 100644
index 0000000..1cf546b
--- /dev/null
+++ b/src/test/ui/async-await/unused-lifetime.rs
@@ -0,0 +1,42 @@
+// edition:2018
+
+// Avoid spurious warnings of unused lifetime. The below async functions
+// are desugered to have an unused lifetime
+// but we don't want to warn about that as there's nothing they can do about it.
+
+#![deny(unused_lifetimes)]
+#![allow(dead_code)]
+
+pub async fn october(s: &str) {
+ println!("{}", s);
+}
+
+pub async fn async_fn(&mut ref s: &mut[i32]) {
+ println!("{:?}", s);
+}
+
+macro_rules! foo_macro {
+ () => {
+ pub async fn async_fn_in_macro(&mut ref _s: &mut[i32]) {}
+ };
+}
+
+foo_macro!();
+
+pub async fn func_with_unused_lifetime<'a>(s: &'a str) {
+ //~^ ERROR lifetime parameter `'a` never used
+ println!("{}", s);
+}
+
+pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
+ //~^ ERROR lifetime parameter `'a` never used
+ //~^^ ERROR lifetime parameter `'b` never used
+ println!("{}", s);
+}
+
+pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) {
+ //~^ ERROR lifetime parameter `'c` never used
+ println!("{}", s);
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/unused-lifetime.stderr b/src/test/ui/async-await/unused-lifetime.stderr
new file mode 100644
index 0000000..885cdc0
--- /dev/null
+++ b/src/test/ui/async-await/unused-lifetime.stderr
@@ -0,0 +1,32 @@
+error: lifetime parameter `'a` never used
+ --> $DIR/unused-lifetime.rs:26:40
+ |
+LL | pub async fn func_with_unused_lifetime<'a>(s: &'a str) {
+ | ^^
+ |
+note: lint level defined here
+ --> $DIR/unused-lifetime.rs:7:9
+ |
+LL | #![deny(unused_lifetimes)]
+ | ^^^^^^^^^^^^^^^^
+
+error: lifetime parameter `'a` never used
+ --> $DIR/unused-lifetime.rs:31:44
+ |
+LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
+ | ^^
+
+error: lifetime parameter `'b` never used
+ --> $DIR/unused-lifetime.rs:31:48
+ |
+LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
+ | ^^
+
+error: lifetime parameter `'c` never used
+ --> $DIR/unused-lifetime.rs:37:54
+ |
+LL | pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) {
+ | ^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
index 4c7c0d1..52d43ea 100644
--- a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
+++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
@@ -24,12 +24,12 @@
|
= note: expected type `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'d>)`
found type `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'d>)`
-note: the lifetime 'c as defined on the method body at 27:24...
+note: the lifetime `'c` as defined on the method body at 27:24...
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
|
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
| ^^
-note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 27:24
+note: ...does not necessarily outlive the lifetime `'c` as defined on the method body at 27:24
--> $DIR/regions-bound-missing-bound-in-impl.rs:27:24
|
LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr
index 3d552f8..0553565 100644
--- a/src/test/ui/c-variadic/variadic-ffi-4.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr
@@ -14,7 +14,7 @@
LL | | ap
LL | | }
| |_^
-note: ...does not necessarily outlive the lifetime 'f as defined on the function body at 7:37
+note: ...does not necessarily outlive the lifetime `'f` as defined on the function body at 7:37
--> $DIR/variadic-ffi-4.rs:7:37
|
LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> {
diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
index ac4666f..8af7f88 100644
--- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
@@ -11,7 +11,7 @@
|
LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
| ^^^^^^^^^^^^^^^^^^^^^^
-note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 11:36
+note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 11:36
--> $DIR/expect-fn-supply-fn.rs:11:36
|
LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
@@ -25,7 +25,7 @@
|
= note: expected type `fn(&u32)`
found type `fn(&'x u32)`
-note: the lifetime 'x as defined on the function body at 11:36...
+note: the lifetime `'x` as defined on the function body at 11:36...
--> $DIR/expect-fn-supply-fn.rs:11:36
|
LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) {
diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr
index e3b623d..9f74738 100644
--- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr
+++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr
@@ -38,7 +38,7 @@
LL | |
LL | | });
| |_____^
-note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 32:30
+note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 32:30
--> $DIR/expect-region-supply-region.rs:32:30
|
LL | fn expect_bound_supply_named<'x>() {
@@ -52,7 +52,7 @@
|
= note: expected type `&u32`
found type `&'x u32`
-note: the lifetime 'x as defined on the function body at 32:30...
+note: the lifetime `'x` as defined on the function body at 32:30...
--> $DIR/expect-region-supply-region.rs:32:30
|
LL | fn expect_bound_supply_named<'x>() {
diff --git a/src/test/ui/const-generics/auxiliary/const_generic_lib.rs b/src/test/ui/const-generics/auxiliary/const_generic_lib.rs
new file mode 100644
index 0000000..901fb5d
--- /dev/null
+++ b/src/test/ui/const-generics/auxiliary/const_generic_lib.rs
@@ -0,0 +1,9 @@
+#![feature(const_generics)]
+
+pub struct Struct<const N: usize>(pub [u8; N]);
+
+pub type Alias = Struct<2>;
+
+pub fn function(value: Struct<3>) -> u8 {
+ value.0[0]
+}
diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs
new file mode 100644
index 0000000..d863d09
--- /dev/null
+++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs
@@ -0,0 +1,10 @@
+// aux-build:const_generic_lib.rs
+
+extern crate const_generic_lib;
+
+fn main() {
+ let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
+ //~^ ERROR mismatched types
+ let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
+ //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr
new file mode 100644
index 0000000..b7fd29c
--- /dev/null
+++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+ --> $DIR/const-argument-cross-crate-mismatch.rs:6:41
+ |
+LL | let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8]));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `3usize`, found `2usize`
+ |
+ = note: expected type `const_generic_lib::Struct<3usize>`
+ found type `const_generic_lib::Struct<_: usize>`
+
+error[E0308]: mismatched types
+ --> $DIR/const-argument-cross-crate-mismatch.rs:8:39
+ |
+LL | let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2usize`, found `3usize`
+ |
+ = note: expected type `const_generic_lib::Struct<2usize>`
+ found type `const_generic_lib::Struct<_: usize>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/const-argument-cross-crate.rs b/src/test/ui/const-generics/const-argument-cross-crate.rs
new file mode 100644
index 0000000..98cf39a
--- /dev/null
+++ b/src/test/ui/const-generics/const-argument-cross-crate.rs
@@ -0,0 +1,12 @@
+// run-pass
+// aux-build:const_generic_lib.rs
+
+extern crate const_generic_lib;
+
+struct Container(const_generic_lib::Alias);
+
+fn main() {
+ let res = const_generic_lib::function(const_generic_lib::Struct([14u8, 1u8, 2u8]));
+ assert_eq!(res, 14u8);
+ let _ = Container(const_generic_lib::Struct([0u8, 1u8]));
+}
diff --git a/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr b/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr
index fddb069..32cf8d8 100644
--- a/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr
+++ b/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr
@@ -10,7 +10,7 @@
--> $DIR/const-parameter-uppercase-lint.rs:6:15
|
LL | fn noop<const x: u32>() {
- | ^ help: convert the identifier to upper case: `X`
+ | ^ help: convert the identifier to upper case (notice the capitalization): `X`
|
note: lint level defined here
--> $DIR/const-parameter-uppercase-lint.rs:4:9
diff --git a/src/test/ui/consts/issue-64506.rs b/src/test/ui/consts/issue-64506.rs
new file mode 100644
index 0000000..db3e85a
--- /dev/null
+++ b/src/test/ui/consts/issue-64506.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+#[derive(Copy, Clone)]
+pub struct ChildStdin {
+ inner: AnonPipe,
+}
+
+#[derive(Copy, Clone)]
+enum AnonPipe {}
+
+const FOO: () = {
+ union Foo {
+ a: ChildStdin,
+ b: (),
+ }
+ let x = unsafe { Foo { b: () }.a };
+ let x = &x.inner;
+};
+
+fn main() {}
diff --git a/src/test/ui/consts/issue-65348.rs b/src/test/ui/consts/issue-65348.rs
new file mode 100644
index 0000000..5eafa83
--- /dev/null
+++ b/src/test/ui/consts/issue-65348.rs
@@ -0,0 +1,23 @@
+// check-pass
+
+struct Generic<T>(T);
+
+impl<T> Generic<T> {
+ const ARRAY: [T; 0] = [];
+ const NEWTYPE_ARRAY: Generic<[T; 0]> = Generic([]);
+ const ARRAY_FIELD: Generic<(i32, [T; 0])> = Generic((0, []));
+}
+
+pub const fn array<T>() -> &'static T {
+ &Generic::<T>::ARRAY[0]
+}
+
+pub const fn newtype_array<T>() -> &'static T {
+ &Generic::<T>::NEWTYPE_ARRAY.0[0]
+}
+
+pub const fn array_field<T>() -> &'static T {
+ &(Generic::<T>::ARRAY_FIELD.0).1[0]
+}
+
+fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr
index d8826d4..ef68bf5 100644
--- a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr
+++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr
@@ -55,7 +55,7 @@
| ^^^^^^^^^^^^^^^^^^^
LL | let z = ManyVariants::Four();
| ^^^^^^^^^^^^^^^^^^
-and 6 other candidates
+ and 6 other candidates
error: aborting due to 5 previous errors
diff --git a/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr
index 8d3a86d..cb350a1 100644
--- a/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr
+++ b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr
@@ -13,7 +13,7 @@
| ^^^^^^^^^
LL | fn setup() -> PutDown { Set }
| ^^^^^^^
-and 3 other candidates
+ and 3 other candidates
error[E0425]: cannot find value `Set` in this scope
--> $DIR/issue-56028-there-is-an-enum-variant.rs:9:21
@@ -30,7 +30,7 @@
|
LL | use PutDown::Set;
|
-and 3 other candidates
+ and 3 other candidates
error: aborting due to 2 previous errors
diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr
index ce631ca..754006b 100644
--- a/src/test/ui/error-codes/E0423.stderr
+++ b/src/test/ui/error-codes/E0423.stderr
@@ -34,7 +34,7 @@
| ^^^
| |
| did you mean `Foo { /* fields */ }`?
- | help: a function with a similar name exists: `foo`
+ | help: a function with a similar name exists (notice the capitalization): `foo`
error[E0423]: expected value, found struct `T`
--> $DIR/E0423.rs:14:8
diff --git a/src/test/ui/error-codes/E0478.stderr b/src/test/ui/error-codes/E0478.stderr
index 587125f..1380840 100644
--- a/src/test/ui/error-codes/E0478.stderr
+++ b/src/test/ui/error-codes/E0478.stderr
@@ -4,12 +4,12 @@
LL | child: Box<dyn Wedding<'kiss> + 'SnowWhite>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: lifetime parameter instantiated with the lifetime 'SnowWhite as defined on the struct at 3:22
+note: lifetime parameter instantiated with the lifetime `'SnowWhite` as defined on the struct at 3:22
--> $DIR/E0478.rs:3:22
|
LL | struct Prince<'kiss, 'SnowWhite> {
| ^^^^^^^^^^
-note: but lifetime parameter must outlive the lifetime 'kiss as defined on the struct at 3:15
+note: but lifetime parameter must outlive the lifetime `'kiss` as defined on the struct at 3:15
--> $DIR/E0478.rs:3:15
|
LL | struct Prince<'kiss, 'SnowWhite> {
diff --git a/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr b/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr
index 4bf2d57..cbd6422 100644
--- a/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr
+++ b/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `Foo<'a, 'b>`
found type `Foo<'b, 'a>`
-note: the lifetime 'b as defined on the impl at 6:9...
+note: the lifetime `'b` as defined on the impl at 6:9...
--> $DIR/explicit-self-lifetime-mismatch.rs:6:9
|
LL | impl<'a,'b> Foo<'a,'b> {
| ^^
-note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 6:6
+note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 6:6
--> $DIR/explicit-self-lifetime-mismatch.rs:6:6
|
LL | impl<'a,'b> Foo<'a,'b> {
@@ -25,12 +25,12 @@
|
= note: expected type `Foo<'a, 'b>`
found type `Foo<'b, 'a>`
-note: the lifetime 'a as defined on the impl at 6:6...
+note: the lifetime `'a` as defined on the impl at 6:6...
--> $DIR/explicit-self-lifetime-mismatch.rs:6:6
|
LL | impl<'a,'b> Foo<'a,'b> {
| ^^
-note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 6:9
+note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 6:9
--> $DIR/explicit-self-lifetime-mismatch.rs:6:9
|
LL | impl<'a,'b> Foo<'a,'b> {
diff --git a/src/test/ui/expr_attr_paren_order.stderr b/src/test/ui/expr_attr_paren_order.stderr
index 89f615f..57a9350 100644
--- a/src/test/ui/expr_attr_paren_order.stderr
+++ b/src/test/ui/expr_attr_paren_order.stderr
@@ -2,7 +2,7 @@
--> $DIR/expr_attr_paren_order.rs:19:17
|
LL | let X = 0;
- | ^ help: convert the identifier to snake case: `x`
+ | ^ help: convert the identifier to snake case (notice the capitalization): `x`
|
note: lint level defined here
--> $DIR/expr_attr_paren_order.rs:17:17
diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr
deleted file mode 100644
index d77fbc1..0000000
--- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0005]: refutable pattern in local binding: `Err(_)` not covered
- --> $DIR/feature-gate-exhaustive-patterns.rs:7:9
- |
-LL | let Ok(_x) = foo();
- | ^^^^^^ pattern `Err(_)` not covered
- |
- = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
- = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
-help: you might want to use `if let` to ignore the variant that isn't matched
- |
-LL | if let Ok(_x) = foo() { /* */ }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0005`.
diff --git a/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs b/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs
new file mode 100644
index 0000000..54b483f
--- /dev/null
+++ b/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.rs
@@ -0,0 +1,14 @@
+#![crate_type="lib"]
+
+struct Nested<K>(K);
+
+fn should_error<T>() where T : Into<&u32> {}
+//~^ ERROR `&` without an explicit lifetime name cannot be used here [E0637]
+
+trait X<'a, K: 'a> {
+ fn foo<'b, L: X<&'b Nested<K>>>();
+ //~^ ERROR missing lifetime specifier [E0106]
+}
+
+fn bar<'b, L: X<&'b Nested<i32>>>(){}
+//~^ ERROR missing lifetime specifier [E0106]
diff --git a/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr b/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr
new file mode 100644
index 0000000..8720288
--- /dev/null
+++ b/src/test/ui/generics/issue-65285-incorrect-explicit-lifetime-name-needed.stderr
@@ -0,0 +1,21 @@
+error[E0637]: `&` without an explicit lifetime name cannot be used here
+ --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:5:37
+ |
+LL | fn should_error<T>() where T : Into<&u32> {}
+ | ^ explicit lifetime name needed here
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:9:19
+ |
+LL | fn foo<'b, L: X<&'b Nested<K>>>();
+ | ^^^^^^^^^^^^^^^^ expected lifetime parameter
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:13:15
+ |
+LL | fn bar<'b, L: X<&'b Nested<i32>>>(){}
+ | ^^^^^^^^^^^^^^^^^^ expected lifetime parameter
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr
index 979f64f..76d97dd 100644
--- a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr
+++ b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr
@@ -10,7 +10,7 @@
|
= note: expected type `std::option::Option<fn(Inv<'y>)>`
found type `std::option::Option<fn(Inv<'x>)>`
-note: the lifetime 'x as defined on the function body at 32:20...
+note: the lifetime `'x` as defined on the function body at 32:20...
--> $DIR/hr-subtype.rs:32:20
|
LL | fn subtype<'x,'y:'x,'z:'y>() {
@@ -19,7 +19,7 @@
LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
LL | | fn(Inv<'y>)) }
| |__________________________________________________- in this macro invocation
-note: ...does not necessarily outlive the lifetime 'y as defined on the function body at 32:23
+note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 32:23
--> $DIR/hr-subtype.rs:32:23
|
LL | fn subtype<'x,'y:'x,'z:'y>() {
@@ -41,7 +41,7 @@
|
= note: expected type `std::option::Option<fn(Inv<'x>)>`
found type `std::option::Option<fn(Inv<'y>)>`
-note: the lifetime 'x as defined on the function body at 38:22...
+note: the lifetime `'x` as defined on the function body at 38:22...
--> $DIR/hr-subtype.rs:38:22
|
LL | fn supertype<'x,'y:'x,'z:'y>() {
@@ -50,7 +50,7 @@
LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>),
LL | | fn(Inv<'y>)) }
| |__________________________________________________- in this macro invocation
-note: ...does not necessarily outlive the lifetime 'y as defined on the function body at 38:25
+note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 38:25
--> $DIR/hr-subtype.rs:38:25
|
LL | fn supertype<'x,'y:'x,'z:'y>() {
diff --git a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr
index 3b6aff5..74f4212 100644
--- a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr
+++ b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr
@@ -10,7 +10,7 @@
|
= note: expected type `std::option::Option<fn(&'x u32)>`
found type `std::option::Option<fn(&'y u32)>`
-note: the lifetime 'x as defined on the function body at 38:22...
+note: the lifetime `'x` as defined on the function body at 38:22...
--> $DIR/hr-subtype.rs:38:22
|
LL | fn supertype<'x,'y:'x,'z:'y>() {
@@ -19,7 +19,7 @@
LL | / check! { free_x_vs_free_y: (fn(&'x u32),
LL | | fn(&'y u32)) }
| |__________________________________________- in this macro invocation
-note: ...does not necessarily outlive the lifetime 'y as defined on the function body at 38:25
+note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 38:25
--> $DIR/hr-subtype.rs:38:25
|
LL | fn supertype<'x,'y:'x,'z:'y>() {
diff --git a/src/test/ui/hygiene/globs.stderr b/src/test/ui/hygiene/globs.stderr
index 7e0f4e4..7acb266 100644
--- a/src/test/ui/hygiene/globs.stderr
+++ b/src/test/ui/hygiene/globs.stderr
@@ -34,7 +34,7 @@
|
LL | use foo::test::g;
|
-and 2 other candidates
+ and 2 other candidates
error[E0425]: cannot find function `f` in this scope
--> $DIR/globs.rs:61:12
diff --git a/src/test/ui/hygiene/rustc-macro-transparency.stderr b/src/test/ui/hygiene/rustc-macro-transparency.stderr
index 5eacfdf..45a2efe 100644
--- a/src/test/ui/hygiene/rustc-macro-transparency.stderr
+++ b/src/test/ui/hygiene/rustc-macro-transparency.stderr
@@ -2,7 +2,7 @@
--> $DIR/rustc-macro-transparency.rs:26:5
|
LL | Opaque;
- | ^^^^^^ help: a local variable with a similar name exists: `opaque`
+ | ^^^^^^ help: a local variable with a similar name exists (notice the capitalization): `opaque`
error[E0423]: expected value, found macro `semitransparent`
--> $DIR/rustc-macro-transparency.rs:29:5
diff --git a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr
index af120fa..5e80c67 100644
--- a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr
+++ b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr
@@ -4,7 +4,7 @@
LL | static_val(x);
| ^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 19:26...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 19:26...
--> $DIR/dyn-trait.rs:19:26
|
LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
diff --git a/src/test/ui/impl-trait/hidden-lifetimes.stderr b/src/test/ui/impl-trait/hidden-lifetimes.stderr
index 6501617..956ac1f 100644
--- a/src/test/ui/impl-trait/hidden-lifetimes.stderr
+++ b/src/test/ui/impl-trait/hidden-lifetimes.stderr
@@ -4,7 +4,7 @@
LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a {
| ^^^^^^^^^^^^^^
|
-note: hidden type `&'a mut &'b T` captures the lifetime 'b as defined on the function body at 28:17
+note: hidden type `&'a mut &'b T` captures the lifetime `'b` as defined on the function body at 28:17
--> $DIR/hidden-lifetimes.rs:28:17
|
LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a {
@@ -16,7 +16,7 @@
LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {
| ^^^^^^^^^^^^^^
|
-note: hidden type `std::rc::Rc<std::cell::RefCell<&'b T>>` captures the lifetime 'b as defined on the function body at 45:24
+note: hidden type `std::rc::Rc<std::cell::RefCell<&'b T>>` captures the lifetime `'b` as defined on the function body at 45:24
--> $DIR/hidden-lifetimes.rs:45:24
|
LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a {
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index a6ea783..2ffb943 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -24,12 +24,12 @@
| |
| this return type evaluates to the `'static` lifetime...
|
-note: ...can't outlive the lifetime 'a as defined on the function body at 6:13
+note: ...can't outlive the lifetime `'a` as defined on the function body at 6:13
--> $DIR/must_outlive_least_region_or_bound.rs:6:13
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
| ^^
-help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the function body at 6:13
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 6:13
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
| ^^^^^^^^^^^^^^
@@ -42,12 +42,12 @@
| |
| this return type evaluates to the `'static` lifetime...
|
-note: ...can't outlive the lifetime 'a as defined on the function body at 12:15
+note: ...can't outlive the lifetime `'a` as defined on the function body at 12:15
--> $DIR/must_outlive_least_region_or_bound.rs:12:15
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| ^^
-help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the function body at 12:15
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 12:15
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr
index 5c8e322..894a65f 100644
--- a/src/test/ui/impl-trait/region-escape-via-bound.stderr
+++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr
@@ -4,7 +4,7 @@
LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y>
| ^^^^^^^^^^^^^^
|
-note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 17:7
+note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime `'x` as defined on the function body at 17:7
--> $DIR/region-escape-via-bound.rs:17:7
|
LL | where 'x: 'y
diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
index 0bc0180..1d6b5f5 100644
--- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
+++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr
@@ -30,12 +30,12 @@
| |
| ...but this borrow...
|
-note: ...can't outlive the lifetime 'a as defined on the method body at 10:20
+note: ...can't outlive the lifetime `'a` as defined on the method body at 10:20
--> $DIR/static-return-lifetime-infered.rs:10:20
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
| ^^
-help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the method body at 10:20
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the method body at 10:20
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr
index a80ebaf..b5287f3 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr
@@ -11,7 +11,7 @@
LL | | x
LL | | }
| |_____^
-note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 9:32...
+note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the method body at 9:32...
--> $DIR/mismatched_trait_impl.rs:9:32
|
LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
index 4dee83d..734ca08 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
@@ -11,7 +11,7 @@
LL | | x
LL | | }
| |_____^
-note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 9:32...
+note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the method body at 9:32...
--> $DIR/mismatched_trait_impl.rs:9:32
|
LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 {
diff --git a/src/test/ui/issues/issue-10200.stderr b/src/test/ui/issues/issue-10200.stderr
index 544716e..b1057d4 100644
--- a/src/test/ui/issues/issue-10200.stderr
+++ b/src/test/ui/issues/issue-10200.stderr
@@ -2,7 +2,7 @@
--> $DIR/issue-10200.rs:6:9
|
LL | foo(x)
- | ^^^ help: a tuple struct with a similar name exists: `Foo`
+ | ^^^ help: a tuple struct with a similar name exists (notice the capitalization): `Foo`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-10291.stderr b/src/test/ui/issues/issue-10291.stderr
index a836593..4fff4ee 100644
--- a/src/test/ui/issues/issue-10291.stderr
+++ b/src/test/ui/issues/issue-10291.stderr
@@ -12,7 +12,7 @@
LL | | x
LL | | }));
| |_____^
-note: ...but the borrowed content is only valid for the lifetime 'x as defined on the function body at 1:9
+note: ...but the borrowed content is only valid for the lifetime `'x` as defined on the function body at 1:9
--> $DIR/issue-10291.rs:1:9
|
LL | fn test<'x>(x: &'x isize) {
diff --git a/src/test/ui/issues/issue-16683.stderr b/src/test/ui/issues/issue-16683.stderr
index a047893..b663e21 100644
--- a/src/test/ui/issues/issue-16683.stderr
+++ b/src/test/ui/issues/issue-16683.stderr
@@ -16,7 +16,7 @@
|
LL | self.a();
| ^^^^
-note: but, the lifetime must be valid for the lifetime 'a as defined on the trait at 1:9...
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the trait at 1:9...
--> $DIR/issue-16683.rs:1:9
|
LL | trait T<'a> {
diff --git a/src/test/ui/issues/issue-17001.stderr b/src/test/ui/issues/issue-17001.stderr
index 2374e82..d7e6069 100644
--- a/src/test/ui/issues/issue-17001.stderr
+++ b/src/test/ui/issues/issue-17001.stderr
@@ -6,3 +6,4 @@
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/issues/issue-17405.stderr b/src/test/ui/issues/issue-17405.stderr
index 4b5678a..37274e2 100644
--- a/src/test/ui/issues/issue-17405.stderr
+++ b/src/test/ui/issues/issue-17405.stderr
@@ -6,3 +6,4 @@
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/issues/issue-17546.stderr b/src/test/ui/issues/issue-17546.stderr
index e27f49b..1f71e15 100644
--- a/src/test/ui/issues/issue-17546.stderr
+++ b/src/test/ui/issues/issue-17546.stderr
@@ -27,7 +27,7 @@
|
LL | use std::result::Result;
|
-and 1 other candidates
+ and 1 other candidates
error[E0573]: expected type, found variant `Result`
--> $DIR/issue-17546.rs:28:13
@@ -44,7 +44,7 @@
|
LL | use std::result::Result;
|
-and 1 other candidates
+ and 1 other candidates
error[E0573]: expected type, found variant `NoResult`
--> $DIR/issue-17546.rs:33:15
diff --git a/src/test/ui/issues/issue-17718-const-naming.stderr b/src/test/ui/issues/issue-17718-const-naming.stderr
index 1fe1821..e320c43 100644
--- a/src/test/ui/issues/issue-17718-const-naming.stderr
+++ b/src/test/ui/issues/issue-17718-const-naming.stderr
@@ -15,7 +15,7 @@
--> $DIR/issue-17718-const-naming.rs:4:7
|
LL | const foo: isize = 3;
- | ^^^ help: convert the identifier to upper case: `FOO`
+ | ^^^ help: convert the identifier to upper case (notice the capitalization): `FOO`
|
note: lint level defined here
--> $DIR/issue-17718-const-naming.rs:2:9
diff --git a/src/test/ui/issues/issue-17740.stderr b/src/test/ui/issues/issue-17740.stderr
index b8a0a06..d392ea3 100644
--- a/src/test/ui/issues/issue-17740.stderr
+++ b/src/test/ui/issues/issue-17740.stderr
@@ -17,7 +17,7 @@
LL | |
LL | | }
| |_____^
-note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 5:7
+note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 5:7
--> $DIR/issue-17740.rs:5:7
|
LL | impl <'a> Foo<'a>{
@@ -31,7 +31,7 @@
|
= note: expected type `Foo<'a>`
found type `Foo<'_>`
-note: the lifetime 'a as defined on the impl at 5:7...
+note: the lifetime `'a` as defined on the impl at 5:7...
--> $DIR/issue-17740.rs:5:7
|
LL | impl <'a> Foo<'a>{
diff --git a/src/test/ui/issues/issue-17758.stderr b/src/test/ui/issues/issue-17758.stderr
index 28a1be5..adcbb62 100644
--- a/src/test/ui/issues/issue-17758.stderr
+++ b/src/test/ui/issues/issue-17758.stderr
@@ -17,7 +17,7 @@
|
LL | self.foo();
| ^^^^
-note: but, the lifetime must be valid for the lifetime 'a as defined on the trait at 4:11...
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the trait at 4:11...
--> $DIR/issue-17758.rs:4:11
|
LL | trait Foo<'a> {
diff --git a/src/test/ui/issues/issue-17905-2.stderr b/src/test/ui/issues/issue-17905-2.stderr
index 585bc9c..04be62d 100644
--- a/src/test/ui/issues/issue-17905-2.stderr
+++ b/src/test/ui/issues/issue-17905-2.stderr
@@ -15,7 +15,7 @@
LL | | println!("{:?}", self);
LL | | }
| |_____^
-note: ...does not necessarily outlive the lifetime '_ as defined on the impl at 5:5
+note: ...does not necessarily outlive the lifetime `'_` as defined on the impl at 5:5
--> $DIR/issue-17905-2.rs:5:5
|
LL | &str,
@@ -29,7 +29,7 @@
|
= note: expected type `Pair<&str, _>`
found type `Pair<&str, _>`
-note: the lifetime '_ as defined on the impl at 5:5...
+note: the lifetime `'_` as defined on the impl at 5:5...
--> $DIR/issue-17905-2.rs:5:5
|
LL | &str,
diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr
index dd89598..13c9c09 100644
--- a/src/test/ui/issues/issue-20831-debruijn.stderr
+++ b/src/test/ui/issues/issue-20831-debruijn.stderr
@@ -23,7 +23,7 @@
LL | | self.sub = t;
LL | | }
| |_____^
-note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 26:6
+note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 26:6
--> $DIR/issue-20831-debruijn.rs:26:6
|
LL | impl<'a> Publisher<'a> for MyStruct<'a> {
@@ -43,7 +43,7 @@
|
= note: expected type `'a`
found type `'_`
-note: the lifetime 'a as defined on the impl at 26:6...
+note: the lifetime `'a` as defined on the impl at 26:6...
--> $DIR/issue-20831-debruijn.rs:26:6
|
LL | impl<'a> Publisher<'a> for MyStruct<'a> {
@@ -83,7 +83,7 @@
LL | | self.sub = t;
LL | | }
| |_____^
-note: ...but the lifetime must also be valid for the lifetime 'a as defined on the impl at 26:6...
+note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the impl at 26:6...
--> $DIR/issue-20831-debruijn.rs:26:6
|
LL | impl<'a> Publisher<'a> for MyStruct<'a> {
diff --git a/src/test/ui/issues/issue-21449.stderr b/src/test/ui/issues/issue-21449.stderr
index 21de1ea..ecaf6fa 100644
--- a/src/test/ui/issues/issue-21449.stderr
+++ b/src/test/ui/issues/issue-21449.stderr
@@ -6,3 +6,4 @@
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/issues/issue-23189.stderr b/src/test/ui/issues/issue-23189.stderr
index 50c09f1..ed06521 100644
--- a/src/test/ui/issues/issue-23189.stderr
+++ b/src/test/ui/issues/issue-23189.stderr
@@ -6,3 +6,4 @@
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/issues/issue-26459.stderr b/src/test/ui/issues/issue-26459.stderr
index c7909a1..1873692 100644
--- a/src/test/ui/issues/issue-26459.stderr
+++ b/src/test/ui/issues/issue-26459.stderr
@@ -6,3 +6,4 @@
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/issues/issue-27815.stderr b/src/test/ui/issues/issue-27815.stderr
index 1d68e3b..43f78cc 100644
--- a/src/test/ui/issues/issue-27815.stderr
+++ b/src/test/ui/issues/issue-27815.stderr
@@ -24,3 +24,4 @@
error: aborting due to 4 previous errors
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/issues/issue-27942.stderr b/src/test/ui/issues/issue-27942.stderr
index e039595..d290b17 100644
--- a/src/test/ui/issues/issue-27942.stderr
+++ b/src/test/ui/issues/issue-27942.stderr
@@ -11,7 +11,7 @@
|
LL | fn select(&self) -> BufferViewHandle<R>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...does not necessarily outlive the lifetime 'a as defined on the trait at 3:18
+note: ...does not necessarily outlive the lifetime `'a` as defined on the trait at 3:18
--> $DIR/issue-27942.rs:3:18
|
LL | pub trait Buffer<'a, R: Resources<'a>> {
@@ -25,7 +25,7 @@
|
= note: expected type `Resources<'_>`
found type `Resources<'a>`
-note: the lifetime 'a as defined on the trait at 3:18...
+note: the lifetime `'a` as defined on the trait at 3:18...
--> $DIR/issue-27942.rs:3:18
|
LL | pub trait Buffer<'a, R: Resources<'a>> {
diff --git a/src/test/ui/issues/issue-28848.stderr b/src/test/ui/issues/issue-28848.stderr
index 5f0f202..726844a 100644
--- a/src/test/ui/issues/issue-28848.stderr
+++ b/src/test/ui/issues/issue-28848.stderr
@@ -4,12 +4,12 @@
LL | Foo::<'a, 'b>::xmute(u)
| ^^^^^^^^^^^^^^^^^^^^
|
-note: lifetime parameter instantiated with the lifetime 'b as defined on the function body at 9:16
+note: lifetime parameter instantiated with the lifetime `'b` as defined on the function body at 9:16
--> $DIR/issue-28848.rs:9:16
|
LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {
| ^^
-note: but lifetime parameter must outlive the lifetime 'a as defined on the function body at 9:12
+note: but lifetime parameter must outlive the lifetime `'a` as defined on the function body at 9:12
--> $DIR/issue-28848.rs:9:12
|
LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {
diff --git a/src/test/ui/issues/issue-37884.stderr b/src/test/ui/issues/issue-37884.stderr
index 9a5f659..8e75d7b 100644
--- a/src/test/ui/issues/issue-37884.stderr
+++ b/src/test/ui/issues/issue-37884.stderr
@@ -21,7 +21,7 @@
LL | | Some(&mut self.0)
LL | | }
| |_____^
-note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 3:6
+note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 3:6
--> $DIR/issue-37884.rs:3:6
|
LL | impl<'a, T: 'a> Iterator for RepeatMut<'a, T> {
diff --git a/src/test/ui/issues/issue-46332.stderr b/src/test/ui/issues/issue-46332.stderr
index 812a500..c7e9d71 100644
--- a/src/test/ui/issues/issue-46332.stderr
+++ b/src/test/ui/issues/issue-46332.stderr
@@ -2,7 +2,7 @@
--> $DIR/issue-46332.rs:9:5
|
LL | TyUInt {};
- | ^^^^^^ help: a struct with a similar name exists: `TyUint`
+ | ^^^^^^ help: a struct with a similar name exists (notice the capitalization): `TyUint`
error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-47486.rs b/src/test/ui/issues/issue-47486.rs
new file mode 100644
index 0000000..d686f02
--- /dev/null
+++ b/src/test/ui/issues/issue-47486.rs
@@ -0,0 +1,4 @@
+fn main() {
+ () < std::mem::size_of::<_>(); //~ ERROR: mismatched types
+ [0u8; std::mem::size_of::<_>()]; //~ ERROR: type annotations needed
+}
diff --git a/src/test/ui/issues/issue-47486.stderr b/src/test/ui/issues/issue-47486.stderr
new file mode 100644
index 0000000..af6e301
--- /dev/null
+++ b/src/test/ui/issues/issue-47486.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-47486.rs:2:10
+ |
+LL | () < std::mem::size_of::<_>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found usize
+ |
+ = note: expected type `()`
+ found type `usize`
+
+error[E0282]: type annotations needed
+ --> $DIR/issue-47486.rs:3:11
+ |
+LL | [0u8; std::mem::size_of::<_>()];
+ | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0282, E0308.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/issues/issue-52213.stderr b/src/test/ui/issues/issue-52213.stderr
index 8d74b8e..b79a5dd 100644
--- a/src/test/ui/issues/issue-52213.stderr
+++ b/src/test/ui/issues/issue-52213.stderr
@@ -4,7 +4,7 @@
LL | match (&t,) {
| ^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 1:23...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 1:23...
--> $DIR/issue-52213.rs:1:23
|
LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
@@ -12,7 +12,7 @@
= note: ...so that the types are compatible:
expected (&&(T,),)
found (&&'a (T,),)
-note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 1:27...
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 1:27...
--> $DIR/issue-52213.rs:1:27
|
LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr
index 7cf597d..7b910f5 100644
--- a/src/test/ui/issues/issue-55796.stderr
+++ b/src/test/ui/issues/issue-55796.stderr
@@ -4,7 +4,7 @@
LL | Box::new(self.out_edges(u).map(|e| e.target()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the trait at 5:17...
--> $DIR/issue-55796.rs:5:17
|
LL | pub trait Graph<'a> {
@@ -25,7 +25,7 @@
LL | Box::new(self.in_edges(u).map(|e| e.target()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the trait at 5:17...
--> $DIR/issue-55796.rs:5:17
|
LL | pub trait Graph<'a> {
diff --git a/src/test/ui/lexical-scopes.stderr b/src/test/ui/lexical-scopes.stderr
index e990f70..38c7393 100644
--- a/src/test/ui/lexical-scopes.stderr
+++ b/src/test/ui/lexical-scopes.stderr
@@ -16,4 +16,5 @@
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0599`.
+Some errors have detailed explanations: E0574, E0599.
+For more information about an error, try `rustc --explain E0574`.
diff --git a/src/test/ui/lifetimes/lifetime-bound-will-change-warning.stderr b/src/test/ui/lifetimes/lifetime-bound-will-change-warning.stderr
index 35d63c1..b401199 100644
--- a/src/test/ui/lifetimes/lifetime-bound-will-change-warning.stderr
+++ b/src/test/ui/lifetimes/lifetime-bound-will-change-warning.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `&std::boxed::Box<(dyn std::ops::Fn() + 'static)>`
found type `&std::boxed::Box<(dyn std::ops::Fn() + 'a)>`
-note: the lifetime 'a as defined on the function body at 32:10...
+note: the lifetime `'a` as defined on the function body at 32:10...
--> $DIR/lifetime-bound-will-change-warning.rs:32:10
|
LL | fn test2<'a>(x: &'a Box<dyn Fn() + 'a>) {
@@ -21,7 +21,7 @@
|
= note: expected type `&std::boxed::Box<(dyn std::ops::Fn() + 'static)>`
found type `&std::boxed::Box<(dyn std::ops::Fn() + 'a)>`
-note: the lifetime 'a as defined on the function body at 37:12...
+note: the lifetime `'a` as defined on the function body at 37:12...
--> $DIR/lifetime-bound-will-change-warning.rs:37:12
|
LL | fn test2cc<'a>(x: &'a Box<dyn Fn() + 'a>) {
diff --git a/src/test/ui/lint/lint-non-camel-case-types.stderr b/src/test/ui/lint/lint-non-camel-case-types.stderr
index 432a16d..177f8c8 100644
--- a/src/test/ui/lint/lint-non-camel-case-types.stderr
+++ b/src/test/ui/lint/lint-non-camel-case-types.stderr
@@ -14,25 +14,25 @@
--> $DIR/lint-non-camel-case-types.rs:7:8
|
LL | struct foo {
- | ^^^ help: convert the identifier to upper camel case: `Foo`
+ | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo`
error: type `foo2` should have an upper camel case name
--> $DIR/lint-non-camel-case-types.rs:11:6
|
LL | enum foo2 {
- | ^^^^ help: convert the identifier to upper camel case: `Foo2`
+ | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo2`
error: type `foo3` should have an upper camel case name
--> $DIR/lint-non-camel-case-types.rs:15:8
|
LL | struct foo3 {
- | ^^^^ help: convert the identifier to upper camel case: `Foo3`
+ | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo3`
error: type `foo4` should have an upper camel case name
--> $DIR/lint-non-camel-case-types.rs:19:6
|
LL | type foo4 = isize;
- | ^^^^ help: convert the identifier to upper camel case: `Foo4`
+ | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo4`
error: variant `bar` should have an upper camel case name
--> $DIR/lint-non-camel-case-types.rs:22:5
@@ -44,7 +44,7 @@
--> $DIR/lint-non-camel-case-types.rs:25:7
|
LL | trait foo6 {
- | ^^^^ help: convert the identifier to upper camel case: `Foo6`
+ | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo6`
error: type parameter `ty` should have an upper camel case name
--> $DIR/lint-non-camel-case-types.rs:29:6
diff --git a/src/test/ui/lint/lint-non-snake-case-functions.stderr b/src/test/ui/lint/lint-non-snake-case-functions.stderr
index 49cbfa9..c5eca89 100644
--- a/src/test/ui/lint/lint-non-snake-case-functions.stderr
+++ b/src/test/ui/lint/lint-non-snake-case-functions.stderr
@@ -38,7 +38,7 @@
--> $DIR/lint-non-snake-case-functions.rs:25:8
|
LL | fn a_b_C(&self) {}
- | ^^^^^ help: convert the identifier to snake case: `a_b_c`
+ | ^^^^^ help: convert the identifier to snake case (notice the capitalization): `a_b_c`
error: trait method `something__else` should have a snake case name
--> $DIR/lint-non-snake-case-functions.rs:28:8
@@ -50,13 +50,13 @@
--> $DIR/lint-non-snake-case-functions.rs:38:4
|
LL | fn Cookie() {}
- | ^^^^^^ help: convert the identifier to snake case: `cookie`
+ | ^^^^^^ help: convert the identifier to snake case (notice the capitalization): `cookie`
error: function `bi_S_Cuit` should have a snake case name
--> $DIR/lint-non-snake-case-functions.rs:41:8
|
LL | pub fn bi_S_Cuit() {}
- | ^^^^^^^^^ help: convert the identifier to snake case: `bi_s_cuit`
+ | ^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `bi_s_cuit`
error: aborting due to 9 previous errors
diff --git a/src/test/ui/lint/lint-non-uppercase-statics.stderr b/src/test/ui/lint/lint-non-uppercase-statics.stderr
index 8b47727..ceb83d0 100644
--- a/src/test/ui/lint/lint-non-uppercase-statics.stderr
+++ b/src/test/ui/lint/lint-non-uppercase-statics.stderr
@@ -2,7 +2,7 @@
--> $DIR/lint-non-uppercase-statics.rs:4:8
|
LL | static foo: isize = 1;
- | ^^^ help: convert the identifier to upper case: `FOO`
+ | ^^^ help: convert the identifier to upper case (notice the capitalization): `FOO`
|
note: lint level defined here
--> $DIR/lint-non-uppercase-statics.rs:1:11
diff --git a/src/test/ui/lint/lint-uppercase-variables.stderr b/src/test/ui/lint/lint-uppercase-variables.stderr
index 9ea3795..f614d5d 100644
--- a/src/test/ui/lint/lint-uppercase-variables.stderr
+++ b/src/test/ui/lint/lint-uppercase-variables.stderr
@@ -21,7 +21,7 @@
--> $DIR/lint-uppercase-variables.rs:10:5
|
LL | X: usize
- | ^ help: convert the identifier to snake case: `x`
+ | ^ help: convert the identifier to snake case (notice the capitalization): `x`
|
note: lint level defined here
--> $DIR/lint-uppercase-variables.rs:3:9
@@ -33,7 +33,7 @@
--> $DIR/lint-uppercase-variables.rs:13:9
|
LL | fn test(Xx: usize) {
- | ^^ help: convert the identifier to snake case: `xx`
+ | ^^ help: convert the identifier to snake case (notice the capitalization): `xx`
error: variable `Test` should have a snake case name
--> $DIR/lint-uppercase-variables.rs:18:9
@@ -45,7 +45,7 @@
--> $DIR/lint-uppercase-variables.rs:22:9
|
LL | Foo => {}
- | ^^^ help: convert the identifier to snake case: `foo`
+ | ^^^ help: convert the identifier to snake case (notice the capitalization): `foo`
error: aborting due to 4 previous errors
diff --git a/src/test/ui/lint/not_found.stderr b/src/test/ui/lint/not_found.stderr
index 70d49a4..5016d9b 100644
--- a/src/test/ui/lint/not_found.stderr
+++ b/src/test/ui/lint/not_found.stderr
@@ -16,5 +16,5 @@
--> $DIR/not_found.rs:10:8
|
LL | #[deny(Warnings)]
- | ^^^^^^^^ help: did you mean: `warnings`
+ | ^^^^^^^^ help: did you mean (notice the capitalization): `warnings`
diff --git a/src/test/ui/lint/reasons.stderr b/src/test/ui/lint/reasons.stderr
index cb5f4dd..139b3f1 100644
--- a/src/test/ui/lint/reasons.stderr
+++ b/src/test/ui/lint/reasons.stderr
@@ -15,7 +15,7 @@
--> $DIR/reasons.rs:30:9
|
LL | let Social_exchange_psychology = CheaterDetectionMechanism {};
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `social_exchange_psychology`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `social_exchange_psychology`
|
= note: people shouldn't have to change their usual style habits
to contribute to our project
diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr
index 678c888..1da5acc 100644
--- a/src/test/ui/lint/use_suggestion_json.stderr
+++ b/src/test/ui/lint/use_suggestion_json.stderr
@@ -395,7 +395,7 @@
\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0muse std::collections::hash_map::Iter;\u001b[0m
\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m
-\u001b[0mand 8 other candidates\u001b[0m
+\u001b[0m and 8 other candidates\u001b[0m
"
}
diff --git a/src/test/ui/lub-if.stderr b/src/test/ui/lub-if.stderr
index 26f756c..0a47440 100644
--- a/src/test/ui/lub-if.stderr
+++ b/src/test/ui/lub-if.stderr
@@ -5,7 +5,7 @@
| ^
|
= note: ...the reference is valid for the static lifetime...
-note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 23:17
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 23:17
--> $DIR/lub-if.rs:23:17
|
LL | pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
@@ -18,7 +18,7 @@
| ^
|
= note: ...the reference is valid for the static lifetime...
-note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 32:17
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 32:17
--> $DIR/lub-if.rs:32:17
|
LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
diff --git a/src/test/ui/lub-match.stderr b/src/test/ui/lub-match.stderr
index 0cb0a23..168a389 100644
--- a/src/test/ui/lub-match.stderr
+++ b/src/test/ui/lub-match.stderr
@@ -5,7 +5,7 @@
| ^
|
= note: ...the reference is valid for the static lifetime...
-note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 25:17
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 25:17
--> $DIR/lub-match.rs:25:17
|
LL | pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
@@ -18,7 +18,7 @@
| ^
|
= note: ...the reference is valid for the static lifetime...
-note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 35:17
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 35:17
--> $DIR/lub-match.rs:35:17
|
LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
diff --git a/src/test/ui/macros/same-sequence-span.rs b/src/test/ui/macros/same-sequence-span.rs
index a4f70b6..e0bb4d9 100644
--- a/src/test/ui/macros/same-sequence-span.rs
+++ b/src/test/ui/macros/same-sequence-span.rs
@@ -4,7 +4,6 @@
// left-hand side of a macro definition behave as if they had unique spans, and in particular that
// they don't crash the compiler.
-#![feature(proc_macro_hygiene)]
#![allow(unused_macros)]
extern crate proc_macro_sequence;
diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr
index 0eef4a2..896f579 100644
--- a/src/test/ui/macros/same-sequence-span.stderr
+++ b/src/test/ui/macros/same-sequence-span.stderr
@@ -1,5 +1,5 @@
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
- --> $DIR/same-sequence-span.rs:15:18
+ --> $DIR/same-sequence-span.rs:14:18
|
LL | (1 $x:expr $($y:tt,)*
| ^^^^^ not allowed after `expr` fragments
@@ -7,7 +7,7 @@
= note: allowed there are: `=>`, `,` or `;`
error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments
- --> $DIR/same-sequence-span.rs:16:18
+ --> $DIR/same-sequence-span.rs:15:18
|
LL | $(= $z:tt)*
| ^ not allowed after `expr` fragments
@@ -15,7 +15,7 @@
= note: allowed there are: `=>`, `,` or `;`
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
- --> $DIR/same-sequence-span.rs:20:1
+ --> $DIR/same-sequence-span.rs:19:1
|
LL | proc_macro_sequence::make_foo!();
| ^--------------------------------
@@ -30,7 +30,7 @@
= note: allowed there are: `=>`, `,` or `;`
error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments
- --> $DIR/same-sequence-span.rs:20:1
+ --> $DIR/same-sequence-span.rs:19:1
|
LL | proc_macro_sequence::make_foo!();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/match/match-ref-mut-invariance.stderr b/src/test/ui/match/match-ref-mut-invariance.stderr
index 30bbb8d7..0a02098 100644
--- a/src/test/ui/match/match-ref-mut-invariance.stderr
+++ b/src/test/ui/match/match-ref-mut-invariance.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `&'a mut &'a i32`
found type `&'a mut &'b i32`
-note: the lifetime 'a as defined on the method body at 9:12...
+note: the lifetime `'a` as defined on the method body at 9:12...
--> $DIR/match-ref-mut-invariance.rs:9:12
|
LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
| ^^
-note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 8:6
+note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 8:6
--> $DIR/match-ref-mut-invariance.rs:8:6
|
LL | impl<'b> S<'b> {
diff --git a/src/test/ui/match/match-ref-mut-let-invariance.stderr b/src/test/ui/match/match-ref-mut-let-invariance.stderr
index 6ca222d..1bea9bc 100644
--- a/src/test/ui/match/match-ref-mut-let-invariance.stderr
+++ b/src/test/ui/match/match-ref-mut-let-invariance.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `&'a mut &'a i32`
found type `&'a mut &'b i32`
-note: the lifetime 'a as defined on the method body at 9:12...
+note: the lifetime `'a` as defined on the method body at 9:12...
--> $DIR/match-ref-mut-let-invariance.rs:9:12
|
LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 {
| ^^
-note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 8:6
+note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 8:6
--> $DIR/match-ref-mut-let-invariance.rs:8:6
|
LL | impl<'b> S<'b> {
diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr
index b19e3a9..74c33df 100644
--- a/src/test/ui/nll/issue-50716.stderr
+++ b/src/test/ui/nll/issue-50716.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `std::marker::Sized`
found type `std::marker::Sized`
-note: the lifetime 'a as defined on the function body at 9:8...
+note: the lifetime `'a` as defined on the function body at 9:8...
--> $DIR/issue-50716.rs:9:8
|
LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
diff --git a/src/test/ui/nll/issue-52742.stderr b/src/test/ui/nll/issue-52742.stderr
index 90a3517..0cdc2d9 100644
--- a/src/test/ui/nll/issue-52742.stderr
+++ b/src/test/ui/nll/issue-52742.stderr
@@ -4,7 +4,7 @@
LL | self.y = b.z
| ^^^
|
-note: ...the reference is valid for the lifetime '_ as defined on the impl at 12:10...
+note: ...the reference is valid for the lifetime `'_` as defined on the impl at 12:10...
--> $DIR/issue-52742.rs:12:10
|
LL | impl Foo<'_, '_> {
diff --git a/src/test/ui/nll/issue-55394.stderr b/src/test/ui/nll/issue-55394.stderr
index e00e6f3..714a63b 100644
--- a/src/test/ui/nll/issue-55394.stderr
+++ b/src/test/ui/nll/issue-55394.stderr
@@ -16,7 +16,7 @@
|
LL | Foo { bar }
| ^^^
-note: but, the lifetime must be valid for the lifetime '_ as defined on the impl at 7:10...
+note: but, the lifetime must be valid for the lifetime `'_` as defined on the impl at 7:10...
--> $DIR/issue-55394.rs:7:10
|
LL | impl Foo<'_> {
diff --git a/src/test/ui/nll/issue-55401.stderr b/src/test/ui/nll/issue-55401.stderr
index 4ec16ba..2dc7236 100644
--- a/src/test/ui/nll/issue-55401.stderr
+++ b/src/test/ui/nll/issue-55401.stderr
@@ -5,7 +5,7 @@
| ^^
|
= note: ...the reference is valid for the static lifetime...
-note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 1:47
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 1:47
--> $DIR/issue-55401.rs:1:47
|
LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 {
diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr
index 77a372d..3a152fb 100644
--- a/src/test/ui/nll/normalization-bounds-error.stderr
+++ b/src/test/ui/nll/normalization-bounds-error.stderr
@@ -4,12 +4,12 @@
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'd as defined on the function body at 12:14...
+note: first, the lifetime cannot outlive the lifetime `'d` as defined on the function body at 12:14...
--> $DIR/normalization-bounds-error.rs:12:14
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
| ^^
-note: ...but the lifetime must also be valid for the lifetime 'a as defined on the function body at 12:18...
+note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the function body at 12:18...
--> $DIR/normalization-bounds-error.rs:12:18
|
LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {}
diff --git a/src/test/ui/nll/trait-associated-constant.stderr b/src/test/ui/nll/trait-associated-constant.stderr
index f39f668..ecf9748 100644
--- a/src/test/ui/nll/trait-associated-constant.stderr
+++ b/src/test/ui/nll/trait-associated-constant.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `std::option::Option<&'b str>`
found type `std::option::Option<&'c str>`
-note: the lifetime 'c as defined on the impl at 20:18...
+note: the lifetime `'c` as defined on the impl at 20:18...
--> $DIR/trait-associated-constant.rs:20:18
|
LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct {
| ^^
-note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 20:14
+note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 20:14
--> $DIR/trait-associated-constant.rs:20:14
|
LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct {
diff --git a/src/test/ui/nll/type-alias-free-regions.stderr b/src/test/ui/nll/type-alias-free-regions.stderr
index 7465174..6986389 100644
--- a/src/test/ui/nll/type-alias-free-regions.stderr
+++ b/src/test/ui/nll/type-alias-free-regions.stderr
@@ -14,7 +14,7 @@
= note: ...so that the expression is assignable:
expected std::boxed::Box<std::boxed::Box<&isize>>
found std::boxed::Box<std::boxed::Box<&isize>>
-note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 15:6...
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 15:6...
--> $DIR/type-alias-free-regions.rs:15:6
|
LL | impl<'a> FromBox<'a> for C<'a> {
@@ -39,7 +39,7 @@
= note: ...so that the expression is assignable:
expected std::boxed::Box<&isize>
found std::boxed::Box<&isize>
-note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 25:6...
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 25:6...
--> $DIR/type-alias-free-regions.rs:25:6
|
LL | impl<'a> FromTuple<'a> for C<'a> {
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr
index f5657f9..4ebd991 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr
@@ -4,7 +4,7 @@
LL | <Foo<'a>>::C
| ^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 7:8...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 7:8...
--> $DIR/constant-in-expr-inherent-1.rs:7:8
|
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr
index 0a8ad42..4c7adf7 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^
|
= note: ...the reference is valid for the static lifetime...
-note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 17:8
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 17:8
--> $DIR/constant-in-expr-normalize.rs:17:8
|
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr
index d596aaf..d01d022 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^
|
= note: ...the reference is valid for the static lifetime...
-note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 9:8
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 9:8
--> $DIR/constant-in-expr-trait-item-1.rs:9:8
|
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr
index 80ff9a0..dd29428 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^
|
= note: ...the reference is valid for the static lifetime...
-note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 9:8
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 9:8
--> $DIR/constant-in-expr-trait-item-2.rs:9:8
|
LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr
index f7db403..d61659e 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr
@@ -4,7 +4,7 @@
LL | T::C
| ^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:8...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:8...
--> $DIR/constant-in-expr-trait-item-3.rs:9:8
|
LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr b/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr
index 217e850..d66322c 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr
@@ -4,7 +4,7 @@
LL | ss
| ^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 54:10...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 54:10...
--> $DIR/object-lifetime-default-elision.rs:54:10
|
LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {
@@ -14,7 +14,7 @@
|
LL | ss
| ^^
-note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 54:13...
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 54:13...
--> $DIR/object-lifetime-default-elision.rs:54:13
|
LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {
@@ -29,7 +29,7 @@
LL | ss
| ^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 54:10...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 54:10...
--> $DIR/object-lifetime-default-elision.rs:54:10
|
LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {
@@ -39,7 +39,7 @@
|
LL | ss
| ^^
-note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 54:13...
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 54:13...
--> $DIR/object-lifetime-default-elision.rs:54:13
|
LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait {
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.stderr
index 4f9cef1..99f0ce0 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `&'a std::boxed::Box<(dyn Test + 'static)>`
found type `&'a std::boxed::Box<(dyn Test + 'a)>`
-note: the lifetime 'a as defined on the function body at 14:6...
+note: the lifetime `'a` as defined on the function body at 14:6...
--> $DIR/object-lifetime-default-from-rptr-box-error.rs:14:6
|
LL | fn c<'a>(t: &'a Box<dyn Test+'a>, mut ss: SomeStruct<'a>) {
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.stderr
index 3b7faee..07d4d8c 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `&'a MyBox<(dyn Test + 'static)>`
found type `&'a MyBox<(dyn Test + 'a)>`
-note: the lifetime 'a as defined on the function body at 20:6...
+note: the lifetime `'a` as defined on the function body at 20:6...
--> $DIR/object-lifetime-default-from-rptr-struct-error.rs:20:6
|
LL | fn c<'a>(t: &'a MyBox<dyn Test+'a>, mut ss: SomeStruct<'a>) {
diff --git a/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr b/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr
index 928b920..f825475 100644
--- a/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr
+++ b/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr
@@ -18,7 +18,7 @@
|
= note: expected type `&MyBox<(dyn SomeTrait + 'static)>`
found type `&MyBox<(dyn SomeTrait + 'a)>`
-note: the lifetime 'a as defined on the function body at 30:10...
+note: the lifetime `'a` as defined on the function body at 30:10...
--> $DIR/object-lifetime-default-mybox.rs:30:10
|
LL | fn load2<'a>(ss: &MyBox<dyn SomeTrait + 'a>) -> MyBox<dyn SomeTrait + 'a> {
diff --git a/src/test/ui/parser/intersection-patterns.rs b/src/test/ui/parser/intersection-patterns.rs
new file mode 100644
index 0000000..adb607c
--- /dev/null
+++ b/src/test/ui/parser/intersection-patterns.rs
@@ -0,0 +1,40 @@
+// This tests the parser recovery in `recover_intersection_pat`
+// and serves as a regression test for the diagnostics issue #65400.
+//
+// The general idea is that for `$pat_lhs @ $pat_rhs` where
+// `$pat_lhs` is not generated by `ref? mut? $ident` we want
+// to suggest either switching the order or note that intersection
+// patterns are not allowed.
+
+fn main() {
+ let s: Option<u8> = None;
+
+ match s {
+ Some(x) @ y => {}
+ //~^ ERROR pattern on wrong side of `@`
+ //~| pattern on the left, should be on the right
+ //~| binding on the right, should be on the left
+ //~| HELP switch the order
+ //~| SUGGESTION y @ Some(x)
+ _ => {}
+ }
+
+ match s {
+ Some(x) @ Some(y) => {}
+ //~^ ERROR left-hand side of `@` must be a binding
+ //~| interpreted as a pattern, not a binding
+ //~| also a pattern
+ //~| NOTE bindings are `x`, `mut x`, `ref x`, and `ref mut x`
+ _ => {}
+ }
+
+ match 2 {
+ 1 ..= 5 @ e => {}
+ //~^ ERROR pattern on wrong side of `@`
+ //~| pattern on the left, should be on the right
+ //~| binding on the right, should be on the left
+ //~| HELP switch the order
+ //~| SUGGESTION e @ 1 ..=5
+ _ => {}
+ }
+}
diff --git a/src/test/ui/parser/intersection-patterns.stderr b/src/test/ui/parser/intersection-patterns.stderr
new file mode 100644
index 0000000..f5bfee5
--- /dev/null
+++ b/src/test/ui/parser/intersection-patterns.stderr
@@ -0,0 +1,33 @@
+error: pattern on wrong side of `@`
+ --> $DIR/intersection-patterns.rs:13:9
+ |
+LL | Some(x) @ y => {}
+ | -------^^^-
+ | | |
+ | | binding on the right, should be on the left
+ | pattern on the left, should be on the right
+ | help: switch the order: `y @ Some(x)`
+
+error: left-hand side of `@` must be a binding
+ --> $DIR/intersection-patterns.rs:23:9
+ |
+LL | Some(x) @ Some(y) => {}
+ | -------^^^-------
+ | | |
+ | | also a pattern
+ | interpreted as a pattern, not a binding
+ |
+ = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x`
+
+error: pattern on wrong side of `@`
+ --> $DIR/intersection-patterns.rs:32:9
+ |
+LL | 1 ..= 5 @ e => {}
+ | -------^^^-
+ | | |
+ | | binding on the right, should be on the left
+ | pattern on the left, should be on the right
+ | help: switch the order: `e @ 1 ..=5`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs b/src/test/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs
new file mode 100644
index 0000000..548fefe
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/gen-macro-rules-hygiene.rs
@@ -0,0 +1,23 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro]
+pub fn gen_macro_rules(_: TokenStream) -> TokenStream {
+ "
+ macro_rules! generated {() => {
+ struct ItemDef;
+ let local_def = 0;
+
+ ItemUse; // OK
+ local_use; // ERROR
+ break 'label_use; // ERROR
+
+ type DollarCrate = $crate::ItemUse; // OK
+ }}
+ ".parse().unwrap()
+}
diff --git a/src/test/ui/proc-macro/auxiliary/more-gates.rs b/src/test/ui/proc-macro/auxiliary/more-gates.rs
deleted file mode 100644
index 6b609ea..0000000
--- a/src/test/ui/proc-macro/auxiliary/more-gates.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// force-host
-// no-prefer-dynamic
-
-#![crate_type = "proc-macro"]
-
-extern crate proc_macro;
-
-use proc_macro::*;
-
-#[proc_macro_attribute]
-pub fn attr2mac1(_: TokenStream, _: TokenStream) -> TokenStream {
- "macro_rules! foo1 { (a) => (a) }".parse().unwrap()
-}
-
-#[proc_macro_attribute]
-pub fn attr2mac2(_: TokenStream, _: TokenStream) -> TokenStream {
- "macro foo2(a) { a }".parse().unwrap()
-}
-
-#[proc_macro]
-pub fn mac2mac1(_: TokenStream) -> TokenStream {
- "macro_rules! foo3 { (a) => (a) }".parse().unwrap()
-}
-
-#[proc_macro]
-pub fn mac2mac2(_: TokenStream) -> TokenStream {
- "macro foo4(a) { a }".parse().unwrap()
-}
-
-#[proc_macro]
-pub fn tricky(_: TokenStream) -> TokenStream {
- "fn foo() {
- macro_rules! foo { (a) => (a) }
- }".parse().unwrap()
-}
diff --git a/src/test/ui/proc-macro/gen-macro-rules-hygiene.rs b/src/test/ui/proc-macro/gen-macro-rules-hygiene.rs
new file mode 100644
index 0000000..195bda8
--- /dev/null
+++ b/src/test/ui/proc-macro/gen-macro-rules-hygiene.rs
@@ -0,0 +1,23 @@
+// `macro_rules` items produced by transparent macros have correct hygiene in basic cases.
+// Local variables and labels are hygienic, items are not hygienic.
+// `$crate` refers to the crate that defines `macro_rules` and not the outer transparent macro.
+
+// aux-build:gen-macro-rules-hygiene.rs
+
+#[macro_use]
+extern crate gen_macro_rules_hygiene;
+
+struct ItemUse;
+
+gen_macro_rules!();
+//~^ ERROR use of undeclared label `'label_use`
+//~| ERROR cannot find value `local_use` in this scope
+
+fn main() {
+ 'label_use: loop {
+ let local_use = 1;
+ generated!();
+ ItemDef; // OK
+ local_def; //~ ERROR cannot find value `local_def` in this scope
+ }
+}
diff --git a/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr b/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr
new file mode 100644
index 0000000..ecebdfa
--- /dev/null
+++ b/src/test/ui/proc-macro/gen-macro-rules-hygiene.stderr
@@ -0,0 +1,28 @@
+error[E0426]: use of undeclared label `'label_use`
+ --> $DIR/gen-macro-rules-hygiene.rs:12:1
+ |
+LL | gen_macro_rules!();
+ | ^^^^^^^^^^^^^^^^^^^ undeclared label `'label_use`
+...
+LL | generated!();
+ | ------------- in this macro invocation
+
+error[E0425]: cannot find value `local_use` in this scope
+ --> $DIR/gen-macro-rules-hygiene.rs:12:1
+ |
+LL | gen_macro_rules!();
+ | ^^^^^^^^^^^^^^^^^^^ not found in this scope
+...
+LL | generated!();
+ | ------------- in this macro invocation
+
+error[E0425]: cannot find value `local_def` in this scope
+ --> $DIR/gen-macro-rules-hygiene.rs:21:9
+ |
+LL | local_def;
+ | ^^^^^^^^^ not found in this scope
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0425, E0426.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/src/test/ui/proc-macro/more-gates.rs b/src/test/ui/proc-macro/more-gates.rs
deleted file mode 100644
index b870b43..0000000
--- a/src/test/ui/proc-macro/more-gates.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// aux-build:more-gates.rs
-
-#![feature(decl_macro)]
-
-extern crate more_gates as foo;
-
-use foo::*;
-
-#[attr2mac1]
-//~^ ERROR: cannot expand to macro definitions
-pub fn a() {}
-#[attr2mac2]
-//~^ ERROR: cannot expand to macro definitions
-pub fn a() {}
-
-mac2mac1!(); //~ ERROR: cannot expand to macro definitions
-mac2mac2!(); //~ ERROR: cannot expand to macro definitions
-
-tricky!();
-//~^ ERROR: cannot expand to macro definitions
-
-fn main() {}
diff --git a/src/test/ui/proc-macro/more-gates.stderr b/src/test/ui/proc-macro/more-gates.stderr
deleted file mode 100644
index ad96f78..0000000
--- a/src/test/ui/proc-macro/more-gates.stderr
+++ /dev/null
@@ -1,48 +0,0 @@
-error[E0658]: procedural macros cannot expand to macro definitions
- --> $DIR/more-gates.rs:9:1
- |
-LL | #[attr2mac1]
- | ^^^^^^^^^^^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/54727
- = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable
-
-error[E0658]: procedural macros cannot expand to macro definitions
- --> $DIR/more-gates.rs:12:1
- |
-LL | #[attr2mac2]
- | ^^^^^^^^^^^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/54727
- = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable
-
-error[E0658]: procedural macros cannot expand to macro definitions
- --> $DIR/more-gates.rs:16:1
- |
-LL | mac2mac1!();
- | ^^^^^^^^^^^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/54727
- = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable
-
-error[E0658]: procedural macros cannot expand to macro definitions
- --> $DIR/more-gates.rs:17:1
- |
-LL | mac2mac2!();
- | ^^^^^^^^^^^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/54727
- = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable
-
-error[E0658]: procedural macros cannot expand to macro definitions
- --> $DIR/more-gates.rs:19:1
- |
-LL | tricky!();
- | ^^^^^^^^^^
- |
- = note: for more information, see https://github.com/rust-lang/rust/issues/54727
- = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr b/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr
index 751a4c1..184cead 100644
--- a/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr
+++ b/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr
@@ -10,12 +10,12 @@
LL | z: Box<dyn Is<'a>+'b+'c>,
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: lifetime parameter instantiated with the lifetime 'b as defined on the struct at 11:15
+note: lifetime parameter instantiated with the lifetime `'b` as defined on the struct at 11:15
--> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:15
|
LL | struct Foo<'a,'b,'c> {
| ^^
-note: but lifetime parameter must outlive the lifetime 'a as defined on the struct at 11:12
+note: but lifetime parameter must outlive the lifetime `'a` as defined on the struct at 11:12
--> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:12
|
LL | struct Foo<'a,'b,'c> {
diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.rs b/src/test/ui/regions/region-invariant-static-error-reporting.rs
index df92ed5..9119048 100644
--- a/src/test/ui/regions/region-invariant-static-error-reporting.rs
+++ b/src/test/ui/regions/region-invariant-static-error-reporting.rs
@@ -3,7 +3,7 @@
// over time, but this test used to exhibit some pretty bogus messages
// that were not remotely helpful.
-// error-pattern:the lifetime 'a
+// error-pattern:the lifetime `'a`
// error-pattern:the static lifetime
struct Invariant<'a>(Option<&'a mut &'a mut ()>);
diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.stderr b/src/test/ui/regions/region-invariant-static-error-reporting.stderr
index 60e70dd..8358a79 100644
--- a/src/test/ui/regions/region-invariant-static-error-reporting.stderr
+++ b/src/test/ui/regions/region-invariant-static-error-reporting.stderr
@@ -13,7 +13,7 @@
|
= note: expected type `Invariant<'a>`
found type `Invariant<'static>`
-note: the lifetime 'a as defined on the function body at 13:10...
+note: the lifetime `'a` as defined on the function body at 13:10...
--> $DIR/region-invariant-static-error-reporting.rs:13:10
|
LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {
diff --git a/src/test/ui/regions/region-object-lifetime-2.stderr b/src/test/ui/regions/region-object-lifetime-2.stderr
index cc8d150..74ea1b7 100644
--- a/src/test/ui/regions/region-object-lifetime-2.stderr
+++ b/src/test/ui/regions/region-object-lifetime-2.stderr
@@ -4,7 +4,7 @@
LL | x.borrowed()
| ^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:42...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:42...
--> $DIR/region-object-lifetime-2.rs:9:42
|
LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () {
@@ -14,7 +14,7 @@
|
LL | x.borrowed()
| ^
-note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 9:45...
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 9:45...
--> $DIR/region-object-lifetime-2.rs:9:45
|
LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () {
diff --git a/src/test/ui/regions/region-object-lifetime-4.stderr b/src/test/ui/regions/region-object-lifetime-4.stderr
index 23fd4d0..1053218 100644
--- a/src/test/ui/regions/region-object-lifetime-4.stderr
+++ b/src/test/ui/regions/region-object-lifetime-4.stderr
@@ -4,7 +4,7 @@
LL | x.borrowed()
| ^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 11:41...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 11:41...
--> $DIR/region-object-lifetime-4.rs:11:41
|
LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () {
@@ -14,7 +14,7 @@
|
LL | x.borrowed()
| ^
-note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 11:44...
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 11:44...
--> $DIR/region-object-lifetime-4.rs:11:44
|
LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () {
diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
index 3ccb886..14934d6 100644
--- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
+++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr
@@ -29,7 +29,7 @@
LL | Box::new(v)
| ^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 25:6...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 25:6...
--> $DIR/region-object-lifetime-in-coercion.rs:25:6
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
@@ -37,7 +37,7 @@
= note: ...so that the expression is assignable:
expected &[u8]
found &'a [u8]
-note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 25:9...
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 25:9...
--> $DIR/region-object-lifetime-in-coercion.rs:25:9
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.stderr
index ac5e5e9..7a051b8 100644
--- a/src/test/ui/regions/regions-addr-of-upvar-self.stderr
+++ b/src/test/ui/regions/regions-addr-of-upvar-self.stderr
@@ -4,7 +4,7 @@
LL | let p: &'static mut usize = &mut self.food;
| ^^^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 9:18...
+note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 9:18...
--> $DIR/regions-addr-of-upvar-self.rs:9:18
|
LL | let _f = || {
diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr
index 61be077..c040178 100644
--- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr
+++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr
@@ -4,12 +4,12 @@
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 33:15
+note: the pointer is valid for the lifetime `'a` as defined on the function body at 33:15
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 33:18
+note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 33:18
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:18
|
LL | fn with_assoc<'a,'b>() {
diff --git a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr
index d01e991..a636c9e 100644
--- a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr
+++ b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr
@@ -4,7 +4,7 @@
LL | impl<'a> Foo<'static> for &'a i32 {
| ^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 14:6...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 14:6...
--> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:14:6
|
LL | impl<'a> Foo<'static> for &'a i32 {
@@ -25,7 +25,7 @@
LL | impl<'a,'b> Foo<'b> for &'a i64 {
| ^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 19:6...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 19:6...
--> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:19:6
|
LL | impl<'a,'b> Foo<'b> for &'a i64 {
@@ -33,7 +33,7 @@
= note: ...so that the types are compatible:
expected Foo<'b>
found Foo<'_>
-note: but, the lifetime must be valid for the lifetime 'b as defined on the impl at 19:9...
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the impl at 19:9...
--> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:19:9
|
LL | impl<'a,'b> Foo<'b> for &'a i64 {
diff --git a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr
index 33a4ea0..81256e3 100644
--- a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr
+++ b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr
@@ -4,7 +4,7 @@
LL | impl<'a> Foo for &'a i32 {
| ^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 9:6...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 9:6...
--> $DIR/regions-assoc-type-static-bound-in-trait-not-met.rs:9:6
|
LL | impl<'a> Foo for &'a i32 {
diff --git a/src/test/ui/regions/regions-bounds.stderr b/src/test/ui/regions/regions-bounds.stderr
index 27eb889..a15710b 100644
--- a/src/test/ui/regions/regions-bounds.stderr
+++ b/src/test/ui/regions/regions-bounds.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `TupleStruct<'b>`
found type `TupleStruct<'a>`
-note: the lifetime 'a as defined on the function body at 8:10...
+note: the lifetime `'a` as defined on the function body at 8:10...
--> $DIR/regions-bounds.rs:8:10
|
LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> {
| ^^
-note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 8:13
+note: ...does not necessarily outlive the lifetime `'b` as defined on the function body at 8:13
--> $DIR/regions-bounds.rs:8:13
|
LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> {
@@ -25,12 +25,12 @@
|
= note: expected type `Struct<'b>`
found type `Struct<'a>`
-note: the lifetime 'a as defined on the function body at 12:10...
+note: the lifetime `'a` as defined on the function body at 12:10...
--> $DIR/regions-bounds.rs:12:10
|
LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> {
| ^^
-note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 12:13
+note: ...does not necessarily outlive the lifetime `'b` as defined on the function body at 12:13
--> $DIR/regions-bounds.rs:12:13
|
LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> {
diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr
index 7af608d..8e473da 100644
--- a/src/test/ui/regions/regions-close-object-into-object-2.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr
@@ -4,7 +4,7 @@
LL | box B(&*v) as Box<dyn X>
| ^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:6...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6...
--> $DIR/regions-close-object-into-object-2.rs:9:6
|
LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr
index ef47db1..c80d13e 100644
--- a/src/test/ui/regions/regions-close-object-into-object-4.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr
@@ -4,7 +4,7 @@
LL | box B(&*v) as Box<dyn X>
| ^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:6...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6...
--> $DIR/regions-close-object-into-object-4.rs:9:6
|
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
diff --git a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr b/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr
index 6f7466a..ef21316 100644
--- a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr
+++ b/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr
@@ -4,7 +4,7 @@
LL | box v as Box<dyn SomeTrait + 'a>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 18:20...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 18:20...
--> $DIR/regions-close-over-type-parameter-multiple.rs:18:20
|
LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'c> {
@@ -14,7 +14,7 @@
|
LL | box v as Box<dyn SomeTrait + 'a>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: but, the lifetime must be valid for the lifetime 'c as defined on the function body at 18:26...
+note: but, the lifetime must be valid for the lifetime `'c` as defined on the function body at 18:26...
--> $DIR/regions-close-over-type-parameter-multiple.rs:18:26
|
LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'c> {
diff --git a/src/test/ui/regions/regions-creating-enums4.stderr b/src/test/ui/regions/regions-creating-enums4.stderr
index 4d00783..12b8978 100644
--- a/src/test/ui/regions/regions-creating-enums4.stderr
+++ b/src/test/ui/regions/regions-creating-enums4.stderr
@@ -4,7 +4,7 @@
LL | Ast::Add(x, y)
| ^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 6:16...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 6:16...
--> $DIR/regions-creating-enums4.rs:6:16
|
LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> {
@@ -12,7 +12,7 @@
= note: ...so that the expression is assignable:
expected &Ast<'_>
found &Ast<'a>
-note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 6:19...
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 6:19...
--> $DIR/regions-creating-enums4.rs:6:19
|
LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> {
diff --git a/src/test/ui/regions/regions-early-bound-error-method.stderr b/src/test/ui/regions/regions-early-bound-error-method.stderr
index 7b9f2c9..9095451 100644
--- a/src/test/ui/regions/regions-early-bound-error-method.stderr
+++ b/src/test/ui/regions/regions-early-bound-error-method.stderr
@@ -4,12 +4,12 @@
LL | g2.get()
| ^^^^^^^^
|
-note: ...the reference is valid for the lifetime 'a as defined on the impl at 18:6...
+note: ...the reference is valid for the lifetime `'a` as defined on the impl at 18:6...
--> $DIR/regions-early-bound-error-method.rs:18:6
|
LL | impl<'a> Box<'a> {
| ^^
-note: ...but the borrowed content is only valid for the lifetime 'b as defined on the method body at 19:11
+note: ...but the borrowed content is only valid for the lifetime `'b` as defined on the method body at 19:11
--> $DIR/regions-early-bound-error-method.rs:19:11
|
LL | fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize {
diff --git a/src/test/ui/regions/regions-early-bound-error.stderr b/src/test/ui/regions/regions-early-bound-error.stderr
index a68355b..162d573 100644
--- a/src/test/ui/regions/regions-early-bound-error.stderr
+++ b/src/test/ui/regions/regions-early-bound-error.stderr
@@ -4,12 +4,12 @@
LL | g1.get()
| ^^^^^^^^
|
-note: ...the reference is valid for the lifetime 'b as defined on the function body at 18:11...
+note: ...the reference is valid for the lifetime `'b` as defined on the function body at 18:11...
--> $DIR/regions-early-bound-error.rs:18:11
|
LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize {
| ^^
-note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 18:8
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 18:8
--> $DIR/regions-early-bound-error.rs:18:8
|
LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize {
diff --git a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr
index 3b8f09f..ad555ef 100644
--- a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr
+++ b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr
@@ -8,12 +8,12 @@
LL | | }
| |_^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 5:14
+note: the pointer is valid for the lifetime `'a` as defined on the function body at 5:14
--> $DIR/regions-free-region-ordering-callee-4.rs:5:14
|
LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 5:18
+note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 5:18
--> $DIR/regions-free-region-ordering-callee-4.rs:5:18
|
LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) {
diff --git a/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr b/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr
index 676e96a..1064417 100644
--- a/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr
+++ b/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr
@@ -4,7 +4,7 @@
LL | None => &self.val
| ^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the method body at 14:12...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the method body at 14:12...
--> $DIR/regions-free-region-ordering-incorrect.rs:14:12
|
LL | fn get<'a>(&'a self) -> &'b T {
@@ -14,7 +14,7 @@
|
LL | None => &self.val
| ^^^^^^^^^
-note: but, the lifetime must be valid for the lifetime 'b as defined on the impl at 13:6...
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the impl at 13:6...
--> $DIR/regions-free-region-ordering-incorrect.rs:13:6
|
LL | impl<'b, T> Node<'b, T> {
diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
index b3390bc..c4ca7e9 100644
--- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
+++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr
@@ -7,12 +7,12 @@
LL | | }
| |_^
|
-note: the pointer is valid for the lifetime 'x as defined on the function body at 21:11
+note: the pointer is valid for the lifetime `'x` as defined on the function body at 21:11
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:11
|
LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
| ^^
-note: but the referenced data is only valid for the lifetime 'y as defined on the function body at 21:15
+note: but the referenced data is only valid for the lifetime `'y` as defined on the function body at 21:15
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:15
|
LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-decl.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-decl.stderr
index d31ed3e..f4e223b 100644
--- a/src/test/ui/regions/regions-infer-invariance-due-to-decl.stderr
+++ b/src/test/ui/regions/regions-infer-invariance-due-to-decl.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `Invariant<'static>`
found type `Invariant<'r>`
-note: the lifetime 'r as defined on the function body at 11:23...
+note: the lifetime `'r` as defined on the function body at 11:23...
--> $DIR/regions-infer-invariance-due-to-decl.rs:11:23
|
LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> {
diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.stderr
index f8bdd01..6322244 100644
--- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.stderr
+++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `Invariant<'static>`
found type `Invariant<'r>`
-note: the lifetime 'r as defined on the function body at 9:23...
+note: the lifetime `'r` as defined on the function body at 9:23...
--> $DIR/regions-infer-invariance-due-to-mutability-3.rs:9:23
|
LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> {
diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.stderr
index 1de6f22..7baae69 100644
--- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.stderr
+++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `Invariant<'static>`
found type `Invariant<'r>`
-note: the lifetime 'r as defined on the function body at 9:23...
+note: the lifetime `'r` as defined on the function body at 9:23...
--> $DIR/regions-infer-invariance-due-to-mutability-4.rs:9:23
|
LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> {
diff --git a/src/test/ui/regions/regions-infer-not-param.stderr b/src/test/ui/regions/regions-infer-not-param.stderr
index f43ab82..6365769 100644
--- a/src/test/ui/regions/regions-infer-not-param.stderr
+++ b/src/test/ui/regions/regions-infer-not-param.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `Direct<'b>`
found type `Direct<'a>`
-note: the lifetime 'a as defined on the function body at 15:16...
+note: the lifetime `'a` as defined on the function body at 15:16...
--> $DIR/regions-infer-not-param.rs:15:16
|
LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p }
| ^^
-note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 15:19
+note: ...does not necessarily outlive the lifetime `'b` as defined on the function body at 15:19
--> $DIR/regions-infer-not-param.rs:15:19
|
LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p }
@@ -25,12 +25,12 @@
|
= note: expected type `Indirect2<'b>`
found type `Indirect2<'a>`
-note: the lifetime 'a as defined on the function body at 19:19...
+note: the lifetime `'a` as defined on the function body at 19:19...
--> $DIR/regions-infer-not-param.rs:19:19
|
LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p }
| ^^
-note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 19:22
+note: ...does not necessarily outlive the lifetime `'b` as defined on the function body at 19:22
--> $DIR/regions-infer-not-param.rs:19:22
|
LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p }
@@ -44,12 +44,12 @@
|
= note: expected type `Indirect2<'b>`
found type `Indirect2<'a>`
-note: the lifetime 'b as defined on the function body at 19:22...
+note: the lifetime `'b` as defined on the function body at 19:22...
--> $DIR/regions-infer-not-param.rs:19:22
|
LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p }
| ^^
-note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 19:19
+note: ...does not necessarily outlive the lifetime `'a` as defined on the function body at 19:19
--> $DIR/regions-infer-not-param.rs:19:19
|
LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p }
diff --git a/src/test/ui/regions/regions-infer-paramd-indirect.stderr b/src/test/ui/regions/regions-infer-paramd-indirect.stderr
index 1b999ed..b1fd337 100644
--- a/src/test/ui/regions/regions-infer-paramd-indirect.stderr
+++ b/src/test/ui/regions/regions-infer-paramd-indirect.stderr
@@ -17,7 +17,7 @@
LL | |
LL | | }
| |_____^
-note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 16:6
+note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 16:6
--> $DIR/regions-infer-paramd-indirect.rs:16:6
|
LL | impl<'a> SetF<'a> for C<'a> {
diff --git a/src/test/ui/regions/regions-nested-fns.stderr b/src/test/ui/regions/regions-nested-fns.stderr
index bc3c06d..f4eb5c8 100644
--- a/src/test/ui/regions/regions-nested-fns.stderr
+++ b/src/test/ui/regions/regions-nested-fns.stderr
@@ -49,7 +49,7 @@
LL | | return z;
LL | | }));
| |_____^
-note: ...but the borrowed content is only valid for the lifetime 'x as defined on the function body at 3:11
+note: ...but the borrowed content is only valid for the lifetime `'x` as defined on the function body at 3:11
--> $DIR/regions-nested-fns.rs:3:11
|
LL | fn nested<'x>(x: &'x isize) {
diff --git a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr
index c44edf1..d29fd80 100644
--- a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr
+++ b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr
@@ -7,12 +7,12 @@
LL | | }
| |_^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 22:8...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:8...
--> $DIR/regions-normalize-in-where-clause-list.rs:22:8
|
LL | fn bar<'a, 'b>()
| ^^
-note: ...but the lifetime must also be valid for the lifetime 'b as defined on the function body at 22:12...
+note: ...but the lifetime must also be valid for the lifetime `'b` as defined on the function body at 22:12...
--> $DIR/regions-normalize-in-where-clause-list.rs:22:12
|
LL | fn bar<'a, 'b>()
diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr
index ed58009..0992d9b 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr
@@ -4,12 +4,12 @@
LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 27:15
+note: the pointer is valid for the lifetime `'a` as defined on the function body at 27:15
--> $DIR/regions-outlives-projection-container-hrtb.rs:27:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 27:18
+note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 27:18
--> $DIR/regions-outlives-projection-container-hrtb.rs:27:18
|
LL | fn with_assoc<'a,'b>() {
@@ -21,12 +21,12 @@
LL | let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 46:19
+note: the pointer is valid for the lifetime `'a` as defined on the function body at 46:19
--> $DIR/regions-outlives-projection-container-hrtb.rs:46:19
|
LL | fn with_assoc_sub<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 46:22
+note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 46:22
--> $DIR/regions-outlives-projection-container-hrtb.rs:46:22
|
LL | fn with_assoc_sub<'a,'b>() {
diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr
index 152e6c5..49e28a1 100644
--- a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr
@@ -4,12 +4,12 @@
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 27:15
+note: the pointer is valid for the lifetime `'a` as defined on the function body at 27:15
--> $DIR/regions-outlives-projection-container-wc.rs:27:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 27:18
+note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 27:18
--> $DIR/regions-outlives-projection-container-wc.rs:27:18
|
LL | fn with_assoc<'a,'b>() {
diff --git a/src/test/ui/regions/regions-outlives-projection-container.stderr b/src/test/ui/regions/regions-outlives-projection-container.stderr
index 3c1a98a..dba15fb 100644
--- a/src/test/ui/regions/regions-outlives-projection-container.stderr
+++ b/src/test/ui/regions/regions-outlives-projection-container.stderr
@@ -4,12 +4,12 @@
LL | let _x: &'a WithAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 28:15
+note: the pointer is valid for the lifetime `'a` as defined on the function body at 28:15
--> $DIR/regions-outlives-projection-container.rs:28:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 28:18
+note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 28:18
--> $DIR/regions-outlives-projection-container.rs:28:18
|
LL | fn with_assoc<'a,'b>() {
@@ -21,12 +21,12 @@
LL | let _x: &'a WithoutAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 50:18
+note: the pointer is valid for the lifetime `'a` as defined on the function body at 50:18
--> $DIR/regions-outlives-projection-container.rs:50:18
|
LL | fn without_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 50:21
+note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 50:21
--> $DIR/regions-outlives-projection-container.rs:50:21
|
LL | fn without_assoc<'a,'b>() {
@@ -38,12 +38,12 @@
LL | call::<&'a WithAssoc<TheType<'b>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 58:20
+note: the pointer is valid for the lifetime `'a` as defined on the function body at 58:20
--> $DIR/regions-outlives-projection-container.rs:58:20
|
LL | fn call_with_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 58:23
+note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 58:23
--> $DIR/regions-outlives-projection-container.rs:58:23
|
LL | fn call_with_assoc<'a,'b>() {
@@ -55,12 +55,12 @@
LL | call::<&'a WithoutAssoc<TheType<'b>>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the function body at 67:23
+note: the pointer is valid for the lifetime `'a` as defined on the function body at 67:23
--> $DIR/regions-outlives-projection-container.rs:67:23
|
LL | fn call_without_assoc<'a,'b>() {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 67:26
+note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 67:26
--> $DIR/regions-outlives-projection-container.rs:67:26
|
LL | fn call_without_assoc<'a,'b>() {
diff --git a/src/test/ui/regions/regions-ret-borrowed-1.stderr b/src/test/ui/regions/regions-ret-borrowed-1.stderr
index 72e47ce..4907667 100644
--- a/src/test/ui/regions/regions-ret-borrowed-1.stderr
+++ b/src/test/ui/regions/regions-ret-borrowed-1.stderr
@@ -12,7 +12,7 @@
= note: ...so that the expression is assignable:
expected &isize
found &isize
-note: but, the lifetime must be valid for the lifetime 'a as defined on the function body at 9:14...
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 9:14...
--> $DIR/regions-ret-borrowed-1.rs:9:14
|
LL | fn return_it<'a>() -> &'a isize {
diff --git a/src/test/ui/regions/regions-ret-borrowed.stderr b/src/test/ui/regions/regions-ret-borrowed.stderr
index ce0c429..eb1ade2 100644
--- a/src/test/ui/regions/regions-ret-borrowed.stderr
+++ b/src/test/ui/regions/regions-ret-borrowed.stderr
@@ -12,7 +12,7 @@
= note: ...so that the expression is assignable:
expected &isize
found &isize
-note: but, the lifetime must be valid for the lifetime 'a as defined on the function body at 12:14...
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 12:14...
--> $DIR/regions-ret-borrowed.rs:12:14
|
LL | fn return_it<'a>() -> &'a isize {
diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
index be441bc..946465b 100644
--- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
+++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr
@@ -4,7 +4,7 @@
LL | let mut f = || &mut x;
| ^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 7:21...
+note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 7:21...
--> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:21
|
LL | let mut f = || &mut x;
diff --git a/src/test/ui/regions/regions-static-bound.migrate.stderr b/src/test/ui/regions/regions-static-bound.migrate.stderr
index 21ead8b..6e631d4 100644
--- a/src/test/ui/regions/regions-static-bound.migrate.stderr
+++ b/src/test/ui/regions/regions-static-bound.migrate.stderr
@@ -5,7 +5,7 @@
| ^
|
= note: ...the reference is valid for the static lifetime...
-note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 8:24
+note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 8:24
--> $DIR/regions-static-bound.rs:8:24
|
LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
diff --git a/src/test/ui/regions/regions-trait-1.stderr b/src/test/ui/regions/regions-trait-1.stderr
index 421f826..f835c00 100644
--- a/src/test/ui/regions/regions-trait-1.stderr
+++ b/src/test/ui/regions/regions-trait-1.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `fn(&HasCtxt<'a>) -> &Ctxt`
found type `fn(&HasCtxt<'a>) -> &'a Ctxt`
-note: the lifetime 'a as defined on the impl at 12:6...
+note: the lifetime `'a` as defined on the impl at 12:6...
--> $DIR/regions-trait-1.rs:12:6
|
LL | impl<'a> GetCtxt for HasCtxt<'a> {
diff --git a/src/test/ui/regions/regions-trait-object-subtyping.stderr b/src/test/ui/regions/regions-trait-object-subtyping.stderr
index d88be05..b7c7f93 100644
--- a/src/test/ui/regions/regions-trait-object-subtyping.stderr
+++ b/src/test/ui/regions/regions-trait-object-subtyping.stderr
@@ -4,12 +4,12 @@
LL | x
| ^
|
-note: lifetime parameter instantiated with the lifetime 'a as defined on the function body at 13:9
+note: lifetime parameter instantiated with the lifetime `'a` as defined on the function body at 13:9
--> $DIR/regions-trait-object-subtyping.rs:13:9
|
LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy {
| ^^
-note: but lifetime parameter must outlive the lifetime 'b as defined on the function body at 13:12
+note: but lifetime parameter must outlive the lifetime `'b` as defined on the function body at 13:12
--> $DIR/regions-trait-object-subtyping.rs:13:12
|
LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy {
@@ -21,7 +21,7 @@
LL | x
| ^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 13:9...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 13:9...
--> $DIR/regions-trait-object-subtyping.rs:13:9
|
LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy {
@@ -31,7 +31,7 @@
|
LL | x
| ^
-note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 13:12...
+note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 13:12...
--> $DIR/regions-trait-object-subtyping.rs:13:12
|
LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy {
@@ -48,12 +48,12 @@
|
= note: expected type `Wrapper<&'b mut (dyn Dummy + 'b)>`
found type `Wrapper<&'a mut (dyn Dummy + 'a)>`
-note: the lifetime 'b as defined on the function body at 20:15...
+note: the lifetime `'b` as defined on the function body at 20:15...
--> $DIR/regions-trait-object-subtyping.rs:20:15
|
LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dummy> {
| ^^
-note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 20:9
+note: ...does not necessarily outlive the lifetime `'a` as defined on the function body at 20:9
--> $DIR/regions-trait-object-subtyping.rs:20:9
|
LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dummy> {
diff --git a/src/test/ui/regions/regions-variance-invariant-use-covariant.stderr b/src/test/ui/regions/regions-variance-invariant-use-covariant.stderr
index 90b37ce..aae519c 100644
--- a/src/test/ui/regions/regions-variance-invariant-use-covariant.stderr
+++ b/src/test/ui/regions/regions-variance-invariant-use-covariant.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `Invariant<'static>`
found type `Invariant<'b>`
-note: the lifetime 'b as defined on the function body at 11:9...
+note: the lifetime `'b` as defined on the function body at 11:9...
--> $DIR/regions-variance-invariant-use-covariant.rs:11:9
|
LL | fn use_<'b>(c: Invariant<'b>) {
diff --git a/src/test/ui/regions/regions-wf-trait-object.stderr b/src/test/ui/regions/regions-wf-trait-object.stderr
index 4e12478..9f39508 100644
--- a/src/test/ui/regions/regions-wf-trait-object.stderr
+++ b/src/test/ui/regions/regions-wf-trait-object.stderr
@@ -4,12 +4,12 @@
LL | x: Box<dyn TheTrait<'a>+'b>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: lifetime parameter instantiated with the lifetime 'b as defined on the struct at 6:15
+note: lifetime parameter instantiated with the lifetime `'b` as defined on the struct at 6:15
--> $DIR/regions-wf-trait-object.rs:6:15
|
LL | struct Foo<'a,'b> {
| ^^
-note: but lifetime parameter must outlive the lifetime 'a as defined on the struct at 6:12
+note: but lifetime parameter must outlive the lifetime `'a` as defined on the struct at 6:12
--> $DIR/regions-wf-trait-object.rs:6:12
|
LL | struct Foo<'a,'b> {
diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr
index 16d27c9..609a401 100644
--- a/src/test/ui/reject-specialized-drops-8142.stderr
+++ b/src/test/ui/reject-specialized-drops-8142.stderr
@@ -34,7 +34,7 @@
|
= note: expected type `N<'n>`
found type `N<'static>`
-note: the lifetime 'n as defined on the struct at 8:10...
+note: the lifetime `'n` as defined on the struct at 8:10...
--> $DIR/reject-specialized-drops-8142.rs:8:10
|
LL | struct N<'n> { x: &'n i8 }
@@ -95,12 +95,12 @@
LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'l1 as defined on the struct at 17:10...
+note: first, the lifetime cannot outlive the lifetime `'l1` as defined on the struct at 17:10...
--> $DIR/reject-specialized-drops-8142.rs:17:10
|
LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 }
| ^^^
-note: ...but the lifetime must also be valid for the lifetime 'l2 as defined on the struct at 17:15...
+note: ...but the lifetime must also be valid for the lifetime `'l2` as defined on the struct at 17:15...
--> $DIR/reject-specialized-drops-8142.rs:17:15
|
LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 }
diff --git a/src/test/ui/resolve/issue-16058.stderr b/src/test/ui/resolve/issue-16058.stderr
index 64177ac..9766f8f 100644
--- a/src/test/ui/resolve/issue-16058.stderr
+++ b/src/test/ui/resolve/issue-16058.stderr
@@ -14,3 +14,4 @@
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr
index d00d873..513e02f 100644
--- a/src/test/ui/resolve/issue-21221-1.stderr
+++ b/src/test/ui/resolve/issue-21221-1.stderr
@@ -27,7 +27,7 @@
|
LL | use mul4::Mul;
|
-and 2 other candidates
+ and 2 other candidates
error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope
--> $DIR/issue-21221-1.rs:63:6
diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr
index 2e3c0f5..e693a0e 100644
--- a/src/test/ui/resolve/levenshtein.stderr
+++ b/src/test/ui/resolve/levenshtein.stderr
@@ -38,13 +38,13 @@
--> $DIR/levenshtein.rs:28:15
|
LL | let b: m::first = m::second; // Misspelled item in module.
- | ^^^^^ help: a struct with a similar name exists: `First`
+ | ^^^^^ help: a struct with a similar name exists (notice the capitalization): `First`
error[E0425]: cannot find value `second` in module `m`
--> $DIR/levenshtein.rs:28:26
|
LL | let b: m::first = m::second; // Misspelled item in module.
- | ^^^^^^ help: a unit struct with a similar name exists: `Second`
+ | ^^^^^^ help: a unit struct with a similar name exists (notice the capitalization): `Second`
error: aborting due to 8 previous errors
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.stderr
index be8b5c6..6efc117 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.stderr
@@ -4,12 +4,12 @@
LL | type Out = &'a Foo<'b>;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the impl at 16:10
+note: the pointer is valid for the lifetime `'a` as defined on the impl at 16:10
--> $DIR/regions-outlives-nominal-type-region-rev.rs:16:10
|
LL | impl<'a, 'b> Trait<'a, 'b> for usize {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 16:14
+note: but the referenced data is only valid for the lifetime `'b` as defined on the impl at 16:14
--> $DIR/regions-outlives-nominal-type-region-rev.rs:16:14
|
LL | impl<'a, 'b> Trait<'a, 'b> for usize {
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.stderr
index 9a3ba2d..06e5f24 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.stderr
@@ -4,12 +4,12 @@
LL | type Out = &'a Foo<'b>;
| ^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the impl at 16:10
+note: the pointer is valid for the lifetime `'a` as defined on the impl at 16:10
--> $DIR/regions-outlives-nominal-type-region.rs:16:10
|
LL | impl<'a, 'b> Trait<'a, 'b> for usize {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 16:14
+note: but the referenced data is only valid for the lifetime `'b` as defined on the impl at 16:14
--> $DIR/regions-outlives-nominal-type-region.rs:16:14
|
LL | impl<'a, 'b> Trait<'a, 'b> for usize {
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.stderr
index 5389bee..d02f7b7 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.stderr
@@ -4,12 +4,12 @@
LL | type Out = &'a Foo<&'b i32>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the impl at 16:10
+note: the pointer is valid for the lifetime `'a` as defined on the impl at 16:10
--> $DIR/regions-outlives-nominal-type-type-rev.rs:16:10
|
LL | impl<'a, 'b> Trait<'a, 'b> for usize {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 16:14
+note: but the referenced data is only valid for the lifetime `'b` as defined on the impl at 16:14
--> $DIR/regions-outlives-nominal-type-type-rev.rs:16:14
|
LL | impl<'a, 'b> Trait<'a, 'b> for usize {
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.stderr
index 2f3ef48..40c70f5 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.stderr
@@ -4,12 +4,12 @@
LL | type Out = &'a Foo<&'b i32>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the impl at 16:10
+note: the pointer is valid for the lifetime `'a` as defined on the impl at 16:10
--> $DIR/regions-outlives-nominal-type-type.rs:16:10
|
LL | impl<'a, 'b> Trait<'a, 'b> for usize {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 16:14
+note: but the referenced data is only valid for the lifetime `'b` as defined on the impl at 16:14
--> $DIR/regions-outlives-nominal-type-type.rs:16:14
|
LL | impl<'a, 'b> Trait<'a, 'b> for usize {
diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
index 5a11c5f..825c101 100644
--- a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
+++ b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr
@@ -32,12 +32,12 @@
LL | type Out = &'a &'b T;
| ^^^^^^^^^^^^^^^^^^^^^
|
-note: the pointer is valid for the lifetime 'a as defined on the impl at 24:6
+note: the pointer is valid for the lifetime `'a` as defined on the impl at 24:6
--> $DIR/regions-struct-not-wf.rs:24:6
|
LL | impl<'a, 'b, T> Trait1<'a, 'b, T> for u32 {
| ^^
-note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 24:10
+note: but the referenced data is only valid for the lifetime `'b` as defined on the impl at 24:10
--> $DIR/regions-struct-not-wf.rs:24:10
|
LL | impl<'a, 'b, T> Trait1<'a, 'b, T> for u32 {
diff --git a/src/test/ui/rust-2018/issue-52202-use-suggestions.stderr b/src/test/ui/rust-2018/issue-52202-use-suggestions.stderr
index 030fa56..973c486 100644
--- a/src/test/ui/rust-2018/issue-52202-use-suggestions.stderr
+++ b/src/test/ui/rust-2018/issue-52202-use-suggestions.stderr
@@ -13,7 +13,7 @@
|
LL | use std::collections::hash_set::Drain;
|
-and 3 other candidates
+ and 3 other candidates
error: aborting due to previous error
diff --git a/src/test/ui/save-analysis/issue-64659.rs b/src/test/ui/save-analysis/issue-64659.rs
new file mode 100644
index 0000000..a3d88a2
--- /dev/null
+++ b/src/test/ui/save-analysis/issue-64659.rs
@@ -0,0 +1,10 @@
+// check-pass
+// compile-flags: -Zsave-analysis
+
+trait Trait { type Assoc; }
+
+fn main() {
+ struct Data<T: Trait> {
+ x: T::Assoc,
+ }
+}
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
index 2fb1524..bce1900 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
@@ -6,12 +6,12 @@
| |
| ...but this borrow...
|
-note: ...can't outlive the lifetime '_ as defined on the method body at 8:26
+note: ...can't outlive the lifetime `'_` as defined on the method body at 8:26
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:26
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| ^
-help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 8:26
+help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'_` as defined on the method body at 8:26
|
LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
| ^^^^^^^^^^^^^^^
diff --git a/src/test/ui/static/static-closures.stderr b/src/test/ui/static/static-closures.stderr
index ced78c0..99235e2 100644
--- a/src/test/ui/static/static-closures.stderr
+++ b/src/test/ui/static/static-closures.stderr
@@ -6,3 +6,4 @@
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0697`.
diff --git a/src/test/ui/static/static-lifetime.stderr b/src/test/ui/static/static-lifetime.stderr
index 8516ac0..bda325d 100644
--- a/src/test/ui/static/static-lifetime.stderr
+++ b/src/test/ui/static/static-lifetime.stderr
@@ -4,7 +4,7 @@
LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {}
| ^^^^^^^^^
|
-note: lifetime parameter instantiated with the lifetime 'a as defined on the impl at 3:6
+note: lifetime parameter instantiated with the lifetime `'a` as defined on the impl at 3:6
--> $DIR/static-lifetime.rs:3:6
|
LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {}
diff --git a/src/test/ui/suggestions/constrain-trait.fixed b/src/test/ui/suggestions/constrain-trait.fixed
new file mode 100644
index 0000000..dda9e93
--- /dev/null
+++ b/src/test/ui/suggestions/constrain-trait.fixed
@@ -0,0 +1,47 @@
+// run-rustfix
+// check-only
+
+#[derive(Debug)]
+struct Demo {
+ a: String
+}
+
+trait GetString {
+ fn get_a(&self) -> &String;
+}
+
+trait UseString: std::fmt::Debug + GetString {
+ fn use_string(&self) {
+ println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self`
+ }
+}
+
+trait UseString2: GetString {
+ fn use_string(&self) {
+ println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self`
+ }
+}
+
+impl GetString for Demo {
+ fn get_a(&self) -> &String {
+ &self.a
+ }
+}
+
+impl UseString for Demo {}
+impl UseString2 for Demo {}
+
+
+#[cfg(test)]
+mod tests {
+ use crate::{Demo, UseString};
+
+ #[test]
+ fn it_works() {
+ let d = Demo { a: "test".to_string() };
+ d.use_string();
+ }
+}
+
+
+fn main() {}
diff --git a/src/test/ui/suggestions/constrain-trait.rs b/src/test/ui/suggestions/constrain-trait.rs
new file mode 100644
index 0000000..4ef0eff
--- /dev/null
+++ b/src/test/ui/suggestions/constrain-trait.rs
@@ -0,0 +1,47 @@
+// run-rustfix
+// check-only
+
+#[derive(Debug)]
+struct Demo {
+ a: String
+}
+
+trait GetString {
+ fn get_a(&self) -> &String;
+}
+
+trait UseString: std::fmt::Debug {
+ fn use_string(&self) {
+ println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self`
+ }
+}
+
+trait UseString2 {
+ fn use_string(&self) {
+ println!("{:?}", self.get_a()); //~ ERROR no method named `get_a` found for type `&Self`
+ }
+}
+
+impl GetString for Demo {
+ fn get_a(&self) -> &String {
+ &self.a
+ }
+}
+
+impl UseString for Demo {}
+impl UseString2 for Demo {}
+
+
+#[cfg(test)]
+mod tests {
+ use crate::{Demo, UseString};
+
+ #[test]
+ fn it_works() {
+ let d = Demo { a: "test".to_string() };
+ d.use_string();
+ }
+}
+
+
+fn main() {}
diff --git a/src/test/ui/suggestions/constrain-trait.stderr b/src/test/ui/suggestions/constrain-trait.stderr
new file mode 100644
index 0000000..3cc351a
--- /dev/null
+++ b/src/test/ui/suggestions/constrain-trait.stderr
@@ -0,0 +1,27 @@
+error[E0599]: no method named `get_a` found for type `&Self` in the current scope
+ --> $DIR/constrain-trait.rs:15:31
+ |
+LL | println!("{:?}", self.get_a());
+ | ^^^^^ method not found in `&Self`
+ |
+ = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following trait defines an item `get_a`, perhaps you need to add another supertrait for it:
+ |
+LL | trait UseString: std::fmt::Debug + GetString {
+ | ^^^^^^^^^^^
+
+error[E0599]: no method named `get_a` found for type `&Self` in the current scope
+ --> $DIR/constrain-trait.rs:21:31
+ |
+LL | println!("{:?}", self.get_a());
+ | ^^^^^ method not found in `&Self`
+ |
+ = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following trait defines an item `get_a`, perhaps you need to add a supertrait for it:
+ |
+LL | trait UseString2: GetString {
+ | ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/traits/trait-as-struct-constructor.stderr b/src/test/ui/traits/trait-as-struct-constructor.stderr
index 434dcbc..e1d54fb 100644
--- a/src/test/ui/traits/trait-as-struct-constructor.stderr
+++ b/src/test/ui/traits/trait-as-struct-constructor.stderr
@@ -6,3 +6,4 @@
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr b/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr
index 4c63d60..88c9c47 100644
--- a/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr
+++ b/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr
@@ -4,12 +4,12 @@
LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> {
| ^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 24:6...
+note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 24:6...
--> $DIR/trait-impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:6
|
LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> {
| ^^
-note: ...but the lifetime must also be valid for the lifetime 'b as defined on the impl at 24:9...
+note: ...but the lifetime must also be valid for the lifetime `'b` as defined on the impl at 24:9...
--> $DIR/trait-impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:9
|
LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> {
diff --git a/src/test/ui/traits/trait-matching-lifetimes.stderr b/src/test/ui/traits/trait-matching-lifetimes.stderr
index 80c5776..e1ccde3 100644
--- a/src/test/ui/traits/trait-matching-lifetimes.stderr
+++ b/src/test/ui/traits/trait-matching-lifetimes.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `fn(Foo<'a, 'b>)`
found type `fn(Foo<'b, 'a>)`
-note: the lifetime 'b as defined on the impl at 13:9...
+note: the lifetime `'b` as defined on the impl at 13:9...
--> $DIR/trait-matching-lifetimes.rs:13:9
|
LL | impl<'a,'b> Tr for Foo<'a,'b> {
| ^^
-note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 13:6
+note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 13:6
--> $DIR/trait-matching-lifetimes.rs:13:6
|
LL | impl<'a,'b> Tr for Foo<'a,'b> {
@@ -25,12 +25,12 @@
|
= note: expected type `fn(Foo<'a, 'b>)`
found type `fn(Foo<'b, 'a>)`
-note: the lifetime 'a as defined on the impl at 13:6...
+note: the lifetime `'a` as defined on the impl at 13:6...
--> $DIR/trait-matching-lifetimes.rs:13:6
|
LL | impl<'a,'b> Tr for Foo<'a,'b> {
| ^^
-note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 13:9
+note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 13:9
--> $DIR/trait-matching-lifetimes.rs:13:9
|
LL | impl<'a,'b> Tr for Foo<'a,'b> {
diff --git a/src/test/ui/try-block/try-block-in-edition2015.stderr b/src/test/ui/try-block/try-block-in-edition2015.stderr
index 7034cdc..c94e431 100644
--- a/src/test/ui/try-block/try-block-in-edition2015.stderr
+++ b/src/test/ui/try-block/try-block-in-edition2015.stderr
@@ -21,3 +21,4 @@
error: aborting due to 2 previous errors
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr
index b2fe1b2..de3a997 100644
--- a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr
+++ b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr
@@ -38,7 +38,7 @@
|
LL | fn dummy2(self: &Bar<T>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 35:6
+note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 35:6
--> $DIR/ufcs-explicit-self-bad.rs:35:6
|
LL | impl<'a, T> SomeTrait for &'a Bar<T> {
@@ -52,7 +52,7 @@
|
= note: expected type `&'a Bar<T>`
found type `&Bar<T>`
-note: the lifetime 'a as defined on the impl at 35:6...
+note: the lifetime `'a` as defined on the impl at 35:6...
--> $DIR/ufcs-explicit-self-bad.rs:35:6
|
LL | impl<'a, T> SomeTrait for &'a Bar<T> {
@@ -76,7 +76,7 @@
|
LL | fn dummy3(self: &&Bar<T>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 35:6
+note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 35:6
--> $DIR/ufcs-explicit-self-bad.rs:35:6
|
LL | impl<'a, T> SomeTrait for &'a Bar<T> {
@@ -90,7 +90,7 @@
|
= note: expected type `&'a Bar<T>`
found type `&Bar<T>`
-note: the lifetime 'a as defined on the impl at 35:6...
+note: the lifetime `'a` as defined on the impl at 35:6...
--> $DIR/ufcs-explicit-self-bad.rs:35:6
|
LL | impl<'a, T> SomeTrait for &'a Bar<T> {
diff --git a/src/test/ui/underscore-imports/hygiene-2.rs b/src/test/ui/underscore-imports/hygiene-2.rs
new file mode 100644
index 0000000..bea61ea
--- /dev/null
+++ b/src/test/ui/underscore-imports/hygiene-2.rs
@@ -0,0 +1,33 @@
+// Make sure that underscore imports with different contexts can exist in the
+// same scope.
+
+// check-pass
+
+#![feature(decl_macro)]
+
+mod x {
+ pub use std::ops::Deref as _;
+}
+
+macro n() {
+ pub use crate::x::*;
+}
+
+#[macro_export]
+macro_rules! p {
+ () => { pub use crate::x::*; }
+}
+
+macro m($y:ident) {
+ mod $y {
+ crate::n!(); // Reexport of `Deref` should not be imported in `main`
+ crate::p!(); // Reexport of `Deref` should be imported into `main`
+ }
+}
+
+m!(y);
+
+fn main() {
+ use crate::y::*;
+ (&()).deref();
+}
diff --git a/src/test/ui/underscore-imports/hygiene.rs b/src/test/ui/underscore-imports/hygiene.rs
new file mode 100644
index 0000000..a254f6e
--- /dev/null
+++ b/src/test/ui/underscore-imports/hygiene.rs
@@ -0,0 +1,40 @@
+// Make sure that underscore imports have the same hygiene considerations as
+// other imports.
+
+#![feature(decl_macro)]
+
+mod x {
+ pub use std::ops::Deref as _;
+}
+
+
+macro glob_import() {
+ pub use crate::x::*;
+}
+
+macro underscore_import() {
+ use std::ops::DerefMut as _;
+}
+
+mod y {
+ crate::glob_import!();
+ crate::underscore_import!();
+}
+
+macro create_module($y:ident) {
+ mod $y {
+ crate::glob_import!();
+ crate::underscore_import!();
+ }
+}
+
+create_module!(z);
+
+fn main() {
+ use crate::y::*;
+ use crate::z::*;
+ glob_import!();
+ underscore_import!();
+ (&()).deref(); //~ ERROR no method named `deref`
+ (&mut ()).deref_mut(); //~ ERROR no method named `deref_mut`
+}
diff --git a/src/test/ui/underscore-imports/hygiene.stderr b/src/test/ui/underscore-imports/hygiene.stderr
new file mode 100644
index 0000000..44cfc5c
--- /dev/null
+++ b/src/test/ui/underscore-imports/hygiene.stderr
@@ -0,0 +1,27 @@
+error[E0599]: no method named `deref` found for type `&()` in the current scope
+ --> $DIR/hygiene.rs:38:11
+ |
+LL | (&()).deref();
+ | ^^^^^ method not found in `&()`
+ |
+ = help: items from traits can only be used if the trait is in scope
+help: the following trait is implemented but not in scope; perhaps add a `use` for it:
+ |
+LL | use std::ops::Deref;
+ |
+
+error[E0599]: no method named `deref_mut` found for type `&mut ()` in the current scope
+ --> $DIR/hygiene.rs:39:15
+ |
+LL | (&mut ()).deref_mut();
+ | ^^^^^^^^^ method not found in `&mut ()`
+ |
+ = help: items from traits can only be used if the trait is in scope
+help: the following trait is implemented but not in scope; perhaps add a `use` for it:
+ |
+LL | use std::ops::DerefMut;
+ |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/underscore-imports/macro-expanded.rs b/src/test/ui/underscore-imports/macro-expanded.rs
new file mode 100644
index 0000000..43f527b
--- /dev/null
+++ b/src/test/ui/underscore-imports/macro-expanded.rs
@@ -0,0 +1,45 @@
+// Check that macro expanded underscore imports behave as expected
+
+// check-pass
+
+#![feature(decl_macro, rustc_attrs)]
+
+mod x {
+ pub use std::ops::Not as _;
+}
+
+macro m() {
+ mod w {
+ mod y {
+ pub use std::ops::Deref as _;
+ }
+ use crate::x::*;
+ use self::y::*;
+ use std::ops::DerefMut as _;
+ fn f() {
+ false.not();
+ (&()).deref();
+ (&mut ()).deref_mut();
+ }
+ }
+}
+
+#[rustc_macro_transparency = "transparent"]
+macro n() {
+ mod z {
+ pub use std::ops::Deref as _;
+ }
+ use crate::x::*;
+ use crate::z::*;
+ use std::ops::DerefMut as _;
+ fn f() {
+ false.not();
+ (&()).deref();
+ (&mut ()).deref_mut();
+ }
+}
+
+m!();
+n!();
+
+fn main() {}
diff --git a/src/test/ui/use/issue-18986.stderr b/src/test/ui/use/issue-18986.stderr
index 14e1bb6..6c23178 100644
--- a/src/test/ui/use/issue-18986.stderr
+++ b/src/test/ui/use/issue-18986.stderr
@@ -6,3 +6,4 @@
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0574`.
diff --git a/src/test/ui/variance/variance-btree-invariant-types.stderr b/src/test/ui/variance/variance-btree-invariant-types.stderr
index 49222fc..0f93927 100644
--- a/src/test/ui/variance/variance-btree-invariant-types.stderr
+++ b/src/test/ui/variance/variance-btree-invariant-types.stderr
@@ -6,7 +6,7 @@
|
= note: expected type `std::collections::btree_map::IterMut<'_, &'new (), _>`
found type `std::collections::btree_map::IterMut<'_, &'static (), _>`
-note: the lifetime 'new as defined on the function body at 3:21...
+note: the lifetime `'new` as defined on the function body at 3:21...
--> $DIR/variance-btree-invariant-types.rs:3:21
|
LL | fn iter_cov_key<'a, 'new>(v: IterMut<'a, &'static (), ()>) -> IterMut<'a, &'new (), ()> {
@@ -21,7 +21,7 @@
|
= note: expected type `std::collections::btree_map::IterMut<'_, _, &'new ()>`
found type `std::collections::btree_map::IterMut<'_, _, &'static ()>`
-note: the lifetime 'new as defined on the function body at 6:21...
+note: the lifetime `'new` as defined on the function body at 6:21...
--> $DIR/variance-btree-invariant-types.rs:6:21
|
LL | fn iter_cov_val<'a, 'new>(v: IterMut<'a, (), &'static ()>) -> IterMut<'a, (), &'new ()> {
@@ -36,7 +36,7 @@
|
= note: expected type `std::collections::btree_map::IterMut<'_, &'static (), _>`
found type `std::collections::btree_map::IterMut<'_, &'new (), _>`
-note: the lifetime 'new as defined on the function body at 9:24...
+note: the lifetime `'new` as defined on the function body at 9:24...
--> $DIR/variance-btree-invariant-types.rs:9:24
|
LL | fn iter_contra_key<'a, 'new>(v: IterMut<'a, &'new (), ()>) -> IterMut<'a, &'static (), ()> {
@@ -51,7 +51,7 @@
|
= note: expected type `std::collections::btree_map::IterMut<'_, _, &'static ()>`
found type `std::collections::btree_map::IterMut<'_, _, &'new ()>`
-note: the lifetime 'new as defined on the function body at 12:24...
+note: the lifetime `'new` as defined on the function body at 12:24...
--> $DIR/variance-btree-invariant-types.rs:12:24
|
LL | fn iter_contra_val<'a, 'new>(v: IterMut<'a, (), &'new ()>) -> IterMut<'a, (), &'static ()> {
@@ -66,7 +66,7 @@
|
= note: expected type `std::collections::btree_map::OccupiedEntry<'_, &'new (), _>`
found type `std::collections::btree_map::OccupiedEntry<'_, &'static (), _>`
-note: the lifetime 'new as defined on the function body at 16:20...
+note: the lifetime `'new` as defined on the function body at 16:20...
--> $DIR/variance-btree-invariant-types.rs:16:20
|
LL | fn occ_cov_key<'a, 'new>(v: OccupiedEntry<'a, &'static (), ()>)
@@ -81,7 +81,7 @@
|
= note: expected type `std::collections::btree_map::OccupiedEntry<'_, _, &'new ()>`
found type `std::collections::btree_map::OccupiedEntry<'_, _, &'static ()>`
-note: the lifetime 'new as defined on the function body at 20:20...
+note: the lifetime `'new` as defined on the function body at 20:20...
--> $DIR/variance-btree-invariant-types.rs:20:20
|
LL | fn occ_cov_val<'a, 'new>(v: OccupiedEntry<'a, (), &'static ()>)
@@ -96,7 +96,7 @@
|
= note: expected type `std::collections::btree_map::OccupiedEntry<'_, &'static (), _>`
found type `std::collections::btree_map::OccupiedEntry<'_, &'new (), _>`
-note: the lifetime 'new as defined on the function body at 24:23...
+note: the lifetime `'new` as defined on the function body at 24:23...
--> $DIR/variance-btree-invariant-types.rs:24:23
|
LL | fn occ_contra_key<'a, 'new>(v: OccupiedEntry<'a, &'new (), ()>)
@@ -111,7 +111,7 @@
|
= note: expected type `std::collections::btree_map::OccupiedEntry<'_, _, &'static ()>`
found type `std::collections::btree_map::OccupiedEntry<'_, _, &'new ()>`
-note: the lifetime 'new as defined on the function body at 28:23...
+note: the lifetime `'new` as defined on the function body at 28:23...
--> $DIR/variance-btree-invariant-types.rs:28:23
|
LL | fn occ_contra_val<'a, 'new>(v: OccupiedEntry<'a, (), &'new ()>)
@@ -126,7 +126,7 @@
|
= note: expected type `std::collections::btree_map::VacantEntry<'_, &'new (), _>`
found type `std::collections::btree_map::VacantEntry<'_, &'static (), _>`
-note: the lifetime 'new as defined on the function body at 33:20...
+note: the lifetime `'new` as defined on the function body at 33:20...
--> $DIR/variance-btree-invariant-types.rs:33:20
|
LL | fn vac_cov_key<'a, 'new>(v: VacantEntry<'a, &'static (), ()>)
@@ -141,7 +141,7 @@
|
= note: expected type `std::collections::btree_map::VacantEntry<'_, _, &'new ()>`
found type `std::collections::btree_map::VacantEntry<'_, _, &'static ()>`
-note: the lifetime 'new as defined on the function body at 37:20...
+note: the lifetime `'new` as defined on the function body at 37:20...
--> $DIR/variance-btree-invariant-types.rs:37:20
|
LL | fn vac_cov_val<'a, 'new>(v: VacantEntry<'a, (), &'static ()>)
@@ -156,7 +156,7 @@
|
= note: expected type `std::collections::btree_map::VacantEntry<'_, &'static (), _>`
found type `std::collections::btree_map::VacantEntry<'_, &'new (), _>`
-note: the lifetime 'new as defined on the function body at 41:23...
+note: the lifetime `'new` as defined on the function body at 41:23...
--> $DIR/variance-btree-invariant-types.rs:41:23
|
LL | fn vac_contra_key<'a, 'new>(v: VacantEntry<'a, &'new (), ()>)
@@ -171,7 +171,7 @@
|
= note: expected type `std::collections::btree_map::VacantEntry<'_, _, &'static ()>`
found type `std::collections::btree_map::VacantEntry<'_, _, &'new ()>`
-note: the lifetime 'new as defined on the function body at 45:23...
+note: the lifetime `'new` as defined on the function body at 45:23...
--> $DIR/variance-btree-invariant-types.rs:45:23
|
LL | fn vac_contra_val<'a, 'new>(v: VacantEntry<'a, (), &'new ()>)
diff --git a/src/test/ui/variance/variance-contravariant-arg-object.stderr b/src/test/ui/variance/variance-contravariant-arg-object.stderr
index 263c849..27017e5 100644
--- a/src/test/ui/variance/variance-contravariant-arg-object.stderr
+++ b/src/test/ui/variance/variance-contravariant-arg-object.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `dyn Get<&'min i32>`
found type `dyn Get<&'max i32>`
-note: the lifetime 'min as defined on the function body at 10:21...
+note: the lifetime `'min` as defined on the function body at 10:21...
--> $DIR/variance-contravariant-arg-object.rs:10:21
|
LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>)
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27
--> $DIR/variance-contravariant-arg-object.rs:10:27
|
LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>)
@@ -25,12 +25,12 @@
|
= note: expected type `dyn Get<&'max i32>`
found type `dyn Get<&'min i32>`
-note: the lifetime 'min as defined on the function body at 17:21...
+note: the lifetime `'min` as defined on the function body at 17:21...
--> $DIR/variance-contravariant-arg-object.rs:17:21
|
LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>)
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 17:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 17:27
--> $DIR/variance-contravariant-arg-object.rs:17:27
|
LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>)
diff --git a/src/test/ui/variance/variance-contravariant-arg-trait-match.stderr b/src/test/ui/variance/variance-contravariant-arg-trait-match.stderr
index ffe690d..1752b3b 100644
--- a/src/test/ui/variance/variance-contravariant-arg-trait-match.stderr
+++ b/src/test/ui/variance/variance-contravariant-arg-trait-match.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `Get<&'min i32>`
found type `Get<&'max i32>`
-note: the lifetime 'min as defined on the function body at 10:21...
+note: the lifetime `'min` as defined on the function body at 10:21...
--> $DIR/variance-contravariant-arg-trait-match.rs:10:21
|
LL | fn get_min_from_max<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27
--> $DIR/variance-contravariant-arg-trait-match.rs:10:27
|
LL | fn get_min_from_max<'min, 'max, G>()
@@ -25,12 +25,12 @@
|
= note: expected type `Get<&'max i32>`
found type `Get<&'min i32>`
-note: the lifetime 'min as defined on the function body at 16:21...
+note: the lifetime `'min` as defined on the function body at 16:21...
--> $DIR/variance-contravariant-arg-trait-match.rs:16:21
|
LL | fn get_max_from_min<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 16:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 16:27
--> $DIR/variance-contravariant-arg-trait-match.rs:16:27
|
LL | fn get_max_from_min<'min, 'max, G>()
diff --git a/src/test/ui/variance/variance-contravariant-self-trait-match.stderr b/src/test/ui/variance/variance-contravariant-self-trait-match.stderr
index 6f445d7..e35aec4 100644
--- a/src/test/ui/variance/variance-contravariant-self-trait-match.stderr
+++ b/src/test/ui/variance/variance-contravariant-self-trait-match.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `Get`
found type `Get`
-note: the lifetime 'min as defined on the function body at 10:21...
+note: the lifetime `'min` as defined on the function body at 10:21...
--> $DIR/variance-contravariant-self-trait-match.rs:10:21
|
LL | fn get_min_from_max<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27
--> $DIR/variance-contravariant-self-trait-match.rs:10:27
|
LL | fn get_min_from_max<'min, 'max, G>()
@@ -25,12 +25,12 @@
|
= note: expected type `Get`
found type `Get`
-note: the lifetime 'min as defined on the function body at 16:21...
+note: the lifetime `'min` as defined on the function body at 16:21...
--> $DIR/variance-contravariant-self-trait-match.rs:16:21
|
LL | fn get_max_from_min<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 16:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 16:27
--> $DIR/variance-contravariant-self-trait-match.rs:16:27
|
LL | fn get_max_from_min<'min, 'max, G>()
diff --git a/src/test/ui/variance/variance-covariant-arg-object.stderr b/src/test/ui/variance/variance-covariant-arg-object.stderr
index 94f80c2..b986edb 100644
--- a/src/test/ui/variance/variance-covariant-arg-object.stderr
+++ b/src/test/ui/variance/variance-covariant-arg-object.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `dyn Get<&'min i32>`
found type `dyn Get<&'max i32>`
-note: the lifetime 'min as defined on the function body at 10:21...
+note: the lifetime `'min` as defined on the function body at 10:21...
--> $DIR/variance-covariant-arg-object.rs:10:21
|
LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>)
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27
--> $DIR/variance-covariant-arg-object.rs:10:27
|
LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>)
@@ -25,12 +25,12 @@
|
= note: expected type `dyn Get<&'max i32>`
found type `dyn Get<&'min i32>`
-note: the lifetime 'min as defined on the function body at 18:21...
+note: the lifetime `'min` as defined on the function body at 18:21...
--> $DIR/variance-covariant-arg-object.rs:18:21
|
LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>)
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 18:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 18:27
--> $DIR/variance-covariant-arg-object.rs:18:27
|
LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>)
diff --git a/src/test/ui/variance/variance-covariant-arg-trait-match.stderr b/src/test/ui/variance/variance-covariant-arg-trait-match.stderr
index c0209ed..aa383fc 100644
--- a/src/test/ui/variance/variance-covariant-arg-trait-match.stderr
+++ b/src/test/ui/variance/variance-covariant-arg-trait-match.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `Get<&'min i32>`
found type `Get<&'max i32>`
-note: the lifetime 'min as defined on the function body at 10:21...
+note: the lifetime `'min` as defined on the function body at 10:21...
--> $DIR/variance-covariant-arg-trait-match.rs:10:21
|
LL | fn get_min_from_max<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27
--> $DIR/variance-covariant-arg-trait-match.rs:10:27
|
LL | fn get_min_from_max<'min, 'max, G>()
@@ -25,12 +25,12 @@
|
= note: expected type `Get<&'max i32>`
found type `Get<&'min i32>`
-note: the lifetime 'min as defined on the function body at 17:21...
+note: the lifetime `'min` as defined on the function body at 17:21...
--> $DIR/variance-covariant-arg-trait-match.rs:17:21
|
LL | fn get_max_from_min<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 17:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 17:27
--> $DIR/variance-covariant-arg-trait-match.rs:17:27
|
LL | fn get_max_from_min<'min, 'max, G>()
diff --git a/src/test/ui/variance/variance-covariant-self-trait-match.stderr b/src/test/ui/variance/variance-covariant-self-trait-match.stderr
index fe5fe10..a25d104 100644
--- a/src/test/ui/variance/variance-covariant-self-trait-match.stderr
+++ b/src/test/ui/variance/variance-covariant-self-trait-match.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `Get`
found type `Get`
-note: the lifetime 'min as defined on the function body at 10:21...
+note: the lifetime `'min` as defined on the function body at 10:21...
--> $DIR/variance-covariant-self-trait-match.rs:10:21
|
LL | fn get_min_from_max<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27
--> $DIR/variance-covariant-self-trait-match.rs:10:27
|
LL | fn get_min_from_max<'min, 'max, G>()
@@ -25,12 +25,12 @@
|
= note: expected type `Get`
found type `Get`
-note: the lifetime 'min as defined on the function body at 17:21...
+note: the lifetime `'min` as defined on the function body at 17:21...
--> $DIR/variance-covariant-self-trait-match.rs:17:21
|
LL | fn get_max_from_min<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 17:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 17:27
--> $DIR/variance-covariant-self-trait-match.rs:17:27
|
LL | fn get_max_from_min<'min, 'max, G>()
diff --git a/src/test/ui/variance/variance-invariant-arg-object.stderr b/src/test/ui/variance/variance-invariant-arg-object.stderr
index 50a8697..8ff1e23 100644
--- a/src/test/ui/variance/variance-invariant-arg-object.stderr
+++ b/src/test/ui/variance/variance-invariant-arg-object.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `dyn Get<&'min i32>`
found type `dyn Get<&'max i32>`
-note: the lifetime 'min as defined on the function body at 7:21...
+note: the lifetime `'min` as defined on the function body at 7:21...
--> $DIR/variance-invariant-arg-object.rs:7:21
|
LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>)
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 7:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 7:27
--> $DIR/variance-invariant-arg-object.rs:7:27
|
LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>)
@@ -25,12 +25,12 @@
|
= note: expected type `dyn Get<&'max i32>`
found type `dyn Get<&'min i32>`
-note: the lifetime 'min as defined on the function body at 14:21...
+note: the lifetime `'min` as defined on the function body at 14:21...
--> $DIR/variance-invariant-arg-object.rs:14:21
|
LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>)
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 14:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 14:27
--> $DIR/variance-invariant-arg-object.rs:14:27
|
LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>)
diff --git a/src/test/ui/variance/variance-invariant-arg-trait-match.stderr b/src/test/ui/variance/variance-invariant-arg-trait-match.stderr
index c8a1111..b589937 100644
--- a/src/test/ui/variance/variance-invariant-arg-trait-match.stderr
+++ b/src/test/ui/variance/variance-invariant-arg-trait-match.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `Get<&'min i32>`
found type `Get<&'max i32>`
-note: the lifetime 'min as defined on the function body at 7:21...
+note: the lifetime `'min` as defined on the function body at 7:21...
--> $DIR/variance-invariant-arg-trait-match.rs:7:21
|
LL | fn get_min_from_max<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 7:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 7:27
--> $DIR/variance-invariant-arg-trait-match.rs:7:27
|
LL | fn get_min_from_max<'min, 'max, G>()
@@ -25,12 +25,12 @@
|
= note: expected type `Get<&'max i32>`
found type `Get<&'min i32>`
-note: the lifetime 'min as defined on the function body at 13:21...
+note: the lifetime `'min` as defined on the function body at 13:21...
--> $DIR/variance-invariant-arg-trait-match.rs:13:21
|
LL | fn get_max_from_min<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 13:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 13:27
--> $DIR/variance-invariant-arg-trait-match.rs:13:27
|
LL | fn get_max_from_min<'min, 'max, G>()
diff --git a/src/test/ui/variance/variance-invariant-self-trait-match.stderr b/src/test/ui/variance/variance-invariant-self-trait-match.stderr
index cb03d95..4a1d4d2 100644
--- a/src/test/ui/variance/variance-invariant-self-trait-match.stderr
+++ b/src/test/ui/variance/variance-invariant-self-trait-match.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `Get`
found type `Get`
-note: the lifetime 'min as defined on the function body at 7:21...
+note: the lifetime `'min` as defined on the function body at 7:21...
--> $DIR/variance-invariant-self-trait-match.rs:7:21
|
LL | fn get_min_from_max<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 7:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 7:27
--> $DIR/variance-invariant-self-trait-match.rs:7:27
|
LL | fn get_min_from_max<'min, 'max, G>()
@@ -25,12 +25,12 @@
|
= note: expected type `Get`
found type `Get`
-note: the lifetime 'min as defined on the function body at 13:21...
+note: the lifetime `'min` as defined on the function body at 13:21...
--> $DIR/variance-invariant-self-trait-match.rs:13:21
|
LL | fn get_max_from_min<'min, 'max, G>()
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 13:27
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 13:27
--> $DIR/variance-invariant-self-trait-match.rs:13:27
|
LL | fn get_max_from_min<'min, 'max, G>()
diff --git a/src/test/ui/variance/variance-use-contravariant-struct-1.stderr b/src/test/ui/variance/variance-use-contravariant-struct-1.stderr
index 7c43337..618f56d 100644
--- a/src/test/ui/variance/variance-use-contravariant-struct-1.stderr
+++ b/src/test/ui/variance/variance-use-contravariant-struct-1.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `SomeStruct<&'min ()>`
found type `SomeStruct<&'max ()>`
-note: the lifetime 'min as defined on the function body at 8:8...
+note: the lifetime `'min` as defined on the function body at 8:8...
--> $DIR/variance-use-contravariant-struct-1.rs:8:8
|
LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>)
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 8:13
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 8:13
--> $DIR/variance-use-contravariant-struct-1.rs:8:13
|
LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>)
diff --git a/src/test/ui/variance/variance-use-covariant-struct-1.stderr b/src/test/ui/variance/variance-use-covariant-struct-1.stderr
index 6ae7d12..0b3a8dc 100644
--- a/src/test/ui/variance/variance-use-covariant-struct-1.stderr
+++ b/src/test/ui/variance/variance-use-covariant-struct-1.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `SomeStruct<&'max ()>`
found type `SomeStruct<&'min ()>`
-note: the lifetime 'min as defined on the function body at 6:8...
+note: the lifetime `'min` as defined on the function body at 6:8...
--> $DIR/variance-use-covariant-struct-1.rs:6:8
|
LL | fn foo<'min,'max>(v: SomeStruct<&'min ()>)
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 6:13
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 6:13
--> $DIR/variance-use-covariant-struct-1.rs:6:13
|
LL | fn foo<'min,'max>(v: SomeStruct<&'min ()>)
diff --git a/src/test/ui/variance/variance-use-invariant-struct-1.stderr b/src/test/ui/variance/variance-use-invariant-struct-1.stderr
index 793954e..31deefb 100644
--- a/src/test/ui/variance/variance-use-invariant-struct-1.stderr
+++ b/src/test/ui/variance/variance-use-invariant-struct-1.stderr
@@ -6,12 +6,12 @@
|
= note: expected type `SomeStruct<&'min ()>`
found type `SomeStruct<&'max ()>`
-note: the lifetime 'min as defined on the function body at 8:8...
+note: the lifetime `'min` as defined on the function body at 8:8...
--> $DIR/variance-use-invariant-struct-1.rs:8:8
|
LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>)
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 8:13
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 8:13
--> $DIR/variance-use-invariant-struct-1.rs:8:13
|
LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>)
@@ -25,12 +25,12 @@
|
= note: expected type `SomeStruct<&'max ()>`
found type `SomeStruct<&'min ()>`
-note: the lifetime 'min as defined on the function body at 15:8...
+note: the lifetime `'min` as defined on the function body at 15:8...
--> $DIR/variance-use-invariant-struct-1.rs:15:8
|
LL | fn bar<'min,'max>(v: SomeStruct<&'min ()>)
| ^^^^
-note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 15:13
+note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 15:13
--> $DIR/variance-use-invariant-struct-1.rs:15:13
|
LL | fn bar<'min,'max>(v: SomeStruct<&'min ()>)
diff --git a/src/test/ui/wf/issue-48638.rs b/src/test/ui/wf/issue-48638.rs
new file mode 100644
index 0000000..f078431
--- /dev/null
+++ b/src/test/ui/wf/issue-48638.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+pub trait D {}
+pub struct DT;
+impl D for DT {}
+
+pub trait A<R: D>: Sized {
+ type AS;
+}
+
+pub struct As<R: D>(R);
+
+pub struct AT;
+impl<R: D> A<R> for AT {
+ type AS = As<R>;
+}
+
+#[repr(packed)]
+struct S(<AT as A<DT>>::AS);
+
+fn main() {}
diff --git a/src/test/ui/wf/wf-static-method.stderr b/src/test/ui/wf/wf-static-method.stderr
index da4e8eb..93d1651 100644
--- a/src/test/ui/wf/wf-static-method.stderr
+++ b/src/test/ui/wf/wf-static-method.stderr
@@ -4,12 +4,12 @@
LL | u
| ^
|
-note: ...the reference is valid for the lifetime 'a as defined on the impl at 14:6...
+note: ...the reference is valid for the lifetime `'a` as defined on the impl at 14:6...
--> $DIR/wf-static-method.rs:14:6
|
LL | impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () {
| ^^
-note: ...but the borrowed content is only valid for the lifetime 'b as defined on the impl at 14:10
+note: ...but the borrowed content is only valid for the lifetime `'b` as defined on the impl at 14:10
--> $DIR/wf-static-method.rs:14:10
|
LL | impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () {
@@ -21,12 +21,12 @@
LL | let me = Self::make_me();
| ^^^^^^^^^^^^^
|
-note: lifetime parameter instantiated with the lifetime 'b as defined on the impl at 23:10
+note: lifetime parameter instantiated with the lifetime `'b` as defined on the impl at 23:10
--> $DIR/wf-static-method.rs:23:10
|
LL | impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> {
| ^^
-note: but lifetime parameter must outlive the lifetime 'a as defined on the impl at 23:6
+note: but lifetime parameter must outlive the lifetime `'a` as defined on the impl at 23:6
--> $DIR/wf-static-method.rs:23:6
|
LL | impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> {
@@ -38,12 +38,12 @@
LL | u
| ^
|
-note: ...the reference is valid for the lifetime 'a as defined on the impl at 31:6...
+note: ...the reference is valid for the lifetime `'a` as defined on the impl at 31:6...
--> $DIR/wf-static-method.rs:31:6
|
LL | impl<'a, 'b> Evil<'a, 'b> {
| ^^
-note: ...but the borrowed content is only valid for the lifetime 'b as defined on the impl at 31:10
+note: ...but the borrowed content is only valid for the lifetime `'b` as defined on the impl at 31:10
--> $DIR/wf-static-method.rs:31:10
|
LL | impl<'a, 'b> Evil<'a, 'b> {
@@ -55,7 +55,7 @@
LL | <()>::static_evil(b)
| ^^^^^^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'b as defined on the function body at 40:13...
+note: first, the lifetime cannot outlive the lifetime `'b` as defined on the function body at 40:13...
--> $DIR/wf-static-method.rs:40:13
|
LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 {
@@ -65,7 +65,7 @@
|
LL | <()>::static_evil(b)
| ^
-note: but, the lifetime must be valid for the lifetime 'a as defined on the function body at 40:9...
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 40:9...
--> $DIR/wf-static-method.rs:40:9
|
LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 {
@@ -82,7 +82,7 @@
LL | <IndirectEvil>::static_evil(b)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
-note: first, the lifetime cannot outlive the lifetime 'b as defined on the function body at 44:22...
+note: first, the lifetime cannot outlive the lifetime `'b` as defined on the function body at 44:22...
--> $DIR/wf-static-method.rs:44:22
|
LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
@@ -92,7 +92,7 @@
|
LL | <IndirectEvil>::static_evil(b)
| ^
-note: but, the lifetime must be valid for the lifetime 'a as defined on the function body at 44:18...
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 44:18...
--> $DIR/wf-static-method.rs:44:18
|
LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 {
diff --git a/src/tools/miri b/src/tools/miri
index 07ac102..2adc39f 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 07ac10277ea5ad42efbb914da5844e0ab08efbf4
+Subproject commit 2adc39f27b7fd2d06b3d1d470827928766731a1d