From 73389f684fed8001f16ae999b18e57f45c56439d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 7 Apr 2016 15:12:13 -0400 Subject: [PATCH 01/11] add regression test for #32505 --- src/test/parse-fail/issue-32505.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/parse-fail/issue-32505.rs diff --git a/src/test/parse-fail/issue-32505.rs b/src/test/parse-fail/issue-32505.rs new file mode 100644 index 0000000000000..e697e98bc0607 --- /dev/null +++ b/src/test/parse-fail/issue-32505.rs @@ -0,0 +1,17 @@ +// 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. + +// compile-flags: -Z parse-only -Z continue-parse-after-error + +pub fn test() { + foo(|_|) //~ ERROR unexpected token: `)` +} + +fn main() { } From 69289c93666cad424627c0d696841c8f78e96448 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 8 Apr 2016 01:56:45 +0200 Subject: [PATCH 02/11] Add doc example for Iter and IterMut --- src/libcore/slice.rs | 166 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 162 insertions(+), 4 deletions(-) diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 6e0e972fa0c83..39ef22071870f 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -38,6 +38,7 @@ use cmp::{Ordering, PartialEq, PartialOrd, Eq, Ord}; use cmp::Ordering::{Less, Equal, Greater}; use cmp; use default::Default; +use fmt; use intrinsics::assume; use iter::*; use ops::{FnMut, self, Index}; @@ -632,8 +633,7 @@ impl ops::Index> for [T] { #[inline] fn index(&self, index: ops::RangeToInclusive) -> &[T] { - // SNAP 4d3eebf change this to `0...index.end` - self.index(ops::RangeInclusive::NonEmpty { start: 0, end: index.end }) + self.index(0...index.end) } } @@ -723,8 +723,7 @@ impl ops::IndexMut> for [T] { impl ops::IndexMut> for [T] { #[inline] fn index_mut(&mut self, index: ops::RangeToInclusive) -> &mut [T] { - // SNAP 4d3eebf change this to `0...index.end` - self.index_mut(ops::RangeInclusive::NonEmpty { start: 0, end: index.end }) + self.index_mut(0...index.end) } } @@ -872,6 +871,20 @@ macro_rules! make_mut_slice { } /// Immutable slice iterator +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// // First, we declare a type which has `iter` method to get the `Iter` struct (&[usize here]): +/// let slice = &[1, 2, 3]; +/// +/// // Then, we iterate over it: +/// for element in slice.iter() { +/// println!("{}", element); +/// } +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T: 'a> { ptr: *const T, @@ -879,6 +892,15 @@ pub struct Iter<'a, T: 'a> { _marker: marker::PhantomData<&'a T>, } +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug> fmt::Debug for Iter<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("Iter") + .field(&self.as_slice()) + .finish() + } +} + #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<'a, T: Sync> Sync for Iter<'a, T> {} #[stable(feature = "rust1", since = "1.0.0")] @@ -889,6 +911,26 @@ impl<'a, T> Iter<'a, T> { /// /// This has the same lifetime as the original slice, and so the /// iterator can continue to be used while this exists. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // First, we declare a type which has the `iter` method to get the `Iter` + /// // struct (&[usize here]): + /// let slice = &[1, 2, 3]; + /// + /// // Then, we get the iterator: + /// let mut iter = slice.iter(); + /// // So if we print what `as_slice` method returns here, we have "[1, 2, 3]": + /// println!("{:?}", iter.as_slice()); + /// + /// // Next, we move to the second element of the slice: + /// iter.next(); + /// // Now `as_slice` returns "[2, 3]": + /// println!("{:?}", iter.as_slice()); + /// ``` #[stable(feature = "iter_to_slice", since = "1.4.0")] pub fn as_slice(&self) -> &'a [T] { make_slice!(self.ptr, self.end) @@ -920,6 +962,24 @@ impl<'a, T> Clone for Iter<'a, T> { } /// Mutable slice iterator. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// // First, we declare a type which has `iter_mut` method to get the `IterMut` +/// // struct (&[usize here]): +/// let mut slice = &mut [1, 2, 3]; +/// +/// // Then, we iterate over it and increment each element value: +/// for element in slice.iter_mut() { +/// *element += 1; +/// } +/// +/// // We now have "[2, 3, 4]": +/// println!("{:?}", slice); +/// ``` #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T: 'a> { ptr: *mut T, @@ -927,6 +987,15 @@ pub struct IterMut<'a, T: 'a> { _marker: marker::PhantomData<&'a mut T>, } +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug> fmt::Debug for IterMut<'a, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("IterMut") + .field(&make_slice!(self.ptr, self.end)) + .finish() + } +} + #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<'a, T: Sync> Sync for IterMut<'a, T> {} #[stable(feature = "rust1", since = "1.0.0")] @@ -939,6 +1008,35 @@ impl<'a, T> IterMut<'a, T> { /// to consume the iterator. Consider using the `Slice` and /// `SliceMut` implementations for obtaining slices with more /// restricted lifetimes that do not consume the iterator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // First, we declare a type which has `iter_mut` method to get the `IterMut` + /// // struct (&[usize here]): + /// let mut slice = &mut [1, 2, 3]; + /// + /// { + /// // Then, we get the iterator: + /// let mut iter = slice.iter_mut(); + /// // We move to next element: + /// iter.next(); + /// // So if we print what `into_slice` method returns here, we have "[2, 3]": + /// println!("{:?}", iter.into_slice()); + /// } + /// + /// // Now let's modify a value of the slice: + /// { + /// // First we get back the iterator: + /// let mut iter = slice.iter_mut(); + /// // We change the value of the first element of the slice returned by the `next` method: + /// *iter.next().unwrap() += 1; + /// } + /// // Now slice is "[2, 2, 3]": + /// println!("{:?}", slice); + /// ``` #[stable(feature = "iter_to_slice", since = "1.4.0")] pub fn into_slice(self) -> &'a mut [T] { make_mut_slice!(self.ptr, self.end) @@ -982,6 +1080,16 @@ pub struct Split<'a, T:'a, P> where P: FnMut(&T) -> bool { finished: bool } +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for Split<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Split") + .field("v", &self.v) + .field("finished", &self.finished) + .finish() + } +} + // FIXME(#19839) Remove in favor of `#[derive(Clone)]` #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T, P> Clone for Split<'a, T, P> where P: Clone + FnMut(&T) -> bool { @@ -1055,6 +1163,16 @@ pub struct SplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool { finished: bool } +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SplitMut") + .field("v", &self.v) + .field("finished", &self.finished) + .finish() + } +} + impl<'a, T, P> SplitIter for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn finish(&mut self) -> Option<&'a mut [T]> { @@ -1129,6 +1247,7 @@ impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where /// An private iterator over subslices separated by elements that /// match a predicate function, splitting at most a fixed number of /// times. +#[derive(Debug)] struct GenericSplitN { iter: I, count: usize, @@ -1164,6 +1283,15 @@ pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { inner: GenericSplitN> } +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitN<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SplitN") + .field("inner", &self.inner) + .finish() + } +} + /// An iterator over subslices separated by elements that match a /// predicate function, limited to a given number of splits, starting /// from the end of the slice. @@ -1172,6 +1300,15 @@ pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { inner: GenericSplitN> } +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitN<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("RSplitN") + .field("inner", &self.inner) + .finish() + } +} + /// An iterator over subslices separated by elements that match a predicate /// function, limited to a given number of splits. #[stable(feature = "rust1", since = "1.0.0")] @@ -1179,6 +1316,15 @@ pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { inner: GenericSplitN> } +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for SplitNMut<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SplitNMut") + .field("inner", &self.inner) + .finish() + } +} + /// An iterator over subslices separated by elements that match a /// predicate function, limited to a given number of splits, starting /// from the end of the slice. @@ -1187,6 +1333,15 @@ pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { inner: GenericSplitN> } +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitNMut<'a, T, P> where P: FnMut(&T) -> bool { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("RSplitNMut") + .field("inner", &self.inner) + .finish() + } +} + macro_rules! forward_iterator { ($name:ident: $elem:ident, $iter_of:ty) => { #[stable(feature = "rust1", since = "1.0.0")] @@ -1214,6 +1369,7 @@ forward_iterator! { SplitNMut: T, &'a mut [T] } forward_iterator! { RSplitNMut: T, &'a mut [T] } /// An iterator over overlapping subslices of length `size`. +#[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Windows<'a, T:'a> { v: &'a [T], @@ -1307,6 +1463,7 @@ impl<'a, T> ExactSizeIterator for Windows<'a, T> {} /// /// When the slice len is not evenly divided by the chunk size, the last slice /// of the iteration will be the remainder. +#[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Chunks<'a, T:'a> { v: &'a [T], @@ -1407,6 +1564,7 @@ impl<'a, T> ExactSizeIterator for Chunks<'a, T> {} /// An iterator over a slice in (non-overlapping) mutable chunks (`size` /// elements at a time). When the slice len is not evenly divided by the chunk /// size, the last slice of the iteration will be the remainder. +#[derive(Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct ChunksMut<'a, T:'a> { v: &'a mut [T], From 942d4c7e5486d28fbf852697995f8dcf804158fb Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Fri, 8 Apr 2016 08:13:29 +0300 Subject: [PATCH 03/11] Blacklist fn item types from being used with variadic functions. --- src/librustc_typeck/check/mod.rs | 21 +++++++++++++++------ src/test/compile-fail/issue-32201.rs | 22 ++++++++++++++++++++++ src/test/compile-fail/variadic-ffi-3.rs | 12 ++++++------ 3 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 src/test/compile-fail/issue-32201.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 45877d7099bbf..67b91f7838c66 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2578,24 +2578,33 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, ty::TyFloat(ast::FloatTy::F32) => { fcx.type_error_message(arg.span, |t| { - format!("can't pass an {} to variadic \ - function, cast to c_double", t) + format!("can't pass an `{}` to variadic \ + function, cast to `c_double`", t) }, arg_ty, None); } ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => { fcx.type_error_message(arg.span, |t| { - format!("can't pass {} to variadic \ - function, cast to c_int", + format!("can't pass `{}` to variadic \ + function, cast to `c_int`", t) }, arg_ty, None); } ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => { fcx.type_error_message(arg.span, |t| { - format!("can't pass {} to variadic \ - function, cast to c_uint", + format!("can't pass `{}` to variadic \ + function, cast to `c_uint`", t) }, arg_ty, None); } + ty::TyFnDef(_, _, f) => { + let ptr_ty = fcx.tcx().mk_ty(ty::TyFnPtr(f)); + let ptr_ty = fcx.infcx().resolve_type_vars_if_possible(&ptr_ty); + fcx.type_error_message(arg.span, + |t| { + format!("can't pass `{}` to variadic \ + function, cast to `{}`", t, ptr_ty) + }, arg_ty, None); + } _ => {} } } diff --git a/src/test/compile-fail/issue-32201.rs b/src/test/compile-fail/issue-32201.rs new file mode 100644 index 0000000000000..bcc53df68a323 --- /dev/null +++ b/src/test/compile-fail/issue-32201.rs @@ -0,0 +1,22 @@ +// Copyright 2016 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. + +extern { + fn foo(a: i32, ...); +} + +fn bar(_: *const u8) {} + +fn main() { + unsafe { + foo(0, bar); + //~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function, cast to `fn(*const u8)` + } +} diff --git a/src/test/compile-fail/variadic-ffi-3.rs b/src/test/compile-fail/variadic-ffi-3.rs index 1d5ebdbae3e2e..6e60562da6749 100644 --- a/src/test/compile-fail/variadic-ffi-3.rs +++ b/src/test/compile-fail/variadic-ffi-3.rs @@ -33,11 +33,11 @@ fn main() { //~| expected variadic fn //~| found non-variadic function - foo(1, 2, 3f32); //~ ERROR: can't pass an f32 to variadic function, cast to c_double - foo(1, 2, true); //~ ERROR: can't pass bool to variadic function, cast to c_int - foo(1, 2, 1i8); //~ ERROR: can't pass i8 to variadic function, cast to c_int - foo(1, 2, 1u8); //~ ERROR: can't pass u8 to variadic function, cast to c_uint - foo(1, 2, 1i16); //~ ERROR: can't pass i16 to variadic function, cast to c_int - foo(1, 2, 1u16); //~ ERROR: can't pass u16 to variadic function, cast to c_uint + foo(1, 2, 3f32); //~ ERROR: can't pass an `f32` to variadic function, cast to `c_double` + foo(1, 2, true); //~ ERROR: can't pass `bool` to variadic function, cast to `c_int` + foo(1, 2, 1i8); //~ ERROR: can't pass `i8` to variadic function, cast to `c_int` + foo(1, 2, 1u8); //~ ERROR: can't pass `u8` to variadic function, cast to `c_uint` + foo(1, 2, 1i16); //~ ERROR: can't pass `i16` to variadic function, cast to `c_int` + foo(1, 2, 1u16); //~ ERROR: can't pass `u16` to variadic function, cast to `c_uint` } } From 4d8fac078acad2944fb953359ee370eb57176d0f Mon Sep 17 00:00:00 2001 From: Alec S Date: Thu, 7 Apr 2016 23:50:37 -0500 Subject: [PATCH 04/11] Add data race to concurrency docs --- src/doc/book/concurrency.md | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/doc/book/concurrency.md b/src/doc/book/concurrency.md index ba4496b93f3a1..c179629a79a72 100644 --- a/src/doc/book/concurrency.md +++ b/src/doc/book/concurrency.md @@ -162,7 +162,7 @@ The same [ownership system](ownership.html) that helps prevent using pointers incorrectly also helps rule out data races, one of the worst kinds of concurrency bugs. -As an example, here is a Rust program that could have a data race in many +As an example, here is a Rust program that would have a data race in many languages. It will not compile: ```ignore @@ -174,7 +174,7 @@ fn main() { for i in 0..3 { thread::spawn(move || { - data[i] += 1; + data[0] += i; }); } @@ -186,7 +186,7 @@ This gives us an error: ```text 8:17 error: capture of moved value: `data` - data[i] += 1; + data[0] += i; ^~~~ ``` @@ -195,11 +195,6 @@ thread, and the thread takes ownership of the reference, we'd have three owners! `data` gets moved out of `main` in the first call to `spawn()`, so subsequent calls in the loop cannot use this variable. -Note that this specific example will not cause a data race since different array -indices are being accessed. But this can't be determined at compile time, and in -a similar situation where `i` is a constant or is random, you would have a data -race. - So, we need some type that lets us have more than one owning reference to a value. Usually, we'd use `Rc` for this, which is a reference counted type that provides shared ownership. It has some runtime bookkeeping that keeps track @@ -223,7 +218,7 @@ fn main() { // use it in a thread thread::spawn(move || { - data_ref[i] += 1; + data_ref[0] += i; }); } @@ -266,7 +261,7 @@ fn main() { for i in 0..3 { let data = data.clone(); thread::spawn(move || { - data[i] += 1; + data[0] += i; }); } @@ -281,7 +276,7 @@ And... still gives us an error. ```text :11:24 error: cannot borrow immutable borrowed content as mutable -:11 data[i] += 1; +:11 data[0] += i; ^~~~ ``` @@ -317,7 +312,7 @@ fn main() { let data = data.clone(); thread::spawn(move || { let mut data = data.lock().unwrap(); - data[i] += 1; + data[0] += i; }); } @@ -360,7 +355,7 @@ Let's examine the body of the thread more closely: # let data = data.clone(); thread::spawn(move || { let mut data = data.lock().unwrap(); - data[i] += 1; + data[0] += i; }); # } # thread::sleep(Duration::from_millis(50)); From 2944fab398155e65bd79f84f05b68195f7ca3e82 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 9 Apr 2016 01:06:57 +0000 Subject: [PATCH 05/11] Improve import resolution diagnostics --- src/librustc_resolve/resolve_imports.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 738a99fbe9200..f0e834d430325 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -539,6 +539,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { (&Failed(_), &Failed(_)) => { let resolutions = target_module.resolutions.borrow(); let names = resolutions.iter().filter_map(|(&(ref name, _), resolution)| { + if *name == source { return None; } // Never suggest the same name match *resolution.borrow() { NameResolution { binding: Some(_), .. } => Some(name), NameResolution { single_imports: SingleImports::None, .. } => None, @@ -549,9 +550,12 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { Some(name) => format!(". Did you mean to use `{}`?", name), None => "".to_owned(), }; - let msg = format!("There is no `{}` in `{}`{}", - source, - module_to_string(target_module), lev_suggestion); + let module_str = module_to_string(target_module); + let msg = if &module_str == "???" { + format!("There is no `{}` in the crate root{}", source, lev_suggestion) + } else { + format!("There is no `{}` in `{}`{}", source, module_str, lev_suggestion) + }; return Failed(Some((directive.span, msg))); } _ => (), From 178c39632616fbf07038e4c1276b6fa127c36e51 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 9 Apr 2016 01:27:36 +0000 Subject: [PATCH 06/11] Update tests --- src/test/compile-fail/use-mod-2.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/compile-fail/use-mod-2.rs b/src/test/compile-fail/use-mod-2.rs index e98224bee02f8..f2384912cdba3 100644 --- a/src/test/compile-fail/use-mod-2.rs +++ b/src/test/compile-fail/use-mod-2.rs @@ -10,10 +10,10 @@ mod foo { use self::{self}; - //~^ ERROR unresolved import `self`. There is no `self` in `???` + //~^ ERROR unresolved import `self`. There is no `self` in the crate root use super::{self}; - //~^ ERROR unresolved import `super`. There is no `super` in `???` + //~^ ERROR unresolved import `super`. There is no `super` in the crate root } fn main() {} From 44ddaa2cd53782a3e654395c136a614e0601280f Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 9 Apr 2016 01:27:46 +0000 Subject: [PATCH 07/11] Add regression test --- src/test/compile-fail/issue-32833.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/test/compile-fail/issue-32833.rs diff --git a/src/test/compile-fail/issue-32833.rs b/src/test/compile-fail/issue-32833.rs new file mode 100644 index 0000000000000..22261d98a128c --- /dev/null +++ b/src/test/compile-fail/issue-32833.rs @@ -0,0 +1,16 @@ +// Copyright 2016 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. + +use bar::Foo; //~ ERROR There is no `Foo` in `bar` [E0432] +mod bar { + use Foo; //~ ERROR There is no `Foo` in the crate root [E0432] +} + +fn main() {} From d1f28f62c7c9dcc666ebe45e0d229a11c6a22b6a Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 9 Apr 2016 02:31:03 +0000 Subject: [PATCH 08/11] Add regression test for #22146 --- src/test/compile-fail/extern-crate-visibility.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/compile-fail/extern-crate-visibility.rs b/src/test/compile-fail/extern-crate-visibility.rs index 56a41a15ab3c0..86aae47214804 100644 --- a/src/test/compile-fail/extern-crate-visibility.rs +++ b/src/test/compile-fail/extern-crate-visibility.rs @@ -30,5 +30,14 @@ fn f() { mod core {} // Check that private crates are not glob imported } +mod bar { + pub extern crate core; +} + +mod baz { + pub use bar::*; + use self::core::cell; // Check that public extern crates are glob imported +} + #[rustc_error] fn main() {} //~ ERROR compilation successful From 1707de2dcaa5c5fefff3cab2865d92c2a96d2099 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 9 Apr 2016 02:34:52 +0000 Subject: [PATCH 09/11] Add regression test for #24883 --- src/test/compile-fail/issue-24883.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/compile-fail/issue-24883.rs diff --git a/src/test/compile-fail/issue-24883.rs b/src/test/compile-fail/issue-24883.rs new file mode 100644 index 0000000000000..097f2a5630cfa --- /dev/null +++ b/src/test/compile-fail/issue-24883.rs @@ -0,0 +1,28 @@ +// Copyright 2016 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. + +#![feature(rustc_attrs)] + +mod a { + pub mod b { pub struct Foo; } + + pub mod c { + use super::b; + pub struct Bar(pub b::Foo); + } + + pub use self::c::*; +} + +#[rustc_error] +fn main() { //~ ERROR compilation successful + let _ = a::c::Bar(a::b::Foo); + let _ = a::Bar(a::b::Foo); +} From 6dd809e79246150eb828106830a4c43eee38f994 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 9 Apr 2016 02:38:50 +0000 Subject: [PATCH 10/11] Add regression test for #26930 --- src/test/compile-fail/issue-26930.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/compile-fail/issue-26930.rs diff --git a/src/test/compile-fail/issue-26930.rs b/src/test/compile-fail/issue-26930.rs new file mode 100644 index 0000000000000..6c98f3e856023 --- /dev/null +++ b/src/test/compile-fail/issue-26930.rs @@ -0,0 +1,20 @@ +// Copyright 2016 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. + +#![feature(rustc_attrs)] +#![allow(unused)] + +extern crate core; +use core as core_export; +use self::x::*; +mod x {} + +#[rustc_error] +fn main() {} //~ ERROR compilation successful From a3329f5452b20fd611537e7db1a86a9fe115008a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Mu=CC=88ller?= Date: Sat, 9 Apr 2016 14:23:11 +0200 Subject: [PATCH 11/11] Don't read past limit for in BufRead instance of Take --- src/libstd/io/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index bcce8ee6abf44..e6db558c8c4e2 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1505,6 +1505,11 @@ impl Read for Take { #[stable(feature = "rust1", since = "1.0.0")] impl BufRead for Take { fn fill_buf(&mut self) -> Result<&[u8]> { + // Don't call into inner reader at all at EOF because it may still block + if self.limit == 0 { + return Ok(&[]); + } + let buf = self.inner.fill_buf()?; let cap = cmp::min(buf.len() as u64, self.limit) as usize; Ok(&buf[..cap]) @@ -1860,9 +1865,16 @@ mod tests { Err(io::Error::new(io::ErrorKind::Other, "")) } } + impl BufRead for R { + fn fill_buf(&mut self) -> io::Result<&[u8]> { + Err(io::Error::new(io::ErrorKind::Other, "")) + } + fn consume(&mut self, _amt: usize) { } + } let mut buf = [0; 1]; assert_eq!(0, R.take(0).read(&mut buf).unwrap()); + assert_eq!(b"", R.take(0).fill_buf().unwrap()); } fn cmp_bufread(mut br1: Br1, mut br2: Br2, exp: &[u8]) {