Auto merge of #43181 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Rollup of 8 pull requests - Successful merges: #42670, #42826, #43000, #43011, #43098, #43100, #43136, #43137 - Failed merges:
This commit is contained in:
commit
f85579d4a2
@ -726,14 +726,14 @@ impl<T: Clone> Clone for Box<[T]> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[stable(feature = "box_borrow", since = "1.1.0")]
|
||||
impl<T: ?Sized> borrow::Borrow<T> for Box<T> {
|
||||
fn borrow(&self) -> &T {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[stable(feature = "box_borrow", since = "1.1.0")]
|
||||
impl<T: ?Sized> borrow::BorrowMut<T> for Box<T> {
|
||||
fn borrow_mut(&mut self) -> &mut T {
|
||||
&mut **self
|
||||
|
@ -942,7 +942,7 @@ impl<'b, T: ?Sized> Ref<'b, T> {
|
||||
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
||||
impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Ref<'b, U>> for Ref<'b, T> {}
|
||||
|
||||
#[stable(feature = "std_guard_impls", since = "1.20")]
|
||||
#[stable(feature = "std_guard_impls", since = "1.20.0")]
|
||||
impl<'a, T: ?Sized + fmt::Display> fmt::Display for Ref<'a, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.value.fmt(f)
|
||||
@ -1041,7 +1041,7 @@ impl<'b, T: ?Sized> DerefMut for RefMut<'b, T> {
|
||||
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
||||
impl<'b, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<RefMut<'b, U>> for RefMut<'b, T> {}
|
||||
|
||||
#[stable(feature = "std_guard_impls", since = "1.20")]
|
||||
#[stable(feature = "std_guard_impls", since = "1.20.0")]
|
||||
impl<'a, T: ?Sized + fmt::Display> fmt::Display for RefMut<'a, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.value.fmt(f)
|
||||
|
@ -210,7 +210,7 @@ impl From<u8> for char {
|
||||
|
||||
|
||||
/// An error which can be returned when parsing a char.
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ParseCharError {
|
||||
kind: CharErrorKind,
|
||||
@ -237,7 +237,7 @@ enum CharErrorKind {
|
||||
TooManyChars,
|
||||
}
|
||||
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||
impl fmt::Display for ParseCharError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.__description().fmt(f)
|
||||
@ -245,7 +245,7 @@ impl fmt::Display for ParseCharError {
|
||||
}
|
||||
|
||||
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||
impl FromStr for char {
|
||||
type Err = ParseCharError;
|
||||
|
||||
|
@ -1627,13 +1627,13 @@ macro_rules! tuple {
|
||||
() => ();
|
||||
( $($name:ident,)+ ) => (
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<$($name:Debug),*> Debug for ($($name,)*) {
|
||||
impl<$($name:Debug),*> Debug for ($($name,)*) where last_type!($($name,)+): ?Sized {
|
||||
#[allow(non_snake_case, unused_assignments, deprecated)]
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
let mut builder = f.debug_tuple("");
|
||||
let ($(ref $name,)*) = *self;
|
||||
$(
|
||||
builder.field($name);
|
||||
builder.field(&$name);
|
||||
)*
|
||||
|
||||
builder.finish()
|
||||
@ -1643,6 +1643,11 @@ macro_rules! tuple {
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! last_type {
|
||||
($a:ident,) => { $a };
|
||||
($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
|
||||
}
|
||||
|
||||
tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -559,7 +559,7 @@ mod impls {
|
||||
|
||||
( $($name:ident)+) => (
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<$($name: Hash),*> Hash for ($($name,)*) {
|
||||
impl<$($name: Hash),*> Hash for ($($name,)*) where last_type!($($name,)+): ?Sized {
|
||||
#[allow(non_snake_case)]
|
||||
fn hash<S: Hasher>(&self, state: &mut S) {
|
||||
let ($(ref $name,)*) = *self;
|
||||
@ -569,6 +569,11 @@ mod impls {
|
||||
);
|
||||
}
|
||||
|
||||
macro_rules! last_type {
|
||||
($a:ident,) => { $a };
|
||||
($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
|
||||
}
|
||||
|
||||
impl_hash_tuple! {}
|
||||
impl_hash_tuple! { A }
|
||||
impl_hash_tuple! { A B }
|
||||
|
@ -462,7 +462,7 @@ macro_rules! writeln {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This will always panic.
|
||||
/// This will always [panic!](macro.panic.html)
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -29,7 +29,7 @@ macro_rules! tuple_impls {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
|
||||
impl<$($T:PartialEq),+> PartialEq for ($($T,)+) where last_type!($($T,)+): ?Sized {
|
||||
#[inline]
|
||||
fn eq(&self, other: &($($T,)+)) -> bool {
|
||||
$(self.$idx == other.$idx)&&+
|
||||
@ -41,10 +41,11 @@ macro_rules! tuple_impls {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<$($T:Eq),+> Eq for ($($T,)+) {}
|
||||
impl<$($T:Eq),+> Eq for ($($T,)+) where last_type!($($T,)+): ?Sized {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
|
||||
impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+)
|
||||
where last_type!($($T,)+): ?Sized {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
|
||||
lexical_partial_cmp!($(self.$idx, other.$idx),+)
|
||||
@ -68,7 +69,7 @@ macro_rules! tuple_impls {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<$($T:Ord),+> Ord for ($($T,)+) {
|
||||
impl<$($T:Ord),+> Ord for ($($T,)+) where last_type!($($T,)+): ?Sized {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &($($T,)+)) -> Ordering {
|
||||
lexical_cmp!($(self.$idx, other.$idx),+)
|
||||
@ -118,6 +119,11 @@ macro_rules! lexical_cmp {
|
||||
($a:expr, $b:expr) => { ($a).cmp(&$b) };
|
||||
}
|
||||
|
||||
macro_rules! last_type {
|
||||
($a:ident,) => { $a };
|
||||
($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
|
||||
}
|
||||
|
||||
tuple_impls! {
|
||||
Tuple1 {
|
||||
(0) -> A
|
||||
|
@ -303,7 +303,7 @@ impl Literal {
|
||||
Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), None))
|
||||
}
|
||||
|
||||
int_literals!(u8, i8, u16, i16, u32, i32, u64, i64);
|
||||
int_literals!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize);
|
||||
fn typed_integer(n: i128, kind: &'static str) -> Literal {
|
||||
Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())),
|
||||
Some(Symbol::intern(kind))))
|
||||
|
@ -347,9 +347,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate {
|
||||
let exp_path = self.tcx.item_path_str(did1);
|
||||
let found_path = self.tcx.item_path_str(did2);
|
||||
let exp_abs_path = self.tcx.absolute_item_path_str(did1);
|
||||
let found_abs_path = self.tcx.absolute_item_path_str(did2);
|
||||
// We compare strings because DefPath can be different
|
||||
// for imported and non-imported crates
|
||||
if exp_path == found_path {
|
||||
if exp_path == found_path
|
||||
|| exp_abs_path == found_abs_path {
|
||||
let crate_name = self.tcx.sess.cstore.crate_name(did1.krate);
|
||||
err.span_note(sp, &format!("Perhaps two different versions \
|
||||
of crate `{}` are being used?",
|
||||
|
@ -330,6 +330,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
.filter(|a| a.check_name("rustc_on_unimplemented"))
|
||||
.next()
|
||||
{
|
||||
let name = self.tcx.item_name(def_id).as_str();
|
||||
let err_sp = item.span.substitute_dummy(span);
|
||||
let trait_str = self.tcx.item_path_str(trait_ref.def_id);
|
||||
if let Some(istring) = item.value_str() {
|
||||
@ -347,6 +348,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
Piece::NextArgument(a) => match a.position {
|
||||
Position::ArgumentNamed(s) => match generic_map.get(s) {
|
||||
Some(val) => Some(val),
|
||||
None if s == name => {
|
||||
Some(&trait_str)
|
||||
}
|
||||
None => {
|
||||
span_err!(self.tcx.sess, err_sp, E0272,
|
||||
"the #[rustc_on_unimplemented] attribute on trait \
|
||||
|
@ -1167,6 +1167,7 @@ fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}) {
|
||||
if let Some(istring) = attr.value_str() {
|
||||
let istring = istring.as_str();
|
||||
let name = tcx.item_name(def_id).as_str();
|
||||
let parser = Parser::new(&istring);
|
||||
let types = &generics.types;
|
||||
for token in parser {
|
||||
@ -1175,13 +1176,14 @@ fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
Piece::NextArgument(a) => match a.position {
|
||||
// `{Self}` is allowed
|
||||
Position::ArgumentNamed(s) if s == "Self" => (),
|
||||
// `{ThisTraitsName}` is allowed
|
||||
Position::ArgumentNamed(s) if s == name => (),
|
||||
// So is `{A}` if A is a type parameter
|
||||
Position::ArgumentNamed(s) => match types.iter().find(|t| {
|
||||
t.name == s
|
||||
}) {
|
||||
Some(_) => (),
|
||||
None => {
|
||||
let name = tcx.item_name(def_id);
|
||||
span_err!(tcx.sess, attr.span, E0230,
|
||||
"there is no type parameter \
|
||||
{} on trait {}",
|
||||
|
@ -340,7 +340,7 @@ impl Error for char::CharTryFromError {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||
impl Error for char::ParseCharError {
|
||||
fn description(&self) -> &str {
|
||||
self.__description()
|
||||
|
@ -276,7 +276,10 @@ impl<R: Seek> Seek for BufReader<R> {
|
||||
/// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying
|
||||
/// writer in large, infrequent batches.
|
||||
///
|
||||
/// The buffer will be written out when the writer is dropped.
|
||||
/// When the `BufWriter` is dropped, the contents of its buffer will be written
|
||||
/// out. However, any errors that happen in the process of flushing the buffer
|
||||
/// when the writer is dropped will be ignored. Code that wishes to handle such
|
||||
/// errors must manually call [`flush`] before the writer is dropped.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -316,6 +319,7 @@ impl<R: Seek> Seek for BufReader<R> {
|
||||
/// [`Write`]: ../../std/io/trait.Write.html
|
||||
/// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write
|
||||
/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
|
||||
/// [`flush`]: #method.flush
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct BufWriter<W: Write> {
|
||||
inner: Option<W>,
|
||||
|
@ -24,6 +24,11 @@
|
||||
/// The multi-argument form of this macro panics with a string and has the
|
||||
/// `format!` syntax for building a string.
|
||||
///
|
||||
/// # Current implementation
|
||||
///
|
||||
/// If the main thread panics it will terminate all your threads and end your
|
||||
/// program with code `101`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```should_panic
|
||||
|
@ -440,7 +440,7 @@ impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "std_guard_impls", since = "1.20")]
|
||||
#[stable(feature = "std_guard_impls", since = "1.20.0")]
|
||||
impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
(**self).fmt(f)
|
||||
|
@ -370,7 +370,7 @@ impl<'a, T: fmt::Debug> fmt::Debug for RwLockReadGuard<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "std_guard_impls", since = "1.20")]
|
||||
#[stable(feature = "std_guard_impls", since = "1.20.0")]
|
||||
impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'a, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
(**self).fmt(f)
|
||||
@ -386,7 +386,7 @@ impl<'a, T: fmt::Debug> fmt::Debug for RwLockWriteGuard<'a, T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "std_guard_impls", since = "1.20")]
|
||||
#[stable(feature = "std_guard_impls", since = "1.20.0")]
|
||||
impl<'a, T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'a, T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
(**self).fmt(f)
|
||||
|
@ -177,6 +177,8 @@ pub trait MetadataExt {
|
||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||
fn mode(&self) -> u32;
|
||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||
fn nlink(&self) -> u64;
|
||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||
fn uid(&self) -> u32;
|
||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||
fn gid(&self) -> u32;
|
||||
@ -194,6 +196,10 @@ pub trait MetadataExt {
|
||||
fn ctime(&self) -> i64;
|
||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||
fn ctime_nsec(&self) -> i64;
|
||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||
fn blksize(&self) -> u64;
|
||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||
fn blocks(&self) -> u64;
|
||||
}
|
||||
|
||||
#[stable(feature = "metadata_ext", since = "1.1.0")]
|
||||
@ -207,6 +213,9 @@ impl MetadataExt for fs::Metadata {
|
||||
fn mode(&self) -> u32 {
|
||||
self.as_inner().as_inner().st_mode as u32
|
||||
}
|
||||
fn nlink(&self) -> u64 {
|
||||
self.as_inner().as_inner().st_nlink as u64
|
||||
}
|
||||
fn uid(&self) -> u32 {
|
||||
self.as_inner().as_inner().st_uid as u32
|
||||
}
|
||||
@ -234,6 +243,12 @@ impl MetadataExt for fs::Metadata {
|
||||
fn ctime_nsec(&self) -> i64 {
|
||||
self.as_inner().as_inner().st_ctime_nsec as i64
|
||||
}
|
||||
fn blksize(&self) -> u64 {
|
||||
self.as_inner().as_inner().st_blksize as u64
|
||||
}
|
||||
fn blocks(&self) -> u64 {
|
||||
self.as_inner().as_inner().st_blocks as u64
|
||||
}
|
||||
}
|
||||
|
||||
/// Add special Redox types (block/char device, fifo and socket)
|
||||
|
@ -119,10 +119,10 @@ impl FilePermissions {
|
||||
impl FileType {
|
||||
pub fn is_dir(&self) -> bool { self.is(syscall::MODE_DIR) }
|
||||
pub fn is_file(&self) -> bool { self.is(syscall::MODE_FILE) }
|
||||
pub fn is_symlink(&self) -> bool { false /*FIXME: Implement symlink mode*/ }
|
||||
pub fn is_symlink(&self) -> bool { self.is(syscall::MODE_SYMLINK) }
|
||||
|
||||
pub fn is(&self, mode: u16) -> bool {
|
||||
self.mode & (syscall::MODE_DIR | syscall::MODE_FILE) == mode
|
||||
self.mode & syscall::MODE_TYPE == mode
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ use tables::{conversions, derived_property, general_category, property};
|
||||
pub use core::char::{MAX, from_digit, from_u32, from_u32_unchecked};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::char::{EscapeDebug, EscapeDefault, EscapeUnicode};
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||
pub use core::char::ParseCharError;
|
||||
|
||||
// unstable reexports
|
||||
|
19
src/test/run-make/type-mismatch-same-crate-name/Makefile
Normal file
19
src/test/run-make/type-mismatch-same-crate-name/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
# compile two different versions of crateA
|
||||
$(RUSTC) --crate-type=rlib crateA.rs -C metadata=-1 -C extra-filename=-1
|
||||
$(RUSTC) --crate-type=rlib crateA.rs -C metadata=-2 -C extra-filename=-2
|
||||
# make crateB depend on version 1 of crateA
|
||||
$(RUSTC) --crate-type=rlib crateB.rs --extern crateA=$(TMPDIR)/libcrateA-1.rlib
|
||||
# make crateC depend on version 2 of crateA
|
||||
$(RUSTC) crateC.rs --extern crateA=$(TMPDIR)/libcrateA-2.rlib 2>&1 | \
|
||||
tr -d '\r\n' | grep \
|
||||
"mismatched types.*\
|
||||
crateB::try_foo(foo2);.*\
|
||||
expected struct \`crateA::foo::Foo\`, found struct \`crateA::Foo\`.*\
|
||||
different versions of crate \`crateA\`.*\
|
||||
mismatched types.*\
|
||||
crateB::try_bar(bar2);.*\
|
||||
expected trait \`crateA::bar::Bar\`, found trait \`crateA::Bar\`.*\
|
||||
different versions of crate \`crateA\`"
|
26
src/test/run-make/type-mismatch-same-crate-name/crateA.rs
Normal file
26
src/test/run-make/type-mismatch-same-crate-name/crateA.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
mod foo {
|
||||
pub struct Foo;
|
||||
}
|
||||
|
||||
mod bar {
|
||||
pub trait Bar{}
|
||||
|
||||
pub fn bar() -> Box<Bar> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
// This makes the publicly accessible path
|
||||
// differ from the internal one.
|
||||
pub use foo::Foo;
|
||||
pub use bar::{Bar, bar};
|
14
src/test/run-make/type-mismatch-same-crate-name/crateB.rs
Normal file
14
src/test/run-make/type-mismatch-same-crate-name/crateB.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate crateA;
|
||||
|
||||
pub fn try_foo(x: crateA::Foo){}
|
||||
pub fn try_bar(x: Box<crateA::Bar>){}
|
35
src/test/run-make/type-mismatch-same-crate-name/crateC.rs
Normal file
35
src/test/run-make/type-mismatch-same-crate-name/crateC.rs
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// This tests the extra note reported when a type error deals with
|
||||
// seemingly identical types.
|
||||
// The main use case of this error is when there are two crates
|
||||
// (generally different versions of the same crate) with the same name
|
||||
// causing a type mismatch.
|
||||
|
||||
// The test is nearly the same as the one in
|
||||
// compile-fail/type-mismatch-same-crate-name.rs
|
||||
// but deals with the case where one of the crates
|
||||
// is only introduced as an indirect dependency.
|
||||
// and the type is accessed via a reexport.
|
||||
// This is similar to how the error can be introduced
|
||||
// when using cargo's automatic dependency resolution.
|
||||
|
||||
extern crate crateA;
|
||||
|
||||
fn main() {
|
||||
let foo2 = crateA::Foo;
|
||||
let bar2 = crateA::bar();
|
||||
{
|
||||
extern crate crateB;
|
||||
crateB::try_foo(foo2);
|
||||
crateB::try_bar(bar2);
|
||||
}
|
||||
}
|
29
src/test/run-pass/unsized-tuple-impls.rs
Normal file
29
src/test/run-pass/unsized-tuple-impls.rs
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(unsized_tuple_coercion)]
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
fn main() {
|
||||
let x : &(i32, i32, [i32]) = &(0, 1, [2, 3]);
|
||||
let y : &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]);
|
||||
let mut a = [y, x];
|
||||
a.sort();
|
||||
assert_eq!(a, [x, y]);
|
||||
|
||||
assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]");
|
||||
|
||||
let mut h = HashSet::new();
|
||||
h.insert(x);
|
||||
h.insert(y);
|
||||
assert!(h.contains(x));
|
||||
assert!(h.contains(y));
|
||||
}
|
22
src/test/ui/on-unimplemented/bad-annotation.stderr
Normal file
22
src/test/ui/on-unimplemented/bad-annotation.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0232]: this attribute must have a value
|
||||
--> $DIR/bad-annotation.rs:26:1
|
||||
|
|
||||
26 | #[rustc_on_unimplemented] //~ ERROR this attribute must have a value
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ attribute requires a value
|
||||
|
|
||||
= note: eg `#[rustc_on_unimplemented = "foo"]`
|
||||
|
||||
error[E0230]: there is no type parameter C on trait BadAnnotation2
|
||||
--> $DIR/bad-annotation.rs:30:1
|
||||
|
|
||||
30 | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0231]: only named substitution parameters are allowed
|
||||
--> $DIR/bad-annotation.rs:35:1
|
||||
|
|
||||
35 | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{}>`"]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
53
src/test/ui/on-unimplemented/multiple-impls.stderr
Normal file
53
src/test/ui/on-unimplemented/multiple-impls.stderr
Normal file
@ -0,0 +1,53 @@
|
||||
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
|
||||
--> $DIR/multiple-impls.rs:43:5
|
||||
|
|
||||
43 | Index::index(&[] as &[i32], 2u32);
|
||||
| ^^^^^^^^^^^^ trait message
|
||||
|
|
||||
= help: the trait `Index<u32>` is not implemented for `[i32]`
|
||||
= note: required by `Index::index`
|
||||
|
||||
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
|
||||
--> $DIR/multiple-impls.rs:43:5
|
||||
|
|
||||
43 | Index::index(&[] as &[i32], 2u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait message
|
||||
|
|
||||
= help: the trait `Index<u32>` is not implemented for `[i32]`
|
||||
|
||||
error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
|
||||
--> $DIR/multiple-impls.rs:49:5
|
||||
|
|
||||
49 | Index::index(&[] as &[i32], Foo(2u32));
|
||||
| ^^^^^^^^^^^^ on impl for Foo
|
||||
|
|
||||
= help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
|
||||
= note: required by `Index::index`
|
||||
|
||||
error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
|
||||
--> $DIR/multiple-impls.rs:49:5
|
||||
|
|
||||
49 | Index::index(&[] as &[i32], Foo(2u32));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo
|
||||
|
|
||||
= help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
|
||||
|
||||
error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
|
||||
--> $DIR/multiple-impls.rs:55:5
|
||||
|
|
||||
55 | Index::index(&[] as &[i32], Bar(2u32));
|
||||
| ^^^^^^^^^^^^ on impl for Bar
|
||||
|
|
||||
= help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
|
||||
= note: required by `Index::index`
|
||||
|
||||
error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
|
||||
--> $DIR/multiple-impls.rs:55:5
|
||||
|
|
||||
55 | Index::index(&[] as &[i32], Bar(2u32));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
|
||||
|
|
||||
= help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
19
src/test/ui/on-unimplemented/on-impl.stderr
Normal file
19
src/test/ui/on-unimplemented/on-impl.stderr
Normal file
@ -0,0 +1,19 @@
|
||||
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
|
||||
--> $DIR/on-impl.rs:32:5
|
||||
|
|
||||
32 | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
|
||||
|
|
||||
= help: the trait `Index<u32>` is not implemented for `[i32]`
|
||||
= note: required by `Index::index`
|
||||
|
||||
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
|
||||
--> $DIR/on-impl.rs:32:5
|
||||
|
|
||||
32 | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
|
||||
|
|
||||
= help: the trait `Index<u32>` is not implemented for `[i32]`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -11,9 +11,12 @@
|
||||
|
||||
#![feature(on_unimplemented)]
|
||||
|
||||
#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}`"]
|
||||
trait Foo<Bar, Baz, Quux>
|
||||
{}
|
||||
pub mod Bar {
|
||||
#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"]
|
||||
pub trait Foo<Bar, Baz, Quux> {}
|
||||
}
|
||||
|
||||
use Bar::Foo;
|
||||
|
||||
fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T {
|
||||
panic!()
|
20
src/test/ui/on-unimplemented/on-trait.stderr
Normal file
20
src/test/ui/on-unimplemented/on-trait.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error[E0277]: the trait bound `std::option::Option<std::vec::Vec<u8>>: MyFromIterator<&u8>` is not satisfied
|
||||
--> $DIR/on-trait.rs:37:30
|
||||
|
|
||||
37 | let y: Option<Vec<u8>> = collect(x.iter()); // this should give approximately the same error for x.iter().collect()
|
||||
| ^^^^^^^ a collection of type `std::option::Option<std::vec::Vec<u8>>` cannot be built from an iterator over elements of type `&u8`
|
||||
|
|
||||
= help: the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option<std::vec::Vec<u8>>`
|
||||
= note: required by `collect`
|
||||
|
||||
error[E0277]: the trait bound `std::string::String: Bar::Foo<u8, _, u32>` is not satisfied
|
||||
--> $DIR/on-trait.rs:42:21
|
||||
|
|
||||
42 | let x: String = foobar(); //~ ERROR
|
||||
| ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo`
|
||||
|
|
||||
= help: the trait `Bar::Foo<u8, _, u32>` is not implemented for `std::string::String`
|
||||
= note: required by `foobar`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
20
src/test/ui/on-unimplemented/slice-index.stderr
Normal file
20
src/test/ui/on-unimplemented/slice-index.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
error[E0277]: the trait bound `i32: std::slice::SliceIndex<[i32]>` is not satisfied
|
||||
--> $DIR/slice-index.rs:21:5
|
||||
|
|
||||
21 | x[1i32]; //~ ERROR E0277
|
||||
| ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `i32`
|
||||
= note: required because of the requirements on the impl of `std::ops::Index<i32>` for `[i32]`
|
||||
|
||||
error[E0277]: the trait bound `std::ops::RangeTo<i32>: std::slice::SliceIndex<[i32]>` is not satisfied
|
||||
--> $DIR/slice-index.rs:24:5
|
||||
|
|
||||
24 | x[..1i32]; //~ ERROR E0277
|
||||
| ^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
||||
|
|
||||
= help: the trait `std::slice::SliceIndex<[i32]>` is not implemented for `std::ops::RangeTo<i32>`
|
||||
= note: required because of the requirements on the impl of `std::ops::Index<std::ops::RangeTo<i32>>` for `[i32]`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
x
Reference in New Issue
Block a user