1
Fork 0

Auto merge of #65570 - tmandry:rollup-hck39pf, r=tmandry

Rollup of 19 pull requests

Successful merges:

 - #65016 (Always inline `mem::{size_of,align_of}` in debug builds)
 - #65197 (Prepare `MutVisitor`s to handle interned projections)
 - #65201 (Disable Go and OCaml bindings when building LLVM)
 - #65334 (Add long error explanation for E0575)
 - #65364 (Collect occurrences of empty blocks for mismatched braces diagnostic)
 - #65455 (Avoid unnecessary `TokenTree` to `TokenStream` conversions)
 - #65472 (Use a sharded dep node to dep node index map)
 - #65480 (Speed up `LexicalResolve::expansion()`)
 - #65493 (Add long error explanation for E0584)
 - #65496 (properly document panics in div_euclid and rem_euclid)
 - #65498 (Plugins deprecation: don’t suggest simply removing the attribute)
 - #65508 (add option to ping llvm ice-breakers to triagebot)
 - #65511 (save-analysis: Nest tables when processing impl block definitions)
 - #65513 (reorder fmt docs for more clarity)
 - #65532 (doc: make BitSet intro more short)
 - #65535 (rustc: arena-allocate the slice in `ty::GenericsPredicate`, not the whole struct.)
 - #65540 (show up some extra info when t!() fails)
 - #65549 (Fix left/right shift typo in wrapping rotate docs)
 - #65552 (Clarify diagnostics when using `~` as a unary op)

Failed merges:

 - #65390 (Add long error explanation for E0576)
 - #65434 (Add long error explanation for E0577)
 - #65471 (Add long error explanation for E0578)

r? @ghost
This commit is contained in:
bors 2019-10-19 01:16:41 +00:00
commit 14f0ed64e3
98 changed files with 877 additions and 496 deletions

View file

@ -1126,7 +1126,7 @@ impl Build {
}
let mut paths = Vec::new();
let contents = t!(fs::read(stamp));
let contents = t!(fs::read(stamp), &stamp);
// This is the method we use for extracting paths from the stamp file passed to us. See
// run_cargo for more information (in compile.rs).
for part in contents.split(|b| *b == 0) {

View file

@ -157,6 +157,7 @@ impl Step for Llvm {
.define("WITH_POLLY", "OFF")
.define("LLVM_ENABLE_TERMINFO", "OFF")
.define("LLVM_ENABLE_LIBEDIT", "OFF")
.define("LLVM_ENABLE_BINDINGS", "OFF")
.define("LLVM_ENABLE_Z3_SOLVER", "OFF")
.define("LLVM_PARALLEL_COMPILE_JOBS", builder.jobs().to_string())
.define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
@ -169,15 +170,6 @@ impl Step for Llvm {
}
}
// By default, LLVM will automatically find OCaml and, if it finds it,
// install the LLVM bindings in LLVM_OCAML_INSTALL_PATH, which defaults
// to /usr/bin/ocaml.
// This causes problem for non-root builds of Rust. Side-step the issue
// by setting LLVM_OCAML_INSTALL_PATH to a relative path, so it installs
// in the prefix.
cfg.define("LLVM_OCAML_INSTALL_PATH",
env::var_os("LLVM_OCAML_INSTALL_PATH").unwrap_or_else(|| "usr/lib/ocaml".into()));
let want_lldb = builder.config.lldb_enabled && !self.emscripten;
// This setting makes the LLVM tools link to the dynamic LLVM library,

View file

@ -21,6 +21,13 @@ macro_rules! t {
Err(e) => panic!("{} failed with {}", stringify!($e), e),
}
};
// it can show extra info in the second parameter
($e:expr, $extra:expr) => {
match $e {
Ok(e) => e,
Err(e) => panic!("{} failed with {} ({:?})", stringify!($e), e, $extra),
}
};
}
// Because Cargo adds the compiler's dylib path to our library search path, llvm-config may

View file

@ -86,27 +86,74 @@
//! parameters (corresponding to `format_spec` in the syntax above). These
//! parameters affect the string representation of what's being formatted.
//!
//! ## Width
//!
//! ```
//! // All of these print "Hello x !"
//! println!("Hello {:5}!", "x");
//! println!("Hello {:1$}!", "x", 5);
//! println!("Hello {1:0$}!", 5, "x");
//! println!("Hello {:width$}!", "x", width = 5);
//! ```
//!
//! This is a parameter for the "minimum width" that the format should take up.
//! If the value's string does not fill up this many characters, then the
//! padding specified by fill/alignment will be used to take up the required
//! space (see below).
//!
//! The value for the width can also be provided as a [`usize`] in the list of
//! parameters by adding a postfix `$`, indicating that the second argument is
//! a [`usize`] specifying the width.
//!
//! Referring to an argument with the dollar syntax does not affect the "next
//! argument" counter, so it's usually a good idea to refer to arguments by
//! position, or use named arguments.
//!
//! ## Fill/Alignment
//!
//! The fill character is provided normally in conjunction with the
//! [`width`](#width)
//! parameter. This indicates that if the value being formatted is smaller than
//! `width` some extra characters will be printed around it. The extra
//! characters are specified by `fill`, and the alignment can be one of the
//! following options:
//! ```
//! assert_eq!(format!("Hello {:<5}!", "x"), "Hello x !");
//! assert_eq!(format!("Hello {:-<5}!", "x"), "Hello x----!");
//! assert_eq!(format!("Hello {:^5}!", "x"), "Hello x !");
//! assert_eq!(format!("Hello {:>5}!", "x"), "Hello x!");
//! ```
//!
//! * `<` - the argument is left-aligned in `width` columns
//! * `^` - the argument is center-aligned in `width` columns
//! * `>` - the argument is right-aligned in `width` columns
//! The optional fill character and alignment is provided normally in conjunction with the
//! [`width`](#width) parameter. It must be defined before `width`, right after the `:`.
//! This indicates that if the value being formatted is smaller than
//! `width` some extra characters will be printed around it.
//! Filling comes in the following variants for different alignments:
//!
//! * `[fill]<` - the argument is left-aligned in `width` columns
//! * `[fill]^` - the argument is center-aligned in `width` columns
//! * `[fill]>` - the argument is right-aligned in `width` columns
//!
//! The default [fill/alignment](#fillalignment) for non-numerics is a space and
//! left-aligned. The
//! defaults for numeric formatters is also a space but with right-alignment. If
//! the `0` flag (see below) is specified for numerics, then the implicit fill character is
//! `0`.
//!
//! Note that alignment may not be implemented by some types. In particular, it
//! is not generally implemented for the `Debug` trait. A good way to ensure
//! padding is applied is to format your input, then use this resulting string
//! to pad your output.
//! padding is applied is to format your input, then pad this resulting string
//! to obtain your output:
//!
//! ```
//! println!("Hello {:^15}!", format!("{:?}", Some("hi"))); // => "Hello Some("hi") !"
//! ```
//!
//! ## Sign/`#`/`0`
//!
//! These can all be interpreted as flags for a particular formatter.
//! ```
//! assert_eq!(format!("Hello {:+}!", 5), "Hello +5!");
//! assert_eq!(format!("{:#x}!", 27), "0x1b!");
//! assert_eq!(format!("Hello {:05}!", 5), "Hello 00005!");
//! assert_eq!(format!("Hello {:05}!", -5), "Hello -0005!");
//! assert_eq!(format!("{:#010x}!", 27), "0x0000001b!");
//! ```
//!
//! These are all flags altering the behavior of the formatter.
//!
//! * `+` - This is intended for numeric types and indicates that the sign
//! should always be printed. Positive signs are never printed by
@ -121,7 +168,7 @@
//! * `#X` - precedes the argument with a `0x`
//! * `#b` - precedes the argument with a `0b`
//! * `#o` - precedes the argument with a `0o`
//! * `0` - This is used to indicate for integer formats that the padding should
//! * `0` - This is used to indicate for integer formats that the padding to `width` should
//! both be done with a `0` character as well as be sign-aware. A format
//! like `{:08}` would yield `00000001` for the integer `1`, while the
//! same format would yield `-0000001` for the integer `-1`. Notice that
@ -129,36 +176,7 @@
//! Note that padding zeroes are always placed after the sign (if any)
//! and before the digits. When used together with the `#` flag, a similar
//! rule applies: padding zeroes are inserted after the prefix but before
//! the digits.
//!
//! ## Width
//!
//! This is a parameter for the "minimum width" that the format should take up.
//! If the value's string does not fill up this many characters, then the
//! padding specified by fill/alignment will be used to take up the required
//! space.
//!
//! The default [fill/alignment](#fillalignment) for non-numerics is a space and
//! left-aligned. The
//! defaults for numeric formatters is also a space but with right-alignment. If
//! the `0` flag is specified for numerics, then the implicit fill character is
//! `0`.
//!
//! The value for the width can also be provided as a [`usize`] in the list of
//! parameters by using the dollar syntax indicating that the second argument is
//! a [`usize`] specifying the width, for example:
//!
//! ```
//! // All of these print "Hello x !"
//! println!("Hello {:5}!", "x");
//! println!("Hello {:1$}!", "x", 5);
//! println!("Hello {1:0$}!", 5, "x");
//! println!("Hello {:width$}!", "x", width = 5);
//! ```
//!
//! Referring to an argument with the dollar syntax does not affect the "next
//! argument" counter, so it's usually a good idea to refer to arguments by
//! position, or use named arguments.
//! the digits. The prefix is included in the total width.
//!
//! ## Precision
//!
@ -235,9 +253,14 @@
//! them with the same character. For example, the `{` character is escaped with
//! `{{` and the `}` character is escaped with `}}`.
//!
//! ```
//! assert_eq!(format!("Hello {{}}"), "Hello {}");
//! assert_eq!(format!("{{ Hello"), "{ Hello");
//! ```
//!
//! # Syntax
//!
//! To summarize, you can find the full grammar of format strings.
//! To summarize, here 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

View file

@ -236,7 +236,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
/// ```
///
/// [alignment]: ./fn.align_of.html
#[inline]
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
pub const fn size_of<T>() -> usize {
@ -328,7 +328,7 @@ pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
///
/// assert_eq!(4, mem::align_of::<i32>());
/// ```
#[inline]
#[inline(always)]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
pub const fn align_of<T>() -> usize {

View file

@ -1864,7 +1864,7 @@ if `self < 0`, this is equal to round towards +/- infinity.
# Panics
This function will panic if `rhs` is 0.
This function will panic if `rhs` is 0 or the division results in overflow.
# Examples
@ -1903,7 +1903,7 @@ This is done as if by the Euclidean division algorithm -- given
# Panics
This function will panic if `rhs` is 0.
This function will panic if `rhs` is 0 or the division results in overflow.
# Examples
@ -3694,6 +3694,10 @@ Since, for the positive integers, all common
definitions of division are equal, this
is exactly equal to `self / rhs`.
# Panics
This function will panic if `rhs` is 0.
# Examples
Basic usage:
@ -3719,6 +3723,10 @@ Since, for the positive integers, all common
definitions of division are equal, this
is exactly equal to `self % rhs`.
# Panics
This function will panic if `rhs` is 0.
# Examples
Basic usage:

View file

@ -437,7 +437,7 @@ assert_eq!(n.trailing_zeros(), 3);
/// wrapping the truncated bits to the end of the resulting
/// integer.
///
/// Please note this isn't the same operation as the `>>` shifting
/// Please note this isn't the same operation as the `<<` shifting
/// operator!
///
/// # Examples
@ -463,7 +463,7 @@ assert_eq!(n.trailing_zeros(), 3);
/// wrapping the truncated bits to the beginning of the resulting
/// integer.
///
/// Please note this isn't the same operation as the `<<` shifting
/// Please note this isn't the same operation as the `>>` shifting
/// operator!
///
/// # Examples

View file

@ -98,7 +98,6 @@ macro_rules! arena_types {
rustc::hir::def_id::DefId,
>,
[few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
[decode] generic_predicates: rustc::ty::GenericPredicates<'tcx>,
[few] lint_levels: rustc::lint::LintLevelMap,
[few] stability_index: rustc::middle::stability::Index<'tcx>,
[few] features: syntax::feature_gate::Features,

View file

@ -4,6 +4,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_index::vec::{Idx, IndexVec};
use smallvec::SmallVec;
use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, AtomicU64, Ordering};
use rustc_data_structures::sharded::{self, Sharded};
use std::sync::atomic::Ordering::SeqCst;
use std::env;
use std::hash::Hash;
@ -381,7 +382,7 @@ impl DepGraph {
#[inline]
pub fn read(&self, v: DepNode) {
if let Some(ref data) = self.data {
let map = data.current.node_to_node_index.lock();
let map = data.current.node_to_node_index.get_shard_by_value(&v).lock();
if let Some(dep_node_index) = map.get(&v).copied() {
std::mem::drop(map);
data.read_index(dep_node_index);
@ -405,6 +406,7 @@ impl DepGraph {
.unwrap()
.current
.node_to_node_index
.get_shard_by_value(dep_node)
.lock()
.get(dep_node)
.cloned()
@ -414,7 +416,11 @@ impl DepGraph {
#[inline]
pub fn dep_node_exists(&self, dep_node: &DepNode) -> bool {
if let Some(ref data) = self.data {
data.current.node_to_node_index.lock().contains_key(dep_node)
data.current
.node_to_node_index
.get_shard_by_value(&dep_node)
.lock()
.contains_key(dep_node)
} else {
false
}
@ -595,7 +601,11 @@ impl DepGraph {
#[cfg(not(parallel_compiler))]
{
debug_assert!(!data.current.node_to_node_index.lock().contains_key(dep_node));
debug_assert!(!data.current
.node_to_node_index
.get_shard_by_value(dep_node)
.lock()
.contains_key(dep_node));
debug_assert!(data.colors.get(prev_dep_node_index).is_none());
}
@ -927,7 +937,7 @@ struct DepNodeData {
/// acquire the lock on `data.`
pub(super) struct CurrentDepGraph {
data: Lock<IndexVec<DepNodeIndex, DepNodeData>>,
node_to_node_index: Lock<FxHashMap<DepNode, DepNodeIndex>>,
node_to_node_index: Sharded<FxHashMap<DepNode, DepNodeIndex>>,
/// Used to trap when a specific edge is added to the graph.
/// This is used for debug purposes and is only active with `debug_assertions`.
@ -985,8 +995,8 @@ impl CurrentDepGraph {
CurrentDepGraph {
data: Lock::new(IndexVec::with_capacity(new_node_count_estimate)),
node_to_node_index: Lock::new(FxHashMap::with_capacity_and_hasher(
new_node_count_estimate,
node_to_node_index: Sharded::new(|| FxHashMap::with_capacity_and_hasher(
new_node_count_estimate / sharded::SHARDS,
Default::default(),
)),
anon_id_seed: stable_hasher.finish(),
@ -1035,7 +1045,10 @@ impl CurrentDepGraph {
edges: SmallVec<[DepNodeIndex; 8]>,
fingerprint: Fingerprint
) -> DepNodeIndex {
debug_assert!(!self.node_to_node_index.lock().contains_key(&dep_node));
debug_assert!(!self.node_to_node_index
.get_shard_by_value(&dep_node)
.lock()
.contains_key(&dep_node));
self.intern_node(dep_node, edges, fingerprint)
}
@ -1045,7 +1058,7 @@ impl CurrentDepGraph {
edges: SmallVec<[DepNodeIndex; 8]>,
fingerprint: Fingerprint
) -> DepNodeIndex {
match self.node_to_node_index.lock().entry(dep_node) {
match self.node_to_node_index.get_shard_by_value(&dep_node).lock().entry(dep_node) {
Entry::Occupied(entry) => *entry.get(),
Entry::Vacant(entry) => {
let mut data = self.data.lock();

View file

@ -19,8 +19,8 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::graph::implementation::{
Direction, Graph, NodeIndex, INCOMING, OUTGOING,
};
use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec};
use smallvec::SmallVec;
use std::fmt;
use syntax_pos::Span;
@ -304,8 +304,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
self.iterate_until_fixed_point(|constraint| {
debug!("expansion: constraint={:?}", constraint);
let mut process_constraint = |constraint: &Constraint<'tcx>| {
let (a_region, b_vid, b_data, retain) = match *constraint {
Constraint::RegSubVar(a_region, b_vid) => {
let b_data = var_values.value_mut(b_vid);
@ -331,7 +330,33 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
let changed = self.expand_node(a_region, b_vid, b_data);
(changed, retain)
})
};
// Using bitsets to track the remaining elements is faster than using a
// `Vec` by itself (which requires removing elements, which requires
// element shuffling, which is slow).
let constraints: Vec<_> = self.data.constraints.keys().collect();
let mut live_indices: BitSet<usize> = BitSet::new_filled(constraints.len());
let mut killed_indices: BitSet<usize> = BitSet::new_empty(constraints.len());
let mut changed = true;
while changed {
changed = false;
for index in live_indices.iter() {
let constraint = constraints[index];
let (edge_changed, retain) = process_constraint(constraint);
if edge_changed {
changed = true;
}
if !retain {
let changed = killed_indices.insert(index);
debug_assert!(changed);
}
}
live_indices.subtract(&killed_indices);
// We could clear `killed_indices` here, but we don't need to and
// it's cheaper not to.
}
}
// This function is very hot in some workloads. There's a single callsite
@ -866,29 +891,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
}
fn iterate_until_fixed_point<F>(&self, mut body: F)
where
F: FnMut(&Constraint<'tcx>) -> (bool, bool),
{
let mut constraints: SmallVec<[_; 16]> = self.data.constraints.keys().collect();
let mut iteration = 0;
let mut changed = true;
while changed {
changed = false;
iteration += 1;
debug!("---- Expansion iteration {}", iteration);
constraints.retain(|constraint| {
let (edge_changed, retain) = body(constraint);
if edge_changed {
debug!("updated due to constraint {:?}", constraint);
changed = true;
}
retain
});
}
debug!("---- Expansion complete after {} iteration(s)", iteration);
}
fn bound_is_met(
&self,
bound: &VerifyBound<'tcx>,

View file

@ -158,22 +158,7 @@ macro_rules! make_mir_visitor {
self.super_place_base(base, context, location);
}
fn visit_projection(&mut self,
base: & $($mutability)? PlaceBase<'tcx>,
projection: & $($mutability)? [PlaceElem<'tcx>],
context: PlaceContext,
location: Location) {
self.super_projection(base, projection, context, location);
}
fn visit_projection_elem(&mut self,
base: & $($mutability)? PlaceBase<'tcx>,
proj_base: & $($mutability)? [PlaceElem<'tcx>],
elem: & $($mutability)? PlaceElem<'tcx>,
context: PlaceContext,
location: Location) {
self.super_projection_elem(base, proj_base, elem, context, location);
}
visit_place_fns!($($mutability)?);
fn visit_constant(&mut self,
constant: & $($mutability)? Constant<'tcx>,
@ -681,28 +666,6 @@ macro_rules! make_mir_visitor {
);
}
fn super_place(&mut self,
place: & $($mutability)? Place<'tcx>,
context: PlaceContext,
location: Location) {
let mut context = context;
if !place.projection.is_empty() {
context = if context.is_mutating_use() {
PlaceContext::MutatingUse(MutatingUseContext::Projection)
} else {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
};
}
self.visit_place_base(& $($mutability)? place.base, context, location);
self.visit_projection(& $($mutability)? place.base,
& $($mutability)? place.projection,
context,
location);
}
fn super_place_base(&mut self,
place_base: & $($mutability)? PlaceBase<'tcx>,
context: PlaceContext,
@ -717,45 +680,6 @@ macro_rules! make_mir_visitor {
}
}
fn super_projection(&mut self,
base: & $($mutability)? PlaceBase<'tcx>,
projection: & $($mutability)? [PlaceElem<'tcx>],
context: PlaceContext,
location: Location) {
let mut cursor = projection;
while let [proj_base @ .., elem] = cursor {
cursor = proj_base;
self.visit_projection_elem(base, cursor, elem, context, location);
}
}
fn super_projection_elem(&mut self,
_base: & $($mutability)? PlaceBase<'tcx>,
_proj_base: & $($mutability)? [PlaceElem<'tcx>],
elem: & $($mutability)? PlaceElem<'tcx>,
_context: PlaceContext,
location: Location) {
match elem {
ProjectionElem::Field(_field, ty) => {
self.visit_ty(ty, TyContext::Location(location));
}
ProjectionElem::Index(local) => {
self.visit_local(
local,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
}
ProjectionElem::Deref |
ProjectionElem::Subslice { from: _, to: _ } |
ProjectionElem::ConstantIndex { offset: _,
min_length: _,
from_end: _ } |
ProjectionElem::Downcast(_, _) => {
}
}
}
fn super_local_decl(&mut self,
local: Local,
local_decl: & $($mutability)? LocalDecl<'tcx>) {
@ -858,6 +782,141 @@ macro_rules! make_mir_visitor {
}
}
macro_rules! visit_place_fns {
(mut) => (
fn super_place(
&mut self,
place: &mut Place<'tcx>,
context: PlaceContext,
location: Location,
) {
self.visit_place_base(&mut place.base, context, location);
if let Some(new_projection) = self.process_projection(&place.projection) {
place.projection = new_projection;
}
}
fn process_projection(
&mut self,
projection: &'a [PlaceElem<'tcx>],
) -> Option<Box<[PlaceElem<'tcx>]>> {
let mut projection = Cow::Borrowed(projection);
for i in 0..projection.len() {
if let Some(elem) = projection.get(i) {
if let Some(elem) = self.process_projection_elem(elem) {
let vec = projection.to_mut();
vec[i] = elem;
}
}
}
match projection {
Cow::Borrowed(_) => None,
Cow::Owned(vec) => Some(vec.into_boxed_slice()),
}
}
fn process_projection_elem(
&mut self,
_elem: &PlaceElem<'tcx>,
) -> Option<PlaceElem<'tcx>> {
None
}
);
() => (
fn visit_projection(
&mut self,
base: &PlaceBase<'tcx>,
projection: &[PlaceElem<'tcx>],
context: PlaceContext,
location: Location,
) {
self.super_projection(base, projection, context, location);
}
fn visit_projection_elem(
&mut self,
base: &PlaceBase<'tcx>,
proj_base: &[PlaceElem<'tcx>],
elem: &PlaceElem<'tcx>,
context: PlaceContext,
location: Location,
) {
self.super_projection_elem(base, proj_base, elem, context, location);
}
fn super_place(
&mut self,
place: &Place<'tcx>,
context: PlaceContext,
location: Location,
) {
let mut context = context;
if !place.projection.is_empty() {
context = if context.is_mutating_use() {
PlaceContext::MutatingUse(MutatingUseContext::Projection)
} else {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
};
}
self.visit_place_base(&place.base, context, location);
self.visit_projection(&place.base,
&place.projection,
context,
location);
}
fn super_projection(
&mut self,
base: &PlaceBase<'tcx>,
projection: &[PlaceElem<'tcx>],
context: PlaceContext,
location: Location,
) {
let mut cursor = projection;
while let [proj_base @ .., elem] = cursor {
cursor = proj_base;
self.visit_projection_elem(base, cursor, elem, context, location);
}
}
fn super_projection_elem(
&mut self,
_base: &PlaceBase<'tcx>,
_proj_base: &[PlaceElem<'tcx>],
elem: &PlaceElem<'tcx>,
_context: PlaceContext,
location: Location,
) {
match elem {
ProjectionElem::Field(_field, ty) => {
self.visit_ty(ty, TyContext::Location(location));
}
ProjectionElem::Index(local) => {
self.visit_local(
local,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
}
ProjectionElem::Deref |
ProjectionElem::Subslice { from: _, to: _ } |
ProjectionElem::ConstantIndex { offset: _,
min_length: _,
from_end: _ } |
ProjectionElem::Downcast(_, _) => {
}
}
}
);
}
make_mir_visitor!(Visitor,);
make_mir_visitor!(MutVisitor,mut);

View file

@ -61,7 +61,7 @@ rustc_queries! {
/// predicate gets in the way of some checks, which are intended
/// to operate over only the actual where-clauses written by the
/// user.)
query predicates_of(key: DefId) -> &'tcx ty::GenericPredicates<'tcx> {
query predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
cache_on_disk_if { key.is_local() }
}
@ -184,12 +184,10 @@ rustc_queries! {
/// predicates (where-clauses) directly defined on it. This is
/// equal to the `explicit_predicates_of` predicates plus the
/// `inferred_outlives_of` predicates.
query predicates_defined_on(_: DefId)
-> &'tcx ty::GenericPredicates<'tcx> {}
query predicates_defined_on(_: DefId) -> ty::GenericPredicates<'tcx> {}
/// Returns the predicates written explicitly by the user.
query explicit_predicates_of(_: DefId)
-> &'tcx ty::GenericPredicates<'tcx> {}
query explicit_predicates_of(_: DefId) -> ty::GenericPredicates<'tcx> {}
/// Returns the inferred outlives predicates (e.g., for `struct
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
@ -201,14 +199,13 @@ rustc_queries! {
/// evaluate them even during type conversion, often before the
/// full predicates are available (note that supertraits have
/// additional acyclicity requirements).
query super_predicates_of(key: DefId) -> &'tcx ty::GenericPredicates<'tcx> {
query super_predicates_of(key: DefId) -> ty::GenericPredicates<'tcx> {
desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) }
}
/// To avoid cycles within the predicates of a single item we compute
/// per-type-parameter predicates for resolving `T::AssocTy`.
query type_param_predicates(key: (DefId, DefId))
-> &'tcx ty::GenericPredicates<'tcx> {
query type_param_predicates(key: (DefId, DefId)) -> ty::GenericPredicates<'tcx> {
no_force
desc { |tcx| "computing the bounds for type parameter `{}`", {
let id = tcx.hir().as_local_hir_id(key.1).unwrap();

View file

@ -419,7 +419,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String>
// The predicates will contain default bounds like `T: Sized`. We need to
// remove these bounds, and add `T: ?Sized` to any untouched type parameters.
let predicates = &tcx.predicates_of(impl_def_id).predicates;
let predicates = tcx.predicates_of(impl_def_id).predicates;
let mut pretty_predicates = Vec::with_capacity(
predicates.len() + types_without_default_bounds.len());

View file

@ -16,6 +16,7 @@ use std::intrinsics;
use crate::ty::{self, Ty, TyCtxt};
use crate::ty::subst::SubstsRef;
use crate::mir::interpret::Allocation;
use syntax_pos::Span;
/// The shorthand encoding uses an enum's variant index `usize`
/// and is offset by this value so it never matches a real variant.
@ -92,16 +93,16 @@ pub fn encode_with_shorthand<E, T, M>(encoder: &mut E,
Ok(())
}
pub fn encode_predicates<'tcx, E, C>(encoder: &mut E,
predicates: &ty::GenericPredicates<'tcx>,
cache: C)
-> Result<(), E::Error>
pub fn encode_spanned_predicates<'tcx, E, C>(
encoder: &mut E,
predicates: &'tcx [(ty::Predicate<'tcx>, Span)],
cache: C,
) -> Result<(), E::Error>
where E: TyEncoder,
C: for<'b> Fn(&'b mut E) -> &'b mut FxHashMap<ty::Predicate<'tcx>, usize>,
{
predicates.parent.encode(encoder)?;
predicates.predicates.len().encode(encoder)?;
for (predicate, span) in &predicates.predicates {
predicates.len().encode(encoder)?;
for (predicate, span) in predicates {
encode_with_shorthand(encoder, predicate, &cache)?;
span.encode(encoder)?;
}
@ -182,13 +183,15 @@ where
}
#[inline]
pub fn decode_predicates<D>(decoder: &mut D) -> Result<ty::GenericPredicates<'tcx>, D::Error>
pub fn decode_spanned_predicates<D>(
decoder: &mut D,
) -> Result<&'tcx [(ty::Predicate<'tcx>, Span)], D::Error>
where
D: TyDecoder<'tcx>,
{
Ok(ty::GenericPredicates {
parent: Decodable::decode(decoder)?,
predicates: (0..decoder.read_usize()?).map(|_| {
let tcx = decoder.tcx();
Ok(tcx.arena.alloc_from_iter(
(0..decoder.read_usize()?).map(|_| {
// Handle shorthands first, if we have an usize > 0x80.
let predicate = if decoder.positioned_at_shorthand() {
let pos = decoder.read_usize()?;
@ -202,7 +205,7 @@ where
Ok((predicate, Decodable::decode(decoder)?))
})
.collect::<Result<Vec<_>, _>>()?,
})
))
}
#[inline]
@ -339,6 +342,8 @@ macro_rules! implement_ty_decoder {
use $crate::ty::subst::SubstsRef;
use $crate::hir::def_id::{CrateNum};
use syntax_pos::Span;
use super::$DecoderName;
impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
@ -393,11 +398,11 @@ macro_rules! implement_ty_decoder {
}
}
impl<$($typaram),*> SpecializedDecoder<ty::GenericPredicates<'tcx>>
impl<$($typaram),*> SpecializedDecoder<&'tcx [(ty::Predicate<'tcx>, Span)]>
for $DecoderName<$($typaram),*> {
fn specialized_decode(&mut self)
-> Result<ty::GenericPredicates<'tcx>, Self::Error> {
decode_predicates(self)
-> Result<&'tcx [(ty::Predicate<'tcx>, Span)], Self::Error> {
decode_spanned_predicates(self)
}
}

View file

@ -148,10 +148,6 @@ impl<'tcx> CtxtInterners<'tcx> {
}
}
pub struct Common<'tcx> {
pub empty_predicates: ty::GenericPredicates<'tcx>,
}
pub struct CommonTypes<'tcx> {
pub unit: Ty<'tcx>,
pub bool: Ty<'tcx>,
@ -1039,9 +1035,6 @@ pub struct GlobalCtxt<'tcx> {
pub prof: SelfProfilerRef,
/// Common objects.
pub common: Common<'tcx>,
/// Common types, pre-interned for your convenience.
pub types: CommonTypes<'tcx>,
@ -1213,12 +1206,6 @@ impl<'tcx> TyCtxt<'tcx> {
s.fatal(&err);
});
let interners = CtxtInterners::new(&arenas.interner);
let common = Common {
empty_predicates: ty::GenericPredicates {
parent: None,
predicates: vec![],
},
};
let common_types = CommonTypes::new(&interners);
let common_lifetimes = CommonLifetimes::new(&interners);
let common_consts = CommonConsts::new(&interners, &common_types);
@ -1273,7 +1260,6 @@ impl<'tcx> TyCtxt<'tcx> {
interners,
dep_graph,
prof: s.prof.clone(),
common,
types: common_types,
lifetimes: common_lifetimes,
consts: common_consts,

View file

@ -1018,15 +1018,12 @@ impl<'tcx> Generics {
}
/// Bounds on generics.
#[derive(Clone, Default, Debug, HashStable)]
#[derive(Copy, Clone, Default, Debug, RustcEncodable, RustcDecodable, HashStable)]
pub struct GenericPredicates<'tcx> {
pub parent: Option<DefId>,
pub predicates: Vec<(Predicate<'tcx>, Span)>,
pub predicates: &'tcx [(Predicate<'tcx>, Span)],
}
impl<'tcx> rustc_serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {}
impl<'tcx> rustc_serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {}
impl<'tcx> GenericPredicates<'tcx> {
pub fn instantiate(
&self,
@ -2321,7 +2318,7 @@ impl<'tcx> AdtDef {
}
#[inline]
pub fn predicates(&self, tcx: TyCtxt<'tcx>) -> &'tcx GenericPredicates<'tcx> {
pub fn predicates(&self, tcx: TyCtxt<'tcx>) -> GenericPredicates<'tcx> {
tcx.predicates_of(self.did)
}
@ -2561,7 +2558,7 @@ impl<'tcx> AdtDef {
def_id: sized_trait,
substs: tcx.mk_substs_trait(ty, &[])
}).to_predicate();
let predicates = &tcx.predicates_of(self.did).predicates;
let predicates = tcx.predicates_of(self.did).predicates;
if predicates.iter().any(|(p, _)| *p == sized_predicate) {
vec![]
} else {

View file

@ -882,15 +882,16 @@ where
}
}
impl<'a, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>> for CacheEncoder<'a, 'tcx, E>
impl<'a, 'tcx, E> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]>
for CacheEncoder<'a, 'tcx, E>
where
E: 'a + TyEncoder,
{
#[inline]
fn specialized_encode(&mut self,
predicates: &ty::GenericPredicates<'tcx>)
predicates: &&'tcx [(ty::Predicate<'tcx>, Span)])
-> Result<(), Self::Error> {
ty_codec::encode_predicates(self, predicates,
ty_codec::encode_spanned_predicates(self, predicates,
|encoder| &mut encoder.predicate_shorthands)
}
}

View file

@ -1218,12 +1218,6 @@ EnumTypeFoldableImpl! {
}
}
BraceStructTypeFoldableImpl! {
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
parent, predicates
}
}
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
// This code is hot enough that it's worth specializing for a list of

View file

@ -2,6 +2,7 @@ use std::hash::{Hasher, Hash};
use std::mem;
use std::borrow::Borrow;
use std::collections::hash_map::RawEntryMut;
use smallvec::SmallVec;
use crate::fx::{FxHasher, FxHashMap};
use crate::sync::{Lock, LockGuard};
@ -18,7 +19,7 @@ const SHARD_BITS: usize = 5;
#[cfg(not(parallel_compiler))]
const SHARD_BITS: usize = 0;
const SHARDS: usize = 1 << SHARD_BITS;
pub const SHARDS: usize = 1 << SHARD_BITS;
/// An array of cache-line aligned inner locked structures with convenience methods.
#[derive(Clone)]
@ -29,21 +30,36 @@ pub struct Sharded<T> {
impl<T: Default> Default for Sharded<T> {
#[inline]
fn default() -> Self {
Self::new(|| T::default())
}
}
impl<T> Sharded<T> {
#[inline]
pub fn new(mut value: impl FnMut() -> T) -> Self {
// Create a vector of the values we want
let mut values: SmallVec<[_; SHARDS]> = (0..SHARDS).map(|_| {
CacheAligned(Lock::new(value()))
}).collect();
// Create an unintialized array
let mut shards: mem::MaybeUninit<[CacheAligned<Lock<T>>; SHARDS]> =
mem::MaybeUninit::uninit();
let first = shards.as_mut_ptr() as *mut CacheAligned<Lock<T>>;
unsafe {
for i in 0..SHARDS {
first.add(i).write(CacheAligned(Lock::new(T::default())));
}
// Copy the values into our array
let first = shards.as_mut_ptr() as *mut CacheAligned<Lock<T>>;
values.as_ptr().copy_to_nonoverlapping(first, SHARDS);
// Ignore the content of the vector
values.set_len(0);
Sharded {
shards: shards.assume_init(),
}
}
}
}
impl<T> Sharded<T> {
#[inline]
pub fn get_shard_by_value<K: Hash + ?Sized>(&self, val: &K) -> &Lock<T> {
if SHARDS == 1 {

View file

@ -13,8 +13,9 @@ pub type Word = u64;
pub const WORD_BYTES: usize = mem::size_of::<Word>();
pub const WORD_BITS: usize = WORD_BYTES * 8;
/// A fixed-size bitset type with a dense representation. It does not support
/// resizing after creation; use `GrowableBitSet` for that.
/// A fixed-size bitset type with a dense representation.
///
/// NOTE: Use [`GrowableBitSet`] if you need support for resizing after creation.
///
/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also
/// just be `usize`.
@ -22,6 +23,8 @@ pub const WORD_BITS: usize = WORD_BYTES * 8;
/// All operations that involve an element will panic if the element is equal
/// to or greater than the domain size. All operations that involve two bitsets
/// will panic if the bitsets have differing domain sizes.
///
/// [`GrowableBitSet`]: struct.GrowableBitSet.html
#[derive(Clone, Eq, PartialEq, RustcDecodable, RustcEncodable)]
pub struct BitSet<T: Idx> {
domain_size: usize,

View file

@ -1241,7 +1241,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
if cx.tcx.features().trivial_bounds {
let def_id = cx.tcx.hir().local_def_id(item.hir_id);
let predicates = cx.tcx.predicates_of(def_id);
for &(predicate, span) in &predicates.predicates {
for &(predicate, span) in predicates.predicates {
let predicate_kind_name = match predicate {
Trait(..) => "Trait",
TypeOutlives(..) |

View file

@ -156,7 +156,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
}
ty::Opaque(def, _) => {
let mut has_emitted = false;
for (predicate, _) in &cx.tcx.predicates_of(def).predicates {
for (predicate, _) in cx.tcx.predicates_of(def).predicates {
if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate {
let trait_ref = poly_trait_predicate.skip_binder().trait_ref;
let def_id = trait_ref.def_id;

View file

@ -97,11 +97,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
generics_of => {
tcx.arena.alloc(cdata.get_generics(def_id.index, tcx.sess))
}
predicates_of => { tcx.arena.alloc(cdata.get_predicates(def_id.index, tcx)) }
predicates_defined_on => {
tcx.arena.alloc(cdata.get_predicates_defined_on(def_id.index, tcx))
}
super_predicates_of => { tcx.arena.alloc(cdata.get_super_predicates(def_id.index, tcx)) }
predicates_of => { cdata.get_predicates(def_id.index, tcx) }
predicates_defined_on => { cdata.get_predicates_defined_on(def_id.index, tcx) }
super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) }
trait_def => {
tcx.arena.alloc(cdata.get_trait_def(def_id.index, tcx.sess))
}

View file

@ -243,11 +243,11 @@ impl<'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'tcx> {
}
}
impl<'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext<'tcx> {
impl<'tcx> SpecializedEncoder<&'tcx [(ty::Predicate<'tcx>, Span)]> for EncodeContext<'tcx> {
fn specialized_encode(&mut self,
predicates: &ty::GenericPredicates<'tcx>)
predicates: &&'tcx [(ty::Predicate<'tcx>, Span)])
-> Result<(), Self::Error> {
ty_codec::encode_predicates(self, predicates, |ecx| &mut ecx.predicate_shorthands)
ty_codec::encode_spanned_predicates(self, predicates, |ecx| &mut ecx.predicate_shorthands)
}
}
@ -826,13 +826,13 @@ impl EncodeContext<'tcx> {
fn encode_predicates(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_predicates({:?})", def_id);
record!(self.per_def.predicates[def_id] <- &*self.tcx.predicates_of(def_id));
record!(self.per_def.predicates[def_id] <- self.tcx.predicates_of(def_id));
}
fn encode_predicates_defined_on(&mut self, def_id: DefId) {
debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id);
record!(self.per_def.predicates_defined_on[def_id] <-
&*self.tcx.predicates_defined_on(def_id))
self.tcx.predicates_defined_on(def_id))
}
fn encode_info_for_trait_item(&mut self, def_id: DefId) {
@ -1166,14 +1166,14 @@ impl EncodeContext<'tcx> {
paren_sugar: trait_def.paren_sugar,
has_auto_impl: self.tcx.trait_is_auto(def_id),
is_marker: trait_def.is_marker,
super_predicates: self.lazy(&*tcx.super_predicates_of(def_id)),
super_predicates: self.lazy(tcx.super_predicates_of(def_id)),
};
EntryKind::Trait(self.lazy(data))
}
hir::ItemKind::TraitAlias(..) => {
let data = TraitAliasData {
super_predicates: self.lazy(&*tcx.super_predicates_of(def_id)),
super_predicates: self.lazy(tcx.super_predicates_of(def_id)),
};
EntryKind::TraitAlias(self.lazy(data))

View file

@ -1,6 +1,6 @@
use rustc::ty::subst::SubstsRef;
use rustc::ty::{self, Ty, TypeFoldable};
use rustc::mir::{Location, Body, Promoted};
use rustc::mir::{Body, Location, PlaceElem, Promoted};
use rustc::mir::visit::{MutVisitor, TyContext};
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
use rustc_index::vec::IndexVec;
@ -62,6 +62,21 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> {
debug!("visit_ty: ty={:?}", ty);
}
fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> Option<PlaceElem<'tcx>> {
if let PlaceElem::Field(field, ty) = elem {
let new_ty = self.renumber_regions(ty);
if new_ty != *ty {
return Some(PlaceElem::Field(*field, new_ty));
}
}
None
}
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
debug!("visit_substs(substs={:?}, location={:?})", substs, location);

View file

@ -25,7 +25,6 @@ impl EraseRegionsVisitor<'tcx> {
impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
*ty = self.tcx.erase_regions(ty);
self.super_ty(ty);
}
fn visit_region(&mut self, region: &mut ty::Region<'tcx>, _: Location) {
@ -39,6 +38,21 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, _: Location) {
*substs = self.tcx.erase_regions(substs);
}
fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> Option<PlaceElem<'tcx>> {
if let PlaceElem::Field(field, ty) = elem {
let new_ty = self.tcx.erase_regions(ty);
if new_ty != *ty {
return Some(PlaceElem::Field(*field, new_ty));
}
}
None
}
}
pub struct EraseRegions;

View file

@ -88,6 +88,18 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor {
*local = self.to;
}
}
fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> Option<PlaceElem<'tcx>> {
match elem {
PlaceElem::Index(local) if *local == self.from => {
Some(PlaceElem::Index(self.to))
}
_ => None,
}
}
}
struct DerefArgVisitor;
@ -110,7 +122,13 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor {
projection: Box::new([ProjectionElem::Deref]),
});
} else {
self.super_place(place, context, location);
self.visit_place_base(&mut place.base, context, location);
for elem in place.projection.iter() {
if let PlaceElem::Index(local) = elem {
assert_ne!(*local, self_arg());
}
}
}
}
}
@ -137,7 +155,13 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
projection: Box::new([ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]),
});
} else {
self.super_place(place, context, location);
self.visit_place_base(&mut place.base, context, location);
for elem in place.projection.iter() {
if let PlaceElem::Index(local) = elem {
assert_ne!(*local, self_arg());
}
}
}
}
}
@ -247,17 +271,25 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
assert_eq!(self.remap.get(local), None);
}
fn visit_place(&mut self,
place: &mut Place<'tcx>,
context: PlaceContext,
location: Location) {
fn visit_place(
&mut self,
place: &mut Place<'tcx>,
context: PlaceContext,
location: Location,
) {
if let PlaceBase::Local(l) = place.base {
// Replace an Local in the remap with a generator struct access
if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) {
replace_base(place, self.make_field(variant_index, idx, ty));
}
} else {
self.super_place(place, context, location);
self.visit_place_base(&mut place.base, context, location);
for elem in place.projection.iter() {
if let PlaceElem::Index(local) = elem {
assert_ne!(*local, self_arg());
}
}
}
}

View file

@ -647,38 +647,45 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> {
debug!("updating target `{:?}`, new: `{:?}`", tgt, new);
new
}
}
impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
fn visit_local(&mut self,
local: &mut Local,
_ctxt: PlaceContext,
_location: Location) {
fn make_integrate_local(&self, local: &Local) -> Local {
if *local == RETURN_PLACE {
match self.destination {
Place {
base: PlaceBase::Local(l),
projection: box [],
} => {
*local = l;
return;
return l;
},
ref place => bug!("Return place is {:?}, not local", place)
}
}
let idx = local.index() - 1;
if idx < self.args.len() {
*local = self.args[idx];
return;
return self.args[idx];
}
*local = self.local_map[Local::new(idx - self.args.len())];
self.local_map[Local::new(idx - self.args.len())]
}
}
impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
fn visit_local(
&mut self,
local: &mut Local,
_ctxt: PlaceContext,
_location: Location,
) {
*local = self.make_integrate_local(local);
}
fn visit_place(&mut self,
place: &mut Place<'tcx>,
_ctxt: PlaceContext,
_location: Location) {
fn visit_place(
&mut self,
place: &mut Place<'tcx>,
context: PlaceContext,
location: Location,
) {
match place {
Place {
base: PlaceBase::Local(RETURN_PLACE),
@ -687,10 +694,27 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
// Return pointer; update the place itself
*place = self.destination.clone();
},
_ => self.super_place(place, _ctxt, _location)
_ => {
self.super_place(place, context, location);
}
}
}
fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> Option<PlaceElem<'tcx>> {
if let PlaceElem::Index(local) = elem {
let new_local = self.make_integrate_local(local);
if new_local != *local {
return Some(PlaceElem::Index(new_local))
}
}
None
}
fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) {
self.in_cleanup_block = data.is_cleanup;
self.super_basic_block_data(block, data);

View file

@ -191,6 +191,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
});
}
fn is_temp_kind(&self, local: Local) -> bool {
self.source.local_kind(local) == LocalKind::Temp
}
/// Copies the initialization of this temp to the
/// promoted MIR, recursing through temps.
fn promote_temp(&mut self, temp: Local) -> Local {
@ -396,10 +400,22 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
local: &mut Local,
_: PlaceContext,
_: Location) {
if self.source.local_kind(*local) == LocalKind::Temp {
if self.is_temp_kind(*local) {
*local = self.promote_temp(*local);
}
}
fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> Option<PlaceElem<'tcx>> {
match elem {
PlaceElem::Index(local) if self.is_temp_kind(*local) => {
Some(PlaceElem::Index(self.promote_temp(*local)))
}
_ => None,
}
}
}
pub fn promote_candidates<'tcx>(

View file

@ -14,7 +14,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
let mut current = def_id;
loop {
let predicates = tcx.predicates_of(current);
for (predicate, _) in &predicates.predicates {
for (predicate, _) in predicates.predicates {
match predicate {
| Predicate::RegionOutlives(_)
| Predicate::TypeOutlives(_)

View file

@ -366,7 +366,20 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater {
});
self.super_basic_block_data(block, data);
}
fn visit_local(&mut self, l: &mut Local, _: PlaceContext, _: Location) {
*l = self.map[*l].unwrap();
}
fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> Option<PlaceElem<'tcx>> {
match elem {
PlaceElem::Index(local) => {
Some(PlaceElem::Index(self.map[*local].unwrap()))
}
_ => None
}
}
}

View file

@ -1,6 +1,6 @@
//! Def-use analysis.
use rustc::mir::{Local, Location, Body};
use rustc::mir::{Body, Local, Location, PlaceElem};
use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor};
use rustc_index::vec::IndexVec;
use std::mem;
@ -47,13 +47,10 @@ impl DefUseAnalysis {
&self.info[local]
}
fn mutate_defs_and_uses<F>(&self, local: Local, body: &mut Body<'_>, mut callback: F)
where F: for<'a> FnMut(&'a mut Local,
PlaceContext,
Location) {
fn mutate_defs_and_uses(&self, local: Local, body: &mut Body<'_>, new_local: Local) {
for place_use in &self.info[local].defs_and_uses {
MutateUseVisitor::new(local,
&mut callback,
new_local,
body).visit_location(body, place_use.location)
}
}
@ -63,7 +60,7 @@ impl DefUseAnalysis {
local: Local,
body: &mut Body<'_>,
new_local: Local) {
self.mutate_defs_and_uses(local, body, |local, _, _| *local = new_local)
self.mutate_defs_and_uses(local, body, new_local)
}
}
@ -117,30 +114,39 @@ impl Info {
}
}
struct MutateUseVisitor<F> {
struct MutateUseVisitor {
query: Local,
callback: F,
new_local: Local,
}
impl<F> MutateUseVisitor<F> {
fn new(query: Local, callback: F, _: &Body<'_>)
-> MutateUseVisitor<F>
where F: for<'a> FnMut(&'a mut Local, PlaceContext, Location) {
impl MutateUseVisitor {
fn new(query: Local, new_local: Local, _: &Body<'_>) -> MutateUseVisitor {
MutateUseVisitor {
query,
callback,
new_local,
}
}
}
impl<F> MutVisitor<'_> for MutateUseVisitor<F>
where F: for<'a> FnMut(&'a mut Local, PlaceContext, Location) {
impl MutVisitor<'_> for MutateUseVisitor {
fn visit_local(&mut self,
local: &mut Local,
context: PlaceContext,
location: Location) {
_context: PlaceContext,
_location: Location) {
if *local == self.query {
(self.callback)(local, context, location)
*local = self.new_local;
}
}
fn process_projection_elem(
&mut self,
elem: &PlaceElem<'tcx>,
) -> Option<PlaceElem<'tcx>> {
match elem {
PlaceElem::Index(local) if *local == self.query => {
Some(PlaceElem::Index(self.new_local))
}
_ => None,
}
}
}

View file

@ -64,7 +64,7 @@ trait DefIdVisitor<'tcx> {
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool {
self.skeleton().visit_trait(trait_ref)
}
fn visit_predicates(&mut self, predicates: &ty::GenericPredicates<'tcx>) -> bool {
fn visit_predicates(&mut self, predicates: ty::GenericPredicates<'tcx>) -> bool {
self.skeleton().visit_predicates(predicates)
}
}
@ -88,7 +88,7 @@ where
(!self.def_id_visitor.shallow() && substs.visit_with(self))
}
fn visit_predicates(&mut self, predicates: &ty::GenericPredicates<'tcx>) -> bool {
fn visit_predicates(&mut self, predicates: ty::GenericPredicates<'tcx>) -> bool {
let ty::GenericPredicates { parent: _, predicates } = predicates;
for (predicate, _span) in predicates {
match predicate {

View file

@ -1735,6 +1735,59 @@ match eco {
```
"##,
E0575: r##"
Something other than a type or an associated type was given.
Erroneous code example:
```compile_fail,E0575
enum Rick { Morty }
let _: <u8 as Rick>::Morty; // error!
trait Age {
type Empire;
fn Mythology() {}
}
impl Age for u8 {
type Empire = u16;
}
let _: <u8 as Age>::Mythology; // error!
```
In both cases, we're declaring a variable (called `_`) and we're giving it a
type. However, `<u8 as Rick>::Morty` and `<u8 as Age>::Mythology` aren't types,
therefore the compiler throws an error.
`<u8 as Rick>::Morty` is an enum variant, you cannot use a variant as a type,
you have to use the enum directly:
```
enum Rick { Morty }
let _: Rick; // ok!
```
`<u8 as Age>::Mythology` is a trait method, which is definitely not a type.
However, the `Age` trait provides an associated type `Empire` which can be
used as a type:
```
trait Age {
type Empire;
fn Mythology() {}
}
impl Age for u8 {
type Empire = u16;
}
let _: <u8 as Age>::Empire; // ok!
```
"##,
E0603: r##"
A private item was used outside its scope.
@ -1862,7 +1915,6 @@ struct Foo<X = Box<Self>> {
// E0427, merged into 530
// E0467, removed
// E0470, removed
E0575,
E0576,
E0577,
E0578,

View file

@ -669,15 +669,18 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
}
}
}
self.visit_ty(&typ);
if let &Some(ref trait_ref) = trait_ref {
self.process_path(trait_ref.ref_id, &trait_ref.path);
}
self.process_generic_params(generics, "", item.id);
for impl_item in impl_items {
let map = &self.tcx.hir();
self.process_impl_item(impl_item, map.local_def_id_from_node_id(item.id));
}
let map = &self.tcx.hir();
self.nest_tables(item.id, |v| {
v.visit_ty(&typ);
if let &Some(ref trait_ref) = trait_ref {
v.process_path(trait_ref.ref_id, &trait_ref.path);
}
v.process_generic_params(generics, "", item.id);
for impl_item in impl_items {
v.process_impl_item(impl_item, map.local_def_id_from_node_id(item.id));
}
});
}
fn process_trait(

View file

@ -218,7 +218,7 @@ fn program_clauses_for_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
let implemented_from_env = Clause::ForAll(ty::Binder::bind(implemented_from_env));
let predicates = &tcx.predicates_defined_on(def_id).predicates;
let predicates = tcx.predicates_defined_on(def_id).predicates;
// Warning: these where clauses are not substituted for bound vars yet,
// so that we don't need to adjust binders in the `FromEnv` rules below
@ -319,7 +319,7 @@ fn program_clauses_for_impl(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> {
let trait_pred = ty::TraitPredicate { trait_ref }.lower();
// `WC`
let predicates = &tcx.predicates_of(def_id).predicates;
let predicates = tcx.predicates_of(def_id).predicates;
let where_clauses = predicates
.iter()
.map(|(wc, _)| wc.lower())

View file

@ -54,8 +54,7 @@ pub trait AstConv<'tcx> {
/// but this can lead to cycle errors. The problem is that we have
/// to do this resolution *in order to create the predicates in
/// the first place*. Hence, we have this "special pass".
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
-> &'tcx ty::GenericPredicates<'tcx>;
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx>;
/// Returns the lifetime to use when a lifetime is omitted (and not elided).
fn re_infer(

View file

@ -44,7 +44,7 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro
ensure_drop_predicates_are_implied_by_item_defn(
tcx,
drop_impl_did,
&dtor_predicates,
dtor_predicates,
adt_def.did,
self_to_impl_substs,
)
@ -140,7 +140,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
tcx: TyCtxt<'tcx>,
drop_impl_did: DefId,
dtor_predicates: &ty::GenericPredicates<'tcx>,
dtor_predicates: ty::GenericPredicates<'tcx>,
self_type_did: DefId,
self_to_impl_substs: SubstsRef<'tcx>,
) -> Result<(), ErrorReported> {
@ -199,7 +199,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
// just to look for all the predicates directly.
assert_eq!(dtor_predicates.parent, None);
for (predicate, _) in &dtor_predicates.predicates {
for (predicate, _) in dtor_predicates.predicates {
// (We do not need to worry about deep analysis of type
// expressions etc because the Drop impls are already forced
// to take on a structure that is roughly an alpha-renaming of

View file

@ -2245,19 +2245,17 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
self.tcx
}
fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
-> &'tcx ty::GenericPredicates<'tcx>
{
fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
let tcx = self.tcx;
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
let item_id = tcx.hir().ty_param_owner(hir_id);
let item_def_id = tcx.hir().local_def_id(item_id);
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id];
tcx.arena.alloc(ty::GenericPredicates {
ty::GenericPredicates {
parent: None,
predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
match predicate {
predicates: tcx.arena.alloc_from_iter(
self.param_env.caller_bounds.iter().filter_map(|&predicate| match predicate {
ty::Predicate::Trait(ref data)
if data.skip_binder().self_ty().is_param(index) => {
// HACK(eddyb) should get the original `Span`.
@ -2265,9 +2263,9 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
Some((predicate, span))
}
_ => None
}
}).collect()
})
}),
),
}
}
fn re_infer(

View file

@ -791,7 +791,7 @@ fn check_opaque_types<'fcx, 'tcx>(
"check_opaque_types: may define, predicates={:#?}",
predicates,
);
for &(pred, _) in predicates.predicates.iter() {
for &(pred, _) in predicates.predicates {
let substituted_pred = pred.subst(fcx.tcx, substs);
// Avoid duplication of predicates that contain no parameters, for example.
if !predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) {
@ -1011,7 +1011,7 @@ fn check_variances_for_type_defn<'tcx>(
identify_constrained_generic_params(
tcx,
&ty_predicates,
ty_predicates,
None,
&mut constrained_parameters,
);

View file

@ -182,8 +182,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
self.tcx
}
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
-> &'tcx ty::GenericPredicates<'tcx> {
fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> ty::GenericPredicates<'tcx> {
self.tcx
.at(span)
.type_param_predicates((self.item_def_id, def_id))
@ -254,7 +253,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
fn type_param_predicates(
tcx: TyCtxt<'_>,
(item_def_id, def_id): (DefId, DefId),
) -> &ty::GenericPredicates<'_> {
) -> ty::GenericPredicates<'_> {
use rustc::hir::*;
// In the AST, bounds can derive from two places. Either
@ -275,10 +274,10 @@ fn type_param_predicates(
tcx.generics_of(item_def_id).parent
};
let result = parent.map_or(&tcx.common.empty_predicates, |parent| {
let mut result = parent.map(|parent| {
let icx = ItemCtxt::new(tcx, parent);
icx.get_type_parameter_bounds(DUMMY_SP, def_id)
});
}).unwrap_or_default();
let mut extend = None;
let item_hir_id = tcx.hir().as_local_hir_id(item_def_id).unwrap();
@ -321,9 +320,7 @@ fn type_param_predicates(
};
let icx = ItemCtxt::new(tcx, item_def_id);
let mut result = (*result).clone();
result.predicates.extend(extend.into_iter());
result.predicates.extend(
let extra_predicates = extend.into_iter().chain(
icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, OnlySelfBounds(true))
.into_iter()
.filter(|(predicate, _)| {
@ -331,9 +328,12 @@ fn type_param_predicates(
ty::Predicate::Trait(ref data) => data.skip_binder().self_ty().is_param(index),
_ => false,
}
})
}),
);
tcx.arena.alloc(result)
result.predicates = tcx.arena.alloc_from_iter(
result.predicates.iter().copied().chain(extra_predicates),
);
result
}
impl ItemCtxt<'tcx> {
@ -698,7 +698,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::AdtDef {
fn super_predicates_of(
tcx: TyCtxt<'_>,
trait_def_id: DefId,
) -> &ty::GenericPredicates<'_> {
) -> ty::GenericPredicates<'_> {
debug!("super_predicates(trait_def_id={:?})", trait_def_id);
let trait_hir_id = tcx.hir().as_local_hir_id(trait_def_id).unwrap();
@ -732,21 +732,23 @@ fn super_predicates_of(
generics, item.hir_id, self_param_ty, OnlySelfBounds(!is_trait_alias));
// Combine the two lists to form the complete set of superbounds:
let superbounds: Vec<_> = superbounds1.into_iter().chain(superbounds2).collect();
let superbounds = &*tcx.arena.alloc_from_iter(
superbounds1.into_iter().chain(superbounds2)
);
// Now require that immediate supertraits are converted,
// which will, in turn, reach indirect supertraits.
for &(pred, span) in &superbounds {
for &(pred, span) in superbounds {
debug!("superbound: {:?}", pred);
if let ty::Predicate::Trait(bound) = pred {
tcx.at(span).super_predicates_of(bound.def_id());
}
}
tcx.arena.alloc(ty::GenericPredicates {
ty::GenericPredicates {
parent: None,
predicates: superbounds,
})
}
}
fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TraitDef {
@ -1958,7 +1960,7 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx: 'a>(
fn predicates_defined_on(
tcx: TyCtxt<'_>,
def_id: DefId,
) -> &ty::GenericPredicates<'_> {
) -> ty::GenericPredicates<'_> {
debug!("predicates_defined_on({:?})", def_id);
let mut result = tcx.explicit_predicates_of(def_id);
debug!(
@ -1974,9 +1976,13 @@ fn predicates_defined_on(
def_id,
inferred_outlives,
);
let mut predicates = (*result).clone();
predicates.predicates.extend(inferred_outlives.iter().map(|&p| (p, span)));
result = tcx.arena.alloc(predicates);
result.predicates = tcx.arena.alloc_from_iter(
result.predicates.iter().copied().chain(
// FIXME(eddyb) use better spans - maybe add `Span`s
// to `inferred_outlives_of` predicates as well?
inferred_outlives.iter().map(|&p| (p, span)),
),
);
}
debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
result
@ -1985,7 +1991,7 @@ fn predicates_defined_on(
/// Returns a list of all type predicates (explicit and implicit) for the definition with
/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus
/// `Self: Trait` predicates for traits.
fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::GenericPredicates<'_> {
fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
let mut result = tcx.predicates_defined_on(def_id);
if tcx.is_trait(def_id) {
@ -2002,9 +2008,11 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::GenericPredicates<'_> {
// used, and adding the predicate into this list ensures
// that this is done.
let span = tcx.def_span(def_id);
let mut predicates = (*result).clone();
predicates.predicates.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span));
result = tcx.arena.alloc(predicates);
result.predicates = tcx.arena.alloc_from_iter(
result.predicates.iter().copied().chain(
std::iter::once((ty::TraitRef::identity(tcx, def_id).to_predicate(), span))
),
);
}
debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
result
@ -2015,7 +2023,7 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::GenericPredicates<'_> {
fn explicit_predicates_of(
tcx: TyCtxt<'_>,
def_id: DefId,
) -> &ty::GenericPredicates<'_> {
) -> ty::GenericPredicates<'_> {
use rustc::hir::*;
use rustc_data_structures::fx::FxHashSet;
@ -2024,6 +2032,7 @@ fn explicit_predicates_of(
/// A data structure with unique elements, which preserves order of insertion.
/// Preserving the order of insertion is important here so as not to break
/// compile-fail UI tests.
// FIXME(eddyb) just use `IndexSet` from `indexmap`.
struct UniquePredicates<'tcx> {
predicates: Vec<(ty::Predicate<'tcx>, Span)>,
uniques: FxHashSet<(ty::Predicate<'tcx>, Span)>,
@ -2133,10 +2142,10 @@ fn explicit_predicates_of(
let bounds_predicates = bounds.predicates(tcx, opaque_ty);
if impl_trait_fn.is_some() {
// opaque types
return tcx.arena.alloc(ty::GenericPredicates {
return ty::GenericPredicates {
parent: None,
predicates: bounds_predicates,
});
predicates: tcx.arena.alloc_from_iter(bounds_predicates),
};
} else {
// named opaque types
predicates.extend(bounds_predicates);
@ -2339,10 +2348,10 @@ fn explicit_predicates_of(
);
}
let result = tcx.arena.alloc(ty::GenericPredicates {
let result = ty::GenericPredicates {
parent: generics.parent,
predicates,
});
predicates: tcx.arena.alloc_from_iter(predicates),
};
debug!("explicit_predicates_of(def_id={:?}) = {:?}", def_id, result);
result
}

View file

@ -86,11 +86,11 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
pub fn identify_constrained_generic_params<'tcx>(
tcx: TyCtxt<'tcx>,
predicates: &ty::GenericPredicates<'tcx>,
predicates: ty::GenericPredicates<'tcx>,
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
input_parameters: &mut FxHashSet<Parameter>,
) {
let mut predicates = predicates.predicates.clone();
let mut predicates = predicates.predicates.to_vec();
setup_constraining_predicates(tcx, &mut predicates, impl_trait_ref, input_parameters);
}

View file

@ -114,7 +114,7 @@ fn enforce_impl_params_are_constrained(
let mut input_parameters = cgp::parameters_for_impl(impl_self_ty, impl_trait_ref);
cgp::identify_constrained_generic_params(
tcx, &impl_predicates, impl_trait_ref, &mut input_parameters);
tcx, impl_predicates, impl_trait_ref, &mut input_parameters);
// Disallow unconstrained lifetimes, but only if they appear in assoc types.
let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter()

View file

@ -30,7 +30,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
let mut required_predicates = RequiredPredicates::default();
// process predicates and convert to `RequiredPredicates` entry, see below
for (pred, _) in predicates.predicates.iter() {
for (pred, _) in predicates.predicates {
match pred {
ty::Predicate::TypeOutlives(predicate) => {
let OutlivesPredicate(ref ty, ref reg) = predicate.skip_binder();

View file

@ -104,7 +104,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
// regardless of the choice of `T`.
let params = (
self.cx.tcx.generics_of(param_env_def_id),
&&self.cx.tcx.common.empty_predicates,
ty::GenericPredicates::default(),
).clean(self.cx).params;
Generics {
@ -489,7 +489,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
let mut generic_params = (
tcx.generics_of(param_env_def_id),
&tcx.explicit_predicates_of(param_env_def_id),
tcx.explicit_predicates_of(param_env_def_id),
).clean(self.cx).params;
let mut has_sized = FxHashSet::default();

View file

@ -107,7 +107,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
unsafety: hir::Unsafety::Normal,
generics: (
self.cx.tcx.generics_of(impl_def_id),
&self.cx.tcx.explicit_predicates_of(impl_def_id),
self.cx.tcx.explicit_predicates_of(impl_def_id),
).clean(self.cx),
provided_trait_methods,
// FIXME(eddyb) compute both `trait_` and `for_` from

View file

@ -193,7 +193,7 @@ pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
let auto_trait = cx.tcx.trait_def(did).has_auto_impl;
let trait_items = cx.tcx.associated_items(did).map(|item| item.clean(cx)).collect();
let predicates = cx.tcx.predicates_of(did);
let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
let generics = filter_non_trait_generics(did, generics);
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
let is_spotlight = load_attrs(cx, did).clean(cx).has_doc_flag(sym::spotlight);
@ -220,7 +220,7 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
let asyncness = cx.tcx.asyncness(did);
let predicates = cx.tcx.predicates_of(did);
let (generics, decl) = clean::enter_impl_trait(cx, || {
((cx.tcx.generics_of(did), &predicates).clean(cx), (did, sig).clean(cx))
((cx.tcx.generics_of(did), predicates).clean(cx), (did, sig).clean(cx))
});
let (all_types, ret_types) = clean::get_all_types(&generics, &decl, cx);
clean::Function {
@ -241,7 +241,7 @@ fn build_enum(cx: &DocContext<'_>, did: DefId) -> clean::Enum {
let predicates = cx.tcx.explicit_predicates_of(did);
clean::Enum {
generics: (cx.tcx.generics_of(did), &predicates).clean(cx),
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
variants_stripped: false,
variants: cx.tcx.adt_def(did).variants.clean(cx),
}
@ -257,7 +257,7 @@ fn build_struct(cx: &DocContext<'_>, did: DefId) -> clean::Struct {
CtorKind::Fn => doctree::Tuple,
CtorKind::Const => doctree::Unit,
},
generics: (cx.tcx.generics_of(did), &predicates).clean(cx),
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
fields: variant.fields.clean(cx),
fields_stripped: false,
}
@ -269,7 +269,7 @@ fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union {
clean::Union {
struct_type: doctree::Plain,
generics: (cx.tcx.generics_of(did), &predicates).clean(cx),
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
fields: variant.fields.clean(cx),
fields_stripped: false,
}
@ -280,7 +280,7 @@ fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef {
clean::Typedef {
type_: cx.tcx.type_of(did).clean(cx),
generics: (cx.tcx.generics_of(did), &predicates).clean(cx),
generics: (cx.tcx.generics_of(did), predicates).clean(cx),
}
}
@ -376,7 +376,7 @@ pub fn build_impl(cx: &DocContext<'_>, did: DefId, attrs: Option<Attrs<'_>>,
}
}).collect::<Vec<_>>(),
clean::enter_impl_trait(cx, || {
(tcx.generics_of(did), &predicates).clean(cx)
(tcx.generics_of(did), predicates).clean(cx)
}),
)
};

View file

@ -1664,8 +1664,7 @@ impl Clean<Generics> for hir::Generics {
}
}
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
&'a &'tcx ty::GenericPredicates<'tcx>) {
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx>) {
fn clean(&self, cx: &DocContext<'_>) -> Generics {
use self::WherePredicate as WP;
use std::collections::BTreeMap;
@ -2369,7 +2368,7 @@ impl Clean<Item> for ty::AssocItem {
}
ty::AssocKind::Method => {
let generics = (cx.tcx.generics_of(self.def_id),
&cx.tcx.explicit_predicates_of(self.def_id)).clean(cx);
cx.tcx.explicit_predicates_of(self.def_id)).clean(cx);
let sig = cx.tcx.fn_sig(self.def_id);
let mut decl = (self.def_id, sig).clean(cx);
@ -2448,7 +2447,7 @@ impl Clean<Item> for ty::AssocItem {
// all of the generics from there and then look for bounds that are
// applied to this associated type in question.
let predicates = cx.tcx.explicit_predicates_of(did);
let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
let generics = (cx.tcx.generics_of(did), predicates).clean(cx);
let mut bounds = generics.where_predicates.iter().filter_map(|pred| {
let (name, self_type, trait_, bounds) = match *pred {
WherePredicate::BoundPredicate {

View file

@ -22,7 +22,7 @@ use crate::ptr::P;
use crate::sess::ParseSess;
use crate::symbol::{sym, Symbol};
use crate::ThinVec;
use crate::tokenstream::{TokenStream, TokenTree, DelimSpan};
use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
use crate::GLOBALS;
use log::debug;
@ -463,7 +463,7 @@ pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: Symbol) -> Option
}
impl MetaItem {
fn tokens(&self) -> TokenStream {
fn token_trees_and_joints(&self) -> Vec<TreeAndJoint> {
let mut idents = vec![];
let mut last_pos = BytePos(0 as u32);
for (i, segment) in self.path.segments.iter().enumerate() {
@ -477,8 +477,8 @@ impl MetaItem {
idents.push(TokenTree::Token(Token::from_ast_ident(segment.ident)).into());
last_pos = segment.ident.span.hi();
}
self.kind.tokens(self.span).append_to_tree_and_joint_vec(&mut idents);
TokenStream::new(idents)
idents.extend(self.kind.token_trees_and_joints(self.span));
idents
}
fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem>
@ -537,13 +537,14 @@ impl MetaItem {
}
impl MetaItemKind {
pub fn tokens(&self, span: Span) -> TokenStream {
pub fn token_trees_and_joints(&self, span: Span) -> Vec<TreeAndJoint> {
match *self {
MetaItemKind::Word => TokenStream::default(),
MetaItemKind::Word => vec![],
MetaItemKind::NameValue(ref lit) => {
let mut vec = vec![TokenTree::token(token::Eq, span).into()];
lit.tokens().append_to_tree_and_joint_vec(&mut vec);
TokenStream::new(vec)
vec![
TokenTree::token(token::Eq, span).into(),
lit.token_tree().into(),
]
}
MetaItemKind::List(ref list) => {
let mut tokens = Vec::new();
@ -551,17 +552,26 @@ impl MetaItemKind {
if i > 0 {
tokens.push(TokenTree::token(token::Comma, span).into());
}
item.tokens().append_to_tree_and_joint_vec(&mut tokens);
tokens.extend(item.token_trees_and_joints())
}
TokenTree::Delimited(
DelimSpan::from_single(span),
token::Paren,
TokenStream::new(tokens).into(),
).into()
vec![
TokenTree::Delimited(
DelimSpan::from_single(span),
token::Paren,
TokenStream::new(tokens).into(),
).into()
]
}
}
}
// Premature conversions of `TokenTree`s to `TokenStream`s can hurt
// performance. Do not use this function if `token_trees_and_joints()` can
// be used instead.
pub fn tokens(&self, span: Span) -> TokenStream {
TokenStream::new(self.token_trees_and_joints(span))
}
fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItemKind>
where I: Iterator<Item = TokenTree>,
{
@ -603,10 +613,10 @@ impl NestedMetaItem {
}
}
fn tokens(&self) -> TokenStream {
fn token_trees_and_joints(&self) -> Vec<TreeAndJoint> {
match *self {
NestedMetaItem::MetaItem(ref item) => item.tokens(),
NestedMetaItem::Literal(ref lit) => lit.tokens(),
NestedMetaItem::MetaItem(ref item) => item.token_trees_and_joints(),
NestedMetaItem::Literal(ref lit) => vec![lit.token_tree().into()],
}
}

View file

@ -295,6 +295,33 @@ named `file_that_doesnt_exist.rs` or `file_that_doesnt_exist/mod.rs` in the
same directory.
"##,
E0584: r##"
A doc comment that is not attached to anything has been encountered.
Erroneous code example:
```compile_fail,E0584
trait Island {
fn lost();
/// I'm lost!
}
```
A little reminder: a doc comment has to be placed before the item it's supposed
to document. So if you want to document the `Island` trait, you need to put a
doc comment before it, not inside it. Same goes for the `lost` method: the doc
comment needs to be before it:
```
/// I'm THE island!
trait Island {
/// I'm lost!
fn lost();
}
```
"##,
E0585: r##"
A documentation comment that doesn't document anything was found.
@ -494,7 +521,6 @@ features in the `-Z allow_features` flag.
E0549,
E0553, // multiple rustc_const_unstable attributes
// E0555, // replaced with a generic attribute input check
E0584, // file for module `..` found at both .. and ..
E0629, // missing 'feature' (rustc_const_unstable)
// rustc_const_unstable attribute must be paired with stable/unstable
// attribute

View file

@ -286,7 +286,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
(
sym::plugin_registrar, Normal, template!(Word),
Gated(
Stability::Deprecated("https://github.com/rust-lang/rust/issues/29597", None),
Stability::Deprecated(
"https://github.com/rust-lang/rust/pull/64675",
Some("may be removed in a future compiler version"),
),
sym::plugin_registrar,
"compiler plugins are deprecated",
cfg_fn!(plugin_registrar)
@ -295,7 +298,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
(
sym::plugin, CrateLevel, template!(List: "name|name(args)"),
Gated(
Stability::Deprecated("https://github.com/rust-lang/rust/issues/29597", None),
Stability::Deprecated(
"https://github.com/rust-lang/rust/pull/64675",
Some("may be removed in a future compiler version"),
),
sym::plugin,
"compiler plugins are deprecated",
cfg_fn!(plugin)

View file

@ -1,3 +1,4 @@
use rustc_data_structures::fx::FxHashMap;
use syntax_pos::Span;
use crate::print::pprust::token_to_string;
@ -16,6 +17,7 @@ impl<'a> StringReader<'a> {
unmatched_braces: Vec::new(),
matching_delim_spans: Vec::new(),
last_unclosed_found_span: None,
last_delim_empty_block_spans: FxHashMap::default()
};
let res = tt_reader.parse_all_token_trees();
(res, tt_reader.unmatched_braces)
@ -34,6 +36,7 @@ struct TokenTreesReader<'a> {
/// Used only for error recovery when arriving to EOF with mismatched braces.
matching_delim_spans: Vec<(token::DelimToken, Span, Span)>,
last_unclosed_found_span: Option<Span>,
last_delim_empty_block_spans: FxHashMap<token::DelimToken, Span>
}
impl<'a> TokenTreesReader<'a> {
@ -121,13 +124,20 @@ impl<'a> TokenTreesReader<'a> {
// Correct delimiter.
token::CloseDelim(d) if d == delim => {
let (open_brace, open_brace_span) = self.open_braces.pop().unwrap();
let close_brace_span = self.token.span;
if tts.is_empty() {
let empty_block_span = open_brace_span.to(close_brace_span);
self.last_delim_empty_block_spans.insert(delim, empty_block_span);
}
if self.open_braces.len() == 0 {
// Clear up these spans to avoid suggesting them as we've found
// properly matched delimiters so far for an entire block.
self.matching_delim_spans.clear();
} else {
self.matching_delim_spans.push(
(open_brace, open_brace_span, self.token.span),
(open_brace, open_brace_span, close_brace_span),
);
}
// Parse the close delimiter.
@ -193,13 +203,20 @@ impl<'a> TokenTreesReader<'a> {
tts.into()
).into())
},
token::CloseDelim(_) => {
token::CloseDelim(delim) => {
// An unexpected closing delimiter (i.e., there is no
// matching opening delimiter).
let token_str = token_to_string(&self.token);
let msg = format!("unexpected close delimiter: `{}`", token_str);
let mut err = self.string_reader.sess.span_diagnostic
.struct_span_err(self.token.span, &msg);
if let Some(span) = self.last_delim_empty_block_spans.remove(&delim) {
err.span_label(
span,
"this block is empty, you might have not meant to close it"
);
}
err.span_label(self.token.span, "unexpected close delimiter");
Err(err)
},

View file

@ -3,7 +3,7 @@
use crate::ast::{self, Lit, LitKind};
use crate::parse::token::{self, Token};
use crate::symbol::{kw, sym, Symbol};
use crate::tokenstream::{TokenStream, TokenTree};
use crate::tokenstream::TokenTree;
use log::debug;
use rustc_data_structures::sync::Lrc;
@ -216,13 +216,13 @@ impl Lit {
Lit { token: kind.to_lit_token(), kind, span }
}
/// Losslessly convert an AST literal into a token stream.
crate fn tokens(&self) -> TokenStream {
/// Losslessly convert an AST literal into a token tree.
crate fn token_tree(&self) -> TokenTree {
let token = match self.token.kind {
token::Bool => token::Ident(self.token.symbol, false),
_ => token::Literal(self.token),
};
TokenTree::token(token, self.span).into()
TokenTree::token(token, self.span)
}
}

View file

@ -285,10 +285,10 @@ impl TokenCursor {
token::NoDelim,
&if doc_comment_style(&name.as_str()) == AttrStyle::Inner {
[TokenTree::token(token::Pound, sp), TokenTree::token(token::Not, sp), body]
.iter().cloned().collect::<TokenStream>().into()
.iter().cloned().collect::<TokenStream>()
} else {
[TokenTree::token(token::Pound, sp), body]
.iter().cloned().collect::<TokenStream>().into()
.iter().cloned().collect::<TokenStream>()
},
)));

View file

@ -6,7 +6,6 @@ use crate::tokenstream::{TokenStream, TokenTree};
use crate::source_map::Span;
use log::debug;
use smallvec::smallvec;
#[derive(Debug)]
enum InnerAttributeParsePolicy<'a> {
@ -193,15 +192,15 @@ impl<'a> Parser<'a> {
is_interpolated_expr = true;
}
}
let tokens = if is_interpolated_expr {
let token_tree = if is_interpolated_expr {
// We need to accept arbitrary interpolated expressions to continue
// supporting things like `doc = $expr` that work on stable.
// Non-literal interpolated expressions are rejected after expansion.
self.parse_token_tree().into()
self.parse_token_tree()
} else {
self.parse_unsuffixed_lit()?.tokens()
self.parse_unsuffixed_lit()?.token_tree()
};
TokenStream::from_streams(smallvec![eq.into(), tokens])
TokenStream::new(vec![eq.into(), token_tree.into()])
} else {
TokenStream::default()
};

View file

@ -423,7 +423,7 @@ impl<'a> Parser<'a> {
self.struct_span_err(span_of_tilde, "`~` cannot be used as a unary operator")
.span_suggestion_short(
span_of_tilde,
"use `!` to perform bitwise negation",
"use `!` to perform bitwise not",
"!".to_owned(),
Applicability::MachineApplicable
)

View file

@ -33,7 +33,7 @@ pub enum BinOpToken {
}
/// A delimiter token.
#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum DelimToken {
/// A round parenthesis (i.e., `(` or `)`).
Paren,

View file

@ -202,9 +202,9 @@ impl From<TokenTree> for TreeAndJoint {
}
}
impl<T: Into<TokenStream>> iter::FromIterator<T> for TokenStream {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
TokenStream::from_streams(iter.into_iter().map(Into::into).collect::<SmallVec<_>>())
impl iter::FromIterator<TokenTree> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenTree>>(iter: I) -> Self {
TokenStream::new(iter.into_iter().map(Into::into).collect::<Vec<TreeAndJoint>>())
}
}
@ -271,10 +271,6 @@ impl TokenStream {
}
}
pub fn append_to_tree_and_joint_vec(self, vec: &mut Vec<TreeAndJoint>) {
vec.extend(self.0.iter().cloned());
}
pub fn trees(&self) -> Cursor {
self.clone().into_trees()
}

View file

@ -7,11 +7,11 @@ LL | #![plugin(attr_plugin_test)]
= note: for more information, see https://github.com/rust-lang/rust/issues/29597
= help: add `#![feature(plugin)]` to the crate attributes to enable
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/gated-plugin.rs:3:1
|
LL | #![plugin(attr_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/issue-15778-fail.rs:6:1
|
LL | #![plugin(lint_for_crate)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/issue-15778-pass.rs:8:1
|
LL | #![plugin(lint_for_crate_rpass)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/issue-40001.rs:6:1
|
LL | #![plugin(issue_40001_plugin)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lint-group-plugin-deny-cmdline.rs:7:1
|
LL | #![plugin(lint_group_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lint-group-plugin.rs:6:1
|
LL | #![plugin(lint_group_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lint-plugin-cmdline-allow.rs:8:1
|
LL | #![plugin(lint_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lint-plugin-deny-attr.rs:5:1
|
LL | #![plugin(lint_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lint-plugin-deny-cmdline.rs:6:1
|
LL | #![plugin(lint_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -7,11 +7,11 @@ LL | #![forbid(test_lint)]
LL | #[allow(test_lint)]
| ^^^^^^^^^ overruled by previous forbid
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lint-plugin-forbid-attrs.rs:5:1
|
LL | #![plugin(lint_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -6,11 +6,11 @@ LL | #[allow(test_lint)]
|
= note: `forbid` lint level was set on command line
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lint-plugin-forbid-cmdline.rs:6:1
|
LL | #![plugin(lint_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lint-plugin.rs:5:1
|
LL | #![plugin(lint_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -2,11 +2,11 @@ warning: lint name `test_lint` is deprecated and does not have an effect anymore
|
= note: requested on the command line with `-A test_lint`
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lint-tool-cmdline-allow.rs:8:1
|
LL | #![plugin(lint_tool_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -32,11 +32,11 @@ warning: lint name `test_lint` is deprecated and may not have an effect in the f
LL | #![cfg_attr(foo, warn(test_lint))]
| ^^^^^^^^^ help: change it to: `clippy::test_lint`
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lint-tool-test.rs:6:1
|
LL | #![plugin(lint_tool_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/llvm-pass-plugin.rs:6:1
|
LL | #![plugin(llvm_pass_plugin)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/lto-syntax-extension.rs:9:1
|
LL | #![plugin(lto_syntax_extension_plugin)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -4,11 +4,11 @@ error[E0457]: plugin `rlib_crate_test` only found in rlib format, but must be av
LL | #![plugin(rlib_crate_test)]
| ^^^^^^^^^^^^^^^
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/macro-crate-rlib.rs:6:1
|
LL | #![plugin(rlib_crate_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/outlive-expansion-phase.rs:6:1
|
LL | #![plugin(outlive_expansion_phase)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/plugin-args-1.rs:6:1
|
LL | #![plugin(plugin_args)]
| ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/plugin-args-2.rs:6:1
|
LL | #![plugin(plugin_args())]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/plugin-args-3.rs:6:1
|
LL | #![plugin(plugin_args(hello(there), how(are="you")))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/plugin-attr-register-deny.rs:5:1
|
LL | #![plugin(attr_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -10,11 +10,11 @@ note: consider marking `mac` as `pub` in the imported module
LL | pub use mac as reexport;
| ^^^^^^^^^^^^^^^
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/plugin-reexport.rs:6:1
|
LL | #![plugin(attr_plugin_test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/roman-numerals-macro.rs:6:1
|
LL | #![plugin(roman_numerals)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -2,7 +2,7 @@ error: `~` cannot be used as a unary operator
--> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:2:13
|
LL | let x = ~1;
| ^ help: use `!` to perform bitwise negation
| ^ help: use `!` to perform bitwise not
error: aborting due to previous error

View file

@ -186,43 +186,43 @@ LL | mod inner { #![macro_escape] }
|
= help: consider an outer attribute, `#[macro_use]` mod ...
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:219:17
|
LL | mod inner { #![plugin_registrar] }
| ^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:224:5
|
LL | #[plugin_registrar] struct S;
| ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:227:5
|
LL | #[plugin_registrar] type T = S;
| ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:230:5
|
LL | #[plugin_registrar] impl S { }
| ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:216:1
|
LL | #[plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:40:1
|
LL | #![plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
warning: use of deprecated attribute `crate_id`: no longer used.
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:90:1

View file

@ -7,11 +7,11 @@ LL | #![plugin(foo)]
= note: for more information, see https://github.com/rust-lang/rust/issues/29597
= help: add `#![feature(plugin)]` to the crate attributes to enable
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/feature-gate-plugin.rs:3:1
|
LL | #![plugin(foo)]
| ^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -16,11 +16,11 @@ LL | #[plugin_registrar]
= note: for more information, see https://github.com/rust-lang/rust/issues/29597
= help: add `#![feature(plugin_registrar)]` to the crate attributes to enable
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/feature-gate-plugin_registrar.rs:5:1
|
LL | #[plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -1,8 +1,8 @@
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/invalid-plugin-attr.rs:4:1
|
LL | #[plugin(bla)]
| ^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -4,11 +4,11 @@ error: malformed `plugin` attribute input
LL | #![plugin]
| ^^^^^^^^^^ help: must be of the form: `#[plugin(name|name(args))]`
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/malformed-plugin-1.rs:2:1
|
LL | #![plugin]
| ^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -4,11 +4,11 @@ error: malformed `plugin` attribute input
LL | #![plugin="bleh"]
| ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[plugin(name|name(args))]`
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/malformed-plugin-2.rs:2:1
|
LL | #![plugin="bleh"]
| ^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -4,11 +4,11 @@ error[E0498]: malformed `plugin` attribute
LL | #![plugin(foo="bleh")]
| ^^^^^^^^^^^^^^^^^^^^^^ malformed attribute
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/malformed-plugin-3.rs:2:1
|
LL | #![plugin(foo="bleh")]
| ^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default

View file

@ -8,3 +8,4 @@ LL | mod mod_file_disambig_aux;
error: aborting due to previous error
For more information about this error, try `rustc --explain E0584`.

View file

@ -1,16 +1,16 @@
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/multiple-plugin-registrars.rs:6:1
|
LL | #[plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
|
= note: `#[warn(deprecated)]` on by default
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/issues/29597
warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675
--> $DIR/multiple-plugin-registrars.rs:9:1
|
LL | #[plugin_registrar]
| ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
| ^^^^^^^^^^^^^^^^^^^ help: may be removed in a future compiler version
error: multiple plugin registration functions found
|

View file

@ -8,3 +8,4 @@ LL | /// empty doc
error: aborting due to previous error
For more information about this error, try `rustc --explain E0584`.

View file

@ -0,0 +1,5 @@
fn main() {
}
let _ = ();
} //~ ERROR unexpected close delimiter

View file

@ -0,0 +1,14 @@
error: unexpected close delimiter: `}`
--> $DIR/mismatched-delim-brace-empty-block.rs:5:1
|
LL | fn main() {
| ___________-
LL | |
LL | | }
| |_- this block is empty, you might have not meant to close it
LL | let _ = ();
LL | }
| ^ unexpected close delimiter
error: aborting due to previous error

View file

@ -0,0 +1,15 @@
// check-pass
// compile-flags: -Zsave-analysis
trait Trait { type Assoc; }
trait GenericTrait<T> {}
struct Wrapper<B> { b: B }
fn func() {
// Processing associated path in impl block definition inside a function
// body does not ICE
impl<B: Trait> GenericTrait<B::Assoc> for Wrapper<B> {}
}
fn main() {}

View file

@ -200,5 +200,5 @@ LL | <u8 as Dr>::X::N;
error: aborting due to 32 previous errors
Some errors have detailed explanations: E0223, E0433, E0599.
Some errors have detailed explanations: E0223, E0433, E0575, E0599.
For more information about an error, try `rustc --explain E0223`.

View file

@ -8,3 +8,14 @@ allow-unauthenticated = [
]
[assign]
[ping.icebreakers-llvm]
message = """\
Hey LLVM ICE-breakers! This bug has been identified as a good
"LLVM ICE-breaking candidate". In case it's useful, here are some
[instructions] for tackling these sorts of bugs. Maybe take a look?
Thanks! <3
[instructions]: https://rust-lang.github.io/rustc-guide/ice-breaker/llvm.html
"""
label = "ICEBreaker-LLVM"