diff --git a/src/Cargo.lock b/src/Cargo.lock index e23bdbd9fd87f..6fadf148e70e4 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -165,7 +165,7 @@ dependencies = [ "hamcrest 0.1.1 (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.22 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -472,7 +472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -600,7 +600,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libgit2-sys" -version = "0.6.10" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cmake 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2056,7 +2056,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum languageserver-types 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97c2985bfcbbcb0189cfa25e1c10c1ac7111df2b6214b652c690127aefdf4e5b" "checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf" "checksum libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)" = "babb8281da88cba992fa1f4ddec7d63ed96280a1a53ec9b919fd37b53d71e502" -"checksum libgit2-sys 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "dd89dd7196d5fa35b659c3eaf3c1b14b9bd961bfd1a07dfca49adeb8a6aa3763" +"checksum libgit2-sys 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d9dc31ee90fb179b706d35fb672e91d0b74e950d7fb4ea7eae3c0f5ecbf2d3d3" "checksum libssh2-sys 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0db4ec23611747ef772db1c4d650f8bd762f07b461727ec998f953c614024b75" "checksum libz-sys 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e5ee912a45d686d393d5ac87fac15ba0ba18daae14e8e7543c63ebf7fb7e970c" "checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 3b37c47e39280..8b70e8be38a27 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -25,7 +25,6 @@ - [cfg_target_has_atomic](language-features/cfg-target-has-atomic.md) - [cfg_target_thread_local](language-features/cfg-target-thread-local.md) - [cfg_target_vendor](language-features/cfg-target-vendor.md) - - [closure_to_fn_coercion](language-features/closure-to-fn-coercion.md) - [compiler_builtins](language-features/compiler-builtins.md) - [concat_idents](language-features/concat-idents.md) - [conservative_impl_trait](language-features/conservative-impl-trait.md) @@ -154,6 +153,7 @@ - [io](library-features/io.md) - [ip](library-features/ip.md) - [iter_rfind](library-features/iter-rfind.md) + - [iterator_step_by](library-features/iterator-step-by.md) - [libstd_io_internals](library-features/libstd-io-internals.md) - [libstd_sys_internals](library-features/libstd-sys-internals.md) - [libstd_thread_internals](library-features/libstd-thread-internals.md) diff --git a/src/doc/unstable-book/src/language-features/closure-to-fn-coercion.md b/src/doc/unstable-book/src/language-features/closure-to-fn-coercion.md deleted file mode 100644 index 4e3b735e24fb6..0000000000000 --- a/src/doc/unstable-book/src/language-features/closure-to-fn-coercion.md +++ /dev/null @@ -1,7 +0,0 @@ -# `closure_to_fn_coercion` - -The tracking issue for this feature is: [#39817] - -[#39817]: https://github.com/rust-lang/rust/issues/39817 - ------------------------- diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 27ecefe043b1e..5faf4dcccaf91 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -91,6 +91,24 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// strong `Arc` pointers from parent nodes to children, and [`Weak`][weak] /// pointers from children back to their parents. /// +/// # Cloning references +/// +/// Creating a new reference from an existing reference counted pointer is done using the +/// `Clone` trait implemented for [`Arc`][`arc`] and [`Weak`][`weak`]. +/// +/// ``` +/// use std::sync::Arc; +/// let foo = Arc::new(vec![1.0, 2.0, 3.0]); +/// // The two syntaxes below are equivalent. +/// let a = foo.clone(); +/// let b = Arc::clone(&foo); +/// // a and b both point to the same memory location as foo. +/// ``` +/// +/// The `Arc::clone(&from)` syntax is the most idiomatic because it conveys more explicitly +/// the meaning of the code. In the example above, this syntax makes it easier to see that +/// this code is creating a new reference rather than copying the whole content of foo. +/// /// ## `Deref` behavior /// /// `Arc` automatically dereferences to `T` (via the [`Deref`][deref] trait), @@ -138,7 +156,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// let five = Arc::new(5); /// /// for _ in 0..10 { -/// let five = five.clone(); +/// let five = Arc::clone(&five); /// /// thread::spawn(move || { /// println!("{:?}", five); @@ -158,7 +176,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// let val = Arc::new(AtomicUsize::new(5)); /// /// for _ in 0..10 { -/// let val = val.clone(); +/// let val = Arc::clone(&val); /// /// thread::spawn(move || { /// let v = val.fetch_add(1, Ordering::SeqCst); @@ -282,7 +300,7 @@ impl Arc { /// assert_eq!(Arc::try_unwrap(x), Ok(3)); /// /// let x = Arc::new(4); - /// let _y = x.clone(); + /// let _y = Arc::clone(&x); /// assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4); /// ``` #[inline] @@ -451,7 +469,7 @@ impl Arc { /// use std::sync::Arc; /// /// let five = Arc::new(5); - /// let _also_five = five.clone(); + /// let _also_five = Arc::clone(&five); /// /// // This assertion is deterministic because we haven't shared /// // the `Arc` between threads. @@ -499,7 +517,7 @@ impl Arc { /// use std::sync::Arc; /// /// let five = Arc::new(5); - /// let same_five = five.clone(); + /// let same_five = Arc::clone(&five); /// let other_five = Arc::new(5); /// /// assert!(Arc::ptr_eq(&five, &same_five)); @@ -524,7 +542,7 @@ impl Clone for Arc { /// /// let five = Arc::new(5); /// - /// five.clone(); + /// Arc::clone(&five); /// ``` #[inline] fn clone(&self) -> Arc { @@ -591,7 +609,7 @@ impl Arc { /// let mut data = Arc::new(5); /// /// *Arc::make_mut(&mut data) += 1; // Won't clone anything - /// let mut other_data = data.clone(); // Won't clone inner data + /// let mut other_data = Arc::clone(&data); // Won't clone inner data /// *Arc::make_mut(&mut data) += 1; // Clones inner data /// *Arc::make_mut(&mut data) += 1; // Won't clone anything /// *Arc::make_mut(&mut other_data) *= 2; // Won't clone anything @@ -679,7 +697,7 @@ impl Arc { /// *Arc::get_mut(&mut x).unwrap() = 4; /// assert_eq!(*x, 4); /// - /// let _y = x.clone(); + /// let _y = Arc::clone(&x); /// assert!(Arc::get_mut(&mut x).is_none()); /// ``` #[inline] @@ -751,7 +769,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc { /// } /// /// let foo = Arc::new(Foo); - /// let foo2 = foo.clone(); + /// let foo2 = Arc::clone(&foo); /// /// drop(foo); // Doesn't print anything /// drop(foo2); // Prints "dropped!" @@ -903,11 +921,11 @@ impl Clone for Weak { /// # Examples /// /// ``` - /// use std::sync::Arc; + /// use std::sync::{Arc, Weak}; /// /// let weak_five = Arc::downgrade(&Arc::new(5)); /// - /// weak_five.clone(); + /// Weak::clone(&weak_five); /// ``` #[inline] fn clone(&self) -> Weak { @@ -956,7 +974,7 @@ impl Drop for Weak { /// # Examples /// /// ``` - /// use std::sync::Arc; + /// use std::sync::{Arc, Weak}; /// /// struct Foo; /// @@ -968,7 +986,7 @@ impl Drop for Weak { /// /// let foo = Arc::new(Foo); /// let weak_foo = Arc::downgrade(&foo); - /// let other_weak_foo = weak_foo.clone(); + /// let other_weak_foo = Weak::clone(&weak_foo); /// /// drop(weak_foo); // Doesn't print anything /// drop(foo); // Prints "dropped!" diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index d6dbf77bfac77..33951b911dd51 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -55,6 +55,24 @@ //! [`Weak`][`Weak`] does not auto-dereference to `T`, because the value may have //! already been destroyed. //! +//! # Cloning references +//! +//! Creating a new reference from an existing reference counted pointer is done using the +//! `Clone` trait implemented for [`Rc`][`Rc`] and [`Weak`][`Weak`]. +//! +//! ``` +//! use std::rc::Rc; +//! let foo = Rc::new(vec![1.0, 2.0, 3.0]); +//! // The two syntaxes below are equivalent. +//! let a = foo.clone(); +//! let b = Rc::clone(&foo); +//! // a and b both point to the same memory location as foo. +//! ``` +//! +//! The `Rc::clone(&from)` syntax is the most idiomatic because it conveys more explicitly +//! the meaning of the code. In the example above, this syntax makes it easier to see that +//! this code is creating a new reference rather than copying the whole content of foo. +//! //! # Examples //! //! Consider a scenario where a set of `Gadget`s are owned by a given `Owner`. @@ -90,11 +108,11 @@ //! // the reference count in the process. //! let gadget1 = Gadget { //! id: 1, -//! owner: gadget_owner.clone(), +//! owner: Rc::clone(&gadget_owner), //! }; //! let gadget2 = Gadget { //! id: 2, -//! owner: gadget_owner.clone(), +//! owner: Rc::clone(&gadget_owner), //! }; //! //! // Dispose of our local variable `gadget_owner`. @@ -163,13 +181,13 @@ //! let gadget1 = Rc::new( //! Gadget { //! id: 1, -//! owner: gadget_owner.clone(), +//! owner: Rc::clone(&gadget_owner), //! } //! ); //! let gadget2 = Rc::new( //! Gadget { //! id: 2, -//! owner: gadget_owner.clone(), +//! owner: Rc::clone(&gadget_owner), //! } //! ); //! @@ -316,7 +334,7 @@ impl Rc { /// assert_eq!(Rc::try_unwrap(x), Ok(3)); /// /// let x = Rc::new(4); - /// let _y = x.clone(); + /// let _y = Rc::clone(&x); /// assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4); /// ``` #[inline] @@ -508,7 +526,7 @@ impl Rc { /// use std::rc::Rc; /// /// let five = Rc::new(5); - /// let _also_five = five.clone(); + /// let _also_five = Rc::clone(&five); /// /// assert_eq!(2, Rc::strong_count(&five)); /// ``` @@ -550,7 +568,7 @@ impl Rc { /// *Rc::get_mut(&mut x).unwrap() = 4; /// assert_eq!(*x, 4); /// - /// let _y = x.clone(); + /// let _y = Rc::clone(&x); /// assert!(Rc::get_mut(&mut x).is_none()); /// ``` #[inline] @@ -576,7 +594,7 @@ impl Rc { /// use std::rc::Rc; /// /// let five = Rc::new(5); - /// let same_five = five.clone(); + /// let same_five = Rc::clone(&five); /// let other_five = Rc::new(5); /// /// assert!(Rc::ptr_eq(&five, &same_five)); @@ -608,7 +626,7 @@ impl Rc { /// let mut data = Rc::new(5); /// /// *Rc::make_mut(&mut data) += 1; // Won't clone anything - /// let mut other_data = data.clone(); // Won't clone inner data + /// let mut other_data = Rc::clone(&data); // Won't clone inner data /// *Rc::make_mut(&mut data) += 1; // Clones inner data /// *Rc::make_mut(&mut data) += 1; // Won't clone anything /// *Rc::make_mut(&mut other_data) *= 2; // Won't clone anything @@ -680,7 +698,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc { /// } /// /// let foo = Rc::new(Foo); - /// let foo2 = foo.clone(); + /// let foo2 = Rc::clone(&foo); /// /// drop(foo); // Doesn't print anything /// drop(foo2); // Prints "dropped!" @@ -720,7 +738,7 @@ impl Clone for Rc { /// /// let five = Rc::new(5); /// - /// five.clone(); + /// Rc::clone(&five); /// ``` #[inline] fn clone(&self) -> Rc { @@ -1050,7 +1068,7 @@ impl Drop for Weak { /// # Examples /// /// ``` - /// use std::rc::Rc; + /// use std::rc::{Rc, Weak}; /// /// struct Foo; /// @@ -1062,7 +1080,7 @@ impl Drop for Weak { /// /// let foo = Rc::new(Foo); /// let weak_foo = Rc::downgrade(&foo); - /// let other_weak_foo = weak_foo.clone(); + /// let other_weak_foo = Weak::clone(&weak_foo); /// /// drop(weak_foo); // Doesn't print anything /// drop(foo); // Prints "dropped!" @@ -1090,11 +1108,11 @@ impl Clone for Weak { /// # Examples /// /// ``` - /// use std::rc::Rc; + /// use std::rc::{Rc, Weak}; /// /// let weak_five = Rc::downgrade(&Rc::new(5)); /// - /// weak_five.clone(); + /// Weak::clone(&weak_five); /// ``` #[inline] fn clone(&self) -> Weak { diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 5eefa59e7ea10..07aed65f7a057 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -520,7 +520,7 @@ impl Iterator for Cycle where I: Clone + Iterator { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for Cycle where I: Clone + Iterator {} -/// An iterator that steps by n elements every iteration. +/// An adapter for stepping iterators by a custom amount. /// /// This `struct` is created by the [`step_by`] method on [`Iterator`]. See /// its documentation for more. @@ -553,8 +553,27 @@ impl Iterator for StepBy where I: Iterator { self.iter.nth(self.step) } } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let inner_hint = self.iter.size_hint(); + + if self.first_take { + let f = |n| if n == 0 { 0 } else { 1 + (n-1)/(self.step+1) }; + (f(inner_hint.0), inner_hint.1.map(f)) + } else { + let f = |n| n / (self.step+1); + (f(inner_hint.0), inner_hint.1.map(f)) + } + } } +// StepBy can only make the iterator shorter, so the len will still fit. +#[unstable(feature = "iterator_step_by", + reason = "unstable replacement of Range::step_by", + issue = "27741")] +impl ExactSizeIterator for StepBy where I: ExactSizeIterator {} + /// An iterator that strings two iterators together. /// /// This `struct` is created by the [`chain`] method on [`Iterator`]. See its diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index ad91ba9be58f2..4030eaf2b2333 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -171,6 +171,79 @@ fn test_iterator_step_by_zero() { it.next(); } +#[test] +fn test_iterator_step_by_size_hint() { + struct StubSizeHint(usize, Option); + impl Iterator for StubSizeHint { + type Item = (); + fn next(&mut self) -> Option<()> { + self.0 -= 1; + if let Some(ref mut upper) = self.1 { + *upper -= 1; + } + Some(()) + } + fn size_hint(&self) -> (usize, Option) { + (self.0, self.1) + } + } + + // The two checks in each case are needed because the logic + // is different before the first call to `next()`. + + let mut it = StubSizeHint(10, Some(10)).step_by(1); + assert_eq!(it.size_hint(), (10, Some(10))); + it.next(); + assert_eq!(it.size_hint(), (9, Some(9))); + + // exact multiple + let mut it = StubSizeHint(10, Some(10)).step_by(3); + assert_eq!(it.size_hint(), (4, Some(4))); + it.next(); + assert_eq!(it.size_hint(), (3, Some(3))); + + // larger base range, but not enough to get another element + let mut it = StubSizeHint(12, Some(12)).step_by(3); + assert_eq!(it.size_hint(), (4, Some(4))); + it.next(); + assert_eq!(it.size_hint(), (3, Some(3))); + + // smaller base range, so fewer resulting elements + let mut it = StubSizeHint(9, Some(9)).step_by(3); + assert_eq!(it.size_hint(), (3, Some(3))); + it.next(); + assert_eq!(it.size_hint(), (2, Some(2))); + + // infinite upper bound + let mut it = StubSizeHint(usize::MAX, None).step_by(1); + assert_eq!(it.size_hint(), (usize::MAX, None)); + it.next(); + assert_eq!(it.size_hint(), (usize::MAX-1, None)); + + // still infinite with larger step + let mut it = StubSizeHint(7, None).step_by(3); + assert_eq!(it.size_hint(), (3, None)); + it.next(); + assert_eq!(it.size_hint(), (2, None)); + + // propagates ExactSizeIterator + let a = [1,2,3,4,5]; + let it = a.iter().step_by(2); + assert_eq!(it.len(), 3); + + // Cannot be TrustedLen as a step greater than one makes an iterator + // with (usize::MAX, None) no longer meet the safety requirements + trait TrustedLenCheck { fn test(self) -> bool; } + impl TrustedLenCheck for T { + default fn test(self) -> bool { false } + } + impl TrustedLenCheck for T { + fn test(self) -> bool { true } + } + assert!(TrustedLenCheck::test(a.iter())); + assert!(!TrustedLenCheck::test(a.iter().step_by(1))); +} + #[test] fn test_filter_map() { let it = (0..).step_by(1).take(10) diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 8c4cd1d0c8458..e9f62dfbaed76 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -32,9 +32,11 @@ #![feature(slice_patterns)] #![feature(sort_internals)] #![feature(sort_unstable)] +#![feature(specialization)] #![feature(step_by)] #![feature(step_trait)] #![feature(test)] +#![feature(trusted_len)] #![feature(try_from)] #![feature(unicode)] #![feature(unique)] diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 291d0d7c937ed..38ad473e4042f 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -176,7 +176,6 @@ pub enum DepNode { IsMirAvailable(D), ItemAttrs(D), FnArgNames(D), - FileMap(D, Arc), } impl DepNode { @@ -307,7 +306,6 @@ impl DepNode { ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic), IsMirAvailable(ref d) => op(d).map(IsMirAvailable), GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)), - FileMap(ref d, ref file_name) => op(d).map(|d| FileMap(d, file_name.clone())), } } } diff --git a/src/librustc/ich/caching_codemap_view.rs b/src/librustc/ich/caching_codemap_view.rs index b21c3a2b21600..9aecd8ad83602 100644 --- a/src/librustc/ich/caching_codemap_view.rs +++ b/src/librustc/ich/caching_codemap_view.rs @@ -8,11 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use dep_graph::{DepGraph, DepNode}; -use hir::def_id::{DefId, CrateNum, CRATE_DEF_INDEX}; -use rustc_data_structures::bitvec::BitVector; use std::rc::Rc; -use std::sync::Arc; use syntax::codemap::CodeMap; use syntax_pos::{BytePos, FileMap}; use ty::TyCtxt; @@ -31,14 +27,12 @@ pub struct CachingCodemapView<'tcx> { codemap: &'tcx CodeMap, line_cache: [CacheEntry; 3], time_stamp: usize, - dep_graph: DepGraph, - dep_tracking_reads: BitVector, } impl<'tcx> CachingCodemapView<'tcx> { pub fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> { let codemap = tcx.sess.codemap(); - let files = codemap.files_untracked(); + let files = codemap.files(); let first_file = files[0].clone(); let entry = CacheEntry { time_stamp: 0, @@ -50,11 +44,9 @@ impl<'tcx> CachingCodemapView<'tcx> { }; CachingCodemapView { - dep_graph: tcx.dep_graph.clone(), codemap: codemap, line_cache: [entry.clone(), entry.clone(), entry.clone()], time_stamp: 0, - dep_tracking_reads: BitVector::new(files.len()), } } @@ -67,9 +59,6 @@ impl<'tcx> CachingCodemapView<'tcx> { for cache_entry in self.line_cache.iter_mut() { if pos >= cache_entry.line_start && pos < cache_entry.line_end { cache_entry.time_stamp = self.time_stamp; - if self.dep_tracking_reads.insert(cache_entry.file_index) { - self.dep_graph.read(dep_node(cache_entry)); - } return Some((cache_entry.file.clone(), cache_entry.line_number, @@ -90,7 +79,7 @@ impl<'tcx> CachingCodemapView<'tcx> { // If the entry doesn't point to the correct file, fix it up if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos { let file_valid; - let files = self.codemap.files_untracked(); + let files = self.codemap.files(); if files.len() > 0 { let file_index = self.codemap.lookup_filemap_idx(pos); @@ -120,21 +109,8 @@ impl<'tcx> CachingCodemapView<'tcx> { cache_entry.line_end = line_bounds.1; cache_entry.time_stamp = self.time_stamp; - if self.dep_tracking_reads.insert(cache_entry.file_index) { - self.dep_graph.read(dep_node(cache_entry)); - } - return Some((cache_entry.file.clone(), cache_entry.line_number, pos - cache_entry.line_start)); } } - -fn dep_node(cache_entry: &CacheEntry) -> DepNode { - let def_id = DefId { - krate: CrateNum::from_u32(cache_entry.file.crate_of_origin), - index: CRATE_DEF_INDEX, - }; - let name = Arc::new(cache_entry.file.name.clone()); - DepNode::FileMap(def_id, name) -} diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs index f25ec8ecd4d71..f8dddc42e48cc 100644 --- a/src/librustc/ich/hcx.rs +++ b/src/librustc/ich/hcx.rs @@ -74,6 +74,11 @@ impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> { } } + pub fn force_span_hashing(mut self) -> Self { + self.hash_spans = true; + self + } + #[inline] pub fn while_hashing_hir_bodies(&mut self, hash_bodies: bool, diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 3ff8ffb35054a..d523d40ccd4ab 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -22,11 +22,55 @@ impl_stable_hash_for!(struct mir::SourceInfo { span, scope }); impl_stable_hash_for!(enum mir::Mutability { Mut, Not }); impl_stable_hash_for!(enum mir::BorrowKind { Shared, Unique, Mut }); impl_stable_hash_for!(enum mir::LocalKind { Var, Temp, Arg, ReturnPointer }); -impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { mutability, ty, name, source_info, -is_user_variable}); +impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { + mutability, + ty, + name, + source_info, + is_user_variable +}); impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref }); impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup }); -impl_stable_hash_for!(struct mir::Terminator<'tcx> { source_info, kind }); + +impl<'a, 'tcx> HashStable> for mir::Terminator<'tcx> { + #[inline] + fn hash_stable(&self, + hcx: &mut StableHashingContext<'a, 'tcx>, + hasher: &mut StableHasher) { + let mir::Terminator { + ref kind, + ref source_info, + } = *self; + + let hash_spans_unconditionally = match *kind { + mir::TerminatorKind::Assert { .. } => { + // Assert terminators generate a panic message that contains the + // source location, so we always have to feed its span into the + // ICH. + true + } + mir::TerminatorKind::Goto { .. } | + mir::TerminatorKind::SwitchInt { .. } | + mir::TerminatorKind::Resume | + mir::TerminatorKind::Return | + mir::TerminatorKind::Unreachable | + mir::TerminatorKind::Drop { .. } | + mir::TerminatorKind::DropAndReplace { .. } | + mir::TerminatorKind::Call { .. } => false, + }; + + if hash_spans_unconditionally { + hcx.while_hashing_spans(true, |hcx| { + source_info.hash_stable(hcx, hasher); + }) + } else { + source_info.hash_stable(hcx, hasher); + } + + kind.hash_stable(hcx, hasher); + } +} + impl<'a, 'tcx> HashStable> for mir::Local { #[inline] diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 814246330a4c2..28531893659e6 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -11,8 +11,9 @@ pub use self::code_stats::{CodeStats, DataTypeKind, FieldInfo}; pub use self::code_stats::{SizeKind, TypeSizeInfo, VariantInfo}; -use dep_graph::{DepGraph, DepNode}; -use hir::def_id::{DefId, CrateNum, DefIndex, CRATE_DEF_INDEX}; +use dep_graph::DepGraph; +use hir::def_id::{CrateNum, DefIndex}; + use lint; use middle::cstore::CrateStore; use middle::dependency_format; @@ -32,7 +33,7 @@ use syntax::parse::ParseSess; use syntax::symbol::Symbol; use syntax::{ast, codemap}; use syntax::feature_gate::AttributeType; -use syntax_pos::{Span, MultiSpan, FileMap}; +use syntax_pos::{Span, MultiSpan}; use rustc_back::{LinkerFlavor, PanicStrategy}; use rustc_back::target::Target; @@ -46,7 +47,6 @@ use std::io::Write; use std::rc::Rc; use std::fmt; use std::time::Duration; -use std::sync::Arc; mod code_stats; pub mod config; @@ -626,21 +626,6 @@ pub fn build_session_(sopts: config::Options, }; let target_cfg = config::build_target_config(&sopts, &span_diagnostic); - // Hook up the codemap with a callback that allows it to register FileMap - // accesses with the dependency graph. - let cm_depgraph = dep_graph.clone(); - let codemap_dep_tracking_callback = Box::new(move |filemap: &FileMap| { - let def_id = DefId { - krate: CrateNum::from_u32(filemap.crate_of_origin), - index: CRATE_DEF_INDEX, - }; - let name = Arc::new(filemap.name.clone()); - let dep_node = DepNode::FileMap(def_id, name); - - cm_depgraph.read(dep_node); - }); - codemap.set_dep_tracking_callback(codemap_dep_tracking_callback); - let p_s = parse::ParseSess::with_span_handler(span_diagnostic, codemap); let default_sysroot = match sopts.maybe_sysroot { Some(_) => None, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 5ee0b1c9e5ea4..64e16c41d1132 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -40,7 +40,7 @@ use ty::layout::{Layout, TargetDataLayout}; use ty::inhabitedness::DefIdForest; use ty::maps; use ty::steal::Steal; -use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet}; +use util::nodemap::{NodeMap, NodeSet, DefIdSet}; use util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::accumulate_vec::AccumulateVec; @@ -499,33 +499,6 @@ pub struct GlobalCtxt<'tcx> { /// Maps Expr NodeId's to `true` iff `&expr` can have 'static lifetime. pub rvalue_promotable_to_static: RefCell>, - /// Maps Fn items to a collection of fragment infos. - /// - /// The main goal is to identify data (each of which may be moved - /// or assigned) whose subparts are not moved nor assigned - /// (i.e. their state is *unfragmented*) and corresponding ast - /// nodes where the path to that data is moved or assigned. - /// - /// In the long term, unfragmented values will have their - /// destructor entirely driven by a single stack-local drop-flag, - /// and their parents, the collections of the unfragmented values - /// (or more simply, "fragmented values"), are mapped to the - /// corresponding collections of stack-local drop-flags. - /// - /// (However, in the short term that is not the case; e.g. some - /// unfragmented paths still need to be zeroed, namely when they - /// reference parent data from an outer scope that was not - /// entirely moved, and therefore that needs to be zeroed so that - /// we do not get double-drop when we hit the end of the parent - /// scope.) - /// - /// Also: currently the table solely holds keys for node-ids of - /// unfragmented values (see `FragmentInfo` enum definition), but - /// longer-term we will need to also store mappings from - /// fragmented data to the set of unfragmented pieces that - /// constitute it. - pub fragment_infos: RefCell>>, - /// The definite name of the current crate after taking into account /// attributes, commandline parameters, etc. pub crate_name: Symbol, @@ -730,7 +703,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { selection_cache: traits::SelectionCache::new(), evaluation_cache: traits::EvaluationCache::new(), rvalue_promotable_to_static: RefCell::new(NodeMap()), - fragment_infos: RefCell::new(DefIdMap()), crate_name: Symbol::intern(crate_name), data_layout: data_layout, layout_cache: RefCell::new(FxHashMap()), diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 963ee9b7165e5..aeffd71a09649 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -444,17 +444,6 @@ pub struct CReaderCacheKey { pub pos: usize, } -/// Describes the fragment-state associated with a NodeId. -/// -/// Currently only unfragmented paths have entries in the table, -/// but longer-term this enum is expected to expand to also -/// include data for fragmented paths. -#[derive(Copy, Clone, Debug)] -pub enum FragmentInfo { - Moved { var: NodeId, move_expr: NodeId }, - Assigned { var: NodeId, assign_expr: NodeId, assignee_id: NodeId }, -} - // Flags that we track on types. These flags are propagated upwards // through the type during type construction, so that we can quickly // check whether the type has various kinds of types in it without diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 01fed11fc97af..eb7744e1213e7 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -266,13 +266,29 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// if not a structure at all. Corresponds to the only possible unsized /// field, and its type can be used to determine unsizing strategy. pub fn struct_tail(self, mut ty: Ty<'tcx>) -> Ty<'tcx> { - while let TyAdt(def, substs) = ty.sty { - if !def.is_struct() { - break; - } - match def.struct_variant().fields.last() { - Some(f) => ty = f.ty(self, substs), - None => break, + loop { + match ty.sty { + ty::TyAdt(def, substs) => { + if !def.is_struct() { + break; + } + match def.struct_variant().fields.last() { + Some(f) => ty = f.ty(self, substs), + None => break, + } + } + + ty::TyTuple(tys, _) => { + if let Some((&last_ty, _)) = tys.split_last() { + ty = last_ty; + } else { + break; + } + } + + _ => { + break; + } } } ty diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs deleted file mode 100644 index b728d4d534516..0000000000000 --- a/src/librustc_borrowck/borrowck/fragments.rs +++ /dev/null @@ -1,542 +0,0 @@ -// Copyright 2012-2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Helper routines used for fragmenting structural paths due to moves for -//! tracking drop obligations. Please see the extensive comments in the -//! section "Structural fragments" in `README.md`. - -use self::Fragment::*; - -use borrowck::InteriorKind::{InteriorField, InteriorElement}; -use borrowck::{self, LoanPath}; -use borrowck::LoanPathKind::{LpVar, LpUpvar, LpDowncast, LpExtend}; -use borrowck::LoanPathElem::{LpDeref, LpInterior}; -use borrowck::move_data::InvalidMovePathIndex; -use borrowck::move_data::{MoveData, MovePathIndex}; -use rustc::hir::def_id::{DefId}; -use rustc::ty::{self, AdtKind, TyCtxt}; -use rustc::middle::mem_categorization as mc; - -use std::mem; -use std::rc::Rc; -use syntax::ast; -use syntax_pos::DUMMY_SP; - -#[derive(PartialEq, Eq, PartialOrd, Ord)] -enum Fragment { - // This represents the path described by the move path index - Just(MovePathIndex), - - // This represents the collection of all but one of the elements - // from an array at the path described by the move path index. - // Note that attached MovePathIndex should have mem_categorization - // of InteriorElement (i.e. array dereference `&foo[..]`). - AllButOneFrom(MovePathIndex), -} - -impl Fragment { - fn loan_path_repr(&self, move_data: &MoveData) -> String { - let lp = |mpi| move_data.path_loan_path(mpi); - match *self { - Just(mpi) => format!("{:?}", lp(mpi)), - AllButOneFrom(mpi) => format!("$(allbutone {:?})", lp(mpi)), - } - } - - fn loan_path_user_string(&self, move_data: &MoveData) -> String { - let lp = |mpi| move_data.path_loan_path(mpi); - match *self { - Just(mpi) => lp(mpi).to_string(), - AllButOneFrom(mpi) => format!("$(allbutone {})", lp(mpi)), - } - } -} - -pub fn build_unfragmented_map(this: &mut borrowck::BorrowckCtxt, - move_data: &MoveData, - id: ast::NodeId) { - let fr = &move_data.fragments.borrow(); - - // For now, don't care about other kinds of fragments; the precise - // classfication of all paths for non-zeroing *drop* needs them, - // but the loose approximation used by non-zeroing moves does not. - let moved_leaf_paths = fr.moved_leaf_paths(); - let assigned_leaf_paths = fr.assigned_leaf_paths(); - - let mut fragment_infos = Vec::with_capacity(moved_leaf_paths.len()); - - let find_var_id = |move_path_index: MovePathIndex| -> Option { - let lp = move_data.path_loan_path(move_path_index); - match lp.kind { - LpVar(var_id) => Some(var_id), - LpUpvar(ty::UpvarId { var_id, closure_expr_id }) => { - // The `var_id` is unique *relative to* the current function. - // (Check that we are indeed talking about the same function.) - assert_eq!(id, closure_expr_id); - Some(var_id) - } - LpDowncast(..) | LpExtend(..) => { - // This simple implementation of non-zeroing move does - // not attempt to deal with tracking substructure - // accurately in the general case. - None - } - } - }; - - let moves = move_data.moves.borrow(); - for &move_path_index in moved_leaf_paths { - let var_id = match find_var_id(move_path_index) { - None => continue, - Some(var_id) => var_id, - }; - - move_data.each_applicable_move(move_path_index, |move_index| { - let info = ty::FragmentInfo::Moved { - var: var_id, - move_expr: moves[move_index.get()].id, - }; - debug!("fragment_infos push({:?} \ - due to move_path_index: {} move_index: {}", - info, move_path_index.get(), move_index.get()); - fragment_infos.push(info); - true - }); - } - - for &move_path_index in assigned_leaf_paths { - let var_id = match find_var_id(move_path_index) { - None => continue, - Some(var_id) => var_id, - }; - - let var_assigns = move_data.var_assignments.borrow(); - for var_assign in var_assigns.iter() - .filter(|&assign| assign.path == move_path_index) - { - let info = ty::FragmentInfo::Assigned { - var: var_id, - assign_expr: var_assign.id, - assignee_id: var_assign.assignee_id, - }; - debug!("fragment_infos push({:?} due to var_assignment", info); - fragment_infos.push(info); - } - } - - let mut fraginfo_map = this.tcx.fragment_infos.borrow_mut(); - let fn_did = this.tcx.hir.local_def_id(id); - let prev = fraginfo_map.insert(fn_did, fragment_infos); - assert!(prev.is_none()); -} - -pub struct FragmentSets { - /// During move_data construction, `moved_leaf_paths` tracks paths - /// that have been used directly by being moved out of. When - /// move_data construction has been completed, `moved_leaf_paths` - /// tracks such paths that are *leaf fragments* (e.g. `a.j` if we - /// never move out any child like `a.j.x`); any parent paths - /// (e.g. `a` for the `a.j` example) are moved over to - /// `parents_of_fragments`. - moved_leaf_paths: Vec, - - /// `assigned_leaf_paths` tracks paths that have been used - /// directly by being overwritten, but is otherwise much like - /// `moved_leaf_paths`. - assigned_leaf_paths: Vec, - - /// `parents_of_fragments` tracks paths that are definitely - /// parents of paths that have been moved. - /// - /// FIXME(pnkfelix) probably do not want/need - /// `parents_of_fragments` at all, if we can avoid it. - /// - /// Update: I do not see a way to avoid it. Maybe just remove - /// above fixme, or at least document why doing this may be hard. - parents_of_fragments: Vec, - - /// During move_data construction (specifically the - /// fixup_fragment_sets call), `unmoved_fragments` tracks paths - /// that have been "left behind" after a sibling has been moved or - /// assigned. When move_data construction has been completed, - /// `unmoved_fragments` tracks paths that were *only* results of - /// being left-behind, and never directly moved themselves. - unmoved_fragments: Vec, -} - -impl FragmentSets { - pub fn new() -> FragmentSets { - FragmentSets { - unmoved_fragments: Vec::new(), - moved_leaf_paths: Vec::new(), - assigned_leaf_paths: Vec::new(), - parents_of_fragments: Vec::new(), - } - } - - pub fn moved_leaf_paths(&self) -> &[MovePathIndex] { - &self.moved_leaf_paths - } - - pub fn assigned_leaf_paths(&self) -> &[MovePathIndex] { - &self.assigned_leaf_paths - } - - pub fn add_move(&mut self, path_index: MovePathIndex) { - self.moved_leaf_paths.push(path_index); - } - - pub fn add_assignment(&mut self, path_index: MovePathIndex) { - self.assigned_leaf_paths.push(path_index); - } -} - -pub fn instrument_move_fragments<'a, 'tcx>(this: &MoveData<'tcx>, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - id: ast::NodeId) { - let span_err = tcx.hir.attrs(id).iter() - .any(|a| a.check_name("rustc_move_fragments")); - let print = tcx.sess.opts.debugging_opts.print_move_fragments; - - if !span_err && !print { return; } - - let sp = tcx.hir.span(id); - - let instrument_all_paths = |kind, vec_rc: &Vec| { - for (i, mpi) in vec_rc.iter().enumerate() { - let lp = || this.path_loan_path(*mpi); - if span_err { - tcx.sess.span_err(sp, &format!("{}: `{}`", kind, lp())); - } - if print { - println!("id:{} {}[{}] `{}`", id, kind, i, lp()); - } - } - }; - - let instrument_all_fragments = |kind, vec_rc: &Vec| { - for (i, f) in vec_rc.iter().enumerate() { - let render = || f.loan_path_user_string(this); - if span_err { - tcx.sess.span_err(sp, &format!("{}: `{}`", kind, render())); - } - if print { - println!("id:{} {}[{}] `{}`", id, kind, i, render()); - } - } - }; - - let fragments = this.fragments.borrow(); - instrument_all_paths("moved_leaf_path", &fragments.moved_leaf_paths); - instrument_all_fragments("unmoved_fragment", &fragments.unmoved_fragments); - instrument_all_paths("parent_of_fragments", &fragments.parents_of_fragments); - instrument_all_paths("assigned_leaf_path", &fragments.assigned_leaf_paths); -} - -/// Normalizes the fragment sets in `this`; i.e., removes duplicate entries, constructs the set of -/// parents, and constructs the left-over fragments. -/// -/// Note: "left-over fragments" means paths that were not directly referenced in moves nor -/// assignments, but must nonetheless be tracked as potential drop obligations. -pub fn fixup_fragment_sets<'a, 'tcx>(this: &MoveData<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>) { - - let mut fragments = this.fragments.borrow_mut(); - - // Swap out contents of fragments so that we can modify the fields - // without borrowing the common fragments. - let mut unmoved = mem::replace(&mut fragments.unmoved_fragments, vec![]); - let mut parents = mem::replace(&mut fragments.parents_of_fragments, vec![]); - let mut moved = mem::replace(&mut fragments.moved_leaf_paths, vec![]); - let mut assigned = mem::replace(&mut fragments.assigned_leaf_paths, vec![]); - - let path_lps = |mpis: &[MovePathIndex]| -> Vec { - mpis.iter().map(|mpi| format!("{:?}", this.path_loan_path(*mpi))).collect() - }; - - let frag_lps = |fs: &[Fragment]| -> Vec { - fs.iter().map(|f| f.loan_path_repr(this)).collect() - }; - - // First, filter out duplicates - moved.sort(); - moved.dedup(); - debug!("fragments 1 moved: {:?}", path_lps(&moved)); - - assigned.sort(); - assigned.dedup(); - debug!("fragments 1 assigned: {:?}", path_lps(&assigned)); - - // Second, build parents from the moved and assigned. - for m in &moved { - let mut p = this.path_parent(*m); - while p != InvalidMovePathIndex { - parents.push(p); - p = this.path_parent(p); - } - } - for a in &assigned { - let mut p = this.path_parent(*a); - while p != InvalidMovePathIndex { - parents.push(p); - p = this.path_parent(p); - } - } - - parents.sort(); - parents.dedup(); - debug!("fragments 2 parents: {:?}", path_lps(&parents)); - - // Third, filter the moved and assigned fragments down to just the non-parents - moved.retain(|f| non_member(*f, &parents)); - debug!("fragments 3 moved: {:?}", path_lps(&moved)); - - assigned.retain(|f| non_member(*f, &parents)); - debug!("fragments 3 assigned: {:?}", path_lps(&assigned)); - - // Fourth, build the leftover from the moved, assigned, and parents. - for m in &moved { - let lp = this.path_loan_path(*m); - add_fragment_siblings(this, tcx, &mut unmoved, lp, None); - } - for a in &assigned { - let lp = this.path_loan_path(*a); - add_fragment_siblings(this, tcx, &mut unmoved, lp, None); - } - for p in &parents { - let lp = this.path_loan_path(*p); - add_fragment_siblings(this, tcx, &mut unmoved, lp, None); - } - - unmoved.sort(); - unmoved.dedup(); - debug!("fragments 4 unmoved: {:?}", frag_lps(&unmoved)); - - // Fifth, filter the leftover fragments down to its core. - unmoved.retain(|f| match *f { - AllButOneFrom(_) => true, - Just(mpi) => non_member(mpi, &parents) && - non_member(mpi, &moved) && - non_member(mpi, &assigned) - }); - debug!("fragments 5 unmoved: {:?}", frag_lps(&unmoved)); - - // Swap contents back in. - fragments.unmoved_fragments = unmoved; - fragments.parents_of_fragments = parents; - fragments.moved_leaf_paths = moved; - fragments.assigned_leaf_paths = assigned; - - return; - - fn non_member(elem: MovePathIndex, set: &[MovePathIndex]) -> bool { - match set.binary_search(&elem) { - Ok(_) => false, - Err(_) => true, - } - } -} - -/// Adds all of the precisely-tracked siblings of `lp` as potential move paths of interest. For -/// example, if `lp` represents `s.x.j`, then adds moves paths for `s.x.i` and `s.x.k`, the -/// siblings of `s.x.j`. -fn add_fragment_siblings<'a, 'tcx>(this: &MoveData<'tcx>, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - gathered_fragments: &mut Vec, - lp: Rc>, - origin_id: Option) { - match lp.kind { - LpVar(_) | LpUpvar(..) => {} // Local variables have no siblings. - - // Consuming a downcast is like consuming the original value, so propage inward. - LpDowncast(ref loan_parent, _) => { - add_fragment_siblings(this, tcx, gathered_fragments, loan_parent.clone(), origin_id); - } - - // *LV for Unique consumes the contents of the box (at - // least when it is non-copy...), so propagate inward. - LpExtend(ref loan_parent, _, LpDeref(mc::Unique)) => { - add_fragment_siblings(this, tcx, gathered_fragments, loan_parent.clone(), origin_id); - } - - // *LV for unsafe and borrowed pointers do not consume their loan path, so stop here. - LpExtend(.., LpDeref(mc::UnsafePtr(..))) | - LpExtend(.., LpDeref(mc::Implicit(..))) | - LpExtend(.., LpDeref(mc::BorrowedPtr(..))) => {} - - // FIXME (pnkfelix): LV[j] should be tracked, at least in the - // sense of we will track the remaining drop obligation of the - // rest of the array. - // - // Well, either that or LV[j] should be made illegal. - // But even then, we will need to deal with destructuring - // bind. - // - // Anyway, for now: LV[j] is not tracked precisely - LpExtend(.., LpInterior(_, InteriorElement(..))) => { - let mp = this.move_path(tcx, lp.clone()); - gathered_fragments.push(AllButOneFrom(mp)); - } - - // field access LV.x and tuple access LV#k are the cases - // we are interested in - LpExtend(ref loan_parent, mc, - LpInterior(_, InteriorField(ref field_name))) => { - let enum_variant_info = match loan_parent.kind { - LpDowncast(ref loan_parent_2, variant_def_id) => - Some((variant_def_id, loan_parent_2.clone())), - LpExtend(..) | LpVar(..) | LpUpvar(..) => - None, - }; - add_fragment_siblings_for_extension( - this, - tcx, - gathered_fragments, - loan_parent, mc, field_name, &lp, origin_id, enum_variant_info); - } - } -} - -/// We have determined that `origin_lp` destructures to LpExtend(parent, original_field_name). -/// Based on this, add move paths for all of the siblings of `origin_lp`. -fn add_fragment_siblings_for_extension<'a, 'tcx>(this: &MoveData<'tcx>, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - gathered_fragments: &mut Vec, - parent_lp: &Rc>, - mc: mc::MutabilityCategory, - origin_field_name: &mc::FieldName, - origin_lp: &Rc>, - origin_id: Option, - enum_variant_info: Option<(DefId, - Rc>)>) { - let parent_ty = parent_lp.to_type(); - - let mut add_fragment_sibling_local = |field_name, variant_did| { - add_fragment_sibling_core( - this, tcx, gathered_fragments, parent_lp.clone(), mc, field_name, origin_lp, - variant_did); - }; - - match parent_ty.sty { - ty::TyTuple(ref v, _) => { - let tuple_idx = match *origin_field_name { - mc::PositionalField(tuple_idx) => tuple_idx, - mc::NamedField(_) => - bug!("tuple type {:?} should not have named fields.", - parent_ty), - }; - let tuple_len = v.len(); - for i in 0..tuple_len { - if i == tuple_idx { continue } - let field_name = mc::PositionalField(i); - add_fragment_sibling_local(field_name, None); - } - } - - ty::TyAdt(def, ..) => match def.adt_kind() { - AdtKind::Struct => { - match *origin_field_name { - mc::NamedField(ast_name) => { - for f in &def.struct_variant().fields { - if f.name == ast_name { - continue; - } - let field_name = mc::NamedField(f.name); - add_fragment_sibling_local(field_name, None); - } - } - mc::PositionalField(tuple_idx) => { - for (i, _f) in def.struct_variant().fields.iter().enumerate() { - if i == tuple_idx { - continue - } - let field_name = mc::PositionalField(i); - add_fragment_sibling_local(field_name, None); - } - } - } - } - AdtKind::Union => { - // Do nothing, all union fields are moved/assigned together. - } - AdtKind::Enum => { - let variant = match enum_variant_info { - Some((vid, ref _lp2)) => def.variant_with_id(vid), - None => { - assert!(def.is_univariant()); - &def.variants[0] - } - }; - match *origin_field_name { - mc::NamedField(ast_name) => { - for field in &variant.fields { - if field.name == ast_name { - continue; - } - let field_name = mc::NamedField(field.name); - add_fragment_sibling_local(field_name, Some(variant.did)); - } - } - mc::PositionalField(tuple_idx) => { - for (i, _f) in variant.fields.iter().enumerate() { - if tuple_idx == i { - continue; - } - let field_name = mc::PositionalField(i); - add_fragment_sibling_local(field_name, None); - } - } - } - } - }, - - ref ty => { - let span = origin_id.map_or(DUMMY_SP, |id| tcx.hir.span(id)); - span_bug!(span, - "type {:?} ({:?}) is not fragmentable", - parent_ty, ty); - } - } -} - -/// Adds the single sibling `LpExtend(parent, new_field_name)` of `origin_lp` (the original -/// loan-path). -fn add_fragment_sibling_core<'a, 'tcx>(this: &MoveData<'tcx>, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - gathered_fragments: &mut Vec, - parent: Rc>, - mc: mc::MutabilityCategory, - new_field_name: mc::FieldName, - origin_lp: &Rc>, - enum_variant_did: Option) - -> MovePathIndex { - let opt_variant_did = match parent.kind { - LpDowncast(_, variant_did) => Some(variant_did), - LpVar(..) | LpUpvar(..) | LpExtend(..) => enum_variant_did, - }; - - let loan_path_elem = LpInterior(opt_variant_did, InteriorField(new_field_name)); - let new_lp_type = match new_field_name { - mc::NamedField(ast_name) => - tcx.named_element_ty(parent.to_type(), ast_name, opt_variant_did), - mc::PositionalField(idx) => - tcx.positional_element_ty(parent.to_type(), idx, opt_variant_did), - }; - let new_lp_variant = LpExtend(parent, mc, loan_path_elem); - let new_lp = LoanPath::new(new_lp_variant, new_lp_type.unwrap()); - debug!("add_fragment_sibling_core(new_lp={:?}, origin_lp={:?})", - new_lp, origin_lp); - let mp = this.move_path(tcx, Rc::new(new_lp)); - - // Do not worry about checking for duplicates here; we will sort - // and dedup after all are added. - gathered_fragments.push(Just(mp)); - - mp -} diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index f7c20542cbf2e..ff5ebb9c1dc5d 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -129,13 +129,6 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) { move_data: flowed_moves } = build_borrowck_dataflow_data(bccx, &cfg, body_id); - move_data::fragments::instrument_move_fragments(&flowed_moves.move_data, - bccx.tcx, - owner_id); - move_data::fragments::build_unfragmented_map(bccx, - &flowed_moves.move_data, - owner_id); - check_loans::check_loans(bccx, &loan_dfcx, &flowed_moves, &all_loans, body); } diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index 3e23086ec7bdd..1b364596a23f7 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -33,9 +33,6 @@ use syntax_pos::Span; use rustc::hir; use rustc::hir::intravisit::IdRange; -#[path="fragments.rs"] -pub mod fragments; - pub struct MoveData<'tcx> { /// Move paths. See section "Move paths" in `README.md`. pub paths: RefCell>>, @@ -62,9 +59,6 @@ pub struct MoveData<'tcx> { /// Assignments to a variable or path, like `x = foo`, but not `x += foo`. pub assignee_ids: RefCell, - - /// Path-fragments from moves in to or out of parts of structured data. - pub fragments: RefCell, } pub struct FlowedMoveData<'a, 'tcx: 'a> { @@ -223,7 +217,6 @@ impl<'a, 'tcx> MoveData<'tcx> { var_assignments: RefCell::new(Vec::new()), variant_matches: RefCell::new(Vec::new()), assignee_ids: RefCell::new(NodeSet()), - fragments: RefCell::new(fragments::FragmentSets::new()), } } @@ -401,8 +394,6 @@ impl<'a, 'tcx> MoveData<'tcx> { let path_index = self.move_path(tcx, lp.clone()); let move_index = MoveIndex(self.moves.borrow().len()); - self.fragments.borrow_mut().add_move(path_index); - let next_move = self.path_first_move(path_index); self.set_path_first_move(path_index, move_index); @@ -458,8 +449,6 @@ impl<'a, 'tcx> MoveData<'tcx> { let path_index = self.move_path(tcx, lp.clone()); - self.fragments.borrow_mut().add_assignment(path_index); - match mode { MutateMode::Init | MutateMode::JustWrite => { self.assignee_ids.borrow_mut().insert(assignee_id); @@ -502,8 +491,6 @@ impl<'a, 'tcx> MoveData<'tcx> { let path_index = self.move_path(tcx, lp.clone()); let base_path_index = self.move_path(tcx, base_lp.clone()); - self.fragments.borrow_mut().add_assignment(path_index); - let variant_match = VariantMatch { path: path_index, base_path: base_path_index, @@ -514,10 +501,6 @@ impl<'a, 'tcx> MoveData<'tcx> { self.variant_matches.borrow_mut().push(variant_match); } - fn fixup_fragment_sets(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) { - fragments::fixup_fragment_sets(self, tcx) - } - /// Adds the gen/kills for the various moves and /// assignments into the provided data flow contexts. /// Moves are generated by moves and killed by assignments and @@ -677,8 +660,6 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { id_range, move_data.var_assignments.borrow().len()); - move_data.fixup_fragment_sets(tcx); - move_data.add_gen_kills(bccx, &mut dfcx_moves, &mut dfcx_assign); diff --git a/src/librustc_incremental/calculate_svh/mod.rs b/src/librustc_incremental/calculate_svh/mod.rs index c9ed9ad3c7d2d..f5727aa0a5ecc 100644 --- a/src/librustc_incremental/calculate_svh/mod.rs +++ b/src/librustc_incremental/calculate_svh/mod.rs @@ -29,10 +29,9 @@ use std::cell::RefCell; use std::hash::Hash; -use std::sync::Arc; use rustc::dep_graph::DepNode; use rustc::hir; -use rustc::hir::def_id::{LOCAL_CRATE, CRATE_DEF_INDEX, DefId}; +use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ich::{Fingerprint, StableHashingContext}; use rustc::ty::TyCtxt; @@ -155,11 +154,6 @@ impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> { // We want to incoporate these into the // SVH. } - DepNode::FileMap(..) => { - // These don't make a semantic - // difference, filter them out. - return None - } DepNode::AllLocalTraitImpls => { // These are already covered by hashing // the HIR. @@ -306,24 +300,6 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) visitor.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id), true, macro_def); } - for filemap in tcx.sess - .codemap() - .files_untracked() - .iter() - .filter(|fm| !fm.is_imported()) { - assert_eq!(LOCAL_CRATE.as_u32(), filemap.crate_of_origin); - let def_id = DefId { - krate: LOCAL_CRATE, - index: CRATE_DEF_INDEX, - }; - let name = Arc::new(filemap.name.clone()); - let dep_node = DepNode::FileMap(def_id, name); - let mut hasher = IchHasher::new(); - filemap.hash_stable(&mut visitor.hcx, &mut hasher); - let fingerprint = hasher.finish(); - visitor.hashes.insert(dep_node, fingerprint); - } - visitor.compute_and_store_ich_for_trait_impls(krate); }); diff --git a/src/librustc_incremental/persist/hash.rs b/src/librustc_incremental/persist/hash.rs index 2f727a80f016e..6ab280be470dd 100644 --- a/src/librustc_incremental/persist/hash.rs +++ b/src/librustc_incremental/persist/hash.rs @@ -51,8 +51,7 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { match *dep_node { DepNode::Krate | DepNode::Hir(_) | - DepNode::HirBody(_) | - DepNode::FileMap(..) => + DepNode::HirBody(_) => true, DepNode::MetaData(def_id) | DepNode::GlobalMetaData(def_id, _) => !def_id.is_local(), @@ -77,20 +76,6 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { Some(self.incremental_hashes_map[dep_node]) } - DepNode::FileMap(def_id, ref name) => { - if def_id.is_local() { - // We will have been able to retrace the DefId (which is - // always the local CRATE_DEF_INDEX), but the file with the - // given name might have been removed, so we use get() in - // order to allow for that case. - self.incremental_hashes_map.get(dep_node).map(|x| *x) - } else { - Some(self.metadata_hash(DepNode::FileMap(def_id, name.clone()), - def_id.krate, - |this| &mut this.global_metadata_hashes)) - } - } - // MetaData from other crates is an *input* to us. // MetaData nodes from *our* crates are an *output*; we // don't hash them, but we do compute a hash for them and @@ -242,7 +227,6 @@ impl<'a, 'tcx> HashContext<'a, 'tcx> { let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX }; let dep_node = match dep_node { DepNode::GlobalMetaData(_, kind) => DepNode::GlobalMetaData(def_id, kind), - DepNode::FileMap(_, name) => DepNode::FileMap(def_id, name), other => { bug!("unexpected DepNode variant: {:?}", other) } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 07c475949d435..a02a82dfe69a6 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -18,7 +18,7 @@ use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary, use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LOCAL_CRATE}; use rustc::hir::map::definitions::DefPathTable; use rustc::dep_graph::{DepNode, GlobalMetaDataKind}; -use rustc::ich::{StableHashingContext, Fingerprint}; +use rustc::ich::Fingerprint; use rustc::middle::dependency_format::Linkage; use rustc::middle::lang_items; use rustc::mir; @@ -29,7 +29,6 @@ use rustc::session::config::{self, CrateTypeProcMacro}; use rustc::util::nodemap::{FxHashMap, NodeSet}; use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque}; -use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; use std::hash::Hash; use std::intrinsics; @@ -37,7 +36,6 @@ use std::io::prelude::*; use std::io::Cursor; use std::path::Path; use std::rc::Rc; -use std::sync::Arc; use std::u32; use syntax::ast::{self, CRATE_NODE_ID}; use syntax::codemap::Spanned; @@ -284,7 +282,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let codemap = self.tcx.sess.codemap(); let all_filemaps = codemap.files(); - let hcx = &mut StableHashingContext::new(self.tcx); let (working_dir, working_dir_was_remapped) = self.tcx.sess.working_dir.clone(); let adapted = all_filemaps.iter() @@ -316,21 +313,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { adapted.name = abs_path; Rc::new(adapted) } - }); - - let filemaps: Vec<_> = if self.compute_ich { - adapted.inspect(|filemap| { - let mut hasher = StableHasher::new(); - filemap.hash_stable(hcx, &mut hasher); - let fingerprint = hasher.finish(); - let dep_node = DepNode::FileMap((), Arc::new(filemap.name.clone())); - self.metadata_hashes.global_hashes.push((dep_node, fingerprint)); - }).collect() - } else { - adapted.collect() - }; + }) + .collect::>(); - self.lazy_seq_ref(filemaps.iter().map(|fm| &**fm)) + self.lazy_seq_ref(adapted.iter().map(|rc| &**rc)) } fn encode_crate_root(&mut self) -> Lazy { diff --git a/src/librustc_metadata/isolated_encoder.rs b/src/librustc_metadata/isolated_encoder.rs index 7722a7b10c996..ed1680fbfaee8 100644 --- a/src/librustc_metadata/isolated_encoder.rs +++ b/src/librustc_metadata/isolated_encoder.rs @@ -35,7 +35,17 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { tcx: tcx, ecx: ecx, hcx: if compute_ich { - Some((StableHashingContext::new(tcx), StableHasher::new())) + // We are always hashing spans for things in metadata because + // don't know if a downstream crate will use them or not. + // Except when -Zquery-dep-graph is specified because we don't + // want to mess up our tests. + let hcx = if tcx.sess.opts.debugging_opts.query_dep_graph { + StableHashingContext::new(tcx) + } else { + StableHashingContext::new(tcx).force_span_hashing() + }; + + Some((hcx, StableHasher::new())) } else { None } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index c228fc6b24abd..883a0a9d88a1c 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -76,7 +76,6 @@ use rustc::ty::relate::RelateResult; use rustc::ty::subst::Subst; use errors::DiagnosticBuilder; use syntax::abi; -use syntax::feature_gate; use syntax::ptr::P; use syntax_pos; @@ -614,14 +613,6 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { let node_id_a = self.tcx.hir.as_local_node_id(def_id_a).unwrap(); match b.sty { ty::TyFnPtr(_) if self.tcx.with_freevars(node_id_a, |v| v.is_empty()) => { - if !self.tcx.sess.features.borrow().closure_to_fn_coercion { - feature_gate::emit_feature_err(&self.tcx.sess.parse_sess, - "closure_to_fn_coercion", - self.cause.span, - feature_gate::GateIssue::Language, - feature_gate::CLOSURE_TO_FN_COERCION); - return self.unify_and(a, b, identity()); - } // We coerce the closure, which has fn type // `extern "rust-call" fn((arg0,arg1,...)) -> _` // to diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index f9ebe3fff5beb..18f33dc22e743 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4078,7 +4078,7 @@ register_diagnostics! { // E0217, // ambiguous associated type, defined in multiple supertraits // E0218, // no associated type defined // E0219, // associated type defined in higher-ranked supertrait -// E0222, // Error code E0045 (variadic function must have C calling +// E0222, // Error code E0045 (variadic function must have C or cdecl calling // convention) duplicate E0224, // at least one non-builtin train is required for an object type E0227, // ambiguous lifetime bound, explicit lifetime bound required diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 6f2c73b892567..699b5f330d457 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -141,11 +141,10 @@ fn require_c_abi_if_variadic(tcx: TyCtxt, decl: &hir::FnDecl, abi: Abi, span: Span) { - if decl.variadic && abi != Abi::C { + if decl.variadic && !(abi == Abi::C || abi == Abi::Cdecl) { let mut err = struct_span_err!(tcx.sess, span, E0045, - "variadic function must have C calling convention"); - err.span_label(span, "variadics require C calling conventions") - .emit(); + "variadic function must have C or cdecl calling convention"); + err.span_label(span, "variadics require C or cdecl calling convention").emit(); } } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index d32c3ec5f46b1..bbe5bd4a10cf1 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -103,18 +103,11 @@ impl FileLoader for RealFileLoader { // pub struct CodeMap { - // The `files` field should not be visible outside of libsyntax so that we - // can do proper dependency tracking. pub(super) files: RefCell>>, file_loader: Box, // This is used to apply the file path remapping as specified via // -Zremap-path-prefix to all FileMaps allocated within this CodeMap. path_mapping: FilePathMapping, - // The CodeMap will invoke this callback whenever a specific FileMap is - // accessed. The callback starts out as a no-op but when the dependency - // graph becomes available later during the compilation process, it is - // be replaced with something that notifies the dep-tracking system. - dep_tracking_callback: RefCell>, } impl CodeMap { @@ -123,7 +116,6 @@ impl CodeMap { files: RefCell::new(Vec::new()), file_loader: Box::new(RealFileLoader), path_mapping: path_mapping, - dep_tracking_callback: RefCell::new(Box::new(|_| {})), } } @@ -134,7 +126,6 @@ impl CodeMap { files: RefCell::new(Vec::new()), file_loader: file_loader, path_mapping: path_mapping, - dep_tracking_callback: RefCell::new(Box::new(|_| {})), } } @@ -142,10 +133,6 @@ impl CodeMap { &self.path_mapping } - pub fn set_dep_tracking_callback(&self, cb: Box) { - *self.dep_tracking_callback.borrow_mut() = cb; - } - pub fn file_exists(&self, path: &Path) -> bool { self.file_loader.file_exists(path) } @@ -156,15 +143,6 @@ impl CodeMap { } pub fn files(&self) -> Ref>> { - let files = self.files.borrow(); - for file in files.iter() { - (self.dep_tracking_callback.borrow())(file); - } - files - } - - /// Only use this if you do your own dependency tracking! - pub fn files_untracked(&self) -> Ref>> { self.files.borrow() } @@ -311,8 +289,6 @@ impl CodeMap { let files = self.files.borrow(); let f = (*files)[idx].clone(); - (self.dep_tracking_callback.borrow())(&f); - match f.lookup_line(pos) { Some(line) => Ok(FileMapAndLine { fm: f, line: line }), None => Err(f) @@ -502,7 +478,6 @@ impl CodeMap { pub fn get_filemap(&self, filename: &str) -> Option> { for fm in self.files.borrow().iter() { if filename == fm.name { - (self.dep_tracking_callback.borrow())(fm); return Some(fm.clone()); } } @@ -513,7 +488,6 @@ impl CodeMap { pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos { let idx = self.lookup_filemap_idx(bpos); let fm = (*self.files.borrow())[idx].clone(); - (self.dep_tracking_callback.borrow())(&fm); let offset = bpos - fm.start_pos; FileMapAndBytePos {fm: fm, pos: offset} } @@ -524,8 +498,6 @@ impl CodeMap { let files = self.files.borrow(); let map = &(*files)[idx]; - (self.dep_tracking_callback.borrow())(map); - // The number of extra bytes due to multibyte chars in the FileMap let mut total_extra_bytes = 0; diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index a9252d0818e38..15042e529e51a 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -84,6 +84,12 @@ impl TTMacroExpander for MacroRulesMacroExpander { } } +fn trace_macros_note(cx: &mut ExtCtxt, sp: Span, message: String) { + let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp); + let mut values: &mut Vec = cx.expansions.entry(sp).or_insert_with(Vec::new); + values.push(message); +} + /// Given `lhses` and `rhses`, this is the new macro we create fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, sp: Span, @@ -93,9 +99,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, rhses: &[quoted::TokenTree]) -> Box { if cx.trace_macros() { - let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp); - let mut values: &mut Vec = cx.expansions.entry(sp).or_insert_with(Vec::new); - values.push(format!("expands to `{}! {{ {} }}`", name, arg)); + trace_macros_note(cx, sp, format!("expanding `{}! {{ {} }}`", name, arg)); } // Which arm's failure should we report? (the one furthest along) @@ -117,6 +121,11 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, }; // rhs has holes ( `$id` and `$(...)` that need filled) let tts = transcribe(&cx.parse_sess.span_diagnostic, Some(named_matches), rhs); + + if cx.trace_macros() { + trace_macros_note(cx, sp, format!("to `{}`", tts)); + } + let directory = Directory { path: cx.current_expansion.module.directory.clone(), ownership: cx.current_expansion.directory_ownership, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c119fad1b736e..b2f52d11db2b1 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -321,9 +321,6 @@ declare_features! ( // `extern "msp430-interrupt" fn()` (active, abi_msp430_interrupt, "1.16.0", Some(38487)), - // Coerces non capturing closures to function pointers - (active, closure_to_fn_coercion, "1.17.0", Some(39817)), - // Used to identify crates that contain sanitizer runtimes // rustc internal (active, sanitizer_runtime, "1.17.0", None), @@ -427,6 +424,8 @@ declare_features! ( (accepted, loop_break_value, "1.19.0", Some(37339)), // Permits numeric fields in struct expressions and patterns. (accepted, relaxed_adts, "1.19.0", Some(35626)), + // Coerces non capturing closures to function pointers + (accepted, closure_to_fn_coercion, "1.19.0", Some(39817)), ); // If you change this, please modify src/doc/unstable-book as well. You must @@ -665,12 +664,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "rustc_attrs", "internal rustc attributes will never be stable", cfg_fn!(rustc_attrs))), - ("rustc_move_fragments", Normal, Gated(Stability::Unstable, - "rustc_attrs", - "the `#[rustc_move_fragments]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), ("rustc_mir", Whitelisted, Gated(Stability::Unstable, "rustc_attrs", "the `#[rustc_mir]` attribute \ @@ -1026,9 +1019,6 @@ pub const EXPLAIN_VIS_MATCHER: &'static str = pub const EXPLAIN_PLACEMENT_IN: &'static str = "placement-in expression syntax is experimental and subject to change."; -pub const CLOSURE_TO_FN_COERCION: &'static str = - "non-capturing closure to fn coercion is experimental"; - struct PostExpansionVisitor<'a> { context: &'a Context<'a>, } diff --git a/src/test/compile-fail/E0045.rs b/src/test/compile-fail/E0045.rs index a3fea8e0db299..3f098861eb60c 100644 --- a/src/test/compile-fail/E0045.rs +++ b/src/test/compile-fail/E0045.rs @@ -9,7 +9,7 @@ // except according to those terms. extern "Rust" { fn foo(x: u8, ...); } //~ ERROR E0045 - //~| NOTE variadics require C calling conventions + //~| NOTE variadics require C or cdecl calling convention fn main() { } diff --git a/src/test/compile-fail/feature-gate-closure_to_fn_coercion.rs b/src/test/compile-fail/feature-gate-closure_to_fn_coercion.rs deleted file mode 100644 index d074a35628ea8..0000000000000 --- a/src/test/compile-fail/feature-gate-closure_to_fn_coercion.rs +++ /dev/null @@ -1,45 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-stage0: new feature, remove this when SNAP -// revisions: a b - -#[cfg(a)] -mod a { - const FOO: fn(u8) -> u8 = |v: u8| { v }; - //[a]~^ ERROR non-capturing closure to fn coercion is experimental - //[a]~^^ ERROR mismatched types - - const BAR: [fn(&mut u32); 1] = [ - |v: &mut u32| *v += 1, - //[a]~^ ERROR non-capturing closure to fn coercion is experimental - //[a]~^^ ERROR mismatched types - ]; -} - -#[cfg(b)] -mod b { - fn func_specific() -> (fn() -> u32) { - || return 42 - //[b]~^ ERROR non-capturing closure to fn coercion is experimental - //[b]~^^ ERROR mismatched types - } - fn foo() { - // Items - assert_eq!(func_specific()(), 42); - let foo: fn(u8) -> u8 = |v: u8| { v }; - //[b]~^ ERROR non-capturing closure to fn coercion is experimental - //[b]~^^ ERROR mismatched types - } - -} - - - diff --git a/src/test/compile-fail/feature-gate-rustc-attrs.rs b/src/test/compile-fail/feature-gate-rustc-attrs.rs index bb5b70829a163..8cfd3e020c69a 100644 --- a/src/test/compile-fail/feature-gate-rustc-attrs.rs +++ b/src/test/compile-fail/feature-gate-rustc-attrs.rs @@ -14,7 +14,6 @@ #[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable #[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable -#[rustc_move_fragments] //~ ERROR the `#[rustc_move_fragments]` attribute is just used for rustc unit tests and will never be stable #[rustc_foo] //~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics diff --git a/src/test/compile-fail/issue-39974.rs b/src/test/compile-fail/issue-39974.rs new file mode 100644 index 0000000000000..6f6b775a2a3c6 --- /dev/null +++ b/src/test/compile-fail/issue-39974.rs @@ -0,0 +1,21 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const LENGTH: f64 = 2; + +struct Thing { + f: [[f64; 2]; LENGTH], + //~^ ERROR mismatched types + //~| expected usize, found f64 +} + +fn main() { + let _t = Thing { f: [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]] }; +} diff --git a/src/test/compile-fail/issue-40000.rs b/src/test/compile-fail/issue-40000.rs index 3ccee0f12becb..7daf4bcbaa44b 100644 --- a/src/test/compile-fail/issue-40000.rs +++ b/src/test/compile-fail/issue-40000.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(closure_to_fn_coercion)] - fn main() { let bar: fn(&mut u32) = |_| {}; diff --git a/src/test/compile-fail/move-fragments-1.rs b/src/test/compile-fail/move-fragments-1.rs deleted file mode 100644 index 0219f5b6becb3..0000000000000 --- a/src/test/compile-fail/move-fragments-1.rs +++ /dev/null @@ -1,58 +0,0 @@ -// 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. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we correctly compute the move fragments for a fn. -// -// Note that the code below is not actually incorrect; the -// `rustc_move_fragments` attribute is a hack that uses the error -// reporting mechanisms as a channel for communicating from the -// internals of the compiler. - -// These are all fairly trivial cases: unused variables or direct -// drops of substructure. - -#![feature(rustc_attrs)] - -pub struct D { d: isize } -impl Drop for D { fn drop(&mut self) { } } - -#[rustc_move_fragments] -pub fn test_noop() { -} - -#[rustc_move_fragments] -pub fn test_take(_x: D) { - //~^ ERROR assigned_leaf_path: `$(local _x)` -} - -pub struct Pair { x: X, y: Y } - -#[rustc_move_fragments] -pub fn test_take_struct(_p: Pair) { - //~^ ERROR assigned_leaf_path: `$(local _p)` -} - -#[rustc_move_fragments] -pub fn test_drop_struct_part(p: Pair) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR moved_leaf_path: `$(local p).x` - //~| ERROR unmoved_fragment: `$(local p).y` - drop(p.x); -} - -#[rustc_move_fragments] -pub fn test_drop_tuple_part(p: (D, D)) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR moved_leaf_path: `$(local p).#0` - //~| ERROR unmoved_fragment: `$(local p).#1` - drop(p.0); -} - -pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-2.rs b/src/test/compile-fail/move-fragments-2.rs deleted file mode 100644 index 15c28ec2713e9..0000000000000 --- a/src/test/compile-fail/move-fragments-2.rs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2014-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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we correctly compute the move fragments for a fn. -// -// Note that the code below is not actually incorrect; the -// `rustc_move_fragments` attribute is a hack that uses the error -// reporting mechanisms as a channel for communicating from the -// internals of the compiler. - -// These are checking that enums are tracked; note that their output -// paths include "downcasts" of the path to a particular enum. - -#![feature(rustc_attrs)] - -use self::Lonely::{Zero, One, Two}; - -pub struct D { d: isize } -impl Drop for D { fn drop(&mut self) { } } - -pub enum Lonely { Zero, One(X), Two(X, Y) } - -#[rustc_move_fragments] -pub fn test_match_partial(p: Lonely) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR assigned_leaf_path: `($(local p) as Lonely::Zero)` - match p { - Zero => {} - _ => {} - } -} - -#[rustc_move_fragments] -pub fn test_match_full(p: Lonely) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR assigned_leaf_path: `($(local p) as Lonely::Zero)` - //~| ERROR assigned_leaf_path: `($(local p) as Lonely::One)` - //~| ERROR assigned_leaf_path: `($(local p) as Lonely::Two)` - match p { - Zero => {} - One(..) => {} - Two(..) => {} - } -} - -#[rustc_move_fragments] -pub fn test_match_bind_one(p: Lonely) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR assigned_leaf_path: `($(local p) as Lonely::Zero)` - //~| ERROR parent_of_fragments: `($(local p) as Lonely::One)` - //~| ERROR moved_leaf_path: `($(local p) as Lonely::One).#0` - //~| ERROR assigned_leaf_path: `($(local p) as Lonely::Two)` - //~| ERROR assigned_leaf_path: `$(local data)` - match p { - Zero => {} - One(data) => {} - Two(..) => {} - } -} - -#[rustc_move_fragments] -pub fn test_match_bind_many(p: Lonely) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR assigned_leaf_path: `($(local p) as Lonely::Zero)` - //~| ERROR parent_of_fragments: `($(local p) as Lonely::One)` - //~| ERROR moved_leaf_path: `($(local p) as Lonely::One).#0` - //~| ERROR assigned_leaf_path: `$(local data)` - //~| ERROR parent_of_fragments: `($(local p) as Lonely::Two)` - //~| ERROR moved_leaf_path: `($(local p) as Lonely::Two).#0` - //~| ERROR moved_leaf_path: `($(local p) as Lonely::Two).#1` - //~| ERROR assigned_leaf_path: `$(local left)` - //~| ERROR assigned_leaf_path: `$(local right)` - match p { - Zero => {} - One(data) => {} - Two(left, right) => {} - } -} - -pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-3.rs b/src/test/compile-fail/move-fragments-3.rs deleted file mode 100644 index a1152333900a0..0000000000000 --- a/src/test/compile-fail/move-fragments-3.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2014-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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we correctly compute the move fragments for a fn. -// -// Note that the code below is not actually incorrect; the -// `rustc_move_fragments` attribute is a hack that uses the error -// reporting mechanisms as a channel for communicating from the -// internals of the compiler. - -// This checks the handling of `_` within variants, especially when mixed -// with bindings. - -#![feature(rustc_attrs)] - -use self::Lonely::{Zero, One, Two}; - -pub struct D { d: isize } -impl Drop for D { fn drop(&mut self) { } } - -pub enum Lonely { Zero, One(X), Two(X, Y) } - -#[rustc_move_fragments] -pub fn test_match_bind_and_underscore(p: Lonely) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR assigned_leaf_path: `($(local p) as Lonely::Zero)` - //~| ERROR assigned_leaf_path: `($(local p) as Lonely::One)` - //~| ERROR parent_of_fragments: `($(local p) as Lonely::Two)` - //~| ERROR moved_leaf_path: `($(local p) as Lonely::Two).#0` - //~| ERROR unmoved_fragment: `($(local p) as Lonely::Two).#1` - //~| ERROR assigned_leaf_path: `$(local left)` - - match p { - Zero => {} - - One(_) => {} // <-- does not fragment `($(local p) as One)` ... - - Two(left, _) => {} // <-- ... *does* fragment `($(local p) as Two)`. - } -} - -pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-4.rs b/src/test/compile-fail/move-fragments-4.rs deleted file mode 100644 index 191e23a28638b..0000000000000 --- a/src/test/compile-fail/move-fragments-4.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we correctly compute the move fragments for a fn. -// -// Note that the code below is not actually incorrect; the -// `rustc_move_fragments` attribute is a hack that uses the error -// reporting mechanisms as a channel for communicating from the -// internals of the compiler. - -// This checks that a move of deep structure is properly tracked. (An -// early draft of the code did not properly traverse up through all of -// the parents of the leaf fragment.) - -#![feature(rustc_attrs)] - -pub struct D { d: isize } -impl Drop for D { fn drop(&mut self) { } } - -pub struct Pair { x: X, y: Y } - -#[rustc_move_fragments] -pub fn test_move_substructure(pppp: Pair, D>, D>, D>) { - //~^ ERROR parent_of_fragments: `$(local pppp)` - //~| ERROR parent_of_fragments: `$(local pppp).x` - //~| ERROR parent_of_fragments: `$(local pppp).x.x` - //~| ERROR unmoved_fragment: `$(local pppp).x.x.x` - //~| ERROR moved_leaf_path: `$(local pppp).x.x.y` - //~| ERROR unmoved_fragment: `$(local pppp).x.y` - //~| ERROR unmoved_fragment: `$(local pppp).y` - drop(pppp.x.x.y); -} - -pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-5.rs b/src/test/compile-fail/move-fragments-5.rs deleted file mode 100644 index 38a385eacac5c..0000000000000 --- a/src/test/compile-fail/move-fragments-5.rs +++ /dev/null @@ -1,94 +0,0 @@ -// 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. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we correctly compute the move fragments for a fn. -// -// Note that the code below is not actually incorrect; the -// `rustc_move_fragments` attribute is a hack that uses the error -// reporting mechanisms as a channel for communicating from the -// internals of the compiler. - -// This is the first test that checks moving into local variables. - -#![feature(rustc_attrs)] - -pub struct D { d: isize } -impl Drop for D { fn drop(&mut self) { } } - -pub struct Pair { x: X, y: Y } - -#[rustc_move_fragments] -pub fn test_move_field_to_local(p: Pair) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR moved_leaf_path: `$(local p).x` - //~| ERROR unmoved_fragment: `$(local p).y` - //~| ERROR assigned_leaf_path: `$(local _x)` - let _x = p.x; -} - -#[rustc_move_fragments] -pub fn test_move_field_to_local_to_local(p: Pair) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR moved_leaf_path: `$(local p).x` - //~| ERROR unmoved_fragment: `$(local p).y` - //~| ERROR assigned_leaf_path: `$(local _x)` - //~| ERROR moved_leaf_path: `$(local _x)` - //~| ERROR assigned_leaf_path: `$(local _y)` - let _x = p.x; - let _y = _x; -} - -// In the following fn's `test_move_field_to_local_delayed` and -// `test_uninitialized_local` , the instrumentation reports that `_x` -// is moved. This is unlike `test_move_field_to_local`, where `_x` is -// just reported as an assigned_leaf_path. Presumably because this is -// how we represent that it did not have an initializing expression at -// the binding site. - -#[rustc_move_fragments] -pub fn test_uninitialized_local(_p: Pair) { - //~^ ERROR assigned_leaf_path: `$(local _p)` - //~| ERROR moved_leaf_path: `$(local _x)` - let _x: D; -} - -#[rustc_move_fragments] -pub fn test_move_field_to_local_delayed(p: Pair) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR moved_leaf_path: `$(local p).x` - //~| ERROR unmoved_fragment: `$(local p).y` - //~| ERROR assigned_leaf_path: `$(local _x)` - //~| ERROR moved_leaf_path: `$(local _x)` - let _x; - _x = p.x; -} - -#[rustc_move_fragments] -pub fn test_move_field_mut_to_local(mut p: Pair) { - //~^ ERROR parent_of_fragments: `$(local mut p)` - //~| ERROR moved_leaf_path: `$(local mut p).x` - //~| ERROR unmoved_fragment: `$(local mut p).y` - //~| ERROR assigned_leaf_path: `$(local _x)` - let _x = p.x; -} - -#[rustc_move_fragments] -pub fn test_move_field_to_local_to_local_mut(p: Pair) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR moved_leaf_path: `$(local p).x` - //~| ERROR unmoved_fragment: `$(local p).y` - //~| ERROR assigned_leaf_path: `$(local mut _x)` - //~| ERROR moved_leaf_path: `$(local mut _x)` - //~| ERROR assigned_leaf_path: `$(local _y)` - let mut _x = p.x; - let _y = _x; -} - -pub fn main() {} diff --git a/src/test/compile-fail/move-fragments-6.rs b/src/test/compile-fail/move-fragments-6.rs deleted file mode 100644 index 122727c3f6b64..0000000000000 --- a/src/test/compile-fail/move-fragments-6.rs +++ /dev/null @@ -1,61 +0,0 @@ -// 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. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we correctly compute the move fragments for a fn. -// -// Note that the code below is not actually incorrect; the -// `rustc_move_fragments` attribute is a hack that uses the error -// reporting mechanisms as a channel for communicating from the -// internals of the compiler. - -// Test that moving into a field (i.e. overwriting it) fragments the -// receiver. - -#![feature(rustc_attrs)] - -use std::mem::drop; - -pub struct Pair { x: X, y: Y } - -#[rustc_move_fragments] -pub fn test_overwrite_uninit_field(z: Z) { - //~^ ERROR parent_of_fragments: `$(local mut p)` - //~| ERROR assigned_leaf_path: `$(local z)` - //~| ERROR moved_leaf_path: `$(local z)` - //~| ERROR assigned_leaf_path: `$(local mut p).x` - //~| ERROR unmoved_fragment: `$(local mut p).y` - - let mut p: Pair; - p.x = z; -} - -#[rustc_move_fragments] -pub fn test_overwrite_moved_field(mut p: Pair, z: Z) { - //~^ ERROR parent_of_fragments: `$(local mut p)` - //~| ERROR assigned_leaf_path: `$(local z)` - //~| ERROR moved_leaf_path: `$(local z)` - //~| ERROR assigned_leaf_path: `$(local mut p).y` - //~| ERROR unmoved_fragment: `$(local mut p).x` - - drop(p); - p.y = z; -} - -#[rustc_move_fragments] -pub fn test_overwrite_same_field(mut p: Pair) { - //~^ ERROR parent_of_fragments: `$(local mut p)` - //~| ERROR moved_leaf_path: `$(local mut p).x` - //~| ERROR assigned_leaf_path: `$(local mut p).x` - //~| ERROR unmoved_fragment: `$(local mut p).y` - - p.x = p.x; -} - -pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-7.rs b/src/test/compile-fail/move-fragments-7.rs deleted file mode 100644 index a2a37208cd616..0000000000000 --- a/src/test/compile-fail/move-fragments-7.rs +++ /dev/null @@ -1,48 +0,0 @@ -// 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. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we correctly compute the move fragments for a fn. -// -// Note that the code below is not actually incorrect; the -// `rustc_move_fragments` attribute is a hack that uses the error -// reporting mechanisms as a channel for communicating from the -// internals of the compiler. - -// Test that moving a Box fragments its containing structure, for -// both moving out of the structure (i.e. reading `*p.x`) and writing -// into the container (i.e. writing `*p.x`). - -#![feature(rustc_attrs)] - -pub struct D { d: isize } -impl Drop for D { fn drop(&mut self) { } } - -pub struct Pair { x: X, y: Y } - -#[rustc_move_fragments] -pub fn test_deref_box_field(p: Pair, Box>) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR parent_of_fragments: `$(local p).x` - //~| ERROR moved_leaf_path: `$(local p).x.*` - //~| ERROR unmoved_fragment: `$(local p).y` - //~| ERROR assigned_leaf_path: `$(local i)` - let i : D = *p.x; -} - -#[rustc_move_fragments] -pub fn test_overwrite_deref_box_field(mut p: Pair, Box>) { - //~^ ERROR parent_of_fragments: `$(local mut p)` - //~| ERROR parent_of_fragments: `$(local mut p).x` - //~| ERROR assigned_leaf_path: `$(local mut p).x.*` - //~| ERROR unmoved_fragment: `$(local mut p).y` - *p.x = D { d: 3 }; -} - -pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-8.rs b/src/test/compile-fail/move-fragments-8.rs deleted file mode 100644 index e57268dbfa32a..0000000000000 --- a/src/test/compile-fail/move-fragments-8.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that we correctly compute the move fragments for a fn. -// -// Note that the code below is not actually incorrect; the -// `rustc_move_fragments` attribute is a hack that uses the error -// reporting mechanisms as a channel for communicating from the -// internals of the compiler. - -// Test that assigning into a `&T` within structured container does -// *not* fragment its containing structure. -// -// Compare against the `Box` handling in move-fragments-7.rs. Note -// also that in this case we cannot do a move out of `&T`, so we only -// test writing `*p.x` here. - -#![feature(rustc_attrs)] - -pub struct D { d: isize } -impl Drop for D { fn drop(&mut self) { } } - -pub struct Pair { x: X, y: Y } - -#[rustc_move_fragments] -pub fn test_overwrite_deref_ampersand_field<'a>(p: Pair<&'a mut D, &'a D>) { - //~^ ERROR parent_of_fragments: `$(local p)` - //~| ERROR parent_of_fragments: `$(local p).x` - //~| ERROR assigned_leaf_path: `$(local p).x.*` - //~| ERROR unmoved_fragment: `$(local p).y` - *p.x = D { d: 3 }; -} - -pub fn main() { } diff --git a/src/test/compile-fail/move-fragments-9.rs b/src/test/compile-fail/move-fragments-9.rs deleted file mode 100644 index 350f416903400..0000000000000 --- a/src/test/compile-fail/move-fragments-9.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test moving array structures, e.g. `[T; 3]` as well as moving -// elements in and out of such arrays. -// -// Note also that the `test_move_array_then_overwrite` tests represent -// cases that we probably should make illegal. - -#![feature(rustc_attrs)] - -pub struct D { d: isize } -impl Drop for D { fn drop(&mut self) { } } - -#[rustc_move_fragments] -pub fn test_move_array_via_return(a: [D; 3]) -> [D; 3] { - //~^ ERROR assigned_leaf_path: `$(local a)` - //~| ERROR moved_leaf_path: `$(local a)` - return a; -} - -#[rustc_move_fragments] -pub fn test_move_array_into_recv(a: [D; 3], recv: &mut [D; 3]) { - //~^ ERROR parent_of_fragments: `$(local recv)` - //~| ERROR assigned_leaf_path: `$(local a)` - //~| ERROR moved_leaf_path: `$(local a)` - //~| ERROR assigned_leaf_path: `$(local recv).*` - *recv = a; -} - -#[rustc_move_fragments] -pub fn test_overwrite_array_elem(mut a: [D; 3], i: usize, d: D) { - //~^ ERROR parent_of_fragments: `$(local mut a)` - //~| ERROR assigned_leaf_path: `$(local i)` - //~| ERROR assigned_leaf_path: `$(local d)` - //~| ERROR moved_leaf_path: `$(local d)` - //~| ERROR assigned_leaf_path: `$(local mut a).[]` - //~| ERROR unmoved_fragment: `$(allbutone $(local mut a).[])` - a[i] = d; -} - -pub fn main() { } diff --git a/src/test/compile-fail/variadic-ffi-2.rs b/src/test/compile-fail/variadic-ffi-2.rs index afcad9d8f9614..ec5669f639277 100644 --- a/src/test/compile-fail/variadic-ffi-2.rs +++ b/src/test/compile-fail/variadic-ffi-2.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn baz(f: extern "cdecl" fn(usize, ...)) { - //~^ ERROR: variadic function must have C calling convention +// ignore-arm stdcall isn't suppported + +fn baz(f: extern "stdcall" fn(usize, ...)) { + //~^ ERROR: variadic function must have C or cdecl calling convention f(22, 44); } diff --git a/src/test/compile-fail/variadic-ffi.rs b/src/test/compile-fail/variadic-ffi.rs index af2b552e20f14..125177efc53c7 100644 --- a/src/test/compile-fail/variadic-ffi.rs +++ b/src/test/compile-fail/variadic-ffi.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -extern "cdecl" { - fn printf(_: *const u8, ...); //~ ERROR: variadic function must have C calling convention +// ignore-arm stdcall isn't suppported + +extern "stdcall" { + fn printf(_: *const u8, ...); //~ ERROR: variadic function must have C or cdecl calling } extern { diff --git a/src/test/incremental/rlib_cross_crate/auxiliary/a.rs b/src/test/incremental/rlib_cross_crate/auxiliary/a.rs index ff5fd63471449..1099aeb921763 100644 --- a/src/test/incremental/rlib_cross_crate/auxiliary/a.rs +++ b/src/test/incremental/rlib_cross_crate/auxiliary/a.rs @@ -9,6 +9,7 @@ // except according to those terms. // no-prefer-dynamic +// compile-flags: -Z query-dep-graph #![crate_type="rlib"] diff --git a/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs b/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs index e1dba1317703d..2ae434071f2c5 100644 --- a/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs +++ b/src/test/incremental/type_alias_cross_crate/auxiliary/a.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z query-dep-graph + #![crate_type="rlib"] #[cfg(rpass1)] diff --git a/src/test/run-pass/closure-to-fn-coercion.rs b/src/test/run-pass/closure-to-fn-coercion.rs index 13d1d6aa13900..7fb26bdc9360d 100644 --- a/src/test/run-pass/closure-to-fn-coercion.rs +++ b/src/test/run-pass/closure-to-fn-coercion.rs @@ -8,10 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-stage0: new feature, remove this when SNAP - -#![feature(closure_to_fn_coercion)] - const FOO: fn(u8) -> u8 = |v: u8| { v }; const BAR: [fn(&mut u32); 5] = [ diff --git a/src/test/run-pass/closure_to_fn_coercion-expected-types.rs b/src/test/run-pass/closure_to_fn_coercion-expected-types.rs index 7214ebfaf0703..41da3089c884e 100644 --- a/src/test/run-pass/closure_to_fn_coercion-expected-types.rs +++ b/src/test/run-pass/closure_to_fn_coercion-expected-types.rs @@ -9,7 +9,6 @@ // except according to those terms. // Ensure that we deduce expected argument types when a `fn()` type is expected (#41755) -#![feature(closure_to_fn_coercion)] fn foo(f: fn(Vec) -> usize) { } fn main() { diff --git a/src/test/run-pass/issue-42210.rs b/src/test/run-pass/issue-42210.rs new file mode 100644 index 0000000000000..ecdf78cd5bdf8 --- /dev/null +++ b/src/test/run-pass/issue-42210.rs @@ -0,0 +1,29 @@ +// 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. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Regression test for #42210. + +// compile-flags: -g + +trait Foo { + fn foo() { } +} + +struct Bar; + +trait Baz { +} + +impl Foo for (Bar, Baz) { } + + +fn main() { + <(Bar, Baz) as Foo>::foo() +} diff --git a/src/test/ui/macros/trace-macro.stderr b/src/test/ui/macros/trace-macro.stderr index 09117a4ca7404..6cf3b0bd35d5e 100644 --- a/src/test/ui/macros/trace-macro.stderr +++ b/src/test/ui/macros/trace-macro.stderr @@ -4,6 +4,9 @@ note: trace_macro 14 | println!("Hello, World!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expands to `println! { "Hello, World!" }` - = note: expands to `print! { concat ! ( "Hello, World!" , "/n" ) }` + = note: expanding `println! { "Hello, World!" }` + = note: to `print ! ( concat ! ( "Hello, World!" , "/n" ) )` + = note: expanding `print! { concat ! ( "Hello, World!" , "/n" ) }` + = note: to `$crate :: io :: _print ( format_args ! ( concat ! ( "Hello, World!" , "/n" ) ) + )`