"crates-io 0.21.0",
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
name = "crates-io"
version = "0.21.0"
dependencies = [
- "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "curl"
-version = "0.4.18"
+version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
[[package]]
name = "curl-sys"
-version = "0.4.13"
+version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
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]]
[[package]]
name = "tar"
-version = "0.4.16"
+version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
"checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4"
-"checksum curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a9e5285b49b44401518c947d3b808d14d99a538a6c9ffb3ec0205c11f9fc4389"
-"checksum curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "08459503c415173da1ce6b41036a37b8bfdd86af46d45abb9964d4c61fe670ef"
+"checksum curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c7c9d851c825e0c033979d4516c9173bc19a78a96eb4d6ae51d4045440eafa16"
+"checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870"
"checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142"
"checksum derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ceed73957c449214f8440eec8ad7fa282b67dc9eacbb24a3085b15d60397a17a"
"checksum derive_more 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46c7f14685a20f5dd08e7f754f2ea8cc064d8f4214ae21116c106a2768ba7b9b"
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
-"checksum tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)" = "e8f41ca4a5689f06998f0247fcb60da6c760f1950cc9df2a10d71575ad0b062a"
+"checksum tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "69e16840a1e0a1f1a880b739ef1cc6a4b85496c99b8aa786ccffce6e0c15624c"
"checksum tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b103c6d08d323b92ff42c8ce62abcd83ca8efa7fd5bf7927efefec75f58c76"
"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508"
"checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
// Pass down configuration from the LLVM build into the build of
// librustc_llvm and librustc_codegen_llvm.
- if builder.is_rust_llvm(target) {
+ if builder.is_rust_llvm(target) && backend != "emscripten" {
cargo.env("LLVM_RUSTLLVM", "1");
}
cargo.env("LLVM_CONFIG", &llvm_config);
RUN sh /scripts/sccache.sh
ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/clang/e1.37.13_64bit/
-ENV PATH=$PATH:/emsdk-portable/emscripten/1.37.13/
-ENV PATH=$PATH:/emsdk-portable/node/4.1.1_64bit/bin/
-ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.37.13/
-ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.37.13_64bit/binaryen/
+ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
+ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
+ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
+ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
+ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
ENV EM_CONFIG=/emsdk-portable/.emscripten
ENV TARGETS=asmjs-unknown-emscripten
RUN sh /scripts/sccache.sh
ENV PATH=$PATH:/emsdk-portable
-ENV PATH=$PATH:/emsdk-portable/clang/e1.37.13_64bit/
-ENV PATH=$PATH:/emsdk-portable/emscripten/1.37.13/
-ENV PATH=$PATH:/node-v8.0.0-linux-x64/bin/
-ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.37.13/
-ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.37.13_64bit/binaryen/
+ENV PATH=$PATH:/emsdk-portable/clang/e1.38.15_64bit/
+ENV PATH=$PATH:/emsdk-portable/emscripten/1.38.15/
+ENV PATH=$PATH:/emsdk-portable/node/8.9.1_64bit/bin/
+ENV EMSCRIPTEN=/emsdk-portable/emscripten/1.38.15/
+ENV BINARYEN_ROOT=/emsdk-portable/clang/e1.38.15_64bit/binaryen/
ENV EM_CONFIG=/emsdk-portable/.emscripten
ENV TARGETS=wasm32-unknown-emscripten
cd /emsdk-portable
./emsdk update
-hide_output ./emsdk install sdk-1.37.13-64bit
-./emsdk activate sdk-1.37.13-64bit
+hide_output ./emsdk install sdk-1.38.15-64bit
+./emsdk activate sdk-1.38.15-64bit
# Compile and cache libc
source ./emsdk_env.sh
# Make emsdk usable by any user
cp /root/.emscripten /emsdk-portable
chmod a+rxw -R /emsdk-portable
-
-# node 8 is required to run wasm
-cd /
-curl -sL https://nodejs.org/dist/v8.0.0/node-v8.0.0-linux-x64.tar.xz | \
- tar -xJ
// 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));
// 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));
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
/// y < 0 or y >= N, where N is the width of T in bits.
pub fn unchecked_shr<T>(x: T, y: T) -> T;
+ /// Performs rotate left.
+ /// The stabilized versions of this intrinsic are available on the integer
+ /// primitives via the `rotate_left` method. For example,
+ /// [`std::u32::rotate_left`](../../std/primitive.u32.html#method.rotate_left)
+ #[cfg(not(stage0))]
+ pub fn rotate_left<T>(x: T, y: T) -> T;
+
+ /// Performs rotate right.
+ /// The stabilized versions of this intrinsic are available on the integer
+ /// primitives via the `rotate_right` method. For example,
+ /// [`std::u32::rotate_right`](../../std/primitive.u32.html#method.rotate_right)
+ #[cfg(not(stage0))]
+ pub fn rotate_right<T>(x: T, y: T) -> T;
+
/// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
/// The stabilized versions of this intrinsic are available on the integer
/// primitives via the `wrapping_add` method. For example,
", $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 }
}
stringify!($MaxV), ");", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_promotable]
#[inline]
pub const fn max_value() -> Self { !0 }
}
#[rustc_const_unstable(feature = "const_int_rotate")]
#[inline]
pub const fn rotate_left(self, n: u32) -> Self {
- (self << (n % $BITS)) | (self >> (($BITS - (n % $BITS)) % $BITS))
+ #[cfg(not(stage0))] {
+ unsafe { intrinsics::rotate_left(self, n as $SelfT) }
+ }
+ #[cfg(stage0)] {
+ (self << (n % $BITS)) | (self >> (($BITS - (n % $BITS)) % $BITS))
+ }
}
}
#[rustc_const_unstable(feature = "const_int_rotate")]
#[inline]
pub const fn rotate_right(self, n: u32) -> Self {
- (self >> (n % $BITS)) | (self << (($BITS - (n % $BITS)) % $BITS))
+ #[cfg(not(stage0))] {
+ unsafe { intrinsics::rotate_right(self, n as $SelfT) }
+ }
+ #[cfg(stage0)] {
+ (self >> (n % $BITS)) | (self << (($BITS - (n % $BITS)) % $BITS))
+ }
}
}
register_diagnostics! {
-// E0006 // merged with E0005
+// E0006, // merged with E0005
// E0101, // replaced with E0282
// E0102, // replaced with E0282
// E0134,
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`
}
/// 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),
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) => {
// 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.
//!
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) => {
.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
.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
"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,
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,
elem: &PlaceElem<'tcx>)
-> PlaceTy<'tcx>
{
- self.projection_ty_core(tcx, elem, |_, _, ty| ty)
+ self.projection_ty_core(tcx, elem, |_, _, ty| -> Result<Ty<'tcx>, ()> { Ok(ty) })
+ .unwrap()
}
/// `place_ty.projection_ty_core(tcx, elem, |...| { ... })`
/// `Ty` or downcast variant corresponding to that projection.
/// The `handle_field` callback must map a `Field` to its `Ty`,
/// (which should be trivial when `T` = `Ty`).
- pub fn projection_ty_core<V, T>(self,
- tcx: TyCtxt<'a, 'gcx, 'tcx>,
- elem: &ProjectionElem<'tcx, V, T>,
- mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>)
- -> PlaceTy<'tcx>
+ pub fn projection_ty_core<V, T, E>(
+ self,
+ tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ elem: &ProjectionElem<'tcx, V, T>,
+ mut handle_field: impl FnMut(&Self, &Field, &T) -> Result<Ty<'tcx>, E>)
+ -> Result<PlaceTy<'tcx>, E>
where
V: ::std::fmt::Debug, T: ::std::fmt::Debug
{
bug!("cannot downcast non-ADT type: `{:?}`", self)
}
},
- ProjectionElem::Field(ref f, ref fty) => PlaceTy::Ty { ty: handle_field(&self, f, fty) }
+ ProjectionElem::Field(ref f, ref fty) =>
+ PlaceTy::Ty { ty: handle_field(&self, f, fty)? },
};
debug!("projection_ty self: {:?} elem: {:?} yields: {:?}", self, elem, answer);
- answer
+ Ok(answer)
}
}
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)]
let recursion_limit = *selcx.tcx().sess.recursion_limit.get();
if obligation.recursion_depth >= recursion_limit {
debug!("project: overflow!");
- selcx.infcx().report_overflow_error(&obligation, true);
+ return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow));
}
let obligation_trait_ref = &obligation.predicate.trait_ref(selcx.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() {
}
}
-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>> {
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;
&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(_, _) => {
}
}
- /// 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.
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,
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,
// 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;
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,
}
_ => 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)
}
}
_ => 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)
}
}
self.instantiate_into(tcx, &mut instantiated, substs);
instantiated
}
+
pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
-> InstantiatedPredicates<'tcx> {
InstantiatedPredicates {
#[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.
/// 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),
//
// 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.
//
// 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).
pub struct TraitPredicate<'tcx> {
pub trait_ref: TraitRef<'tcx>
}
+
pub type PolyTraitPredicate<'tcx> = ty::Binder<TraitPredicate<'tcx>>;
impl<'tcx> TraitPredicate<'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>>;
/// 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`
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.
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
}
}
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 {
/// 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)
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)
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)
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)
}
}
- /// 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) {
///
/// 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() {
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 {
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
}
// 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)]
}
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
// 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);
}
}
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)));
}
use util::captures::Captures;
use mir::interpret::{Scalar, Pointer};
+use smallvec::SmallVec;
use std::iter;
use std::cmp::Ordering;
use rustc_target::spec::abi;
/// 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,
/// 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,
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
/// 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> {
}
}
- /// 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(_) |
Param(_) |
Bound(..) |
Infer(_) |
- Error => {
- vec![]
- }
+ Error => {}
}
}
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
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, _| {
})
}
- /// 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>,
}
#[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)
}
#[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)
// `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)
[dependencies]
bitflags = "1.0"
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
+smallvec = { version = "0.6.5", features = ["union"] }
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};
// 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
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 {
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);
#[macro_use]
extern crate bitflags;
+extern crate smallvec;
use std::cmp::Ordering;
use std::fmt;
ifn!("llvm.bitreverse.i64", fn(t_i64) -> t_i64);
ifn!("llvm.bitreverse.i128", fn(t_i128) -> t_i128);
+ ifn!("llvm.fshl.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
+ ifn!("llvm.fshl.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
+ ifn!("llvm.fshl.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
+ ifn!("llvm.fshl.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
+ ifn!("llvm.fshl.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
+
+ ifn!("llvm.fshr.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
+ ifn!("llvm.fshr.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
+ ifn!("llvm.fshr.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
+ ifn!("llvm.fshr.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
+ ifn!("llvm.fshr.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
+
ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
ifn!("llvm.sadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
use llvm;
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
DICompositeType, DILexicalBlock, DIFlags};
+use llvm_util;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc::hir::CodegenFnAttrFlags;
fn use_enum_fallback(cx: &CodegenCx) -> bool {
// On MSVC we have to use the fallback mode, because LLVM doesn't
// lower variant parts to PDB.
- return cx.sess().target.target.options.is_like_msvc || unsafe {
- llvm::LLVMRustVersionMajor() < 7
- };
+ return cx.sess().target.target.options.is_like_msvc
+ || llvm_util::get_major_version() < 7;
}
// Describes the members of an enum value: An enum is described as a union of
use attributes;
use intrinsics::{self, Intrinsic};
use llvm::{self, TypeKind};
+use llvm_util;
use abi::{Abi, FnType, LlvmType, PassMode};
use mir::place::PlaceRef;
use mir::operand::{OperandRef, OperandValue};
"ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
"bitreverse" | "add_with_overflow" | "sub_with_overflow" |
"mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
- "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "exact_div" => {
+ "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" | "exact_div" |
+ "rotate_left" | "rotate_right" => {
let ty = arg_tys[0];
match int_type_width_signed(ty, cx) {
Some((width, signed)) =>
} else {
bx.lshr(args[0].immediate(), args[1].immediate())
},
+ "rotate_left" | "rotate_right" => {
+ let is_left = name == "rotate_left";
+ let val = args[0].immediate();
+ let raw_shift = args[1].immediate();
+ if llvm_util::get_major_version() >= 7 {
+ // rotate = funnel shift with first two args the same
+ let llvm_name = &format!("llvm.fsh{}.i{}",
+ if is_left { 'l' } else { 'r' }, width);
+ let llfn = cx.get_intrinsic(llvm_name);
+ bx.call(llfn, &[val, val, raw_shift], None)
+ } else {
+ // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
+ // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
+ let width = C_uint(Type::ix(cx, width), width);
+ let shift = bx.urem(raw_shift, width);
+ let inv_shift = bx.urem(bx.sub(width, raw_shift), width);
+ let shift1 = bx.shl(val, if is_left { shift } else { inv_shift });
+ let shift2 = bx.lshr(val, if !is_left { shift } else { inv_shift });
+ bx.or(shift1, shift2)
+ }
+ },
_ => bug!(),
},
None => {
"hexagon" => HEXAGON_WHITELIST,
"mips" | "mips64" => MIPS_WHITELIST,
"powerpc" | "powerpc64" => POWERPC_WHITELIST,
- "wasm32" => WASM_WHITELIST,
+ // wasm32 on emscripten does not support these target features
+ "wasm32" if !sess.target.target.options.is_like_emscripten => WASM_WHITELIST,
_ => &[],
}
}
}
}
+pub fn get_major_version() -> u32 {
+ unsafe { llvm::LLVMRustVersionMajor() }
+}
+
pub fn print_passes() {
// Can be called without initializing LLVM
unsafe { llvm::LLVMRustPrintPasses(); }
use libc::c_uint;
use llvm::{self, BasicBlock};
use llvm::debuginfo::DIScope;
+use llvm_util;
use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts};
use rustc::ty::layout::{LayoutOf, TyLayout};
use rustc::mir::{self, Mir};
// doesn't actually strip the offset when splitting the closure
// environment into its components so it ends up out of bounds.
// (cuviper) It seems to be fine without the alloca on LLVM 6 and later.
- let env_alloca = !env_ref && unsafe { llvm::LLVMRustVersionMajor() < 6 };
+ let env_alloca = !env_ref && llvm_util::get_major_version() < 6;
let env_ptr = if env_alloca {
let scratch = PlaceRef::alloca(bx,
bx.cx.layout_of(tcx.mk_mut_ptr(arg.layout.ty)),
codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
if is_extern && !std_internal {
+ // Emscripten cannot export statics, so reduce their export level here
+ if tcx.sess.target.target.options.is_like_emscripten {
+ if let Some(Node::Item(&hir::Item {
+ node: hir::ItemKind::Static(..),
+ ..
+ })) = tcx.hir.get_if_local(sym_def_id) {
+ return SymbolExportLevel::Rust;
+ }
+ }
+
SymbolExportLevel::C
} else {
SymbolExportLevel::Rust
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>",
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
let v1 = ty::Contravariant.xform(v);
let tcx = self.infcx.tcx;
- let mut projected_ty = PlaceTy::from_ty(ty);
+ let ty = self.normalize(ty, locations);
+
+ // We need to follow any provided projetions into the type.
+ //
+ // if we hit a ty var as we descend, then just skip the
+ // attempt to relate the mir local with any type.
+ #[derive(Debug)] struct HitTyVar;
+ let mut curr_projected_ty: Result<PlaceTy, HitTyVar>;
+
+ curr_projected_ty = Ok(PlaceTy::from_ty(ty));
for proj in &user_ty.projs {
- projected_ty = projected_ty.projection_ty_core(
+ let projected_ty = if let Ok(projected_ty) = curr_projected_ty {
+ projected_ty
+ } else {
+ break;
+ };
+ curr_projected_ty = projected_ty.projection_ty_core(
tcx, proj, |this, field, &()| {
- let ty = this.field_ty(tcx, field);
- self.normalize(ty, locations)
+ if this.to_ty(tcx).is_ty_var() {
+ Err(HitTyVar)
+ } else {
+ let ty = this.field_ty(tcx, field);
+ Ok(self.normalize(ty, locations))
+ }
});
}
debug!("user_ty base: {:?} freshened: {:?} projs: {:?} yields: {:?}",
- user_ty.base, ty, user_ty.projs, projected_ty);
+ user_ty.base, ty, user_ty.projs, curr_projected_ty);
- let ty = projected_ty.to_ty(tcx);
-
- self.relate_types(ty, v1, a, locations, category)?;
+ if let Ok(projected_ty) = curr_projected_ty {
+ let ty = projected_ty.to_ty(tcx);
+ self.relate_types(ty, v1, a, locations, category)?;
+ }
}
UserTypeAnnotation::TypeOf(def_id, canonical_substs) => {
let (
}
self.write_scalar(val, dest)?;
}
+ "rotate_left" | "rotate_right" => {
+ // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
+ // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
+ let layout = self.layout_of(substs.type_at(0))?;
+ let val_bits = self.read_scalar(args[0])?.to_bits(layout.size)?;
+ let raw_shift_bits = self.read_scalar(args[1])?.to_bits(layout.size)?;
+ let width_bits = layout.size.bits() as u128;
+ let shift_bits = raw_shift_bits % width_bits;
+ let inv_shift_bits = (width_bits - raw_shift_bits) % width_bits;
+ let result_bits = if intrinsic_name == "rotate_left" {
+ (val_bits << shift_bits) | (val_bits >> inv_shift_bits)
+ } else {
+ (val_bits >> shift_bits) | (val_bits << inv_shift_bits)
+ };
+ let truncated_bits = self.truncate(result_bits, layout);
+ let result = Scalar::from_uint(truncated_bits, layout.size);
+ self.write_scalar(result, dest)?;
+ }
"transmute" => {
self.copy_op_transmute(args[0], dest)?;
}
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;
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); }
_ => {},
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 {
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: \
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;
// 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;
// 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);
}
}
}
}
}
+ 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>)
| "overflowing_mul"
| "unchecked_shl"
| "unchecked_shr"
+ | "rotate_left"
+ | "rotate_right"
| "add_with_overflow"
| "sub_with_overflow"
| "mul_with_overflow"
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;
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)
}
},
/// 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()
debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
let ty = self.normalize(ty);
- let mut projected_ty = PlaceTy::from_ty(ty);
+ // We need to follow any provided projetions into the type.
+ //
+ // if we hit a ty var as we descend, then just skip the
+ // attempt to relate the mir local with any type.
+
+ struct HitTyVar;
+ let mut curr_projected_ty: Result<PlaceTy, HitTyVar>;
+ curr_projected_ty = Ok(PlaceTy::from_ty(ty));
for proj in projs {
- projected_ty = projected_ty.projection_ty_core(
+ let projected_ty = if let Ok(projected_ty) = curr_projected_ty {
+ projected_ty
+ } else {
+ break;
+ };
+ curr_projected_ty = projected_ty.projection_ty_core(
tcx, proj, |this, field, &()| {
- let ty = this.field_ty(tcx, field);
- self.normalize(ty)
+ if this.to_ty(tcx).is_ty_var() {
+ Err(HitTyVar)
+ } else {
+ let ty = this.field_ty(tcx, field);
+ Ok(self.normalize(ty))
+ }
});
}
- let ty = projected_ty.to_ty(tcx);
- self.relate(mir_ty, variance, ty)?;
+ if let Ok(projected_ty) = curr_projected_ty {
+ let ty = projected_ty.to_ty(tcx);
+ self.relate(mir_ty, variance, ty)?;
+ }
if let Some(UserSelfTy {
impl_def_id,
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>;
}
// 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);
}
}
- // (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(¶m) = params.peek() {
if param.index == 0 {
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 {
}
}
- /// 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>,
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))
}));
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.
// That is, consider this case:
//
// ```
- // trait SubTrait : SuperTrait<int> { }
+ // trait SubTrait: SuperTrait<int> { }
// trait SuperTrait<A> { type T; }
//
// ... B : SubTrait<T=foo> ...
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);
}
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,
.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());
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 {
.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))
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,
}
// 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,
// 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,
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);
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);
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()
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);
Diverges::Maybe => Diverges::Maybe,
Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
}
- });
+ }).collect();
// Now typecheck the blocks.
//
"unchecked_div" | "unchecked_rem" | "exact_div" =>
(1, vec![param(0), param(0)], param(0)),
- "unchecked_shl" | "unchecked_shr" =>
+ "unchecked_shl" | "unchecked_shr" |
+ "rotate_left" | "rotate_right" =>
(1, vec![param(0), param(0)], param(0)),
"overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
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,
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));
}
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);
}
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]
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>,
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 {
}
}
- 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)
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
}
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
//
// 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:
-Subproject commit 2717444753318e461e0c3b30dacd03ffbac96903
+Subproject commit 7f23313edff8beccb3fe44b815714269c5124c15
LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
const char* PGOGenPath, const char* PGOUsePath) {
-#if LLVM_RUSTLLVM
+#if LLVM_VERSION_GE(7, 0)
unwrap(PMBR)->MergeFunctions = MergeFunctions;
#endif
unwrap(PMBR)->SLPVectorize = SLPVectorize;
--- /dev/null
+// 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
if self.0 == 1 {
panic!("panic 1");
} else {
- eprint!("drop {}", self.0);
+ eprintln!("drop {}", self.0);
}
}
}
fn main() {
panic::set_hook(Box::new(|i| {
- eprint!("greetings from the panic handler");
+ eprintln!("greetings from the panic handler");
}));
panic!("foobar");
}
--- /dev/null
+// 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;
+}
assert_eq!(BE_U32, b(55u32).to_be());
assert_eq!(LE_U32, b(55u32).to_le());
- #[cfg(not(target_arch = "asmjs"))]
+ #[cfg(not(target_os = "emscripten"))]
{
const BE_U128: u128 = 999999u128.to_be();
const LE_I128: i128 = (-999999i128).to_le();
--- /dev/null
+// 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);
+}
+++ /dev/null
-// 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 = PartialEq<i32> + Send;
-trait Bar = Foo + Sync;
-
-trait I32Iterator = Iterator<Item = i32>;
-
-pub fn main() {
- let a: &dyn Bar = &123;
- assert!(*a == 123);
- 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));
-}
--- /dev/null
+// 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 = PartialEq<i32> + Send;
+trait Bar = Foo + Sync;
+
+trait I32Iterator = Iterator<Item = i32>;
+
+pub fn main() {
+ let a: &dyn Bar = &123;
+ assert!(*a == 123);
+ let b = Box::new(456) as Box<dyn Foo>;
+ assert!(*b == 456);
+
+ let c: &mut dyn I32Iterator = &mut vec![123].into_iter();
+ assert_eq!(c.next(), Some(123));
+}
--- /dev/null
+// 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();
+}
--- /dev/null
+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`.
--- /dev/null
+// 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>;
+}
--- /dev/null
+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`.
--- /dev/null
+error[E0382]: use of moved value: `a`
+ --> $DIR/borrowck-box-insensitivity.rs:37:9
+ |
+LL | let _x = a.x;
+ | -- value moved here
+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
+
+error[E0382]: use of moved value: `a`
+ --> $DIR/borrowck-box-insensitivity.rs:46:9
+ |
+LL | let _x = a.x;
+ | -- value moved here
+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
+
+error[E0382]: use of moved value: `a`
+ --> $DIR/borrowck-box-insensitivity.rs:55:15
+ |
+LL | let _x = a.x;
+ | -- value moved here
+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
+
+error[E0505]: cannot move out of `a.y` because it is borrowed
+ --> $DIR/borrowck-box-insensitivity.rs:63:9
+ |
+LL | let _x = &a.x;
+ | --- borrow of `a.x` occurs here
+LL | let _y = a.y;
+ | ^^ move out of `a.y` occurs here
+
+error[E0503]: cannot use `a.y` because it was mutably borrowed
+ --> $DIR/borrowck-box-insensitivity.rs:71:9
+ |
+LL | let _x = &mut a.x;
+ | --- borrow of `a.x` occurs here
+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
+ --> $DIR/borrowck-box-insensitivity.rs:77:9
+ |
+LL | let _x = &mut a.x;
+ | --- borrow of `a.x` occurs here
+LL | let _y = a.y;
+ | ^^ move out of `a.y` occurs here
+
+error[E0502]: cannot borrow `a` (via `a.y`) as immutable because `a` is also borrowed as mutable (via `a.x`)
+ --> $DIR/borrowck-box-insensitivity.rs:85:15
+ |
+LL | let _x = &mut a.x;
+ | --- mutable borrow occurs here (via `a.x`)
+LL | let _y = &a.y; //[ast]~ ERROR cannot borrow
+ | ^^^ immutable borrow occurs here (via `a.y`)
+...
+LL | }
+ | - mutable borrow ends here
+
+error[E0502]: cannot borrow `a` (via `a.y`) as mutable because `a` is also borrowed as immutable (via `a.x`)
+ --> $DIR/borrowck-box-insensitivity.rs:92:19
+ |
+LL | let _x = &a.x;
+ | --- immutable borrow occurs here (via `a.x`)
+LL | let _y = &mut a.y; //[ast]~ ERROR cannot borrow
+ | ^^^ mutable borrow occurs here (via `a.y`)
+...
+LL | }
+ | - immutable borrow ends here
+
+error[E0382]: use of collaterally moved value: `a.y`
+ --> $DIR/borrowck-box-insensitivity.rs:100:9
+ |
+LL | let _x = a.x.x;
+ | -- value moved here
+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
+
+error[E0382]: use of collaterally moved value: `a.y`
+ --> $DIR/borrowck-box-insensitivity.rs:108:9
+ |
+LL | let _x = a.x.x;
+ | -- value moved here
+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
+
+error[E0382]: use of collaterally moved value: `a.y`
+ --> $DIR/borrowck-box-insensitivity.rs:116:15
+ |
+LL | let _x = a.x.x;
+ | -- value moved here
+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
+
+error[E0505]: cannot move out of `a.y` because it is borrowed
+ --> $DIR/borrowck-box-insensitivity.rs:124:9
+ |
+LL | let _x = &a.x.x;
+ | ----- 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
+
+error[E0503]: cannot use `a.y` because it was mutably borrowed
+ --> $DIR/borrowck-box-insensitivity.rs:132:9
+ |
+LL | let _x = &mut a.x.x;
+ | ----- borrow of `a.x.x` occurs here
+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
+ --> $DIR/borrowck-box-insensitivity.rs:138:9
+ |
+LL | let _x = &mut a.x.x;
+ | ----- borrow of `a.x.x` occurs here
+LL | let _y = a.y;
+ | ^^ move out of `a.y` occurs here
+
+error[E0502]: cannot borrow `a.y` as immutable because `a.x.x` is also borrowed as mutable
+ --> $DIR/borrowck-box-insensitivity.rs:147:15
+ |
+LL | let _x = &mut a.x.x;
+ | ----- mutable borrow occurs here
+LL | //[ast]~^ mutable borrow occurs here
+LL | let _y = &a.y; //[ast]~ ERROR cannot borrow
+ | ^^^ immutable borrow occurs here
+...
+LL | }
+ | - mutable borrow ends here
+
+error[E0502]: cannot borrow `a.y` as mutable because `a.x.x` is also borrowed as immutable
+ --> $DIR/borrowck-box-insensitivity.rs:155:19
+ |
+LL | let _x = &a.x.x;
+ | ----- immutable borrow occurs here
+LL | //[ast]~^ immutable borrow occurs here
+LL | let _y = &mut a.y; //[ast]~ ERROR cannot borrow
+ | ^^^ mutable borrow occurs here
+...
+LL | }
+ | - immutable borrow ends here
+
+error: aborting due to 16 previous errors
+
+Some errors occurred: E0382, E0502, E0503, E0505.
+For more information about an error, try `rustc --explain E0382`.
--- /dev/null
+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
+
-// 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 {
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();
borrow_after_mut_borrow_nested();
mut_borrow_after_borrow_nested();
}
+
+fn use_mut<T>(_: &mut T) { }
+fn use_imm<T>(_: &T) { }
+++ /dev/null
-error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-box-insensitivity.rs:37:9
- |
-LL | let _x = a.x;
- | -- value moved here
-LL | //~^ value moved here
-LL | let _y = a.y; //~ 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
-
-error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-box-insensitivity.rs:46:9
- |
-LL | let _x = a.x;
- | -- value moved here
-LL | //~^ value moved here
-LL | let _y = a.y; //~ 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
-
-error[E0382]: use of moved value: `a`
- --> $DIR/borrowck-box-insensitivity.rs:55:15
- |
-LL | let _x = a.x;
- | -- value moved here
-LL | //~^ value moved here
-LL | let _y = &a.y; //~ 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
-
-error[E0505]: cannot move out of `a.y` because it is borrowed
- --> $DIR/borrowck-box-insensitivity.rs:63:9
- |
-LL | let _x = &a.x;
- | --- borrow of `a.x` occurs here
-LL | let _y = a.y;
- | ^^ move out of `a.y` occurs here
-
-error[E0503]: cannot use `a.y` because it was mutably borrowed
- --> $DIR/borrowck-box-insensitivity.rs:71:9
- |
-LL | let _x = &mut a.x;
- | --- borrow of `a.x` occurs here
-LL | let _y = a.y; //~ ERROR cannot use
- | ^^ use of borrowed `a.x`
-
-error[E0505]: cannot move out of `a.y` because it is borrowed
- --> $DIR/borrowck-box-insensitivity.rs:77:9
- |
-LL | let _x = &mut a.x;
- | --- borrow of `a.x` occurs here
-LL | let _y = a.y;
- | ^^ move out of `a.y` occurs here
-
-error[E0502]: cannot borrow `a` (via `a.y`) as immutable because `a` is also borrowed as mutable (via `a.x`)
- --> $DIR/borrowck-box-insensitivity.rs:85:15
- |
-LL | let _x = &mut a.x;
- | --- mutable borrow occurs here (via `a.x`)
-LL | let _y = &a.y; //~ ERROR cannot borrow
- | ^^^ immutable borrow occurs here (via `a.y`)
-LL | //~^ immutable borrow occurs here (via `a.y`)
-LL | }
- | - mutable borrow ends here
-
-error[E0502]: cannot borrow `a` (via `a.y`) as mutable because `a` is also borrowed as immutable (via `a.x`)
- --> $DIR/borrowck-box-insensitivity.rs:92:19
- |
-LL | let _x = &a.x;
- | --- immutable borrow occurs here (via `a.x`)
-LL | let _y = &mut a.y; //~ ERROR cannot borrow
- | ^^^ mutable borrow occurs here (via `a.y`)
-LL | //~^ mutable borrow occurs here (via `a.y`)
-LL | }
- | - immutable borrow ends here
-
-error[E0382]: use of collaterally moved value: `a.y`
- --> $DIR/borrowck-box-insensitivity.rs:100:9
- |
-LL | let _x = a.x.x;
- | -- value moved here
-LL | //~^ value moved here
-LL | let _y = a.y; //~ 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
-
-error[E0382]: use of collaterally moved value: `a.y`
- --> $DIR/borrowck-box-insensitivity.rs:108:9
- |
-LL | let _x = a.x.x;
- | -- value moved here
-LL | //~^ value moved here
-LL | let _y = a.y; //~ 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
-
-error[E0382]: use of collaterally moved value: `a.y`
- --> $DIR/borrowck-box-insensitivity.rs:116:15
- |
-LL | let _x = a.x.x;
- | -- value moved here
-LL | //~^ value moved here
-LL | let _y = &a.y; //~ 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
-
-error[E0505]: cannot move out of `a.y` because it is borrowed
- --> $DIR/borrowck-box-insensitivity.rs:124:9
- |
-LL | let _x = &a.x.x;
- | ----- borrow of `a.x.x` occurs here
-LL | //~^ borrow of `a.x.x` occurs here
-LL | let _y = a.y;
- | ^^ move out of `a.y` occurs here
-
-error[E0503]: cannot use `a.y` because it was mutably borrowed
- --> $DIR/borrowck-box-insensitivity.rs:132:9
- |
-LL | let _x = &mut a.x.x;
- | ----- borrow of `a.x.x` occurs here
-LL | let _y = a.y; //~ ERROR cannot use
- | ^^ use of borrowed `a.x.x`
-
-error[E0505]: cannot move out of `a.y` because it is borrowed
- --> $DIR/borrowck-box-insensitivity.rs:138:9
- |
-LL | let _x = &mut a.x.x;
- | ----- borrow of `a.x.x` occurs here
-LL | let _y = a.y;
- | ^^ move out of `a.y` occurs here
-
-error[E0502]: cannot borrow `a.y` as immutable because `a.x.x` is also borrowed as mutable
- --> $DIR/borrowck-box-insensitivity.rs:147:15
- |
-LL | let _x = &mut a.x.x;
- | ----- mutable borrow occurs here
-LL | //~^ mutable borrow occurs here
-LL | let _y = &a.y; //~ ERROR cannot borrow
- | ^^^ immutable borrow occurs here
-LL | //~^ immutable borrow occurs here
-LL | }
- | - mutable borrow ends here
-
-error[E0502]: cannot borrow `a.y` as mutable because `a.x.x` is also borrowed as immutable
- --> $DIR/borrowck-box-insensitivity.rs:155:19
- |
-LL | let _x = &a.x.x;
- | ----- immutable borrow occurs here
-LL | //~^ immutable borrow occurs here
-LL | let _y = &mut a.y; //~ ERROR cannot borrow
- | ^^^ mutable borrow occurs here
-LL | //~^ mutable borrow occurs here
-LL | }
- | - immutable borrow ends here
-
-error: aborting due to 16 previous errors
-
-Some errors occurred: E0382, E0502, E0503, E0505.
-For more information about an error, try `rustc --explain E0382`.
--- /dev/null
+// compile-pass
+
+// rust-lang/rust#55552: The strategy pnkfelix landed in PR #55274
+// (for ensuring that NLL respects user-provided lifetime annotations)
+// did not handle the case where the ascribed type has some expliit
+// wildcards (`_`) mixed in, and it caused an internal compiler error
+// (ICE).
+//
+// This test is just checking that we do not ICE when such things
+// occur.
+
+struct X;
+struct Y;
+struct Z;
+
+struct Pair { x: X, y: Y }
+
+pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
+where A: FnOnce() -> RA + Send,
+ B: FnOnce() -> RB + Send,
+ RA: Send,
+ RB: Send
+{
+ (oper_a(), oper_b())
+}
+
+fn main() {
+ let ((_x, _y), _z): (_, Z) = join(|| (X, Y), || Z);
+
+ let (Pair { x: _x, y: _y }, Z): (_, Z) = join(|| Pair { x: X, y: Y }, || Z);
+}
--- /dev/null
+// 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 }
+}
--- /dev/null
+fn main() {
+ [0; 3][3u64 as usize]; //~ ERROR the len is 3 but the index is 3
+}
--- /dev/null
+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
+
--- /dev/null
+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
+}
--- /dev/null
+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
+
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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();
+}
type Foo = Trait; //~ ERROR E0191
-fn main() {
-}
+fn main() {}
--- /dev/null
+// 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, Item = i32> {}
+
+type Unit = ();
+
+fn test() -> Box<Iterator<Item = (), Item = Unit>> {
+ Box::new(None.into_iter())
+}
+
+fn main() {
+ let _: &Iterator<Item = i32, Item = i32>;
+ test();
+}
--- /dev/null
+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`.
// Test that the compiler will catch invalid inline assembly constraints.
+// ignore-emscripten
+
#![feature(asm)]
extern "C" {
error[E0668]: malformed inline assembly
- --> $DIR/inline-asm-bad-constraint.rs:29:9
+ --> $DIR/inline-asm-bad-constraint.rs:31:9
|
LL | asm!("" :"={rax"(rax)) //~ ERROR E0668
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0668]: malformed inline assembly
- --> $DIR/inline-asm-bad-constraint.rs:37:9
+ --> $DIR/inline-asm-bad-constraint.rs:39:9
|
LL | asm!("callq $0" : : "0"(foo)) //~ ERROR E0668
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0668]: malformed inline assembly
- --> $DIR/inline-asm-bad-constraint.rs:44:9
+ --> $DIR/inline-asm-bad-constraint.rs:46:9
|
LL | asm!("addb $1, $0" : "={rax}"((0i32, rax))); //~ ERROR E0668
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Test that the compiler will catch passing invalid values to inline assembly
// operands.
+// ignore-emscripten
+
#![feature(asm)]
#[repr(C)]
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:29:24
+ --> $DIR/inline-asm-bad-operand.rs:31:24
|
LL | asm!("" :: "r"("")); //~ ERROR E0669
| ^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:34:32
+ --> $DIR/inline-asm-bad-operand.rs:36:32
|
LL | asm!("ret" : : "{rdi}"(target)); //~ ERROR E0669
| ^^^^^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:41:29
+ --> $DIR/inline-asm-bad-operand.rs:43:29
|
LL | unsafe { asm!("" :: "i"(hello)) }; //~ ERROR E0669
| ^^^^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:49:38
+ --> $DIR/inline-asm-bad-operand.rs:51:38
|
LL | asm!("movups $1, %xmm0"::"m"(arr)); //~ ERROR E0669
| ^^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:56:32
+ --> $DIR/inline-asm-bad-operand.rs:58:32
|
LL | asm!("mov sp, $0"::"r"(addr)); //~ ERROR E0669
| ^^^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:63:32
+ --> $DIR/inline-asm-bad-operand.rs:65:32
|
LL | asm!("mov sp, $0"::"r"(addr), //~ ERROR E0669
| ^^^^
error[E0669]: invalid value for constraint in inline assembly
- --> $DIR/inline-asm-bad-operand.rs:64:32
+ --> $DIR/inline-asm-bad-operand.rs:66:32
|
LL | "r"("hello e0669")); //~ ERROR E0669
| ^^^^^^^^^^^^^
+++ /dev/null
-// 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
-}
-error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next`
+error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: std::marker::Sized`
--> $DIR/issue-23122-2.rs:17:15
|
LL | impl<T: Next> Next for GetNext<T> {
| ^^^^
|
= help: consider adding a `#![recursion_limit="128"]` attribute to your crate
+ = note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>`
error: aborting due to previous error
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-
// compile-pass
+// ignore-emscripten no i128 support
#![feature(nll)]
--- /dev/null
+// 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
+}
--- /dev/null
+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()))
+ }
+}
--- /dev/null
+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`.
+++ /dev/null
-// 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
-
-use std::iter::Iterator;
-
-type Unit = ();
-
-fn test() -> Box<Iterator<Item = (), Item = Unit>> {
- Box::new(None.into_iter())
-}
-
-fn main() {
- test();
-}
+++ /dev/null
-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>
-
+++ /dev/null
-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
-
+++ /dev/null
-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
-
// 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
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 {
}
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
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
+
}
--- /dev/null
+error: variable does not need to be mutable
+ --> $DIR/lint-unused-mut-variables.rs:59:14
+ |
+LL | let x = |mut y: isize| 10; //~ 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; //~ 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; //~ 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; //~ 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]; //~ 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); //~ 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; //~ 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; //~ 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 => {} //~ 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) | //~ 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; //~ 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,); //~ 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; //~ 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![]; //~ 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) {} //~ 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]; //~ 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
+
--- /dev/null
+// 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() { }
--- /dev/null
+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
+
use core::ops::RangeBounds;
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(any(not(target_arch = "wasm32"), target_os = "emscripten"))]
#[lang = "eh_personality"]
extern fn eh_personality() {}
--- /dev/null
+// 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 EqAlias = Eq;
+trait IteratorAlias = Iterator;
+
+fn main() {
+ let _: &dyn EqAlias = &123;
+ let _: &dyn IteratorAlias = &vec![123].into_iter();
+}
--- /dev/null
+error[E0038]: the trait `EqAlias` cannot be made into an object
+ --> $DIR/trait-alias-object.rs:17:13
+ |
+LL | let _: &dyn EqAlias = &123;
+ | ^^^^^^^^^^^ the trait `EqAlias` cannot be made into an object
+ |
+ = 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-object.rs:18:13
+ |
+LL | let _: &dyn IteratorAlias = &vec![123].into_iter();
+ | ^^^^^^^^^^^^^^^^^ missing associated type `Item` value
+
+error: aborting due to 2 previous errors
+
+Some errors occurred: E0038, E0191.
+For more information about an error, try `rustc --explain E0038`.
+++ /dev/null
-// 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 EqAlias = Eq;
-trait IteratorAlias = Iterator;
-
-fn main() {
- let _: &dyn EqAlias = &123;
- let _: &dyn IteratorAlias = &vec![123].into_iter();
-}
+++ /dev/null
-error[E0038]: the trait `EqAlias` cannot be made into an object
- --> $DIR/trait-alias-objects.rs:17:13
- |
-LL | let _: &dyn EqAlias = &123;
- | ^^^^^^^^^^^ the trait `EqAlias` cannot be made into an object
- |
- = 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
- |
-LL | let _: &dyn IteratorAlias = &vec![123].into_iter();
- | ^^^^^^^^^^^^^^^^^ missing associated type `Item` value
-
-error: aborting due to 2 previous errors
-
-Some errors occurred: E0038, E0191.
-For more information about an error, try `rustc --explain E0038`.
--- /dev/null
+// 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 => {}
+ }
+}
-Subproject commit 1fa30882067703202d13ad0bd53d630bc2c1de66
+Subproject commit 241fac0e3933063fa48a1a01f5d577e40af12e4d
} else {
self.fatal("no NodeJS binary found (--nodejs)");
}
- }
-
- // If this is otherwise wasm , then run tests under nodejs with our
+ // If this is otherwise wasm, then run tests under nodejs with our
// shim
- if self.config.target.contains("wasm32") {
+ } else if self.config.target.contains("wasm32") {
if let Some(ref p) = self.config.nodejs {
args.push(p.clone());
} else {
[features]
-all-static = ['openssl/vendored', 'curl-sys/static-curl']
+all-static = ['openssl/vendored', 'curl-sys/static-curl', 'curl-sys/force-system-lib-on-osx']