Auto merge of #55859 - pietroalbini:rollup, r=kennytm

Rollup of 17 pull requests

Successful merges:

 - #55630 (resolve: Filter away macro prelude in modules with `#[no_implicit_prelude]` on 2018 edition)
 - #55687 (Take supertraits into account when calculating associated types)
 - #55745 (Convert `outlives_components`' return value to a `SmallVec` outparam.)
 - #55764 (Fix Rc/Arc allocation layout)
 - #55792 (Prevent ICE in const-prop array oob check)
 - #55799 (Removed unneeded instance of `// revisions` from a lint test)
 - #55800 (Fix ICE in `return_type_impl_trait`)
 - #55801 (NLL: Update box insensitivity test)
 - #55802 (Don't inline virtual calls (take 2))
 - #55816 (Use `SmallVec` to avoid allocations in `from_decimal_string`.)
 - #55819 (Typecheck patterns of all match arms first, so we get types for bindings)
 - #55822 (ICE with #![feature(nll)] and elided lifetimes)
 - #55828 (Add missing `rustc_promotable` attribute to unsigned `min_value` and `max_value`)
 - #55839 (Fix docstring spelling mistakes)
 - #55844 (Fix documentation typos.)
 - #55845 (Set BINARYEN_TRAP_MODE=clamp)
 - #55856 (rustdoc: refactor: move all static-file include!s into a single module)
This commit is contained in:
bors 2018-11-11 06:26:21 +00:00
commit b76ee83254
85 changed files with 1117 additions and 666 deletions

View File

@ -2096,6 +2096,7 @@ version = "0.0.0"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_cratesio_shim 0.0.0",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]

View File

@ -672,14 +672,16 @@ impl<T: ?Sized> Rc<T> {
// Previously, layout was calculated on the expression
// `&*(ptr as *const RcBox<T>)`, but this created a misaligned
// reference (see #54908).
let (layout, _) = Layout::new::<RcBox<()>>()
.extend(Layout::for_value(&*ptr)).unwrap();
let layout = Layout::new::<RcBox<()>>()
.extend(Layout::for_value(&*ptr)).unwrap().0
.pad_to_align().unwrap();
let mem = Global.alloc(layout)
.unwrap_or_else(|_| handle_alloc_error(layout));
// Initialize the RcBox
let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut RcBox<T>;
debug_assert_eq!(Layout::for_value(&*inner), layout);
ptr::write(&mut (*inner).strong, Cell::new(1));
ptr::write(&mut (*inner).weak, Cell::new(1));

View File

@ -575,14 +575,16 @@ impl<T: ?Sized> Arc<T> {
// Previously, layout was calculated on the expression
// `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
// reference (see #54908).
let (layout, _) = Layout::new::<ArcInner<()>>()
.extend(Layout::for_value(&*ptr)).unwrap();
let layout = Layout::new::<ArcInner<()>>()
.extend(Layout::for_value(&*ptr)).unwrap().0
.pad_to_align().unwrap();
let mem = Global.alloc(layout)
.unwrap_or_else(|_| handle_alloc_error(layout));
// Initialize the ArcInner
let inner = set_data_ptr(ptr as *mut T, mem.as_ptr() as *mut u8) as *mut ArcInner<T>;
debug_assert_eq!(Layout::for_value(&*inner), layout);
ptr::write(&mut (*inner).strong, atomic::AtomicUsize::new(1));
ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1));

View File

@ -218,6 +218,23 @@ impl Layout {
len_rounded_up.wrapping_sub(len)
}
/// Creates a layout by rounding the size of this layout up to a multiple
/// of the layout's alignment.
///
/// Returns `Err` if the padded size would overflow.
///
/// This is equivalent to adding the result of `padding_needed_for`
/// to the layout's current size.
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub fn pad_to_align(&self) -> Result<Layout, LayoutErr> {
let pad = self.padding_needed_for(self.align());
let new_size = self.size().checked_add(pad)
.ok_or(LayoutErr { private: () })?;
Layout::from_size_align(new_size, self.align())
}
/// Creates a layout describing the record for `n` instances of
/// `self`, with a suitable amount of padding between each to
/// ensure that each instance is given its requested size and
@ -506,7 +523,7 @@ pub unsafe trait GlobalAlloc {
ptr
}
/// Shink or grow a block of memory to the given `new_size`.
/// Shrink or grow a block of memory to the given `new_size`.
/// The block is described by the given `ptr` pointer and `layout`.
///
/// If this returns a non-null pointer, then ownership of the memory block
@ -757,7 +774,7 @@ pub unsafe trait Alloc {
// realloc. alloc_excess, realloc_excess
/// Returns a pointer suitable for holding data described by
/// a new layout with `layout`s alginment and a size given
/// a new layout with `layout`s alignment and a size given
/// by `new_size`. To
/// accomplish this, this may extend or shrink the allocation
/// referenced by `ptr` to fit the new layout.

View File

@ -17,7 +17,7 @@ use ops;
use pin::Pin;
use task::{Poll, LocalWaker};
/// A future represents an asychronous computation.
/// A future represents an asynchronous computation.
///
/// A future is a value that may not have finished computing yet. This kind of
/// "asynchronous value" makes it possible for a thread to continue doing useful

View File

@ -228,7 +228,7 @@ mod nonzero;
mod tuple;
mod unit;
// Pull in the the `coresimd` crate directly into libcore. This is where all the
// Pull in the `coresimd` crate directly into libcore. This is where all the
// architecture-specific (and vendor-specific) intrinsics are defined. AKA
// things like SIMD and such. Note that the actual source for all this lies in a
// different repository, rust-lang-nursery/stdsimd. That's why the setup here is

View File

@ -350,9 +350,8 @@ macro_rules! try {
/// assert_eq!(v, b"s = \"abc 123\"");
/// ```
///
/// Note: This macro can be used in `no_std` setups as well
/// In a `no_std` setup you are responsible for the
/// implementation details of the components.
/// Note: This macro can be used in `no_std` setups as well.
/// In a `no_std` setup you are responsible for the implementation details of the components.
///
/// ```no_run
/// # extern crate core;
@ -440,7 +439,7 @@ macro_rules! writeln {
///
/// If the determination that the code is unreachable proves incorrect, the
/// program immediately terminates with a [`panic!`]. The function [`unreachable_unchecked`],
/// which belongs to the [`std::hint`] module, informs the compilier to
/// which belongs to the [`std::hint`] module, informs the compiler to
/// optimize the code out of the release version entirely.
///
/// [`panic!`]: ../std/macro.panic.html

View File

@ -202,7 +202,7 @@ pub fn forget<T>(t: T) {
///
/// ## Size of Enums
///
/// Enums that carry no data other than the descriminant have the same size as C enums
/// Enums that carry no data other than the discriminant have the same size as C enums
/// on the platform they are compiled for.
///
/// ## Size of Unions
@ -1081,7 +1081,7 @@ impl<T> MaybeUninit<T> {
///
/// # Unsafety
///
/// It is up to the caller to guarantee that the the `MaybeUninit` really is in an initialized
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
/// state, otherwise this will immediately cause undefined behavior.
#[unstable(feature = "maybe_uninit", issue = "53491")]
pub unsafe fn into_inner(self) -> T {
@ -1092,7 +1092,7 @@ impl<T> MaybeUninit<T> {
///
/// # Unsafety
///
/// It is up to the caller to guarantee that the the `MaybeUninit` really is in an initialized
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
/// state, otherwise this will immediately cause undefined behavior.
#[unstable(feature = "maybe_uninit", issue = "53491")]
pub unsafe fn get_ref(&self) -> &T {
@ -1103,7 +1103,7 @@ impl<T> MaybeUninit<T> {
///
/// # Unsafety
///
/// It is up to the caller to guarantee that the the `MaybeUninit` really is in an initialized
/// It is up to the caller to guarantee that the `MaybeUninit` really is in an initialized
/// state, otherwise this will immediately cause undefined behavior.
#[unstable(feature = "maybe_uninit", issue = "53491")]
pub unsafe fn get_mut(&mut self) -> &mut T {

View File

@ -2152,6 +2152,7 @@ Basic usage:
", $Feature, "assert_eq!(", stringify!($SelfT), "::min_value(), 0);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
#[inline]
pub const fn min_value() -> Self { 0 }
}
@ -2168,6 +2169,7 @@ Basic usage:
stringify!($MaxV), ");", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_promotable]
#[inline]
pub const fn max_value() -> Self { !0 }
}

View File

@ -3,7 +3,7 @@
//! It is sometimes useful to have objects that are guaranteed to not move,
//! in the sense that their placement in memory does not change, and can thus be relied upon.
//!
//! A prime example of such a scenario would be building self-referencial structs,
//! A prime example of such a scenario would be building self-referential structs,
//! since moving an object with pointers to itself will invalidate them,
//! which could cause undefined behavior.
//!
@ -39,7 +39,7 @@
//! use std::marker::Pinned;
//! use std::ptr::NonNull;
//!
//! // This is a self referencial struct since the slice field points to the data field.
//! // This is a self-referential struct since the slice field points to the data field.
//! // We cannot inform the compiler about that with a normal reference,
//! // since this pattern cannot be described with the usual borrowing rules.
//! // Instead we use a raw pointer, though one which is known to not be null,

View File

@ -120,7 +120,7 @@ pub use intrinsics::write_bytes;
///
/// Additionally, if `T` is not [`Copy`], using the pointed-to value after
/// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
/// foo` counts as a use because it will cause the the value to be dropped
/// foo` counts as a use because it will cause the value to be dropped
/// again. [`write`] can be used to overwrite data without causing it to be
/// dropped.
///
@ -371,7 +371,7 @@ pub(crate) unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
#[inline]
unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
// The approach here is to utilize simd to swap x & y efficiently. Testing reveals
// that swapping either 32 bytes or 64 bytes at a time is most efficient for intel
// that swapping either 32 bytes or 64 bytes at a time is most efficient for Intel
// Haswell E processors. LLVM is more able to optimize if we give a struct a
// #[repr(simd)], even if we don't actually use this struct directly.
//
@ -1005,7 +1005,7 @@ impl<T: ?Sized> *const T {
/// # Null-unchecked version
///
/// If you are sure the pointer can never be null and are looking for some kind of
/// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>, know that you can
/// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
/// dereference the pointer directly.
///
/// ```
@ -1625,7 +1625,7 @@ impl<T: ?Sized> *mut T {
/// # Null-unchecked version
///
/// If you are sure the pointer can never be null and are looking for some kind of
/// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>, know that you can
/// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
/// dereference the pointer directly.
///
/// ```

View File

@ -2134,7 +2134,7 @@ static X: u32 = 42;
register_diagnostics! {
// E0006 // merged with E0005
// E0006, // merged with E0005
// E0101, // replaced with E0282
// E0102, // replaced with E0282
// E0134,
@ -2183,9 +2183,7 @@ register_diagnostics! {
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
E0697, // closures cannot be static
E0707, // multiple elided lifetimes used in arguments of `async fn`
E0708, // `async` non-`move` closures with arguments are not currently supported
E0709, // multiple different lifetimes used in arguments of `async fn`

View File

@ -506,9 +506,9 @@ pub enum TraitBoundModifier {
}
/// The AST represents all type param bounds as types.
/// typeck::collect::compute_bounds matches these against
/// the "special" built-in traits (see middle::lang_items) and
/// detects Copy, Send and Sync.
/// `typeck::collect::compute_bounds` matches these against
/// the "special" built-in traits (see `middle::lang_items`) and
/// detects `Copy`, `Send` and `Sync`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum GenericBound {
Trait(PolyTraitRef, TraitBoundModifier),

View File

@ -366,7 +366,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let mut types = vec![concrete_ty];
let bound_region = |r| self.sub_regions(infer::CallReturn(span), least_region, r);
while let Some(ty) = types.pop() {
let mut components = self.tcx.outlives_components(ty);
let mut components = smallvec![];
self.tcx.push_outlives_components(ty, &mut components);
while let Some(component) = components.pop() {
match component {
Component::Region(r) => {

View File

@ -9,7 +9,7 @@
// except according to those terms.
//! Code that handles "type-outlives" constraints like `T: 'a`. This
//! is based on the `outlives_components` function defined on the tcx,
//! is based on the `push_outlives_components` function defined on the tcx,
//! but it adds a bit of heuristics on top, in particular to deal with
//! associated types and projections.
//!
@ -307,17 +307,18 @@ where
assert!(!ty.has_escaping_bound_vars());
let components = self.tcx.outlives_components(ty);
self.components_must_outlive(origin, components, region);
let mut components = smallvec![];
self.tcx.push_outlives_components(ty, &mut components);
self.components_must_outlive(origin, &components, region);
}
fn components_must_outlive(
&mut self,
origin: infer::SubregionOrigin<'tcx>,
components: Vec<Component<'tcx>>,
components: &[Component<'tcx>],
region: ty::Region<'tcx>,
) {
for component in components {
for component in components.iter() {
let origin = origin.clone();
match component {
Component::Region(region1) => {
@ -325,13 +326,13 @@ where
.push_sub_region_constraint(origin, region, region1);
}
Component::Param(param_ty) => {
self.param_ty_must_outlive(origin, region, param_ty);
self.param_ty_must_outlive(origin, region, *param_ty);
}
Component::Projection(projection_ty) => {
self.projection_must_outlive(origin, region, projection_ty);
self.projection_must_outlive(origin, region, *projection_ty);
}
Component::EscapingProjection(subcomponents) => {
self.components_must_outlive(origin, subcomponents, region);
self.components_must_outlive(origin, &subcomponents, region);
}
Component::UnresolvedInferenceVariable(v) => {
// ignore this, we presume it will yield an error

View File

@ -155,7 +155,8 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
.map(|subty| self.type_bound(subty))
.collect::<Vec<_>>();
let mut regions = ty.regions();
let mut regions = smallvec![];
ty.push_regions(&mut regions);
regions.retain(|r| !r.is_late_bound()); // ignore late-bound regions
bounds.push(VerifyBound::AllBounds(
regions

View File

@ -300,12 +300,6 @@ declare_lint! {
"detects labels that are never used"
}
declare_lint! {
pub DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
Warn,
"warns about duplicate associated type bindings in generics"
}
declare_lint! {
pub DUPLICATE_MACRO_EXPORTS,
Deny,
@ -418,7 +412,6 @@ impl LintPass for HardwiredLints {
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
UNSTABLE_NAME_COLLISIONS,
IRREFUTABLE_LET_PATTERNS,
DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
DUPLICATE_MACRO_EXPORTS,
INTRA_DOC_LINK_RESOLUTION_FAILURE,
MISSING_DOC_CODE_EXAMPLES,

View File

@ -963,6 +963,10 @@ impl Session {
self.opts.debugging_opts.teach && self.diagnostic().must_teach(code)
}
pub fn rust_2015(&self) -> bool {
self.opts.edition == Edition::Edition2015
}
/// Are we allowed to use features from the Rust 2018 edition?
pub fn rust_2018(&self) -> bool {
self.opts.edition >= Edition::Edition2018

View File

@ -50,11 +50,8 @@ pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError
pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
pub use self::specialize::find_associated_item;
pub use self::engine::{TraitEngine, TraitEngineExt};
pub use self::util::elaborate_predicates;
pub use self::util::supertraits;
pub use self::util::Supertraits;
pub use self::util::supertrait_def_ids;
pub use self::util::SupertraitDefIds;
pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
pub use self::util::{supertraits, supertrait_def_ids, Supertraits, SupertraitDefIds};
pub use self::util::transitive_bounds;
#[allow(dead_code)]

View File

@ -200,8 +200,10 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> {
}
let visited = &mut self.visited;
let mut components = smallvec![];
tcx.push_outlives_components(ty_max, &mut components);
self.stack.extend(
tcx.outlives_components(ty_max)
components
.into_iter()
.filter_map(|component| match component {
Component::Region(r) => if r.is_late_bound() {
@ -333,7 +335,7 @@ impl<I> FilterToTraits<I> {
}
}
impl<'tcx,I:Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
type Item = ty::PolyTraitRef<'tcx>;
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {

View File

@ -17,7 +17,7 @@ use session::Session;
use session::config::{BorrowckMode, OutputFilenames};
use session::config::CrateType;
use middle;
use hir::{TraitCandidate, HirId, ItemLocalId, Node};
use hir::{TraitCandidate, HirId, ItemKind, ItemLocalId, Node};
use hir::def::{Def, Export};
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
use hir::map as hir_map;
@ -1602,6 +1602,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
&self,
scope_def_id: DefId,
) -> Option<Ty<'tcx>> {
// HACK: `type_of_def_id()` will fail on these (#55796), so return None
let node_id = self.hir.as_local_node_id(scope_def_id).unwrap();
match self.hir.get(node_id) {
Node::Item(item) => {
match item.node {
ItemKind::Fn(..) => { /* type_of_def_id() will work */ }
_ => {
return None;
}
}
}
_ => { /* type_of_def_id() will work or panic */ }
}
let ret_ty = self.type_of(scope_def_id);
match ret_ty.sty {
ty::FnDef(_, _) => {

View File

@ -294,7 +294,7 @@ impl Visibility {
}
}
/// Returns true if an item with this visibility is accessible from the given block.
/// Returns `true` if an item with this visibility is accessible from the given block.
pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool {
let restriction = match self {
// Public items are visible everywhere.
@ -309,7 +309,7 @@ impl Visibility {
tree.is_descendant_of(module, restriction)
}
/// Returns true if this visibility is at least as accessible as the given visibility
/// Returns `true` if this visibility is at least as accessible as the given visibility
pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool {
let vis_restriction = match vis {
Visibility::Public => return self == Visibility::Public,
@ -320,7 +320,7 @@ impl Visibility {
self.is_accessible_from(vis_restriction, tree)
}
// Returns true if this item is visible anywhere in the local crate.
// Returns `true` if this item is visible anywhere in the local crate.
pub fn is_visible_locally(self) -> bool {
match self {
Visibility::Public => true,
@ -451,7 +451,7 @@ bitflags! {
// FIXME: Rename this to the actual property since it's used for generators too
const HAS_TY_CLOSURE = 1 << 9;
// true if there are "names" of types and regions and so forth
// `true` if there are "names" of types and regions and so forth
// that are local to a particular fn
const HAS_FREE_LOCAL_NAMES = 1 << 10;
@ -544,14 +544,14 @@ impl<'tcx> TyS<'tcx> {
pub fn is_primitive_ty(&self) -> bool {
match self.sty {
TyKind::Bool |
TyKind::Char |
TyKind::Int(_) |
TyKind::Uint(_) |
TyKind::Float(_) |
TyKind::Infer(InferTy::IntVar(_)) |
TyKind::Infer(InferTy::FloatVar(_)) |
TyKind::Infer(InferTy::FreshIntTy(_)) |
TyKind::Infer(InferTy::FreshFloatTy(_)) => true,
TyKind::Char |
TyKind::Int(_) |
TyKind::Uint(_) |
TyKind::Float(_) |
TyKind::Infer(InferTy::IntVar(_)) |
TyKind::Infer(InferTy::FloatVar(_)) |
TyKind::Infer(InferTy::FreshIntTy(_)) |
TyKind::Infer(InferTy::FreshFloatTy(_)) => true,
TyKind::Ref(_, x, _) => x.is_primitive_ty(),
_ => false,
}
@ -953,7 +953,7 @@ impl<'a, 'gcx, 'tcx> Generics {
_ => bug!("expected lifetime parameter, but found another generic parameter")
}
} else {
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
.region_param(param, tcx)
}
}
@ -970,7 +970,7 @@ impl<'a, 'gcx, 'tcx> Generics {
_ => bug!("expected type parameter, but found another generic parameter")
}
} else {
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?"))
.type_param(param, tcx)
}
}
@ -993,6 +993,7 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
self.instantiate_into(tcx, &mut instantiated, substs);
instantiated
}
pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
-> InstantiatedPredicates<'tcx> {
InstantiatedPredicates {
@ -1041,15 +1042,15 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Predicate<'tcx> {
/// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
/// Corresponds to `where Foo: Bar<A,B,C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
/// would be the type parameters.
Trait(PolyTraitPredicate<'tcx>),
/// where `'a : 'b`
/// where `'a: 'b`
RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),
/// where `T : 'a`
/// where `T: 'a`
TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),
/// where `<T as TraitRef>::Name == X`, approximately.
@ -1062,7 +1063,7 @@ pub enum Predicate<'tcx> {
/// trait must be object-safe
ObjectSafe(DefId),
/// No direct syntax. May be thought of as `where T : FnFoo<...>`
/// No direct syntax. May be thought of as `where T: FnFoo<...>`
/// for some substitutions `...` and `T` being a closure type.
/// Satisfied (or refuted) once we know the closure's kind.
ClosureKind(DefId, ClosureSubsts<'tcx>, ClosureKind),
@ -1111,11 +1112,11 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
//
// Let's start with an easy case. Consider two traits:
//
// trait Foo<'a> : Bar<'a,'a> { }
// trait Foo<'a>: Bar<'a,'a> { }
// trait Bar<'b,'c> { }
//
// Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
// we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
// Now, if we have a trait reference `for<'x> T: Foo<'x>`, then
// we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we
// knew that `Foo<'x>` (for any 'x) then we also know that
// `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
// normal substitution.
@ -1128,21 +1129,21 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
//
// Another example to be careful of is this:
//
// trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
// trait Foo1<'a>: for<'b> Bar1<'a,'b> { }
// trait Bar1<'b,'c> { }
//
// Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
// The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
// Here, if we have `for<'x> T: Foo1<'x>`, then what do we know?
// The answer is that we know `for<'x,'b> T: Bar1<'x,'b>`. The
// reason is similar to the previous example: any impl of
// `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
// `T:Foo1<'x>` must show that `for<'b> T: Bar1<'x, 'b>`. So
// basically we would want to collapse the bound lifetimes from
// the input (`trait_ref`) and the supertraits.
//
// To achieve this in practice is fairly straightforward. Let's
// consider the more complicated scenario:
//
// - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
// has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
// - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x`
// has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`,
// where both `'x` and `'b` would have a DB index of 1.
// The substitution from the input trait-ref is therefore going to be
// `'a => 'x` (where `'x` has a DB index of 1).
@ -1194,6 +1195,7 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
pub struct TraitPredicate<'tcx> {
pub trait_ref: TraitRef<'tcx>
}
pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
impl<'tcx> TraitPredicate<'tcx> {
@ -1218,7 +1220,7 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A: B`
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>,
ty::Region<'tcx>>;
@ -1238,11 +1240,11 @@ pub type PolySubtypePredicate<'tcx> = ty::Binder<SubtypePredicate<'tcx>>;
/// This kind of predicate has no *direct* correspondent in the
/// syntax, but it roughly corresponds to the syntactic forms:
///
/// 1. `T : TraitRef<..., Item=Type>`
/// 1. `T: TraitRef<..., Item=Type>`
/// 2. `<T as TraitRef<...>>::Item == Type` (NYI)
///
/// In particular, form #1 is "desugared" to the combination of a
/// normal trait predicate (`T : TraitRef<...>`) and one of these
/// normal trait predicate (`T: TraitRef<...>`) and one of these
/// predicates. Form #2 is a broader form in that it also permits
/// equality between arbitrary types. Processing an instance of
/// Form #2 eventually yields one of these `ProjectionPredicate`
@ -1256,14 +1258,14 @@ pub struct ProjectionPredicate<'tcx> {
pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
impl<'tcx> PolyProjectionPredicate<'tcx> {
/// Returns the def-id of the associated item being projected.
/// Returns the `DefId` of the associated item being projected.
pub fn item_def_id(&self) -> DefId {
self.skip_binder().projection_ty.item_def_id
}
pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'_, '_, '_>) -> PolyTraitRef<'tcx> {
// Note: unlike with TraitRef::to_poly_trait_ref(),
// self.0.trait_ref is permitted to have escaping regions.
// Note: unlike with `TraitRef::to_poly_trait_ref()`,
// `self.0.trait_ref` is permitted to have escaping regions.
// This is because here `self` has a `Binder` and so does our
// return value, so we are preserving the number of binding
// levels.
@ -1274,12 +1276,12 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
self.map_bound(|predicate| predicate.ty)
}
/// The DefId of the TraitItem for the associated type.
/// The `DefId` of the `TraitItem` for the associated type.
///
/// Note that this is not the DefId of the TraitRef containing this
/// associated type, which is in tcx.associated_item(projection_def_id()).container.
/// Note that this is not the `DefId` of the `TraitRef` containing this
/// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
pub fn projection_def_id(&self) -> DefId {
// ok to skip binder since trait def-id does not care about regions
// okay to skip binder since trait def-id does not care about regions
self.skip_binder().projection_ty.item_def_id
}
}
@ -1515,14 +1517,14 @@ impl UniverseIndex {
UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
}
/// True if `self` can name a name from `other` -- in other words,
/// Returns `true` if `self` can name a name from `other` -- in other words,
/// if the set of names in `self` is a superset of those in
/// `other` (`self >= other`).
pub fn can_name(self, other: UniverseIndex) -> bool {
self.private >= other.private
}
/// True if `self` cannot name some names from `other` -- in other
/// Returns `true` if `self` cannot name some names from `other` -- in other
/// words, if the set of names in `self` is a strict subset of
/// those in `other` (`self < other`).
pub fn cannot_name(self, other: UniverseIndex) -> bool {
@ -1574,7 +1576,7 @@ impl<'tcx> ParamEnv<'tcx> {
/// are revealed. This is suitable for monomorphized, post-typeck
/// environments like codegen or doing optimizations.
///
/// NB. If you want to have predicates in scope, use `ParamEnv::new`,
/// N.B. If you want to have predicates in scope, use `ParamEnv::new`,
/// or invoke `param_env.with_reveal_all()`.
pub fn reveal_all() -> Self {
Self::new(List::empty(), Reveal::All)
@ -1979,14 +1981,14 @@ impl ReprOptions {
self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize))
}
/// Returns true if this `#[repr()]` should inhabit "smart enum
/// Returns `true` if this `#[repr()]` should inhabit "smart enum
/// layout" optimizations, such as representing `Foo<&T>` as a
/// single pointer.
pub fn inhibit_enum_layout_opt(&self) -> bool {
self.c() || self.int.is_some()
}
/// Returns true if this `#[repr()]` should inhibit struct field reordering
/// Returns `true` if this `#[repr()]` should inhibit struct field reordering
/// optimizations, such as with repr(C) or repr(packed(1)).
pub fn inhibit_struct_field_reordering_opt(&self) -> bool {
!(self.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty() || (self.pack == 1)
@ -2089,7 +2091,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
self.flags.intersects(AdtFlags::IS_FUNDAMENTAL)
}
/// Returns true if this is PhantomData<T>.
/// Returns `true` if this is PhantomData<T>.
#[inline]
pub fn is_phantom_data(&self) -> bool {
self.flags.intersects(AdtFlags::IS_PHANTOM_DATA)
@ -2105,7 +2107,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
self.flags.intersects(AdtFlags::IS_RC)
}
/// Returns true if this is Box<T>.
/// Returns `true` if this is Box<T>.
#[inline]
pub fn is_box(&self) -> bool {
self.flags.intersects(AdtFlags::IS_BOX)
@ -2422,7 +2424,7 @@ impl<'a, 'tcx> ClosureKind {
}
}
/// True if this a type that impls this closure kind
/// Returns `true` if this a type that impls this closure kind
/// must also implement `other`.
pub fn extends(self, other: ty::ClosureKind) -> bool {
match (self, other) {
@ -2475,7 +2477,7 @@ impl<'tcx> TyS<'tcx> {
///
/// Note: prefer `ty.walk()` where possible.
pub fn maybe_walk<F>(&'tcx self, mut f: F)
where F : FnMut(Ty<'tcx>) -> bool
where F: FnMut(Ty<'tcx>) -> bool
{
let mut walker = self.walk();
while let Some(ty) = walker.next() {
@ -2678,7 +2680,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
as Box<dyn Iterator<Item = AssociatedItem> + 'a>
}
/// Returns true if the impls are the same polarity and the trait either
/// Returns `true` if the impls are the same polarity and the trait either
/// has no items or is annotated #[marker] and prevents item overrides.
pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) -> bool {
if self.features().overlapping_marker_traits {
@ -2802,7 +2804,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
attr::contains_name(&self.get_attrs(did), attr)
}
/// Returns true if this is an `auto trait`.
/// Returns `true` if this is an `auto trait`.
pub fn trait_is_auto(self, trait_def_id: DefId) -> bool {
self.trait_def(trait_def_id).has_auto_impl
}

View File

@ -12,6 +12,7 @@
// refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that
// RFC for reference.
use smallvec::SmallVec;
use ty::{self, Ty, TyCtxt, TypeFoldable};
#[derive(Debug)]
@ -55,17 +56,15 @@ pub enum Component<'tcx> {
}
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// Returns all the things that must outlive `'a` for the condition
/// Push onto `out` all the things that must outlive `'a` for the condition
/// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**.
pub fn outlives_components(&self, ty0: Ty<'tcx>)
-> Vec<Component<'tcx>> {
let mut components = vec![];
self.compute_components(ty0, &mut components);
debug!("components({:?}) = {:?}", ty0, components);
components
pub fn push_outlives_components(&self, ty0: Ty<'tcx>,
out: &mut SmallVec<[Component<'tcx>; 4]>) {
self.compute_components(ty0, out);
debug!("components({:?}) = {:?}", ty0, out);
}
fn compute_components(&self, ty: Ty<'tcx>, out: &mut Vec<Component<'tcx>>) {
fn compute_components(&self, ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
// Descend through the types, looking for the various "base"
// components and collecting them into `out`. This is not written
// with `collect()` because of the need to sometimes skip subtrees
@ -164,7 +163,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// list is maintained explicitly, because bound regions
// themselves can be readily identified.
push_region_constraints(out, ty.regions());
push_region_constraints(ty, out);
for subty in ty.walk_shallow() {
self.compute_components(subty, out);
}
@ -173,15 +172,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
fn capture_components(&self, ty: Ty<'tcx>) -> Vec<Component<'tcx>> {
let mut temp = vec![];
push_region_constraints(&mut temp, ty.regions());
let mut temp = smallvec![];
push_region_constraints(ty, &mut temp);
for subty in ty.walk_shallow() {
self.compute_components(subty, &mut temp);
}
temp
temp.into_iter().collect()
}
}
fn push_region_constraints<'tcx>(out: &mut Vec<Component<'tcx>>, regions: Vec<ty::Region<'tcx>>) {
fn push_region_constraints<'tcx>(ty: Ty<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>) {
let mut regions = smallvec![];
ty.push_regions(&mut regions);
out.extend(regions.iter().filter(|&r| !r.is_late_bound()).map(|r| Component::Region(r)));
}

View File

@ -22,6 +22,7 @@ use ty::{List, TyS, ParamEnvAnd, ParamEnv};
use util::captures::Captures;
use mir::interpret::{Scalar, Pointer};
use smallvec::SmallVec;
use std::iter;
use std::cmp::Ordering;
use rustc_target::spec::abi;
@ -627,7 +628,7 @@ impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
/// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where clause:
///
/// T : Foo<U>
/// T: Foo<U>
///
/// This would be represented by a trait-reference where the def-id is the
/// def-id for the trait `Foo` and the substs define `T` as parameter 0,
@ -637,8 +638,8 @@ impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
/// that case the `Self` parameter is absent from the substitutions.
///
/// Note that a `TraitRef` introduces a level of region binding, to
/// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
/// U>` or higher-ranked object types.
/// account for higher-ranked trait bounds like `T: for<'a> Foo<&'a U>`
/// or higher-ranked object types.
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct TraitRef<'tcx> {
pub def_id: DefId,
@ -663,7 +664,7 @@ impl<'tcx> TraitRef<'tcx> {
self.substs.type_at(0)
}
pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
// Select only the "input types" from a trait-reference. For
// now this is all the types that appear in the
// trait-reference, but it should eventually exclude
@ -886,16 +887,16 @@ pub struct ProjectionTy<'tcx> {
/// The parameters of the associated item.
pub substs: &'tcx Substs<'tcx>,
/// The DefId of the TraitItem for the associated type N.
/// The `DefId` of the `TraitItem` for the associated type `N`.
///
/// Note that this is not the DefId of the TraitRef containing this
/// associated type, which is in tcx.associated_item(item_def_id).container.
/// Note that this is not the `DefId` of the `TraitRef` containing this
/// associated type, which is in `tcx.associated_item(item_def_id).container`.
pub item_def_id: DefId,
}
impl<'a, 'tcx> ProjectionTy<'tcx> {
/// Construct a ProjectionTy by searching the trait from trait_ref for the
/// associated item named item_name.
/// Construct a `ProjectionTy` by searching the trait from `trait_ref` for the
/// associated item named `item_name`.
pub fn from_ref_and_name(
tcx: TyCtxt<'_, '_, '_>, trait_ref: ty::TraitRef<'tcx>, item_name: Ident
) -> ProjectionTy<'tcx> {
@ -1846,28 +1847,27 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}
}
/// Returns the regions directly referenced from this type (but
/// not types reachable from this type via `walk_tys`). This
/// ignores late-bound regions binders.
pub fn regions(&self) -> Vec<ty::Region<'tcx>> {
/// Push onto `out` the regions directly referenced from this type (but not
/// types reachable from this type via `walk_tys`). This ignores late-bound
/// regions binders.
pub fn push_regions(&self, out: &mut SmallVec<[ty::Region<'tcx>; 4]>) {
match self.sty {
Ref(region, _, _) => {
vec![region]
out.push(region);
}
Dynamic(ref obj, region) => {
let mut v = vec![region];
v.extend(obj.principal().skip_binder().substs.regions());
v
out.push(region);
out.extend(obj.principal().skip_binder().substs.regions());
}
Adt(_, substs) | Opaque(_, substs) => {
substs.regions().collect()
out.extend(substs.regions())
}
Closure(_, ClosureSubsts { ref substs }) |
Generator(_, GeneratorSubsts { ref substs }, _) => {
substs.regions().collect()
out.extend(substs.regions())
}
Projection(ref data) | UnnormalizedProjection(ref data) => {
data.substs.regions().collect()
out.extend(data.substs.regions())
}
FnDef(..) |
FnPtr(_) |
@ -1887,9 +1887,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
Param(_) |
Bound(..) |
Infer(_) |
Error => {
vec![]
}
Error => {}
}
}

View File

@ -27,7 +27,7 @@ use std::marker::PhantomData;
use std::mem;
use std::num::NonZeroUsize;
/// An entity in the Rust typesystem, which can be one of
/// An entity in the Rust type system, which can be one of
/// several kinds (only types and lifetimes for now).
/// To reduce memory usage, a `Kind` is a interned pointer,
/// with the lowest 2 bits being reserved for a tag to
@ -171,7 +171,7 @@ impl<'tcx> Decodable for Kind<'tcx> {
pub type Substs<'tcx> = List<Kind<'tcx>>;
impl<'a, 'gcx, 'tcx> Substs<'tcx> {
/// Creates a Substs that maps each generic parameter to itself.
/// Creates a `Substs` that maps each generic parameter to itself.
pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId)
-> &'tcx Substs<'tcx> {
Substs::for_item(tcx, def_id, |param, _| {
@ -179,9 +179,9 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
})
}
/// Creates a Substs for generic parameter definitions,
/// Creates a `Substs` for generic parameter definitions,
/// by calling closures to obtain each kind.
/// The closures get to observe the Substs as they're
/// The closures get to observe the `Substs` as they're
/// being built, which can be used to correctly
/// substitute defaults of generic parameters.
pub fn for_item<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
@ -242,7 +242,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}
#[inline]
pub fn types(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
pub fn types(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
self.iter().filter_map(|k| {
if let UnpackedKind::Type(ty) = k.unpack() {
Some(ty)
@ -253,7 +253,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}
#[inline]
pub fn regions(&'a self) -> impl DoubleEndedIterator<Item=ty::Region<'tcx>> + 'a {
pub fn regions(&'a self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'a {
self.iter().filter_map(|k| {
if let UnpackedKind::Lifetime(lt) = k.unpack() {
Some(lt)
@ -332,7 +332,7 @@ impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
// `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
// there is more information available (for better errors).
pub trait Subst<'tcx> : Sized {
pub trait Subst<'tcx>: Sized {
fn subst<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
substs: &[Kind<'tcx>]) -> Self {
self.subst_spanned(tcx, substs, None)

View File

@ -10,3 +10,4 @@ path = "lib.rs"
[dependencies]
bitflags = "1.0"
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
smallvec = { version = "0.6.5", features = ["union"] }

View File

@ -11,6 +11,7 @@
use {Category, ExpInt, IEK_INF, IEK_NAN, IEK_ZERO};
use {Float, FloatConvert, ParseError, Round, Status, StatusAnd};
use smallvec::{SmallVec, smallvec};
use std::cmp::{self, Ordering};
use std::convert::TryFrom;
use std::fmt::{self, Write};
@ -1962,7 +1963,7 @@ impl<S: Semantics> IeeeFloat<S> {
// to hold the full significand, and an extra limb required by
// tcMultiplyPart.
let max_limbs = limbs_for_bits(1 + 196 * significand_digits / 59);
let mut dec_sig = Vec::with_capacity(max_limbs);
let mut dec_sig: SmallVec<[Limb; 1]> = SmallVec::with_capacity(max_limbs);
// Convert to binary efficiently - we do almost all multiplication
// in a Limb. When this would overflow do we do a single
@ -2021,11 +2022,11 @@ impl<S: Semantics> IeeeFloat<S> {
const FIRST_EIGHT_POWERS: [Limb; 8] = [1, 5, 25, 125, 625, 3125, 15625, 78125];
let mut p5_scratch = vec![];
let mut p5 = vec![FIRST_EIGHT_POWERS[4]];
let mut p5_scratch = smallvec![];
let mut p5: SmallVec<[Limb; 1]> = smallvec![FIRST_EIGHT_POWERS[4]];
let mut r_scratch = vec![];
let mut r = vec![FIRST_EIGHT_POWERS[power & 7]];
let mut r_scratch = smallvec![];
let mut r: SmallVec<[Limb; 1]> = smallvec![FIRST_EIGHT_POWERS[power & 7]];
power >>= 3;
while power > 0 {
@ -2064,7 +2065,7 @@ impl<S: Semantics> IeeeFloat<S> {
let calc_precision = (LIMB_BITS << attempt) - 1;
attempt += 1;
let calc_normal_from_limbs = |sig: &mut Vec<Limb>,
let calc_normal_from_limbs = |sig: &mut SmallVec<[Limb; 1]>,
limbs: &[Limb]|
-> StatusAnd<ExpInt> {
sig.resize(limbs_for_bits(calc_precision), 0);

View File

@ -53,6 +53,7 @@ extern crate rustc_cratesio_shim;
#[macro_use]
extern crate bitflags;
extern crate smallvec;
use std::cmp::Ordering;
use std::fmt;

View File

@ -317,11 +317,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>",
edition: None,
},
FutureIncompatibleInfo {
id: LintId::of(DUPLICATE_ASSOCIATED_TYPE_BINDINGS),
reference: "issue #50589 <https://github.com/rust-lang/rust/issues/50589>",
edition: None,
},
FutureIncompatibleInfo {
id: LintId::of(PROC_MACRO_DERIVE_RESOLUTION_FALLBACK),
reference: "issue #50504 <https://github.com/rust-lang/rust/issues/50504>",

View File

@ -687,22 +687,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let mir_node_id = tcx.hir.as_local_node_id(mir_def_id).expect("non-local mir");
let (return_span, mir_description) =
if let hir::ExprKind::Closure(_, _, _, span, gen_move) =
tcx.hir.expect_expr(mir_node_id).node
{
(
tcx.sess.source_map().end_point(span),
if gen_move.is_some() {
" of generator"
} else {
" of closure"
},
)
} else {
// unreachable?
(mir.span, "")
};
let (return_span, mir_description) = match tcx.hir.get(mir_node_id) {
hir::Node::Expr(hir::Expr {
node: hir::ExprKind::Closure(_, _, _, span, gen_move),
..
}) => (
tcx.sess.source_map().end_point(*span),
if gen_move.is_some() {
" of generator"
} else {
" of closure"
},
),
hir::Node::ImplItem(hir::ImplItem {
node: hir::ImplItemKind::Method(method_sig, _),
..
}) => (method_sig.decl.output.span(), ""),
_ => (mir.span, ""),
};
Some(RegionName {
// This counter value will already have been used, so this function will increment it

View File

@ -37,6 +37,7 @@ use rustc::mir::{BasicBlock, FakeReadCause, Local, Location, Mir, Place};
use rustc::mir::{Rvalue, Statement, StatementKind};
use rustc::mir::visit::{MutVisitor, Visitor, TyContext};
use rustc::ty::{Ty, RegionKind, TyCtxt};
use smallvec::smallvec;
use transform::{MirPass, MirSource};
pub struct CleanEndRegions;
@ -80,7 +81,11 @@ impl<'tcx> Visitor<'tcx> for GatherBorrowedRegions {
fn visit_ty(&mut self, ty: &Ty<'tcx>, _: TyContext) {
// Gather regions that occur in types
for re in ty.walk().flat_map(|t| t.regions()) {
let mut regions = smallvec![];
for t in ty.walk() {
t.push_regions(&mut regions);
}
for re in regions {
match *re {
RegionKind::ReScope(ce) => { self.seen_regions.insert(ce); }
_ => {},

View File

@ -591,8 +591,8 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
if let TerminatorKind::Assert { expected, msg, cond, .. } = kind {
if let Some(value) = self.eval_operand(cond, source_info) {
trace!("assertion on {:?} should be {:?}", value, expected);
let expected = Immediate::Scalar(Scalar::from_bool(*expected).into());
if expected != value.0.to_immediate() {
let expected = ScalarMaybeUndef::from(Scalar::from_bool(*expected));
if expected != self.ecx.read_scalar(value.0).unwrap() {
// poison all places this operand references so that further code
// doesn't use the invalid value
match cond {
@ -628,20 +628,20 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
let len = self
.eval_operand(len, source_info)
.expect("len must be const");
let len = match len.0.to_immediate() {
Immediate::Scalar(ScalarMaybeUndef::Scalar(Scalar::Bits {
let len = match self.ecx.read_scalar(len.0) {
Ok(ScalarMaybeUndef::Scalar(Scalar::Bits {
bits, ..
})) => bits,
_ => bug!("const len not primitive: {:?}", len),
other => bug!("const len not primitive: {:?}", other),
};
let index = self
.eval_operand(index, source_info)
.expect("index must be const");
let index = match index.0.to_immediate() {
Immediate::Scalar(ScalarMaybeUndef::Scalar(Scalar::Bits {
let index = match self.ecx.read_scalar(index.0) {
Ok(ScalarMaybeUndef::Scalar(Scalar::Bits {
bits, ..
})) => bits,
_ => bug!("const index not primitive: {:?}", index),
other => bug!("const index not primitive: {:?}", other),
};
format!(
"index out of bounds: \

View File

@ -19,7 +19,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc::mir::*;
use rustc::mir::visit::*;
use rustc::ty::{self, Instance, InstanceDef, Ty, TyCtxt};
use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc::ty::subst::{Subst,Substs};
use std::collections::VecDeque;
@ -85,39 +85,16 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
// Only do inlining into fn bodies.
let id = self.tcx.hir.as_local_node_id(self.source.def_id).unwrap();
let body_owner_kind = self.tcx.hir.body_owner_kind(id);
if let (hir::BodyOwnerKind::Fn, None) = (body_owner_kind, self.source.promoted) {
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
// Don't inline calls that are in cleanup blocks.
if bb_data.is_cleanup { continue; }
// Only consider direct calls to functions
let terminator = bb_data.terminator();
if let TerminatorKind::Call {
func: ref op, .. } = terminator.kind {
if let ty::FnDef(callee_def_id, substs) = op.ty(caller_mir, self.tcx).sty {
if let Some(instance) = Instance::resolve(self.tcx,
param_env,
callee_def_id,
substs) {
let is_virtual =
if let InstanceDef::Virtual(..) = instance.def {
true
} else {
false
};
if !is_virtual {
callsites.push_back(CallSite {
callee: instance.def_id(),
substs: instance.substs,
bb,
location: terminator.source_info
});
}
}
}
}
if let Some(callsite) = self.get_valid_function_call(bb,
bb_data,
caller_mir,
param_env) {
callsites.push_back(callsite);
}
}
} else {
return;
@ -163,20 +140,13 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
// Add callsites from inlined function
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated().skip(start) {
// Only consider direct calls to functions
let terminator = bb_data.terminator();
if let TerminatorKind::Call {
func: Operand::Constant(ref f), .. } = terminator.kind {
if let ty::FnDef(callee_def_id, substs) = f.ty.sty {
// Don't inline the same function multiple times.
if callsite.callee != callee_def_id {
callsites.push_back(CallSite {
callee: callee_def_id,
substs,
bb,
location: terminator.source_info
});
}
if let Some(new_callsite) = self.get_valid_function_call(bb,
bb_data,
caller_mir,
param_env) {
// Don't inline the same function multiple times.
if callsite.callee != new_callsite.callee {
callsites.push_back(new_callsite);
}
}
}
@ -198,6 +168,40 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
}
}
fn get_valid_function_call(&self,
bb: BasicBlock,
bb_data: &BasicBlockData<'tcx>,
caller_mir: &Mir<'tcx>,
param_env: ParamEnv<'tcx>,
) -> Option<CallSite<'tcx>> {
// Don't inline calls that are in cleanup blocks.
if bb_data.is_cleanup { return None; }
// Only consider direct calls to functions
let terminator = bb_data.terminator();
if let TerminatorKind::Call { func: ref op, .. } = terminator.kind {
if let ty::FnDef(callee_def_id, substs) = op.ty(caller_mir, self.tcx).sty {
let instance = Instance::resolve(self.tcx,
param_env,
callee_def_id,
substs)?;
if let InstanceDef::Virtual(..) = instance.def {
return None;
}
return Some(CallSite {
callee: instance.def_id(),
substs: instance.substs,
bb,
location: terminator.source_info
});
}
}
None
}
fn consider_optimizing(&self,
callsite: CallSite<'tcx>,
callee_mir: &Mir<'tcx>)

View File

@ -663,10 +663,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
binding.map(|binding| (binding, Flags::MODULE, Flags::empty()))
}
WhereToResolve::MacroUsePrelude => {
match self.macro_use_prelude.get(&ident.name).cloned() {
Some(binding) => Ok((binding, Flags::PRELUDE, Flags::empty())),
None => Err(Determinacy::Determined),
let mut result = Err(Determinacy::Determined);
if use_prelude || self.session.rust_2015() {
if let Some(binding) = self.macro_use_prelude.get(&ident.name).cloned() {
result = Ok((binding, Flags::PRELUDE, Flags::empty()));
}
}
result
}
WhereToResolve::BuiltinMacros => {
match self.builtin_macros.get(&ident.name).cloned() {
@ -685,7 +688,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}
}
WhereToResolve::LegacyPluginHelpers => {
if self.session.plugin_attributes.borrow().iter()
if (use_prelude || self.session.rust_2015()) &&
self.session.plugin_attributes.borrow().iter()
.any(|(name, _)| ident.name == &**name) {
let binding = (Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
ty::Visibility::Public, ident.span, Mark::root())

View File

@ -11,12 +11,18 @@
use super::{LinkArgs, LinkerFlavor, Target, TargetOptions};
pub fn target() -> Result<Target, String> {
// FIXME(nikic) BINARYEN_TRAP_MODE=clamp is needed to avoid trapping in our
// -Zsaturating-float-casts implementation. This can be dropped if/when
// we have native fpto[su]i.sat intrinsics, or the implementation otherwise
// stops relying on non-trapping fpto[su]i.
let mut post_link_args = LinkArgs::new();
post_link_args.insert(LinkerFlavor::Em,
vec!["-s".to_string(),
"BINARYEN=1".to_string(),
"-s".to_string(),
"ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()]);
"ERROR_ON_UNDEFINED_SYMBOLS=1".to_string(),
"-s".to_string(),
"BINARYEN_TRAP_MODE='clamp'".to_string()]);
let opts = TargetOptions {
dynamic_linking: false,

View File

@ -20,6 +20,7 @@ use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::ty::outlives::Component;
use rustc::ty::query::Providers;
use rustc::ty::wf;
use smallvec::{SmallVec, smallvec};
use syntax::ast::DUMMY_NODE_ID;
use syntax::source_map::DUMMY_SP;
use rustc::traits::FulfillmentContext;
@ -133,7 +134,8 @@ fn compute_implied_outlives_bounds<'tcx>(
None => vec![],
Some(ty::OutlivesPredicate(ty_a, r_b)) => {
let ty_a = infcx.resolve_type_vars_if_possible(&ty_a);
let components = tcx.outlives_components(ty_a);
let mut components = smallvec![];
tcx.push_outlives_components(ty_a, &mut components);
implied_bounds_from_components(r_b, components)
}
},
@ -155,7 +157,7 @@ fn compute_implied_outlives_bounds<'tcx>(
/// those relationships.
fn implied_bounds_from_components(
sub_region: ty::Region<'tcx>,
sup_components: Vec<Component<'tcx>>,
sup_components: SmallVec<[Component<'tcx>; 4]>,
) -> Vec<OutlivesBound<'tcx>> {
sup_components
.into_iter()

View File

@ -37,7 +37,7 @@ use std::iter;
use syntax::ast;
use syntax::ptr::P;
use syntax::feature_gate::{GateIssue, emit_feature_err};
use syntax_pos::{Span, MultiSpan};
use syntax_pos::{DUMMY_SP, Span, MultiSpan};
pub trait AstConv<'gcx, 'tcx> {
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>;
@ -451,7 +451,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
}
// We manually build up the substitution, rather than using convenience
// methods in subst.rs so that we can iterate over the arguments and
// methods in `subst.rs` so that we can iterate over the arguments and
// parameters in lock-step linearly, rather than trying to match each pair.
let mut substs: SmallVec<[Kind<'tcx>; 8]> = SmallVec::with_capacity(count);
@ -469,7 +469,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
}
}
// (Unless it's been handled in `parent_substs`) `Self` is handled first.
// `Self` is handled first, unless it's been handled in `parent_substs`.
if has_self {
if let Some(&param) = params.peek() {
if param.index == 0 {
@ -698,7 +698,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
trait_ref.path.segments.last().unwrap())
}
/// Get the DefId of the given trait ref. It _must_ actually be a trait.
/// Get the `DefId` of the given trait ref. It _must_ actually be a trait.
fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId {
let path = &trait_ref.path;
match path.def {
@ -711,7 +711,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
}
}
/// The given `trait_ref` must actually be trait.
/// The given trait ref must actually be a trait.
pub(super) fn instantiate_poly_trait_ref_inner(&self,
trait_ref: &hir::TraitRef,
self_ty: Ty<'tcx>,
@ -738,7 +738,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
let predicate: Result<_, ErrorReported> =
self.ast_type_binding_to_poly_projection_predicate(
trait_ref.ref_id, poly_trait_ref, binding, speculative, &mut dup_bindings);
// ok to ignore Err because ErrorReported (see above)
// okay to ignore Err because of ErrorReported (see above)
Some((predicate.ok()?, binding.span))
}));
@ -831,7 +831,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
let tcx = self.tcx();
if !speculative {
// Given something like `U : SomeTrait<T=X>`, we want to produce a
// Given something like `U: SomeTrait<T = X>`, we want to produce a
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
// subtle in the event that `T` is defined in a supertrait of
// `SomeTrait`, because in that case we need to upcast.
@ -839,7 +839,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
// That is, consider this case:
//
// ```
// trait SubTrait : SuperTrait<int> { }
// trait SubTrait: SuperTrait<int> { }
// trait SuperTrait<A> { type T; }
//
// ... B : SubTrait<T=foo> ...
@ -908,16 +908,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
if !speculative {
dup_bindings.entry(assoc_ty.def_id)
.and_modify(|prev_span| {
let mut err = self.tcx().struct_span_lint_node(
::rustc::lint::builtin::DUPLICATE_ASSOCIATED_TYPE_BINDINGS,
ref_id,
binding.span,
&format!("associated type binding `{}` specified more than once",
binding.item_name)
);
err.span_label(binding.span, "used more than once");
err.span_label(*prev_span, format!("first use of `{}`", binding.item_name));
err.emit();
struct_span_err!(self.tcx().sess, binding.span, E0719,
"the value of the associated type `{}` (from the trait `{}`) \
is already specified",
binding.item_name,
tcx.item_path_str(assoc_ty.container.id()))
.span_label(binding.span, "re-bound here")
.span_label(*prev_span, format!("`{}` bound here first", binding.item_name))
.emit();
})
.or_insert(binding.span);
}
@ -969,7 +967,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
return tcx.types.err;
}
let mut projection_bounds = vec![];
let mut projection_bounds = Vec::new();
let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF);
let principal = self.instantiate_poly_trait_ref(&trait_bounds[0],
dummy_self,
@ -994,23 +992,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
.emit();
}
// Erase the dummy_self (TRAIT_OBJECT_DUMMY_SELF) used above.
let existential_principal = principal.map_bound(|trait_ref| {
self.trait_ref_to_existential(trait_ref)
});
let existential_projections = projection_bounds.iter().map(|(bound, _)| {
bound.map_bound(|b| {
let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
ty::ExistentialProjection {
ty: b.ty,
item_def_id: b.projection_ty.item_def_id,
substs: trait_ref.substs,
}
})
});
// Check that there are no gross object safety violations;
// most importantly, that the supertraits don't contain Self,
// most importantly, that the supertraits don't contain `Self`,
// to avoid ICEs.
let object_safety_violations =
tcx.global_tcx().astconv_object_safety_violations(principal.def_id());
@ -1021,13 +1004,22 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
return tcx.types.err;
}
// Use a BTreeSet to keep output in a more consistent order.
// Use a `BTreeSet` to keep output in a more consistent order.
let mut associated_types = BTreeSet::default();
for tr in traits::supertraits(tcx, principal) {
associated_types.extend(tcx.associated_items(tr.def_id())
.filter(|item| item.kind == ty::AssociatedKind::Type)
.map(|item| item.def_id));
for tr in traits::elaborate_trait_ref(tcx, principal) {
match tr {
ty::Predicate::Trait(pred) => {
associated_types.extend(tcx.associated_items(pred.def_id())
.filter(|item| item.kind == ty::AssociatedKind::Type)
.map(|item| item.def_id));
}
ty::Predicate::Projection(pred) => {
// Include projections defined on supertraits.
projection_bounds.push((pred, DUMMY_SP))
}
_ => ()
}
}
for (projection_bound, _) in &projection_bounds {
@ -1046,11 +1038,26 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
.emit();
}
// Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above.
let existential_principal = principal.map_bound(|trait_ref| {
self.trait_ref_to_existential(trait_ref)
});
let existential_projections = projection_bounds.iter().map(|(bound, _)| {
bound.map_bound(|b| {
let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
ty::ExistentialProjection {
ty: b.ty,
item_def_id: b.projection_ty.item_def_id,
substs: trait_ref.substs,
}
})
});
// Dedup auto traits so that `dyn Trait + Send + Send` is the same as `dyn Trait + Send`.
auto_traits.sort();
auto_traits.dedup();
// skip_binder is okay, because the predicates are re-bound.
// Calling `skip_binder` is okay, because the predicates are re-bound.
let mut v =
iter::once(ty::ExistentialPredicate::Trait(*existential_principal.skip_binder()))
.chain(auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait))
@ -1128,8 +1135,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
span)
}
// Checks that bounds contains exactly one element and reports appropriate
// Checks that `bounds` contains exactly one element and reports appropriate
// errors otherwise.
fn one_bound_for_assoc_type<I>(&self,
mut bounds: I,
@ -1186,11 +1192,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
}
// Create a type from a path to an associated type.
// For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C
// and item_segment is the path segment for D. We return a type and a def for
// For a path `A::B::C::D`, `ty` and `ty_path_def` are the type and def for `A::B::C`
// and item_segment is the path segment for `D`. We return a type and a def for
// the whole path.
// Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type
// parameter or Self.
// Will fail except for `T::A` and `Self::A`; i.e., if `ty`/`ty_path_def` are not a type
// parameter or `Self`.
pub fn associated_path_def_to_ty(&self,
ref_id: ast::NodeId,
span: Span,
@ -1210,7 +1216,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
// item is declared.
let bound = match (&ty.sty, ty_path_def) {
(_, Def::SelfTy(Some(_), Some(impl_def_id))) => {
// `Self` in an impl of a trait - we have a concrete self type and a
// `Self` in an impl of a trait - we have a concrete `self` type and a
// trait reference.
let trait_ref = match tcx.impl_trait_ref(impl_def_id) {
Some(trait_ref) => trait_ref,
@ -1361,7 +1367,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
let span = path.span;
match path.def {
Def::Existential(did) => {
// check for desugared impl trait
// Check for desugared impl trait.
assert!(ty::is_impl_trait_defn(tcx, did).is_none());
let item_segment = path.segments.split_last().unwrap();
self.prohibit_generics(item_segment.1);
@ -1398,7 +1404,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
tcx.mk_ty_param(index, tcx.hir.name(node_id).as_interned_str())
}
Def::SelfTy(_, Some(def_id)) => {
// Self in impl (we know the concrete type).
// `Self` in impl (we know the concrete type)
assert_eq!(opt_self_ty, None);
self.prohibit_generics(&path.segments);
@ -1406,7 +1412,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
tcx.at(span).type_of(def_id)
}
Def::SelfTy(Some(_), None) => {
// Self in trait.
// `Self` in trait
assert_eq!(opt_self_ty, None);
self.prohibit_generics(&path.segments);
tcx.mk_self_type()

View File

@ -626,9 +626,9 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
let discrim_diverges = self.diverges.get();
self.diverges.set(Diverges::Maybe);
// Typecheck the patterns first, so that we get types for all the
// bindings.
let all_arm_pats_diverge = arms.iter().map(|arm| {
// rust-lang/rust#55810: Typecheck patterns first (via eager
// collection into `Vec`), so we get types for all bindings.
let all_arm_pats_diverge: Vec<_> = arms.iter().map(|arm| {
let mut all_pats_diverge = Diverges::WarnedAlways;
for p in &arm.pats {
self.diverges.set(Diverges::Maybe);
@ -644,7 +644,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
Diverges::Maybe => Diverges::Maybe,
Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
}
});
}).collect();
// Now typecheck the blocks.
//

View File

@ -28,9 +28,9 @@ use errors::{DiagnosticBuilder, DiagnosticId};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir;
/// Helper type of a temporary returned by .for_item(...).
/// Helper type of a temporary returned by `.for_item(...)`.
/// Necessary because we can't write the following bound:
/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>).
/// `F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>)`.
struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>,
id: ast::NodeId,
@ -186,6 +186,8 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
item_id: ast::NodeId,
span: Span,
sig_if_method: Option<&hir::MethodSig>) {
debug!("check_associated_item: {:?}", item_id);
let code = ObligationCauseCode::MiscObligation;
for_id(tcx, item_id, span).with_fcx(|fcx, tcx| {
let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id));
@ -311,6 +313,8 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) {
debug!("check_trait: {:?}", item.id);
let trait_def_id = tcx.hir.local_def_id(item.id);
let trait_def = tcx.trait_def(trait_def_id);
@ -1012,7 +1016,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
None => {
// Inherent impl: take implied bounds from the self type.
// Inherent impl: take implied bounds from the `self` type.
let self_ty = self.tcx.type_of(impl_def_id);
let self_ty = self.normalize_associated_types_in(span, &self_ty);
vec![self_ty]

View File

@ -1978,9 +1978,9 @@ pub enum SizedByDefault {
No,
}
/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
/// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
/// built-in trait (formerly known as kind): Send.
/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped `Ty`
/// or a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
/// built-in trait `Send`.
pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
astconv: &dyn AstConv<'gcx, 'tcx>,
param_ty: Ty<'tcx>,
@ -1988,8 +1988,8 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
sized_by_default: SizedByDefault,
span: Span,
) -> Bounds<'tcx> {
let mut region_bounds = vec![];
let mut trait_bounds = vec![];
let mut region_bounds = Vec::new();
let mut trait_bounds = Vec::new();
for ast_bound in ast_bounds {
match *ast_bound {
@ -1999,7 +1999,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(
}
}
let mut projection_bounds = vec![];
let mut projection_bounds = Vec::new();
let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
(astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds), bound.span)

View File

@ -4909,4 +4909,5 @@ register_diagnostics! {
E0641, // cannot cast to/from a pointer with an unknown kind
E0645, // trait aliases not finished
E0698, // type inside generator must be known in this context
E0719, // duplicate values for associated type binding
}

View File

@ -11,6 +11,7 @@
use rustc::ty::outlives::Component;
use rustc::ty::subst::{Kind, UnpackedKind};
use rustc::ty::{self, Region, RegionKind, Ty, TyCtxt};
use smallvec::smallvec;
use std::collections::BTreeSet;
/// Tracks the `T: 'a` or `'a: 'a` predicates that we have inferred
@ -40,7 +41,9 @@ pub fn insert_outlives_predicate<'tcx>(
//
// Or if within `struct Foo<U>` you had `T = Vec<U>`, then
// we would want to add `U: 'outlived_region`
for component in tcx.outlives_components(ty) {
let mut components = smallvec![];
tcx.push_outlives_components(ty, &mut components);
for component in components {
match component {
Component::Region(r) => {
// This would arise from something like:

View File

@ -29,6 +29,7 @@ use core::new_handler;
use externalfiles::ExternalHtml;
use html;
use html::markdown::IdMap;
use html::static_files;
use opts;
use passes::{self, DefaultPassOption};
use theme;
@ -261,7 +262,7 @@ impl Options {
let to_check = matches.opt_strs("theme-checker");
if !to_check.is_empty() {
let paths = theme::load_css_paths(include_bytes!("html/static/themes/light.css"));
let paths = theme::load_css_paths(static_files::themes::LIGHT.as_bytes());
let mut errors = 0;
println!("rustdoc: [theme-checker] Starting tests!");
@ -338,7 +339,7 @@ impl Options {
let mut themes = Vec::new();
if matches.opt_present("themes") {
let paths = theme::load_css_paths(include_bytes!("html/static/themes/light.css"));
let paths = theme::load_css_paths(static_files::themes::LIGHT.as_bytes());
for (theme_file, theme_s) in matches.opt_strs("themes")
.iter()

View File

@ -76,7 +76,7 @@ use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
use html::format::fmt_impl_for_trait_page;
use html::item_type::ItemType;
use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine, ErrorCodes, IdMap};
use html::{highlight, layout};
use html::{highlight, layout, static_files};
use minifier;
@ -767,10 +767,10 @@ fn write_shared(
// overwrite them anyway to make sure that they're fresh and up-to-date.
write_minify(cx.dst.join(&format!("rustdoc{}.css", cx.shared.resource_suffix)),
include_str!("static/rustdoc.css"),
static_files::RUSTDOC_CSS,
options.enable_minification)?;
write_minify(cx.dst.join(&format!("settings{}.css", cx.shared.resource_suffix)),
include_str!("static/settings.css"),
static_files::SETTINGS_CSS,
options.enable_minification)?;
// To avoid "light.css" to be overwritten, we'll first run over the received themes and only
@ -790,15 +790,15 @@ fn write_shared(
}
write(cx.dst.join(&format!("brush{}.svg", cx.shared.resource_suffix)),
include_bytes!("static/brush.svg"))?;
static_files::BRUSH_SVG)?;
write(cx.dst.join(&format!("wheel{}.svg", cx.shared.resource_suffix)),
include_bytes!("static/wheel.svg"))?;
static_files::WHEEL_SVG)?;
write_minify(cx.dst.join(&format!("light{}.css", cx.shared.resource_suffix)),
include_str!("static/themes/light.css"),
static_files::themes::LIGHT,
options.enable_minification)?;
themes.insert("light".to_owned());
write_minify(cx.dst.join(&format!("dark{}.css", cx.shared.resource_suffix)),
include_str!("static/themes/dark.css"),
static_files::themes::DARK,
options.enable_minification)?;
themes.insert("dark".to_owned());
@ -854,16 +854,16 @@ themePicker.onblur = handleThemeButtonsBlur;
)?;
write_minify(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
include_str!("static/main.js"),
static_files::MAIN_JS,
options.enable_minification)?;
write_minify(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
include_str!("static/settings.js"),
static_files::SETTINGS_JS,
options.enable_minification)?;
{
let mut data = format!("var resourcesSuffix = \"{}\";\n",
cx.shared.resource_suffix);
data.push_str(include_str!("static/storage.js"));
data.push_str(static_files::STORAGE_JS);
write_minify(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)),
&data,
options.enable_minification)?;
@ -882,36 +882,36 @@ themePicker.onblur = handleThemeButtonsBlur;
}
}
write_minify(cx.dst.join(&format!("normalize{}.css", cx.shared.resource_suffix)),
include_str!("static/normalize.css"),
static_files::NORMALIZE_CSS,
options.enable_minification)?;
write(cx.dst.join("FiraSans-Regular.woff"),
include_bytes!("static/FiraSans-Regular.woff"))?;
static_files::fira_sans::REGULAR)?;
write(cx.dst.join("FiraSans-Medium.woff"),
include_bytes!("static/FiraSans-Medium.woff"))?;
static_files::fira_sans::MEDIUM)?;
write(cx.dst.join("FiraSans-LICENSE.txt"),
include_bytes!("static/FiraSans-LICENSE.txt"))?;
static_files::fira_sans::LICENSE)?;
write(cx.dst.join("Heuristica-Italic.woff"),
include_bytes!("static/Heuristica-Italic.woff"))?;
static_files::heuristica::ITALIC)?;
write(cx.dst.join("Heuristica-LICENSE.txt"),
include_bytes!("static/Heuristica-LICENSE.txt"))?;
static_files::heuristica::LICENSE)?;
write(cx.dst.join("SourceSerifPro-Regular.woff"),
include_bytes!("static/SourceSerifPro-Regular.woff"))?;
static_files::source_serif_pro::REGULAR)?;
write(cx.dst.join("SourceSerifPro-Bold.woff"),
include_bytes!("static/SourceSerifPro-Bold.woff"))?;
static_files::source_serif_pro::BOLD)?;
write(cx.dst.join("SourceSerifPro-LICENSE.txt"),
include_bytes!("static/SourceSerifPro-LICENSE.txt"))?;
static_files::source_serif_pro::LICENSE)?;
write(cx.dst.join("SourceCodePro-Regular.woff"),
include_bytes!("static/SourceCodePro-Regular.woff"))?;
static_files::source_code_pro::REGULAR)?;
write(cx.dst.join("SourceCodePro-Semibold.woff"),
include_bytes!("static/SourceCodePro-Semibold.woff"))?;
static_files::source_code_pro::SEMIBOLD)?;
write(cx.dst.join("SourceCodePro-LICENSE.txt"),
include_bytes!("static/SourceCodePro-LICENSE.txt"))?;
static_files::source_code_pro::LICENSE)?;
write(cx.dst.join("LICENSE-MIT.txt"),
include_bytes!("static/LICENSE-MIT.txt"))?;
static_files::LICENSE_MIT)?;
write(cx.dst.join("LICENSE-APACHE.txt"),
include_bytes!("static/LICENSE-APACHE.txt"))?;
static_files::LICENSE_APACHE)?;
write(cx.dst.join("COPYRIGHT.txt"),
include_bytes!("static/COPYRIGHT.txt"))?;
static_files::COPYRIGHT)?;
fn collect(path: &Path, krate: &str, key: &str) -> io::Result<(Vec<String>, Vec<String>)> {
let mut ret = Vec::new();

View File

@ -0,0 +1,111 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Static files bundled with documentation output.
//!
//! All the static files are included here for centralized access in case anything other than the
//! HTML rendering code (say, the theme checker) needs to access one of these files.
//!
//! Note about types: CSS and JavaScript files are included as `&'static str` to allow for the
//! minifier to run on them. All other files are included as `&'static [u8]` so they can be
//! directly written to a `Write` handle.
/// The file contents of the main `rustdoc.css` file, responsible for the core layout of the page.
pub static RUSTDOC_CSS: &'static str = include_str!("static/rustdoc.css");
/// The file contents of `settings.css`, responsible for the items on the settings page.
pub static SETTINGS_CSS: &'static str = include_str!("static/settings.css");
/// The file contents of `normalize.css`, included to even out standard elements between browser
/// implementations.
pub static NORMALIZE_CSS: &'static str = include_str!("static/normalize.css");
/// The file contents of `main.js`, which contains the core JavaScript used on documentation pages,
/// including search behavior and docblock folding, among others.
pub static MAIN_JS: &'static str = include_str!("static/main.js");
/// The file contents of `settings.js`, which contains the JavaScript used to handle the settings
/// page.
pub static SETTINGS_JS: &'static str = include_str!("static/settings.js");
/// The file contents of `storage.js`, which contains functionality related to browser Local
/// Storage, used to store documentation settings.
pub static STORAGE_JS: &'static str = include_str!("static/storage.js");
/// The file contents of `brush.svg`, the icon used for the theme-switch button.
pub static BRUSH_SVG: &'static [u8] = include_bytes!("static/brush.svg");
/// The file contents of `wheel.svg`, the icon used for the settings button.
pub static WHEEL_SVG: &'static [u8] = include_bytes!("static/wheel.svg");
/// The contents of `COPYRIGHT.txt`, the license listing for files distributed with documentation
/// output.
pub static COPYRIGHT: &'static [u8] = include_bytes!("static/COPYRIGHT.txt");
/// The contents of `LICENSE-APACHE.txt`, the text of the Apache License, version 2.0.
pub static LICENSE_APACHE: &'static [u8] = include_bytes!("static/LICENSE-APACHE.txt");
/// The contents of `LICENSE-MIT.txt`, the text of the MIT License.
pub static LICENSE_MIT: &'static [u8] = include_bytes!("static/LICENSE-MIT.txt");
/// The built-in themes given to every documentation site.
pub mod themes {
/// The "light" theme, selected by default when no setting is available. Used as the basis for
/// the `--theme-checker` functionality.
pub static LIGHT: &'static str = include_str!("static/themes/light.css");
/// The "dark" theme.
pub static DARK: &'static str = include_str!("static/themes/dark.css");
}
/// Files related to the Fira Sans font.
pub mod fira_sans {
/// The file `FiraSans-Regular.woff`, the Regular variant of the Fira Sans font.
pub static REGULAR: &'static [u8] = include_bytes!("static/FiraSans-Regular.woff");
/// The file `FiraSans-Medium.woff`, the Medium variant of the Fira Sans font.
pub static MEDIUM: &'static [u8] = include_bytes!("static/FiraSans-Medium.woff");
/// The file `FiraSans-LICENSE.txt`, the license text for the Fira Sans font.
pub static LICENSE: &'static [u8] = include_bytes!("static/FiraSans-LICENSE.txt");
}
/// Files related to the Heuristica font.
pub mod heuristica {
/// The file `Heuristica-Italic.woff`, the Italic variant of the Heuristica font.
pub static ITALIC: &'static [u8] = include_bytes!("static/Heuristica-Italic.woff");
/// The file `Heuristica-LICENSE.txt`, the license text for the Heuristica font.
pub static LICENSE: &'static [u8] = include_bytes!("static/Heuristica-LICENSE.txt");
}
/// Files related to the Source Serif Pro font.
pub mod source_serif_pro {
/// The file `SourceSerifPro-Regular.woff`, the Regular variant of the Source Serif Pro font.
pub static REGULAR: &'static [u8] = include_bytes!("static/SourceSerifPro-Regular.woff");
/// The file `SourceSerifPro-Bold.woff`, the Bold variant of the Source Serif Pro font.
pub static BOLD: &'static [u8] = include_bytes!("static/SourceSerifPro-Bold.woff");
/// The file `SourceSerifPro-LICENSE.txt`, the license text for the Source Serif Pro font.
pub static LICENSE: &'static [u8] = include_bytes!("static/SourceSerifPro-LICENSE.txt");
}
/// Files related to the Source Code Pro font.
pub mod source_code_pro {
/// The file `SourceCodePro-Regular.woff`, the Regular variant of the Source Code Pro font.
pub static REGULAR: &'static [u8] = include_bytes!("static/SourceCodePro-Regular.woff");
/// The file `SourceCodePro-Semibold.woff`, the Semibold variant of the Source Code Pro font.
pub static SEMIBOLD: &'static [u8] = include_bytes!("static/SourceCodePro-Semibold.woff");
/// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font.
pub static LICENSE: &'static [u8] = include_bytes!("static/SourceCodePro-LICENSE.txt");
}

View File

@ -78,6 +78,7 @@ pub mod html {
crate mod layout;
pub mod markdown;
crate mod render;
crate mod static_files;
crate mod toc;
}
mod markdown;

View File

@ -1178,7 +1178,7 @@ impl CStr {
///
/// If the contents of the `CStr` are valid UTF-8 data, this
/// function will return a [`Cow`]`::`[`Borrowed`]`(`[`&str`]`)`
/// with the the corresponding [`&str`] slice. Otherwise, it will
/// with the corresponding [`&str`] slice. Otherwise, it will
/// replace any invalid UTF-8 sequences with
/// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD] and return a
/// [`Cow`]`::`[`Owned`]`(`[`String`]`)` with the result.

View File

@ -495,7 +495,7 @@ mod memchr;
// compiler
pub mod rt;
// Pull in the the `stdsimd` crate directly into libstd. This is the same as
// Pull in the `stdsimd` crate directly into libstd. This is the same as
// libcore's arch/simd modules where the source of truth here is in a different
// repository, but we pull things in here manually to get it into libstd.
//

View File

@ -0,0 +1,36 @@
// compile-flags: -Z span_free_formats -Z mir-opt-level=3
#[inline]
fn test(x: &dyn X) -> bool {
x.y()
}
fn test2(x: &dyn X) -> bool {
test(x)
}
trait X {
fn y(&self) -> bool {
false
}
}
impl X for () {
fn y(&self) -> bool {
true
}
}
fn main() {
println!("Should be true: {}", test2(&()));
}
// END RUST SOURCE
// START rustc.test2.Inline.after.mir
// ...
// bb0: {
// ...
// _0 = const X::y(move _2) -> bb1;
// }
// ...
// END rustc.test2.Inline.after.mir

View File

@ -0,0 +1,16 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
trait Foo: Iterator<Item = i32> {}
trait Bar: Foo {}
fn main() {
let _: &dyn Bar;
}

View File

@ -0,0 +1,22 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
trait Foo: Fn(i32) -> i32 + Send {}
impl<T: ?Sized + Fn(i32) -> i32 + Send> Foo for T {}
fn wants_foo(f: Box<Foo>) -> i32 {
f(42)
}
fn main() {
let f = Box::new(|x| x);
assert_eq!(wants_foo(f), 42);
}

View File

@ -21,7 +21,6 @@ pub fn main() {
let b = Box::new(456) as Box<dyn Foo>;
assert!(*b == 456);
// FIXME(alexreg): associated type should be gotten from trait alias definition
// let c: &dyn I32Iterator = &vec![123].into_iter();
// assert_eq!(c.next(), Some(123));
let c: &mut dyn I32Iterator = &mut vec![123].into_iter();
assert_eq!(c.next(), Some(123));
}

View File

@ -0,0 +1,17 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(trait_alias)]
trait I32Iterator = Iterator<Item = i32>;
fn main() {
let _: &I32Iterator<Item = u32> = &vec![42].into_iter();
}

View File

@ -0,0 +1,13 @@
error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as std::iter::Iterator>::Item == i32`
--> $DIR/associated-types-overridden-binding-2.rs:16:39
|
LL | let _: &I32Iterator<Item = u32> = &vec![42].into_iter();
| ^^^^^^^^^^^^^^^^^^^^^ expected u32, found i32
|
= note: expected type `u32`
found type `i32`
= note: required for the cast to the object type `dyn I32Iterator<Item=u32, Item=i32>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0271`.

View File

@ -0,0 +1,21 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(trait_alias)]
trait Foo: Iterator<Item = i32> {}
trait Bar: Foo<Item = u32> {}
trait I32Iterator = Iterator<Item = i32>;
trait U32Iterator = I32Iterator<Item = u32>;
fn main() {
let _: &I32Iterator<Item = u32>;
}

View File

@ -0,0 +1,15 @@
error[E0284]: type annotations required: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
--> $DIR/associated-types-overridden-binding.rs:14:1
|
LL | trait Bar: Foo<Item = u32> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: required by `Foo`
--> $DIR/associated-types-overridden-binding.rs:13:1
|
LL | trait Foo: Iterator<Item = i32> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0284`.

View File

@ -3,8 +3,8 @@ error[E0382]: use of moved value: `a`
|
LL | let _x = a.x;
| -- value moved here
LL | //~^ value moved here
LL | let _y = a.y; //~ ERROR use of moved
LL | //[ast]~^ value moved here
LL | let _y = a.y; //[ast]~ ERROR use of moved
| ^^ value used here after move
|
= note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@ -14,8 +14,8 @@ error[E0382]: use of moved value: `a`
|
LL | let _x = a.x;
| -- value moved here
LL | //~^ value moved here
LL | let _y = a.y; //~ ERROR use of moved
LL | //[ast]~^ value moved here
LL | let _y = a.y; //[ast]~ ERROR use of moved
| ^^ value used here after move
|
= note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@ -25,8 +25,8 @@ error[E0382]: use of moved value: `a`
|
LL | let _x = a.x;
| -- value moved here
LL | //~^ value moved here
LL | let _y = &a.y; //~ ERROR use of moved
LL | //[ast]~^ value moved here
LL | let _y = &a.y; //[ast]~ ERROR use of moved
| ^^^ value used here after move
|
= note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@ -44,7 +44,7 @@ error[E0503]: cannot use `a.y` because it was mutably borrowed
|
LL | let _x = &mut a.x;
| --- borrow of `a.x` occurs here
LL | let _y = a.y; //~ ERROR cannot use
LL | let _y = a.y; //[ast]~ ERROR cannot use
| ^^ use of borrowed `a.x`
error[E0505]: cannot move out of `a.y` because it is borrowed
@ -60,9 +60,9 @@ error[E0502]: cannot borrow `a` (via `a.y`) as immutable because `a` is also bor
|
LL | let _x = &mut a.x;
| --- mutable borrow occurs here (via `a.x`)
LL | let _y = &a.y; //~ ERROR cannot borrow
LL | let _y = &a.y; //[ast]~ ERROR cannot borrow
| ^^^ immutable borrow occurs here (via `a.y`)
LL | //~^ immutable borrow occurs here (via `a.y`)
...
LL | }
| - mutable borrow ends here
@ -71,9 +71,9 @@ error[E0502]: cannot borrow `a` (via `a.y`) as mutable because `a` is also borro
|
LL | let _x = &a.x;
| --- immutable borrow occurs here (via `a.x`)
LL | let _y = &mut a.y; //~ ERROR cannot borrow
LL | let _y = &mut a.y; //[ast]~ ERROR cannot borrow
| ^^^ mutable borrow occurs here (via `a.y`)
LL | //~^ mutable borrow occurs here (via `a.y`)
...
LL | }
| - immutable borrow ends here
@ -82,8 +82,8 @@ error[E0382]: use of collaterally moved value: `a.y`
|
LL | let _x = a.x.x;
| -- value moved here
LL | //~^ value moved here
LL | let _y = a.y; //~ ERROR use of collaterally moved
LL | //[ast]~^ value moved here
LL | let _y = a.y; //[ast]~ ERROR use of collaterally moved
| ^^ value used here after move
|
= note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@ -93,8 +93,8 @@ error[E0382]: use of collaterally moved value: `a.y`
|
LL | let _x = a.x.x;
| -- value moved here
LL | //~^ value moved here
LL | let _y = a.y; //~ ERROR use of collaterally moved
LL | //[ast]~^ value moved here
LL | let _y = a.y; //[ast]~ ERROR use of collaterally moved
| ^^ value used here after move
|
= note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@ -104,8 +104,8 @@ error[E0382]: use of collaterally moved value: `a.y`
|
LL | let _x = a.x.x;
| -- value moved here
LL | //~^ value moved here
LL | let _y = &a.y; //~ ERROR use of collaterally moved
LL | //[ast]~^ value moved here
LL | let _y = &a.y; //[ast]~ ERROR use of collaterally moved
| ^^^ value used here after move
|
= note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
@ -115,7 +115,7 @@ error[E0505]: cannot move out of `a.y` because it is borrowed
|
LL | let _x = &a.x.x;
| ----- borrow of `a.x.x` occurs here
LL | //~^ borrow of `a.x.x` occurs here
LL | //[ast]~^ borrow of `a.x.x` occurs here
LL | let _y = a.y;
| ^^ move out of `a.y` occurs here
@ -124,7 +124,7 @@ error[E0503]: cannot use `a.y` because it was mutably borrowed
|
LL | let _x = &mut a.x.x;
| ----- borrow of `a.x.x` occurs here
LL | let _y = a.y; //~ ERROR cannot use
LL | let _y = a.y; //[ast]~ ERROR cannot use
| ^^ use of borrowed `a.x.x`
error[E0505]: cannot move out of `a.y` because it is borrowed
@ -140,10 +140,10 @@ error[E0502]: cannot borrow `a.y` as immutable because `a.x.x` is also borrowed
|
LL | let _x = &mut a.x.x;
| ----- mutable borrow occurs here
LL | //~^ mutable borrow occurs here
LL | let _y = &a.y; //~ ERROR cannot borrow
LL | //[ast]~^ mutable borrow occurs here
LL | let _y = &a.y; //[ast]~ ERROR cannot borrow
| ^^^ immutable borrow occurs here
LL | //~^ immutable borrow occurs here
...
LL | }
| - mutable borrow ends here
@ -152,10 +152,10 @@ error[E0502]: cannot borrow `a.y` as mutable because `a.x.x` is also borrowed as
|
LL | let _x = &a.x.x;
| ----- immutable borrow occurs here
LL | //~^ immutable borrow occurs here
LL | let _y = &mut a.y; //~ ERROR cannot borrow
LL | //[ast]~^ immutable borrow occurs here
LL | let _y = &mut a.y; //[ast]~ ERROR cannot borrow
| ^^^ mutable borrow occurs here
LL | //~^ mutable borrow occurs here
...
LL | }
| - immutable borrow ends here

View File

@ -0,0 +1,14 @@
error: compilation successful
--> $DIR/borrowck-box-insensitivity.rs:160:1
|
LL | / fn main() { //[mir]~ ERROR compilation successful
LL | | copy_after_move();
LL | | move_after_move();
LL | | borrow_after_move();
... |
LL | | mut_borrow_after_borrow_nested();
LL | | }
| |_^
error: aborting due to previous error

View File

@ -1,13 +1,13 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
// This test is an artifact of the old policy that `Box<T>` should not
// be treated specially by the AST-borrowck.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// NLL goes back to treating `Box<T>` specially (namely, knowing that
// it uniquely owns the data it holds). See rust-lang/rfcs#130.
// revisions: ast mir
//[ast] compile-flags: -Z borrowck=ast
//[mir] compile-flags: -Z borrowck=mir
// ignore-compare-mode-nll
#![feature(box_syntax, rustc_attrs)]
struct A {
@ -33,131 +33,131 @@ struct D {
fn copy_after_move() {
let a: Box<_> = box A { x: box 0, y: 1 };
let _x = a.x;
//~^ value moved here
let _y = a.y; //~ ERROR use of moved
//~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
//~| value used here after move
//[ast]~^ value moved here
let _y = a.y; //[ast]~ ERROR use of moved
//[ast]~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
//[ast]~| value used here after move
}
fn move_after_move() {
let a: Box<_> = box B { x: box 0, y: box 1 };
let _x = a.x;
//~^ value moved here
let _y = a.y; //~ ERROR use of moved
//~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
//~| value used here after move
//[ast]~^ value moved here
let _y = a.y; //[ast]~ ERROR use of moved
//[ast]~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
//[ast]~| value used here after move
}
fn borrow_after_move() {
let a: Box<_> = box A { x: box 0, y: 1 };
let _x = a.x;
//~^ value moved here
let _y = &a.y; //~ ERROR use of moved
//~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
//~| value used here after move
//[ast]~^ value moved here
let _y = &a.y; //[ast]~ ERROR use of moved
//[ast]~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
//[ast]~| value used here after move
}
fn move_after_borrow() {
let a: Box<_> = box B { x: box 0, y: box 1 };
let _x = &a.x;
let _y = a.y;
//~^ ERROR cannot move
//~| move out of
//[ast]~^ ERROR cannot move
//[ast]~| move out of
use_imm(_x);
}
fn copy_after_mut_borrow() {
let mut a: Box<_> = box A { x: box 0, y: 1 };
let _x = &mut a.x;
let _y = a.y; //~ ERROR cannot use
let _y = a.y; //[ast]~ ERROR cannot use
use_mut(_x);
}
fn move_after_mut_borrow() {
let mut a: Box<_> = box B { x: box 0, y: box 1 };
let _x = &mut a.x;
let _y = a.y;
//~^ ERROR cannot move
//~| move out of
//[ast]~^ ERROR cannot move
//[ast]~| move out of
use_mut(_x);
}
fn borrow_after_mut_borrow() {
let mut a: Box<_> = box A { x: box 0, y: 1 };
let _x = &mut a.x;
let _y = &a.y; //~ ERROR cannot borrow
//~^ immutable borrow occurs here (via `a.y`)
let _y = &a.y; //[ast]~ ERROR cannot borrow
//[ast]~^ immutable borrow occurs here (via `a.y`)
use_mut(_x);
}
fn mut_borrow_after_borrow() {
let mut a: Box<_> = box A { x: box 0, y: 1 };
let _x = &a.x;
let _y = &mut a.y; //~ ERROR cannot borrow
//~^ mutable borrow occurs here (via `a.y`)
let _y = &mut a.y; //[ast]~ ERROR cannot borrow
//[ast]~^ mutable borrow occurs here (via `a.y`)
use_imm(_x);
}
fn copy_after_move_nested() {
let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = a.x.x;
//~^ value moved here
let _y = a.y; //~ ERROR use of collaterally moved
//~| value used here after move
//[ast]~^ value moved here
let _y = a.y; //[ast]~ ERROR use of collaterally moved
//[ast]~| value used here after move
}
fn move_after_move_nested() {
let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = a.x.x;
//~^ value moved here
let _y = a.y; //~ ERROR use of collaterally moved
//~| value used here after move
//[ast]~^ value moved here
let _y = a.y; //[ast]~ ERROR use of collaterally moved
//[ast]~| value used here after move
}
fn borrow_after_move_nested() {
let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = a.x.x;
//~^ value moved here
let _y = &a.y; //~ ERROR use of collaterally moved
//~| value used here after move
//[ast]~^ value moved here
let _y = &a.y; //[ast]~ ERROR use of collaterally moved
//[ast]~| value used here after move
}
fn move_after_borrow_nested() {
let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = &a.x.x;
//~^ borrow of `a.x.x` occurs here
//[ast]~^ borrow of `a.x.x` occurs here
let _y = a.y;
//~^ ERROR cannot move
//~| move out of
//[ast]~^ ERROR cannot move
//[ast]~| move out of
use_imm(_x);
}
fn copy_after_mut_borrow_nested() {
let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = &mut a.x.x;
let _y = a.y; //~ ERROR cannot use
let _y = a.y; //[ast]~ ERROR cannot use
use_mut(_x);
}
fn move_after_mut_borrow_nested() {
let mut a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = &mut a.x.x;
let _y = a.y;
//~^ ERROR cannot move
//~| move out of
//[ast]~^ ERROR cannot move
//[ast]~| move out of
use_mut(_x);
}
fn borrow_after_mut_borrow_nested() {
let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = &mut a.x.x;
//~^ mutable borrow occurs here
let _y = &a.y; //~ ERROR cannot borrow
//~^ immutable borrow occurs here
//[ast]~^ mutable borrow occurs here
let _y = &a.y; //[ast]~ ERROR cannot borrow
//[ast]~^ immutable borrow occurs here
use_mut(_x);
}
fn mut_borrow_after_borrow_nested() {
let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = &a.x.x;
//~^ immutable borrow occurs here
let _y = &mut a.y; //~ ERROR cannot borrow
//~^ mutable borrow occurs here
//[ast]~^ immutable borrow occurs here
let _y = &mut a.y; //[ast]~ ERROR cannot borrow
//[ast]~^ mutable borrow occurs here
use_imm(_x);
}
#[rustc_error]
fn main() {
fn main() { //[mir]~ ERROR compilation successful
copy_after_move();
move_after_move();
borrow_after_move();
@ -180,3 +180,6 @@ fn main() {
borrow_after_mut_borrow_nested();
mut_borrow_after_borrow_nested();
}
fn use_mut<T>(_: &mut T) { }
fn use_imm<T>(_: &T) { }

View File

@ -0,0 +1,31 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Crate that exports a const fn. Used for testing cross-crate.
#![feature(staged_api, rustc_attrs)]
#![stable(since="1.0.0", feature = "mep")]
#![crate_type="rlib"]
#[rustc_promotable]
#[stable(since="1.0.0", feature = "mep")]
#[inline]
pub const fn foo() -> usize { 22 }
#[stable(since="1.0.0", feature = "mep")]
pub struct Foo(usize);
impl Foo {
#[stable(since="1.0.0", feature = "mep")]
#[inline]
#[rustc_promotable]
pub const fn foo() -> usize { 22 }
}

View File

@ -0,0 +1,3 @@
fn main() {
[0; 3][3u64 as usize]; //~ ERROR the len is 3 but the index is 3
}

View File

@ -0,0 +1,10 @@
error: index out of bounds: the len is 3 but the index is 3
--> $DIR/const-prop-ice.rs:2:5
|
LL | [0; 3][3u64 as usize]; //~ ERROR the len is 3 but the index is 3
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(const_err)] on by default
error: aborting due to previous error

View File

@ -0,0 +1,5 @@
fn main() {
enum Enum { One=1 }
let xs=[0;1 as usize];
println!("{}", xs[Enum::One as usize]); //~ ERROR the len is 1 but the index is 1
}

View File

@ -0,0 +1,10 @@
error: index out of bounds: the len is 1 but the index is 1
--> $DIR/const-prop-ice2.rs:4:20
|
LL | println!("{}", xs[Enum::One as usize]); //~ ERROR the len is 1 but the index is 1
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[deny(const_err)] on by default
error: aborting due to previous error

View File

@ -0,0 +1,13 @@
// compile-pass
// aux-build:promotable_const_fn_lib.rs
#![feature(nll)]
extern crate promotable_const_fn_lib;
use promotable_const_fn_lib::{foo, Foo};
fn main() {
let x: &'static usize = &foo();
let x: &'static usize = &Foo::foo();
}

View File

@ -0,0 +1,30 @@
// compile-pass
#![feature(nll)]
fn main() {
let x: &'static u8 = &u8::max_value();
let x: &'static u16 = &u16::max_value();
let x: &'static u32 = &u32::max_value();
let x: &'static u64 = &u64::max_value();
let x: &'static u128 = &u128::max_value();
let x: &'static usize = &usize::max_value();
let x: &'static u8 = &u8::min_value();
let x: &'static u16 = &u16::min_value();
let x: &'static u32 = &u32::min_value();
let x: &'static u64 = &u64::min_value();
let x: &'static u128 = &u128::min_value();
let x: &'static usize = &usize::min_value();
let x: &'static i8 = &i8::max_value();
let x: &'static i16 = &i16::max_value();
let x: &'static i32 = &i32::max_value();
let x: &'static i64 = &i64::max_value();
let x: &'static i128 = &i128::max_value();
let x: &'static isize = &isize::max_value();
let x: &'static i8 = &i8::min_value();
let x: &'static i16 = &i16::min_value();
let x: &'static i32 = &i32::min_value();
let x: &'static i64 = &i64::min_value();
let x: &'static i128 = &i128::min_value();
let x: &'static isize = &isize::min_value();
}

View File

@ -14,5 +14,4 @@ trait Trait {
type Foo = Trait; //~ ERROR E0191
fn main() {
}
fn main() {}

View File

@ -8,16 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-pass
use std::iter::Iterator;
trait Foo: Iterator<Item = i32, Item = i32> {}
type Unit = ();
fn test() -> Box<Iterator<Item = (), Item = Unit>> {
fn test() -> Box<Iterator<Item = (), Item = Unit>> {
Box::new(None.into_iter())
}
fn main() {
let _: &Iterator<Item = i32, Item = i32>;
test();
}

View File

@ -0,0 +1,19 @@
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
--> $DIR/E0719.rs:11:33
|
LL | trait Foo: Iterator<Item = i32, Item = i32> {}
| ---------- ^^^^^^^^^^ re-bound here
| |
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified
--> $DIR/E0719.rs:15:38
|
LL | fn test() -> Box<Iterator<Item = (), Item = Unit>> {
| --------- ^^^^^^^^^^^ re-bound here
| |
| `Item` bound here first
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0719`.

View File

@ -0,0 +1,11 @@
// edition:2018
#[no_implicit_prelude]
mod bar {
fn f() {
::std::print!(""); // OK
print!(); //~ ERROR cannot find macro `print!` in this scope
}
}
fn main() {}

View File

@ -0,0 +1,10 @@
error: cannot find macro `print!` in this scope
--> $DIR/no_implicit_prelude-2018.rs:7:9
|
LL | print!(); //~ ERROR cannot find macro `print!` in this scope
| ^^^^^
|
= help: have you added the `#[macro_use]` on the module/import?
error: aborting due to previous error

View File

@ -21,7 +21,10 @@ mod bar {
Vec::new(); //~ ERROR failed to resolve
().clone() //~ ERROR no method named `clone` found
}
fn f() { ::foo::m!(); }
fn f() {
::foo::m!();
println!(); // OK on 2015 edition (at least for now)
}
}
fn main() {}

View File

@ -1,17 +0,0 @@
// compile-pass
#![crate_type = "lib"]
#![feature(linkage)]
// MergeFunctions will merge these via an anonymous internal
// backing function, which must be named if ThinLTO buffers are used
#[linkage = "weak"]
pub fn fn1(a: u32, b: u32, c: u32) -> u32 {
a + b + c
}
#[linkage = "weak"]
pub fn fn2(a: u32, b: u32, c: u32) -> u32 {
a + b + c
}

View File

@ -0,0 +1,27 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-pass
#![crate_type = "lib"]
#![feature(linkage)]
// MergeFunctions will merge these via an anonymous internal
// backing function, which must be named if ThinLTO buffers are used
#[linkage = "weak"]
pub fn fn1(a: u32, b: u32, c: u32) -> u32 {
a + b + c
}
#[linkage = "weak"]
pub fn fn2(a: u32, b: u32, c: u32) -> u32 {
a + b + c
}

View File

@ -0,0 +1,22 @@
pub trait EdgeTrait<N> {
fn target(&self) -> N;
}
pub trait Graph<'a> {
type Node;
type Edge: EdgeTrait<Self::Node>;
type NodesIter: Iterator<Item = Self::Node> + 'a;
type EdgesIter: Iterator<Item = Self::Edge> + 'a;
fn nodes(&'a self) -> Self::NodesIter;
fn out_edges(&'a self, u: &Self::Node) -> Self::EdgesIter;
fn in_edges(&'a self, u: &Self::Node) -> Self::EdgesIter;
fn out_neighbors(&'a self, u: &Self::Node) -> Box<Iterator<Item = Self::Node>> {
Box::new(self.out_edges(u).map(|e| e.target()))
}
fn in_neighbors(&'a self, u: &Self::Node) -> Box<Iterator<Item = Self::Node>> {
Box::new(self.in_edges(u).map(|e| e.target()))
}
}

View File

@ -0,0 +1,50 @@
error[E0601]: `main` function not found in crate `issue_55796`
|
= note: consider adding a `main` function to `$DIR/issue-55796.rs`
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/issue-55796.rs:16:9
|
LL | Box::new(self.out_edges(u).map(|e| e.target()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17...
--> $DIR/issue-55796.rs:5:17
|
LL | pub trait Graph<'a> {
| ^^
note: ...so that the type `std::iter::Map<<Self as Graph<'a>>::EdgesIter, [closure@$DIR/issue-55796.rs:16:40: 16:54]>` will meet its required lifetime bounds
--> $DIR/issue-55796.rs:16:9
|
LL | Box::new(self.out_edges(u).map(|e| e.target()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected std::boxed::Box<(dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node> + 'static)>
found std::boxed::Box<dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node>>
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/issue-55796.rs:20:9
|
LL | Box::new(self.in_edges(u).map(|e| e.target()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17...
--> $DIR/issue-55796.rs:5:17
|
LL | pub trait Graph<'a> {
| ^^
note: ...so that the type `std::iter::Map<<Self as Graph<'a>>::EdgesIter, [closure@$DIR/issue-55796.rs:20:39: 20:53]>` will meet its required lifetime bounds
--> $DIR/issue-55796.rs:20:9
|
LL | Box::new(self.in_edges(u).map(|e| e.target()))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the expression is assignable:
expected std::boxed::Box<(dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node> + 'static)>
found std::boxed::Box<dyn std::iter::Iterator<Item=<Self as Graph<'a>>::Node>>
error: aborting due to 3 previous errors
Some errors occurred: E0495, E0601.
For more information about an error, try `rustc --explain E0495`.

View File

@ -1,23 +0,0 @@
warning: associated type binding `Item` specified more than once
--> $DIR/issue-50589-multiple-associated-types.rs:17:39
|
LL | fn test() -> Box<Iterator<Item = (), Item = Unit>> {
| --------- ^^^^^^^^^^^ used more than once
| |
| first use of `Item`
|
= note: #[warn(duplicate_associated_type_bindings)] on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #50589 <https://github.com/rust-lang/rust/issues/50589>
warning: associated type binding `Item` specified more than once
--> $DIR/issue-50589-multiple-associated-types.rs:17:39
|
LL | fn test() -> Box<Iterator<Item = (), Item = Unit>> {
| --------- ^^^^^^^^^^^ used more than once
| |
| first use of `Item`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #50589 <https://github.com/rust-lang/rust/issues/50589>

View File

@ -1,150 +0,0 @@
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:59:14
|
LL | let x = |mut y: isize| 10; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
|
note: lint level defined here
--> $DIR/lint-unused-mut-variables.rs:19:9
|
LL | #![deny(unused_mut)]
| ^^^^^^^^^^
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:24:9
|
LL | let mut a = 3; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:26:9
|
LL | let mut a = 2; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:28:9
|
LL | let mut b = 3; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:30:9
|
LL | let mut a = vec![3]; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:32:10
|
LL | let (mut a, b) = (1, 2); //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:34:9
|
LL | let mut a; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:38:9
|
LL | let mut b; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:47:9
|
LL | mut x => {} //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:51:8
|
LL | (mut x, 1) | //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:64:9
|
LL | let mut a = &mut 5; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:69:9
|
LL | let mut b = (&mut a,); //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:72:9
|
LL | let mut x = &mut 1; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:84:9
|
LL | let mut v : &mut Vec<()> = &mut vec![]; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:61:13
|
LL | fn what(mut foo: isize) {} //[lexical]~ ERROR: variable does not need to be mutable
| ----^^^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:79:20
|
LL | fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
| ----^^^
| |
| help: remove this `mut`
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:143:9
|
LL | let mut b = vec![2]; //[lexical]~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
|
note: lint level defined here
--> $DIR/lint-unused-mut-variables.rs:139:8
|
LL | #[deny(unused_mut)]
| ^^^^^^^^^^
error: aborting due to 17 previous errors

View File

@ -8,8 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// revisions: lexical nll
#![cfg_attr(nll, feature(nll))]
// Exercise the unused_mut attribute in some positive and negative cases
@ -21,22 +21,22 @@
fn main() {
// negative cases
let mut a = 3; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let mut a = 2; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let mut b = 3; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let mut a = vec![3]; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let (mut a, b) = (1, 2); //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let mut a; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let mut a = 3; //~ ERROR: variable does not need to be mutable
let mut a = 2; //~ ERROR: variable does not need to be mutable
let mut b = 3; //~ ERROR: variable does not need to be mutable
let mut a = vec![3]; //~ ERROR: variable does not need to be mutable
let (mut a, b) = (1, 2); //~ ERROR: variable does not need to be mutable
let mut a; //~ ERROR: variable does not need to be mutable
a = 3;
let mut b; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let mut b; //~ ERROR: variable does not need to be mutable
if true {
b = 3;
} else {
@ -44,45 +44,45 @@ fn main() {
}
match 30 {
mut x => {} //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
mut x => {} //~ ERROR: variable does not need to be mutable
}
match (30, 2) {
(mut x, 1) | //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
(mut x, 1) | //~ ERROR: variable does not need to be mutable
(mut x, 2) |
(mut x, 3) => {
}
_ => {}
}
let x = |mut y: isize| 10; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
fn what(mut foo: isize) {} //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let x = |mut y: isize| 10; //~ ERROR: variable does not need to be mutable
fn what(mut foo: isize) {} //~ ERROR: variable does not need to be mutable
let mut a = &mut 5; //~ ERROR: variable does not need to be mutable
let mut a = &mut 5; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
*a = 4;
let mut a = 5;
let mut b = (&mut a,); //[lexical]~ ERROR: variable does not need to be mutable
*b.0 = 4; //[nll]~^ ERROR: variable does not need to be mutable
let mut b = (&mut a,); //~ ERROR: variable does not need to be mutable
*b.0 = 4;
let mut x = &mut 1; //~ ERROR: variable does not need to be mutable
let mut x = &mut 1; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let mut f = || {
*x += 1;
};
f();
fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
&mut arg[..] //[lexical]~^ ERROR: variable does not need to be mutable
//[nll]~^^ ERROR: variable does not need to be mutable
&mut arg[..] //~^ ERROR: variable does not need to be mutable
}
let mut v : &mut Vec<()> = &mut vec![]; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let mut v : &mut Vec<()> = &mut vec![]; //~ ERROR: variable does not need to be mutable
v.push(());
// positive cases
@ -140,6 +140,6 @@ fn foo(mut a: isize) {
fn bar() {
#[allow(unused_mut)]
let mut a = 3;
let mut b = vec![2]; //[lexical]~ ERROR: variable does not need to be mutable
//[nll]~^ ERROR: variable does not need to be mutable
let mut b = vec![2]; //~ ERROR: variable does not need to be mutable
}

View File

@ -1,7 +1,7 @@
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:59:14
|
LL | let x = |mut y: isize| 10; //[lexical]~ ERROR: variable does not need to be mutable
LL | let x = |mut y: isize| 10; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -15,7 +15,7 @@ LL | #![deny(unused_mut)]
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:24:9
|
LL | let mut a = 3; //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut a = 3; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -23,7 +23,7 @@ LL | let mut a = 3; //[lexical]~ ERROR: variable does not need to be mutable
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:26:9
|
LL | let mut a = 2; //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut a = 2; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -31,7 +31,7 @@ LL | let mut a = 2; //[lexical]~ ERROR: variable does not need to be mutable
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:28:9
|
LL | let mut b = 3; //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut b = 3; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -39,7 +39,7 @@ LL | let mut b = 3; //[lexical]~ ERROR: variable does not need to be mutable
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:30:9
|
LL | let mut a = vec![3]; //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut a = vec![3]; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -47,7 +47,7 @@ LL | let mut a = vec![3]; //[lexical]~ ERROR: variable does not need to be m
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:32:10
|
LL | let (mut a, b) = (1, 2); //[lexical]~ ERROR: variable does not need to be mutable
LL | let (mut a, b) = (1, 2); //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -55,7 +55,7 @@ LL | let (mut a, b) = (1, 2); //[lexical]~ ERROR: variable does not need to
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:34:9
|
LL | let mut a; //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut a; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -63,7 +63,7 @@ LL | let mut a; //[lexical]~ ERROR: variable does not need to be mutable
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:38:9
|
LL | let mut b; //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut b; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -71,7 +71,7 @@ LL | let mut b; //[lexical]~ ERROR: variable does not need to be mutable
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:47:9
|
LL | mut x => {} //[lexical]~ ERROR: variable does not need to be mutable
LL | mut x => {} //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -79,7 +79,7 @@ LL | mut x => {} //[lexical]~ ERROR: variable does not need to be mutabl
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:51:8
|
LL | (mut x, 1) | //[lexical]~ ERROR: variable does not need to be mutable
LL | (mut x, 1) | //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -87,7 +87,7 @@ LL | (mut x, 1) | //[lexical]~ ERROR: variable does not need to be mutable
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:64:9
|
LL | let mut a = &mut 5; //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut a = &mut 5; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -95,7 +95,7 @@ LL | let mut a = &mut 5; //[lexical]~ ERROR: variable does not need to be mu
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:69:9
|
LL | let mut b = (&mut a,); //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut b = (&mut a,); //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -103,7 +103,7 @@ LL | let mut b = (&mut a,); //[lexical]~ ERROR: variable does not need to be
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:72:9
|
LL | let mut x = &mut 1; //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut x = &mut 1; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -111,7 +111,7 @@ LL | let mut x = &mut 1; //[lexical]~ ERROR: variable does not need to be mu
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:84:9
|
LL | let mut v : &mut Vec<()> = &mut vec![]; //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut v : &mut Vec<()> = &mut vec![]; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`
@ -119,7 +119,7 @@ LL | let mut v : &mut Vec<()> = &mut vec![]; //[lexical]~ ERROR: variable do
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:61:13
|
LL | fn what(mut foo: isize) {} //[lexical]~ ERROR: variable does not need to be mutable
LL | fn what(mut foo: isize) {} //~ ERROR: variable does not need to be mutable
| ----^^^
| |
| help: remove this `mut`
@ -135,7 +135,7 @@ LL | fn mut_ref_arg(mut arg : &mut [u8]) -> &mut [u8] {
error: variable does not need to be mutable
--> $DIR/lint-unused-mut-variables.rs:143:9
|
LL | let mut b = vec![2]; //[lexical]~ ERROR: variable does not need to be mutable
LL | let mut b = vec![2]; //~ ERROR: variable does not need to be mutable
| ----^
| |
| help: remove this `mut`

View File

@ -0,0 +1,25 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(nll)]
struct Bar;
struct Foo<'s> {
bar: &'s mut Bar,
}
impl Foo<'_> {
fn new(bar: &mut Bar) -> Self {
Foo { bar }
}
}
fn main() { }

View File

@ -0,0 +1,12 @@
error: unsatisfied lifetime constraints
--> $DIR/issue-55394.rs:21:9
|
LL | fn new(bar: &mut Bar) -> Self {
| - ---- return type is Foo<'2>
| |
| let's call the lifetime of this reference `'1`
LL | Foo { bar }
| ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
error: aborting due to previous error

View File

@ -1,5 +1,5 @@
error[E0038]: the trait `EqAlias` cannot be made into an object
--> $DIR/trait-alias-objects.rs:17:13
--> $DIR/trait-alias-object.rs:17:13
|
LL | let _: &dyn EqAlias = &123;
| ^^^^^^^^^^^ the trait `EqAlias` cannot be made into an object
@ -7,7 +7,7 @@ LL | let _: &dyn EqAlias = &123;
= note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses
error[E0191]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified
--> $DIR/trait-alias-objects.rs:18:13
--> $DIR/trait-alias-object.rs:18:13
|
LL | let _: &dyn IteratorAlias = &vec![123].into_iter();
| ^^^^^^^^^^^^^^^^^ missing associated type `Item` value

View File

@ -0,0 +1,23 @@
// compile-pass
// rust-lang/rust#55810: types for a binding in a match arm can be
// inferred from arms that come later in the match.
struct S;
impl S {
fn method(&self) -> bool {
unimplemented!()
}
}
fn get<T>() -> T {
unimplemented!()
}
fn main() {
match get() {
x if x.method() => {}
&S => {}
}
}