Auto merge of #70427 - Centril:rollup-lrcad2c, r=Centril
Rollup of 5 pull requests Successful merges: - #68004 (permit negative impls for non-auto traits) - #70385 (Miri nits: comment and var name improvement) - #70411 (Fix for #62691: use the largest niche across all fields) - #70417 (parser: recover on `...` as a pattern, suggesting `..`) - #70424 (simplify match stmt) Failed merges: r? @ghost
This commit is contained in:
commit
2fbb07525e
@ -0,0 +1,57 @@
|
||||
# `negative_impls`
|
||||
|
||||
The tracking issue for this feature is [#68318].
|
||||
|
||||
[#68318]: https://github.com/rust-lang/rust/issues/68318
|
||||
|
||||
----
|
||||
|
||||
With the feature gate `negative_impls`, you can write negative impls as well as positive ones:
|
||||
|
||||
```rust
|
||||
#![feature(negative_impls)]
|
||||
trait DerefMut { }
|
||||
impl<T: ?Sized> !DerefMut for &T { }
|
||||
```
|
||||
|
||||
Negative impls indicate a semver guarantee that the given trait will not be implemented for the given types. Negative impls play an additional purpose for auto traits, described below.
|
||||
|
||||
Negative impls have the following characteristics:
|
||||
|
||||
* They do not have any items.
|
||||
* They must obey the orphan rules as if they were a positive impl.
|
||||
* They cannot "overlap" with any positive impls.
|
||||
|
||||
## Semver interaction
|
||||
|
||||
It is a breaking change to remove a negative impl. Negative impls are a commitment not to implement the given trait for the named types.
|
||||
|
||||
## Orphan and overlap rules
|
||||
|
||||
Negative impls must obey the same orphan rules as a positive impl. This implies you cannot add a negative impl for types defined in upstream crates and so forth.
|
||||
|
||||
Similarly, negative impls cannot overlap with positive impls, again using the same "overlap" check that we ordinarily use to determine if two impls overlap. (Note that positive impls typically cannot overlap with one another either, except as permitted by specialization.)
|
||||
|
||||
## Interaction with auto traits
|
||||
|
||||
Declaring a negative impl `impl !SomeAutoTrait for SomeType` for an
|
||||
auto-trait serves two purposes:
|
||||
|
||||
* as with any trait, it declares that `SomeType` will never implement `SomeAutoTrait`;
|
||||
* it disables the automatic `SomeType: SomeAutoTrait` impl that would otherwise have been generated.
|
||||
|
||||
Note that, at present, there is no way to indicate that a given type
|
||||
does not implement an auto trait *but that it may do so in the
|
||||
future*. For ordinary types, this is done by simply not declaring any
|
||||
impl at all, but that is not an option for auto traits. A workaround
|
||||
is that one could embed a marker type as one of the fields, where the
|
||||
marker type is `!AutoTrait`.
|
||||
|
||||
## Immediate uses
|
||||
|
||||
Negative impls are used to declare that `&T: !DerefMut` and `&mut T: !Clone`, as required to fix the soundness of `Pin` described in [#66544](https://github.com/rust-lang/rust/issues/66544).
|
||||
|
||||
This serves two purposes:
|
||||
|
||||
* For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists.
|
||||
* It prevents downstream crates from creating such impls.
|
@ -10,7 +10,8 @@ The `optin_builtin_traits` feature gate allows you to define auto traits.
|
||||
|
||||
Auto traits, like [`Send`] or [`Sync`] in the standard library, are marker traits
|
||||
that are automatically implemented for every type, unless the type, or a type it contains,
|
||||
has explicitly opted out via a negative impl.
|
||||
has explicitly opted out via a negative impl. (Negative impls are separately controlled
|
||||
by the `negative_impls` feature.)
|
||||
|
||||
[`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
|
||||
[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
|
||||
@ -22,6 +23,7 @@ impl !Trait for Type
|
||||
Example:
|
||||
|
||||
```rust
|
||||
#![feature(negative_impls)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
auto trait Valid {}
|
||||
@ -43,3 +45,63 @@ fn main() {
|
||||
// must_be_valid( MaybeValid(False) );
|
||||
}
|
||||
```
|
||||
|
||||
## Automatic trait implementations
|
||||
|
||||
When a type is declared as an `auto trait`, we will automatically
|
||||
create impls for every struct/enum/union, unless an explicit impl is
|
||||
provided. These automatic impls contain a where clause for each field
|
||||
of the form `T: AutoTrait`, where `T` is the type of the field and
|
||||
`AutoTrait` is the auto trait in question. As an example, consider the
|
||||
struct `List` and the auto trait `Send`:
|
||||
|
||||
```rust
|
||||
struct List<T> {
|
||||
data: T,
|
||||
next: Option<Box<List<T>>>,
|
||||
}
|
||||
```
|
||||
|
||||
Presuming that there is no explicit impl of `Send` for `List`, the
|
||||
compiler will supply an automatic impl of the form:
|
||||
|
||||
```rust
|
||||
struct List<T> {
|
||||
data: T,
|
||||
next: Option<Box<List<T>>>,
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for List<T>
|
||||
where
|
||||
T: Send, // from the field `data`
|
||||
Option<Box<List<T>>>: Send, // from the field `next`
|
||||
{ }
|
||||
```
|
||||
|
||||
Explicit impls may be either positive or negative. They take the form:
|
||||
|
||||
```rust,ignore
|
||||
impl<...> AutoTrait for StructName<..> { }
|
||||
impl<...> !AutoTrait for StructName<..> { }
|
||||
```
|
||||
|
||||
## Coinduction: Auto traits permit cyclic matching
|
||||
|
||||
Unlike ordinary trait matching, auto traits are **coinductive**. This
|
||||
means, in short, that cycles which occur in trait matching are
|
||||
considered ok. As an example, consider the recursive struct `List`
|
||||
introduced in the previous section. In attempting to determine whether
|
||||
`List: Send`, we would wind up in a cycle: to apply the impl, we must
|
||||
show that `Option<Box<List>>: Send`, which will in turn require
|
||||
`Box<List>: Send` and then finally `List: Send` again. Under ordinary
|
||||
trait matching, this cycle would be an error, but for an auto trait it
|
||||
is considered a successful match.
|
||||
|
||||
## Items
|
||||
|
||||
Auto traits cannot have any trait items, such as methods or associated types. This ensures that we can generate default implementations.
|
||||
|
||||
## Supertraits
|
||||
|
||||
Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile.
|
||||
|
||||
|
@ -99,6 +99,7 @@
|
||||
#![feature(internal_uninit_const)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(libc)]
|
||||
#![cfg_attr(not(bootstrap), feature(negative_impls))]
|
||||
#![feature(nll)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(pattern)]
|
||||
|
@ -219,7 +219,7 @@ mod impls {
|
||||
}
|
||||
}
|
||||
|
||||
// Shared references can be cloned, but mutable references *cannot*!
|
||||
/// Shared references can be cloned, but mutable references *cannot*!
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Clone for &T {
|
||||
#[inline]
|
||||
@ -227,4 +227,9 @@ mod impls {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
/// Shared references can be cloned, but mutable references *cannot*!
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[cfg(not(bootstrap))]
|
||||
impl<T: ?Sized> !Clone for &mut T {}
|
||||
}
|
||||
|
@ -98,6 +98,7 @@
|
||||
#![feature(is_sorted)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(link_llvm_intrinsics)]
|
||||
#![cfg_attr(not(bootstrap), feature(negative_impls))]
|
||||
#![feature(never_type)]
|
||||
#![feature(nll)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
|
@ -87,7 +87,7 @@ impl<T: ?Sized> !Send for *mut T {}
|
||||
message = "the size for values of type `{Self}` cannot be known at compilation time",
|
||||
label = "doesn't have a size known at compile-time",
|
||||
note = "to learn more, visit <https://doc.rust-lang.org/book/\
|
||||
ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>"
|
||||
ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>"
|
||||
)]
|
||||
#[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable
|
||||
#[cfg_attr(not(bootstrap), rustc_specialization_trait)]
|
||||
@ -790,7 +790,7 @@ mod copy_impls {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Copy for *mut T {}
|
||||
|
||||
// Shared references can be copied, but mutable references *cannot*!
|
||||
/// Shared references can be copied, but mutable references *cannot*!
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Copy for &T {}
|
||||
}
|
||||
|
@ -81,6 +81,10 @@ impl<T: ?Sized> Deref for &T {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> !DerefMut for &T {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Deref for &mut T {
|
||||
type Target = T;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#![feature(decl_macro)]
|
||||
#![feature(extern_types)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![cfg_attr(not(bootstrap), feature(negative_impls))]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![cfg_attr(bootstrap, feature(specialization))]
|
||||
|
@ -282,8 +282,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
|
||||
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
||||
|
||||
let mut sized = true;
|
||||
let mut offsets = vec![Size::ZERO; fields.len()];
|
||||
let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect();
|
||||
|
||||
let mut optimize = !repr.inhibit_struct_field_reordering_opt();
|
||||
@ -320,6 +318,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
// At the bottom of this function, we invert `inverse_memory_index` to
|
||||
// produce `memory_index` (see `invert_mapping`).
|
||||
|
||||
let mut sized = true;
|
||||
let mut offsets = vec![Size::ZERO; fields.len()];
|
||||
let mut offset = Size::ZERO;
|
||||
let mut largest_niche = None;
|
||||
let mut largest_niche_available = 0;
|
||||
@ -900,18 +900,19 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
let count = (niche_variants.end().as_u32()
|
||||
- niche_variants.start().as_u32()
|
||||
+ 1) as u128;
|
||||
// FIXME(#62691) use the largest niche across all fields,
|
||||
// not just the first one.
|
||||
for (field_index, &field) in variants[i].iter().enumerate() {
|
||||
let niche = match &field.largest_niche {
|
||||
Some(niche) => niche,
|
||||
_ => continue,
|
||||
};
|
||||
let (niche_start, niche_scalar) = match niche.reserve(self, count) {
|
||||
Some(pair) => pair,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
// Find the field with the largest niche
|
||||
let niche_candidate = variants[i]
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(j, &field)| Some((j, field.largest_niche.as_ref()?)))
|
||||
.max_by_key(|(_, niche)| niche.available(dl));
|
||||
|
||||
if let Some((field_index, niche, (niche_start, niche_scalar))) =
|
||||
niche_candidate.and_then(|(field_index, niche)| {
|
||||
Some((field_index, niche, niche.reserve(self, count)?))
|
||||
})
|
||||
{
|
||||
let mut align = dl.aggregate_align;
|
||||
let st = variants
|
||||
.iter_enumerated()
|
||||
|
@ -289,11 +289,7 @@ impl<'a> AstValidator<'a> {
|
||||
match expr.kind {
|
||||
ExprKind::Lit(..) | ExprKind::Err => {}
|
||||
ExprKind::Path(..) if allow_paths => {}
|
||||
ExprKind::Unary(UnOp::Neg, ref inner)
|
||||
if match inner.kind {
|
||||
ExprKind::Lit(_) => true,
|
||||
_ => false,
|
||||
} => {}
|
||||
ExprKind::Unary(UnOp::Neg, ref inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
|
||||
_ => self.err_handler().span_err(
|
||||
expr.span,
|
||||
"arbitrary expressions aren't allowed \
|
||||
|
@ -286,8 +286,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
start,
|
||||
i.span,
|
||||
"`#[start]` functions are experimental \
|
||||
and their signature may change \
|
||||
over time"
|
||||
and their signature may change \
|
||||
over time"
|
||||
);
|
||||
}
|
||||
if attr::contains_name(&i.attrs[..], sym::main) {
|
||||
@ -296,8 +296,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
main,
|
||||
i.span,
|
||||
"declaration of a non-standard `#[main]` \
|
||||
function may change over time, for now \
|
||||
a top-level `fn main()` is required"
|
||||
function may change over time, for now \
|
||||
a top-level `fn main()` is required"
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -341,7 +341,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
if let ast::ImplPolarity::Negative(span) = polarity {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
optin_builtin_traits,
|
||||
negative_impls,
|
||||
span.to(of_trait.as_ref().map(|t| t.path.span).unwrap_or(span)),
|
||||
"negative trait bounds are not yet fully implemented; \
|
||||
use marker types for now"
|
||||
|
@ -97,7 +97,6 @@ E0184: include_str!("./error_codes/E0184.md"),
|
||||
E0185: include_str!("./error_codes/E0185.md"),
|
||||
E0186: include_str!("./error_codes/E0186.md"),
|
||||
E0191: include_str!("./error_codes/E0191.md"),
|
||||
E0192: include_str!("./error_codes/E0192.md"),
|
||||
E0193: include_str!("./error_codes/E0193.md"),
|
||||
E0195: include_str!("./error_codes/E0195.md"),
|
||||
E0197: include_str!("./error_codes/E0197.md"),
|
||||
@ -426,6 +425,9 @@ E0745: include_str!("./error_codes/E0745.md"),
|
||||
E0746: include_str!("./error_codes/E0746.md"),
|
||||
E0747: include_str!("./error_codes/E0747.md"),
|
||||
E0748: include_str!("./error_codes/E0748.md"),
|
||||
E0749: include_str!("./error_codes/E0749.md"),
|
||||
E0750: include_str!("./error_codes/E0750.md"),
|
||||
E0751: include_str!("./error_codes/E0751.md"),
|
||||
;
|
||||
// E0006, // merged with E0005
|
||||
// E0008, // cannot bind by-move into a pattern guard
|
||||
@ -460,6 +462,7 @@ E0748: include_str!("./error_codes/E0748.md"),
|
||||
// E0188, // can not cast an immutable reference to a mutable pointer
|
||||
// E0189, // deprecated: can only cast a boxed pointer to a boxed object
|
||||
// E0190, // deprecated: can only cast a &-pointer to an &-object
|
||||
// E0192, // negative impl only applicable to auto traits
|
||||
// E0194, // merged into E0403
|
||||
// E0196, // cannot determine a type for this closure
|
||||
E0208,
|
||||
|
4
src/librustc_error_codes/error_codes/E0749.md
Normal file
4
src/librustc_error_codes/error_codes/E0749.md
Normal file
@ -0,0 +1,4 @@
|
||||
Negative impls are not allowed to have any items. Negative impls
|
||||
declare that a trait is **not** implemented (and never will be) and
|
||||
hence there is no need to specify the values for trait methods or
|
||||
other items.
|
4
src/librustc_error_codes/error_codes/E0750.md
Normal file
4
src/librustc_error_codes/error_codes/E0750.md
Normal file
@ -0,0 +1,4 @@
|
||||
Negative impls cannot be default impls. A default impl supplies
|
||||
default values for the items within to be used by other impls, whereas
|
||||
a negative impl declares that there are no other impls. These don't
|
||||
make sense to combine.
|
12
src/librustc_error_codes/error_codes/E0751.md
Normal file
12
src/librustc_error_codes/error_codes/E0751.md
Normal file
@ -0,0 +1,12 @@
|
||||
There are both a positive and negative trait implementation for the same type.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0748
|
||||
trait MyTrait {}
|
||||
impl MyTrait for i32 { }
|
||||
impl !MyTrait for i32 { }
|
||||
```
|
||||
|
||||
Negative implementations are a promise that the trait will never be
|
||||
implemented for the given types.
|
@ -802,13 +802,13 @@ impl HandlerInner {
|
||||
));
|
||||
self.failure(&format!(
|
||||
"For more information about an error, try \
|
||||
`rustc --explain {}`.",
|
||||
`rustc --explain {}`.",
|
||||
&error_codes[0]
|
||||
));
|
||||
} else {
|
||||
self.failure(&format!(
|
||||
"For more information about this error, try \
|
||||
`rustc --explain {}`.",
|
||||
`rustc --explain {}`.",
|
||||
&error_codes[0]
|
||||
));
|
||||
}
|
||||
|
@ -554,6 +554,9 @@ declare_features! (
|
||||
// Allows limiting the evaluation steps of const expressions
|
||||
(active, const_eval_limit, "1.43.0", Some(67217), None),
|
||||
|
||||
/// Allow negative trait implementations.
|
||||
(active, negative_impls, "1.44.0", Some(68318), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: actual feature gates
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -178,7 +178,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
|
||||
|
||||
type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation)>;
|
||||
|
||||
const GLOBAL_KIND: Option<!> = None; // no copying of globals allowed
|
||||
const GLOBAL_KIND: Option<!> = None; // no copying of globals from `tcx` to machine memory
|
||||
|
||||
// We do not check for alignment to avoid having to carry an `Align`
|
||||
// in `ConstValue::ByRef`.
|
||||
@ -350,15 +350,15 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
|
||||
memory_extra: &MemoryExtra,
|
||||
alloc_id: AllocId,
|
||||
allocation: &Allocation,
|
||||
def_id: Option<DefId>,
|
||||
static_def_id: Option<DefId>,
|
||||
is_write: bool,
|
||||
) -> InterpResult<'tcx> {
|
||||
if is_write && allocation.mutability == Mutability::Not {
|
||||
Err(err_ub!(WriteToReadOnly(alloc_id)).into())
|
||||
} else if is_write {
|
||||
Err(ConstEvalErrKind::ModifiedGlobal.into())
|
||||
} else if memory_extra.can_access_statics || def_id.is_none() {
|
||||
// `def_id.is_none()` indicates this is not a static, but a const or so.
|
||||
} else if memory_extra.can_access_statics || static_def_id.is_none() {
|
||||
// `static_def_id.is_none()` indicates this is not a static, but a const or so.
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ConstEvalErrKind::ConstAccessesStatic.into())
|
||||
|
@ -215,7 +215,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||
_memory_extra: &Self::MemoryExtra,
|
||||
_alloc_id: AllocId,
|
||||
_allocation: &Allocation,
|
||||
_def_id: Option<DefId>,
|
||||
_static_def_id: Option<DefId>,
|
||||
_is_write: bool,
|
||||
) -> InterpResult<'tcx> {
|
||||
Ok(())
|
||||
|
@ -172,7 +172,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
|
||||
|
||||
type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation)>;
|
||||
|
||||
const GLOBAL_KIND: Option<!> = None;
|
||||
const GLOBAL_KIND: Option<!> = None; // no copying of globals from `tcx` to machine memory
|
||||
|
||||
const CHECK_ALIGN: bool = false;
|
||||
|
||||
@ -274,7 +274,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
|
||||
_memory_extra: &(),
|
||||
_alloc_id: AllocId,
|
||||
allocation: &Allocation<Self::PointerTag, Self::AllocExtra>,
|
||||
def_id: Option<DefId>,
|
||||
static_def_id: Option<DefId>,
|
||||
is_write: bool,
|
||||
) -> InterpResult<'tcx> {
|
||||
if is_write {
|
||||
@ -285,7 +285,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
|
||||
if allocation.mutability == Mutability::Mut {
|
||||
throw_machine_stop_str!("can't eval mutable globals in ConstProp");
|
||||
}
|
||||
if def_id.is_some() && allocation.relocations().len() > 0 {
|
||||
if static_def_id.is_some() && allocation.relocations().len() > 0 {
|
||||
throw_machine_stop_str!("can't eval statics with pointers in ConstProp");
|
||||
}
|
||||
|
||||
|
@ -295,6 +295,8 @@ impl<'a> Parser<'a> {
|
||||
// A rest pattern `..`.
|
||||
self.bump(); // `..`
|
||||
PatKind::Rest
|
||||
} else if self.check(&token::DotDotDot) && !self.is_pat_range_end_start(1) {
|
||||
self.recover_dotdotdot_rest_pat(lo)
|
||||
} else if let Some(form) = self.parse_range_end() {
|
||||
self.parse_pat_range_to(form)? // `..=X`, `...X`, or `..X`.
|
||||
} else if self.eat_keyword(kw::Underscore) {
|
||||
@ -362,6 +364,25 @@ impl<'a> Parser<'a> {
|
||||
Ok(pat)
|
||||
}
|
||||
|
||||
/// Recover from a typoed `...` pattern that was encountered
|
||||
/// Ref: Issue #70388
|
||||
fn recover_dotdotdot_rest_pat(&mut self, lo: Span) -> PatKind {
|
||||
// A typoed rest pattern `...`.
|
||||
self.bump(); // `...`
|
||||
|
||||
// The user probably mistook `...` for a rest pattern `..`.
|
||||
self.struct_span_err(lo, "unexpected `...`")
|
||||
.span_label(lo, "not a valid pattern")
|
||||
.span_suggestion_short(
|
||||
lo,
|
||||
"for a rest pattern, use `..` instead of `...`",
|
||||
"..".to_owned(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
PatKind::Rest
|
||||
}
|
||||
|
||||
/// Try to recover the more general form `intersect ::= $pat_lhs @ $pat_rhs`.
|
||||
///
|
||||
/// Allowed binding patterns generated by `binding ::= ref? mut? $ident @ $pat_rhs`
|
||||
|
@ -9,6 +9,7 @@
|
||||
#![feature(const_if_match)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(const_panic)]
|
||||
#![cfg_attr(not(bootstrap), feature(negative_impls))]
|
||||
#![feature(nll)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(specialization)]
|
||||
|
@ -473,6 +473,7 @@ symbols! {
|
||||
needs_drop,
|
||||
needs_panic_runtime,
|
||||
negate_unsigned,
|
||||
negative_impls,
|
||||
never,
|
||||
never_type,
|
||||
never_type_fallback,
|
||||
|
@ -324,86 +324,7 @@ pub(super) fn specialization_graph_provider(
|
||||
};
|
||||
|
||||
if let Some(overlap) = overlap {
|
||||
let impl_span =
|
||||
tcx.sess.source_map().guess_head_span(tcx.span_of_impl(impl_def_id).unwrap());
|
||||
|
||||
// Work to be done after we've built the DiagnosticBuilder. We have to define it
|
||||
// now because the struct_lint methods don't return back the DiagnosticBuilder
|
||||
// that's passed in.
|
||||
let decorate = |err: LintDiagnosticBuilder<'_>| {
|
||||
let msg = format!(
|
||||
"conflicting implementations of trait `{}`{}:{}",
|
||||
overlap.trait_desc,
|
||||
overlap
|
||||
.self_desc
|
||||
.clone()
|
||||
.map_or(String::new(), |ty| { format!(" for type `{}`", ty) }),
|
||||
match used_to_be_allowed {
|
||||
Some(FutureCompatOverlapErrorKind::Issue33140) => " (E0119)",
|
||||
_ => "",
|
||||
}
|
||||
);
|
||||
let mut err = err.build(&msg);
|
||||
match tcx.span_of_impl(overlap.with_impl) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"first implementation here".to_string(),
|
||||
);
|
||||
|
||||
err.span_label(
|
||||
impl_span,
|
||||
format!(
|
||||
"conflicting implementation{}",
|
||||
overlap
|
||||
.self_desc
|
||||
.map_or(String::new(), |ty| format!(" for `{}`", ty))
|
||||
),
|
||||
);
|
||||
}
|
||||
Err(cname) => {
|
||||
let msg = match to_pretty_impl_header(tcx, overlap.with_impl) {
|
||||
Some(s) => format!(
|
||||
"conflicting implementation in crate `{}`:\n- {}",
|
||||
cname, s
|
||||
),
|
||||
None => format!("conflicting implementation in crate `{}`", cname),
|
||||
};
|
||||
err.note(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
for cause in &overlap.intercrate_ambiguity_causes {
|
||||
cause.add_intercrate_ambiguity_hint(&mut err);
|
||||
}
|
||||
|
||||
if overlap.involves_placeholder {
|
||||
coherence::add_placeholder_note(&mut err);
|
||||
}
|
||||
err.emit()
|
||||
};
|
||||
|
||||
match used_to_be_allowed {
|
||||
None => {
|
||||
sg.has_errored = true;
|
||||
let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
|
||||
decorate(LintDiagnosticBuilder::new(err));
|
||||
}
|
||||
Some(kind) => {
|
||||
let lint = match kind {
|
||||
FutureCompatOverlapErrorKind::Issue33140 => {
|
||||
ORDER_DEPENDENT_TRAIT_OBJECTS
|
||||
}
|
||||
FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
|
||||
};
|
||||
tcx.struct_span_lint_hir(
|
||||
lint,
|
||||
tcx.hir().as_local_hir_id(impl_def_id).unwrap(),
|
||||
impl_span,
|
||||
decorate,
|
||||
)
|
||||
}
|
||||
};
|
||||
report_overlap_conflict(tcx, overlap, impl_def_id, used_to_be_allowed, &mut sg);
|
||||
}
|
||||
} else {
|
||||
let parent = tcx.impl_parent(impl_def_id).unwrap_or(trait_id);
|
||||
@ -414,6 +335,170 @@ pub(super) fn specialization_graph_provider(
|
||||
tcx.arena.alloc(sg)
|
||||
}
|
||||
|
||||
fn report_overlap_conflict(
|
||||
tcx: TyCtxt<'_>,
|
||||
overlap: OverlapError,
|
||||
impl_def_id: DefId,
|
||||
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
|
||||
sg: &mut specialization_graph::Graph,
|
||||
) {
|
||||
let impl_polarity = tcx.impl_polarity(impl_def_id);
|
||||
let other_polarity = tcx.impl_polarity(overlap.with_impl);
|
||||
match (impl_polarity, other_polarity) {
|
||||
(ty::ImplPolarity::Negative, ty::ImplPolarity::Positive) => {
|
||||
report_negative_positive_conflict(
|
||||
tcx,
|
||||
&overlap,
|
||||
impl_def_id,
|
||||
impl_def_id,
|
||||
overlap.with_impl,
|
||||
sg,
|
||||
);
|
||||
}
|
||||
|
||||
(ty::ImplPolarity::Positive, ty::ImplPolarity::Negative) => {
|
||||
report_negative_positive_conflict(
|
||||
tcx,
|
||||
&overlap,
|
||||
impl_def_id,
|
||||
overlap.with_impl,
|
||||
impl_def_id,
|
||||
sg,
|
||||
);
|
||||
}
|
||||
|
||||
_ => {
|
||||
report_conflicting_impls(tcx, overlap, impl_def_id, used_to_be_allowed, sg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn report_negative_positive_conflict(
|
||||
tcx: TyCtxt<'_>,
|
||||
overlap: &OverlapError,
|
||||
local_impl_def_id: DefId,
|
||||
negative_impl_def_id: DefId,
|
||||
positive_impl_def_id: DefId,
|
||||
sg: &mut specialization_graph::Graph,
|
||||
) {
|
||||
let impl_span =
|
||||
tcx.sess.source_map().guess_head_span(tcx.span_of_impl(local_impl_def_id).unwrap());
|
||||
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_span,
|
||||
E0748,
|
||||
"found both positive and negative implementation of trait `{}`{}:",
|
||||
overlap.trait_desc,
|
||||
overlap.self_desc.clone().map_or(String::new(), |ty| format!(" for type `{}`", ty))
|
||||
);
|
||||
|
||||
match tcx.span_of_impl(negative_impl_def_id) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"negative implementation here".to_string(),
|
||||
);
|
||||
}
|
||||
Err(cname) => {
|
||||
err.note(&format!("negative implementation in crate `{}`", cname));
|
||||
}
|
||||
}
|
||||
|
||||
match tcx.span_of_impl(positive_impl_def_id) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"positive implementation here".to_string(),
|
||||
);
|
||||
}
|
||||
Err(cname) => {
|
||||
err.note(&format!("positive implementation in crate `{}`", cname));
|
||||
}
|
||||
}
|
||||
|
||||
sg.has_errored = true;
|
||||
err.emit();
|
||||
}
|
||||
|
||||
fn report_conflicting_impls(
|
||||
tcx: TyCtxt<'_>,
|
||||
overlap: OverlapError,
|
||||
impl_def_id: DefId,
|
||||
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
|
||||
sg: &mut specialization_graph::Graph,
|
||||
) {
|
||||
let impl_span = tcx.sess.source_map().guess_head_span(tcx.span_of_impl(impl_def_id).unwrap());
|
||||
|
||||
// Work to be done after we've built the DiagnosticBuilder. We have to define it
|
||||
// now because the struct_lint methods don't return back the DiagnosticBuilder
|
||||
// that's passed in.
|
||||
let decorate = |err: LintDiagnosticBuilder<'_>| {
|
||||
let msg = format!(
|
||||
"conflicting implementations of trait `{}`{}:{}",
|
||||
overlap.trait_desc,
|
||||
overlap.self_desc.clone().map_or(String::new(), |ty| { format!(" for type `{}`", ty) }),
|
||||
match used_to_be_allowed {
|
||||
Some(FutureCompatOverlapErrorKind::Issue33140) => " (E0119)",
|
||||
_ => "",
|
||||
}
|
||||
);
|
||||
let mut err = err.build(&msg);
|
||||
match tcx.span_of_impl(overlap.with_impl) {
|
||||
Ok(span) => {
|
||||
err.span_label(
|
||||
tcx.sess.source_map().guess_head_span(span),
|
||||
"first implementation here".to_string(),
|
||||
);
|
||||
|
||||
err.span_label(
|
||||
impl_span,
|
||||
format!(
|
||||
"conflicting implementation{}",
|
||||
overlap.self_desc.map_or(String::new(), |ty| format!(" for `{}`", ty))
|
||||
),
|
||||
);
|
||||
}
|
||||
Err(cname) => {
|
||||
let msg = match to_pretty_impl_header(tcx, overlap.with_impl) {
|
||||
Some(s) => format!("conflicting implementation in crate `{}`:\n- {}", cname, s),
|
||||
None => format!("conflicting implementation in crate `{}`", cname),
|
||||
};
|
||||
err.note(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
for cause in &overlap.intercrate_ambiguity_causes {
|
||||
cause.add_intercrate_ambiguity_hint(&mut err);
|
||||
}
|
||||
|
||||
if overlap.involves_placeholder {
|
||||
coherence::add_placeholder_note(&mut err);
|
||||
}
|
||||
err.emit()
|
||||
};
|
||||
|
||||
match used_to_be_allowed {
|
||||
None => {
|
||||
sg.has_errored = true;
|
||||
let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
|
||||
decorate(LintDiagnosticBuilder::new(err));
|
||||
}
|
||||
Some(kind) => {
|
||||
let lint = match kind {
|
||||
FutureCompatOverlapErrorKind::Issue33140 => ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||
FutureCompatOverlapErrorKind::LeakCheck => COHERENCE_LEAK_CHECK,
|
||||
};
|
||||
tcx.struct_span_lint_hir(
|
||||
lint,
|
||||
tcx.hir().as_local_hir_id(impl_def_id).unwrap(),
|
||||
impl_span,
|
||||
decorate,
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a
|
||||
/// string.
|
||||
fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String> {
|
||||
|
@ -1659,11 +1659,14 @@ fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: DefId, span:
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
tcx.sess.span_err(span, &format!(
|
||||
tcx.sess.span_err(
|
||||
span,
|
||||
&format!(
|
||||
"`{}` return type cannot contain a projection or `Self` that references lifetimes from \
|
||||
a parent scope",
|
||||
if is_async { "async fn" } else { "impl Trait" },
|
||||
));
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1841,8 +1844,8 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span)
|
||||
Ok(ConstValue::ByRef { alloc, .. }) => {
|
||||
if alloc.relocations().len() != 0 {
|
||||
let msg = "statics with a custom `#[link_section]` must be a \
|
||||
simple list of bytes on the wasm target with no \
|
||||
extra levels of indirection such as references";
|
||||
simple list of bytes on the wasm target with no \
|
||||
extra levels of indirection such as references";
|
||||
tcx.sess.span_err(span, msg);
|
||||
}
|
||||
}
|
||||
@ -1971,6 +1974,24 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
return;
|
||||
}
|
||||
|
||||
// Negative impls are not expected to have any items
|
||||
match tcx.impl_polarity(impl_id) {
|
||||
ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
|
||||
ty::ImplPolarity::Negative => {
|
||||
if let [first_item_ref, ..] = impl_item_refs {
|
||||
let first_item_span = tcx.hir().impl_item(first_item_ref.id).span;
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
first_item_span,
|
||||
E0749,
|
||||
"negative impls cannot have any items"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Locate trait definition and items
|
||||
let trait_def = tcx.trait_def(impl_trait_ref.def_id);
|
||||
|
||||
@ -2010,7 +2031,7 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
impl_item.span,
|
||||
E0323,
|
||||
"item `{}` is an associated const, \
|
||||
which doesn't match its trait `{}`",
|
||||
which doesn't match its trait `{}`",
|
||||
ty_impl_item.ident,
|
||||
impl_trait_ref.print_only_trait_path()
|
||||
);
|
||||
@ -3554,7 +3575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let adjusted_ty = autoderef.unambiguous_final_ty(self);
|
||||
debug!(
|
||||
"try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
|
||||
index_ty={:?})",
|
||||
index_ty={:?})",
|
||||
expr, base_expr, adjusted_ty, index_ty
|
||||
);
|
||||
|
||||
@ -4705,7 +4726,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
err.span_label(
|
||||
fn_span,
|
||||
"implicitly returns `()` as its body has no tail or `return` \
|
||||
expression",
|
||||
expression",
|
||||
);
|
||||
}
|
||||
},
|
||||
@ -5577,11 +5598,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
|
||||
Ok(ok) => self.register_infer_ok_obligations(ok),
|
||||
Err(_) => {
|
||||
self.tcx.sess.delay_span_bug(span, &format!(
|
||||
self.tcx.sess.delay_span_bug(
|
||||
span,
|
||||
&format!(
|
||||
"instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
|
||||
self_ty,
|
||||
impl_ty,
|
||||
));
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5767,7 +5791,7 @@ fn fatally_break_rust(sess: &Session) {
|
||||
handler.note_without_error("the compiler expectedly panicked. this is a feature.");
|
||||
handler.note_without_error(
|
||||
"we would appreciate a joke overview: \
|
||||
https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
|
||||
https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
|
||||
);
|
||||
handler.note_without_error(&format!(
|
||||
"rustc {} running on {}",
|
||||
|
@ -124,18 +124,16 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
|
||||
}
|
||||
(ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
|
||||
// FIXME(#27579): what amount of WF checking do we need for neg impls?
|
||||
if let (Some(of_trait), false) = (of_trait, is_auto) {
|
||||
if let hir::Defaultness::Default { .. } = defaultness {
|
||||
let mut spans = vec![span];
|
||||
spans.extend(defaultness_span);
|
||||
struct_span_err!(
|
||||
tcx.sess,
|
||||
span.to(of_trait.path.span),
|
||||
E0192,
|
||||
"invalid negative impl"
|
||||
spans,
|
||||
E0750,
|
||||
"negative impls cannot be default impls"
|
||||
)
|
||||
.note(
|
||||
"negative impls are only allowed for auto traits, like `Send` and \
|
||||
`Sync`",
|
||||
)
|
||||
.emit()
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
(ty::ImplPolarity::Reservation, _) => {
|
||||
@ -902,13 +900,13 @@ fn check_opaque_types<'fcx, 'tcx>(
|
||||
.struct_span_err(
|
||||
span,
|
||||
"non-defining opaque type use \
|
||||
in defining scope",
|
||||
in defining scope",
|
||||
)
|
||||
.span_label(
|
||||
param_span,
|
||||
"cannot use static lifetime; use a bound lifetime \
|
||||
instead or remove the lifetime parameter from the \
|
||||
opaque type",
|
||||
instead or remove the lifetime parameter from the \
|
||||
opaque type",
|
||||
)
|
||||
.emit();
|
||||
} else {
|
||||
@ -923,13 +921,13 @@ fn check_opaque_types<'fcx, 'tcx>(
|
||||
.struct_span_err(
|
||||
span,
|
||||
"non-defining opaque type use \
|
||||
in defining scope",
|
||||
in defining scope",
|
||||
)
|
||||
.span_note(
|
||||
tcx.def_span(param.def_id),
|
||||
&format!(
|
||||
"used non-generic const {} for \
|
||||
generic parameter",
|
||||
generic parameter",
|
||||
ty,
|
||||
),
|
||||
)
|
||||
@ -944,7 +942,7 @@ fn check_opaque_types<'fcx, 'tcx>(
|
||||
.struct_span_err(
|
||||
span,
|
||||
"non-defining opaque type use \
|
||||
in defining scope",
|
||||
in defining scope",
|
||||
)
|
||||
.span_note(spans, "lifetime used multiple times")
|
||||
.emit();
|
||||
@ -1030,7 +1028,7 @@ fn check_method_receiver<'fcx, 'tcx>(
|
||||
span,
|
||||
&format!(
|
||||
"`{}` cannot be used as the type of `self` without \
|
||||
the `arbitrary_self_types` feature",
|
||||
the `arbitrary_self_types` feature",
|
||||
receiver_ty,
|
||||
),
|
||||
)
|
||||
|
@ -278,6 +278,7 @@
|
||||
#![feature(maybe_uninit_ref)]
|
||||
#![feature(maybe_uninit_slice)]
|
||||
#![feature(needs_panic_runtime)]
|
||||
#![cfg_attr(not(bootstrap), feature(negative_impls))]
|
||||
#![feature(never_type)]
|
||||
#![feature(nll)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
// pp-exact
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
pub struct Foo;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// aux-build:rustdoc-impl-parts-crosscrate.rs
|
||||
// ignore-cross-compile
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
extern crate rustdoc_impl_parts_crosscrate;
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![feature(negative_impls)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
pub auto trait AnOibit {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
// @has issue_55321/struct.A.html
|
||||
// @has - '//*[@id="implementations-list"]/*[@class="impl"]//code' "impl !Send for A"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![crate_name = "foo"]
|
||||
|
||||
pub struct Foo;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
// @matches negative_impl/struct.Alpha.html '//pre' "pub struct Alpha"
|
||||
pub struct Alpha;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
// edition:2018
|
||||
|
||||
// This tests the the specialized async-await-specific error when futures don't implement an
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
// edition:2018
|
||||
|
||||
// This tests the the specialized async-await-specific error when futures don't implement an
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
// edition:2018
|
||||
|
||||
// This tests the the unspecialized async-await-specific error when futures don't implement an
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl std::future::Future`
|
||||
--> $DIR/issue-64130-3-other.rs:23:5
|
||||
--> $DIR/issue-64130-3-other.rs:24:5
|
||||
|
|
||||
LL | fn is_qux<T: Qux>(t: T) { }
|
||||
| ------ --- required by this bound in `is_qux`
|
||||
@ -13,7 +13,7 @@ LL | is_qux(bar());
|
||||
= help: the following implementations were found:
|
||||
<Foo as Qux>
|
||||
note: future does not implement `Qux` as this value is used across an await
|
||||
--> $DIR/issue-64130-3-other.rs:17:5
|
||||
--> $DIR/issue-64130-3-other.rs:18:5
|
||||
|
|
||||
LL | let x = Foo;
|
||||
| - has type `Foo`
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
fn main() {
|
||||
struct Foo;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(marker_trait_attr)]
|
||||
|
||||
#[marker]
|
||||
@ -6,13 +6,11 @@ trait MyTrait {}
|
||||
|
||||
struct TestType<T>(::std::marker::PhantomData<T>);
|
||||
|
||||
unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
|
||||
unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
|
||||
impl<T: MyTrait> !Send for TestType<T> {}
|
||||
//~^ ERROR conflicting implementations
|
||||
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation
|
||||
|
||||
unsafe impl<T:'static> Send for TestType<T> {}
|
||||
//~^ ERROR conflicting implementations
|
||||
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
|
||||
|
||||
impl !Send for TestType<i32> {}
|
||||
|
||||
|
@ -1,21 +1,22 @@
|
||||
error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`:
|
||||
error[E0748]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
|
||||
--> $DIR/coherence-conflicting-negative-trait-impl.rs:11:1
|
||||
|
|
||||
LL | unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
|
||||
| ---------------------------------------------------- first implementation here
|
||||
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
| ------------------------------------------------------ positive implementation here
|
||||
LL |
|
||||
LL | impl<T: MyTrait> !Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`:
|
||||
--> $DIR/coherence-conflicting-negative-trait-impl.rs:14:1
|
||||
--> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1
|
||||
|
|
||||
LL | unsafe impl<T: MyTrait+'static> Send for TestType<T> {}
|
||||
| ---------------------------------------------------- first implementation here
|
||||
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
| ------------------------------------------------------ first implementation here
|
||||
...
|
||||
LL | unsafe impl<T:'static> Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||
LL | unsafe impl<T: 'static> Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
Some errors have detailed explanations: E0119, E0748.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait MySafeTrait {}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0199]: implementing the trait `MySafeTrait` is not unsafe
|
||||
--> $DIR/coherence-default-trait-impl.rs:7:1
|
||||
--> $DIR/coherence-default-trait-impl.rs:8:1
|
||||
|
|
||||
LL | unsafe impl MySafeTrait for Foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0200]: the trait `MyUnsafeTrait` requires an `unsafe impl` declaration
|
||||
--> $DIR/coherence-default-trait-impl.rs:12:1
|
||||
--> $DIR/coherence-default-trait-impl.rs:13:1
|
||||
|
|
||||
LL | impl MyUnsafeTrait for Foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
// Test for issue #56934 - that it is impossible to redundantly
|
||||
// implement an auto-trait for a trait object type that contains it.
|
||||
|
@ -1,17 +1,17 @@
|
||||
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:14:1
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
|
||||
|
|
||||
LL | impl !Marker1 for dyn Object + Marker2 { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
|
||||
|
||||
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:16:1
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:17:1
|
||||
|
|
||||
LL | impl !Marker2 for dyn Object + Marker2 { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
|
||||
|
||||
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:22:1
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:23:1
|
||||
|
|
||||
LL | impl !Send for dyn Marker2 {}
|
||||
| ^^^^^^^^^^^^^^^-----------
|
||||
@ -22,13 +22,13 @@ LL | impl !Send for dyn Marker2 {}
|
||||
= note: define and implement a trait or new type instead
|
||||
|
||||
error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)`
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:26:1
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:27:1
|
||||
|
|
||||
LL | impl !Send for dyn Object {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
|
||||
|
||||
error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)`
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:27:1
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:28:1
|
||||
|
|
||||
LL | impl !Send for dyn Object + Marker2 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
// Test for issue #56934 - that it is impossible to redundantly
|
||||
// implement an auto-trait for a trait object type that contains it.
|
||||
|
@ -1,17 +1,17 @@
|
||||
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:14:1
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1
|
||||
|
|
||||
LL | impl Marker1 for dyn Object + Marker2 { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
|
||||
|
||||
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:16:1
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:17:1
|
||||
|
|
||||
LL | impl Marker2 for dyn Object + Marker2 { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
|
||||
|
||||
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:22:1
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:23:1
|
||||
|
|
||||
LL | unsafe impl Send for dyn Marker2 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^-----------
|
||||
@ -22,13 +22,13 @@ LL | unsafe impl Send for dyn Marker2 {}
|
||||
= note: define and implement a trait or new type instead
|
||||
|
||||
error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)`
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:26:1
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:27:1
|
||||
|
|
||||
LL | unsafe impl Send for dyn Object {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
|
||||
|
||||
error[E0321]: cross-crate traits with a default impl, like `std::marker::Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)`
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:27:1
|
||||
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:28:1
|
||||
|
|
||||
LL | unsafe impl Send for dyn Object + Marker2 {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Copy;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Copy;
|
||||
|
||||
enum TestE {
|
||||
A
|
||||
A,
|
||||
}
|
||||
|
||||
struct MyType;
|
||||
@ -26,5 +26,4 @@ unsafe impl Send for &'static [NotSync] {}
|
||||
//~^ ERROR conflicting implementations of trait
|
||||
//~| ERROR only traits defined in the current crate
|
||||
|
||||
fn main() {
|
||||
}
|
||||
fn main() {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Copy;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#![allow(dead_code)]
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// aux-build:coherence_orphan_lib.rs
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
extern crate coherence_orphan_lib as lib;
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait Trait {
|
||||
type Bar;
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl !Trait for Foo { } //~ ERROR E0192
|
||||
|
||||
fn main() {
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
error[E0192]: invalid negative impl
|
||||
--> $DIR/E0192.rs:9:6
|
||||
|
|
||||
LL | impl !Trait for Foo { }
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: negative impls are only allowed for auto traits, like `Send` and `Sync`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0192`.
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
|
@ -13,8 +13,8 @@ error[E0658]: negative trait bounds are not yet fully implemented; use marker ty
|
||||
LL | impl !AutoDummyTrait for DummyStruct {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #13231 <https://github.com/rust-lang/rust/issues/13231> for more information
|
||||
= help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable
|
||||
= note: see issue #68318 <https://github.com/rust-lang/rust/issues/68318> for more information
|
||||
= help: add `#![feature(negative_impls)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/auto-trait-regions.rs:45:24
|
||||
--> $DIR/auto-trait-regions.rs:46:24
|
||||
|
|
||||
LL | let a = A(&mut true, &mut true, No);
|
||||
| ^^^^ - temporary value is freed at the end of this statement
|
||||
@ -12,7 +12,7 @@ LL | assert_foo(a);
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/auto-trait-regions.rs:45:35
|
||||
--> $DIR/auto-trait-regions.rs:46:35
|
||||
|
|
||||
LL | let a = A(&mut true, &mut true, No);
|
||||
| ^^^^ - temporary value is freed at the end of this statement
|
||||
@ -25,13 +25,13 @@ LL | assert_foo(a);
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/auto-trait-regions.rs:30:5
|
||||
--> $DIR/auto-trait-regions.rs:31:5
|
||||
|
|
||||
LL | assert_foo(gen);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/auto-trait-regions.rs:49:5
|
||||
--> $DIR/auto-trait-regions.rs:50:5
|
||||
|
|
||||
LL | assert_foo(gen);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
@ -1,5 +1,6 @@
|
||||
#![feature(generators)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait Foo {}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: implementation of `Foo` is not general enough
|
||||
--> $DIR/auto-trait-regions.rs:30:5
|
||||
--> $DIR/auto-trait-regions.rs:31:5
|
||||
|
|
||||
LL | auto trait Foo {}
|
||||
| ----------------- trait `Foo` defined here
|
||||
@ -11,7 +11,7 @@ LL | assert_foo(gen);
|
||||
= note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Foo` is not general enough
|
||||
--> $DIR/auto-trait-regions.rs:30:5
|
||||
--> $DIR/auto-trait-regions.rs:31:5
|
||||
|
|
||||
LL | auto trait Foo {}
|
||||
| ----------------- trait `Foo` defined here
|
||||
@ -23,7 +23,7 @@ LL | assert_foo(gen);
|
||||
= note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Foo` is not general enough
|
||||
--> $DIR/auto-trait-regions.rs:49:5
|
||||
--> $DIR/auto-trait-regions.rs:50:5
|
||||
|
|
||||
LL | auto trait Foo {}
|
||||
| ----------------- trait `Foo` defined here
|
||||
@ -35,7 +35,7 @@ LL | assert_foo(gen);
|
||||
= note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2`
|
||||
|
||||
error: implementation of `Foo` is not general enough
|
||||
--> $DIR/auto-trait-regions.rs:49:5
|
||||
--> $DIR/auto-trait-regions.rs:50:5
|
||||
|
|
||||
LL | auto trait Foo {}
|
||||
| ----------------- trait `Foo` defined here
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Sync;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
//~ ERROR
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
unsafe auto trait Trait {
|
||||
type Output; //~ ERROR E0380
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0380]: auto traits cannot have methods or associated items
|
||||
--> $DIR/issue-23080-2.rs:6:10
|
||||
--> $DIR/issue-23080-2.rs:7:10
|
||||
|
|
||||
LL | unsafe auto trait Trait {
|
||||
| ----- auto trait cannot have items
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
unsafe auto trait Trait {
|
||||
fn method(&self) { //~ ERROR E0380
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0380]: auto traits cannot have methods or associated items
|
||||
--> $DIR/issue-23080.rs:4:8
|
||||
--> $DIR/issue-23080.rs:5:8
|
||||
|
|
||||
LL | unsafe auto trait Trait {
|
||||
| ----- auto trait cannot have items
|
||||
|
@ -1,5 +1,6 @@
|
||||
// check-pass
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait NotSame {}
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![allow(order_dependent_trait_objects)]
|
||||
|
||||
// Check that the issue #33140 hack does not allow unintended things.
|
||||
|
||||
// OK
|
||||
trait Trait0 {
|
||||
}
|
||||
trait Trait0 {}
|
||||
|
||||
impl Trait0 for dyn Send {}
|
||||
impl Trait0 for dyn Send {}
|
||||
@ -20,58 +19,49 @@ impl Trait1 for dyn Send {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
// Problem 2: negative impl
|
||||
trait Trait2 {
|
||||
}
|
||||
trait Trait2 {}
|
||||
|
||||
impl Trait2 for dyn Send {}
|
||||
impl !Trait2 for dyn Send {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
//~^ ERROR E0748
|
||||
|
||||
// Problem 3: type parameter
|
||||
trait Trait3<T: ?Sized> {
|
||||
}
|
||||
trait Trait3<T: ?Sized> {}
|
||||
|
||||
impl Trait3<dyn Sync> for dyn Send {}
|
||||
impl Trait3<dyn Sync> for dyn Send {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
// Problem 4a: not a trait object - generic
|
||||
trait Trait4a {
|
||||
}
|
||||
trait Trait4a {}
|
||||
|
||||
impl<T: ?Sized> Trait4a for T {}
|
||||
impl Trait4a for dyn Send {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
// Problem 4b: not a trait object - misc
|
||||
trait Trait4b {
|
||||
}
|
||||
trait Trait4b {}
|
||||
|
||||
impl Trait4b for () {}
|
||||
impl Trait4b for () {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
// Problem 4c: not a principal-less trait object
|
||||
trait Trait4c {
|
||||
}
|
||||
trait Trait4c {}
|
||||
|
||||
impl Trait4c for dyn Trait1 + Send {}
|
||||
impl Trait4c for dyn Trait1 + Send {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
// Problem 4d: lifetimes
|
||||
trait Trait4d {
|
||||
}
|
||||
trait Trait4d {}
|
||||
|
||||
impl<'a> Trait4d for dyn Send + 'a {}
|
||||
impl<'a> Trait4d for dyn Send + 'a {}
|
||||
//~^ ERROR E0119
|
||||
|
||||
|
||||
// Problem 5: where-clauses
|
||||
trait Trait5 {
|
||||
}
|
||||
trait Trait5 {}
|
||||
|
||||
impl Trait5 for dyn Send {}
|
||||
impl Trait5 for dyn Send where u32: Copy {}
|
||||
|
@ -1,21 +1,21 @@
|
||||
error[E0119]: conflicting implementations of trait `Trait1` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:19:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:18:1
|
||||
|
|
||||
LL | impl Trait1 for dyn Send {}
|
||||
| ------------------------ first implementation here
|
||||
LL | impl Trait1 for dyn Send {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:27:1
|
||||
error[E0748]: found both positive and negative implementation of trait `Trait2` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:25:1
|
||||
|
|
||||
LL | impl Trait2 for dyn Send {}
|
||||
| ------------------------ first implementation here
|
||||
| ------------------------ positive implementation here
|
||||
LL | impl !Trait2 for dyn Send {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait3<(dyn std::marker::Sync + 'static)>` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:36:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:32:1
|
||||
|
|
||||
LL | impl Trait3<dyn Sync> for dyn Send {}
|
||||
| ---------------------------------- first implementation here
|
||||
@ -23,7 +23,7 @@ LL | impl Trait3<dyn Sync> for dyn Send {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait4a` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:44:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:39:1
|
||||
|
|
||||
LL | impl<T: ?Sized> Trait4a for T {}
|
||||
| ----------------------------- first implementation here
|
||||
@ -31,7 +31,7 @@ LL | impl Trait4a for dyn Send {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait4b` for type `()`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:52:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:46:1
|
||||
|
|
||||
LL | impl Trait4b for () {}
|
||||
| ------------------- first implementation here
|
||||
@ -39,7 +39,7 @@ LL | impl Trait4b for () {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait4c` for type `(dyn Trait1 + std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:60:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:53:1
|
||||
|
|
||||
LL | impl Trait4c for dyn Trait1 + Send {}
|
||||
| ---------------------------------- first implementation here
|
||||
@ -47,7 +47,7 @@ LL | impl Trait4c for dyn Trait1 + Send {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn Trait1 + std::marker::Send + 'static)`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait4d` for type `dyn std::marker::Send`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:68:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:60:1
|
||||
|
|
||||
LL | impl<'a> Trait4d for dyn Send + 'a {}
|
||||
| ---------------------------------- first implementation here
|
||||
@ -55,7 +55,7 @@ LL | impl<'a> Trait4d for dyn Send + 'a {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `dyn std::marker::Send`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Trait5` for type `(dyn std::marker::Send + 'static)`:
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:77:1
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:67:1
|
||||
|
|
||||
LL | impl Trait5 for dyn Send {}
|
||||
| ------------------------ first implementation here
|
||||
@ -64,4 +64,5 @@ LL | impl Trait5 for dyn Send where u32: Copy {}
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
Some errors have detailed explanations: E0119, E0748.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Tests that an `&` pointer to something inherently mutable is itself
|
||||
// to be considered mutable.
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Sync;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(never_type)]
|
||||
|
||||
fn main() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Sync;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Sync;
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
struct Foo(i32);
|
||||
|
||||
fn main() {
|
||||
let Foo(...) = Foo(0); //~ ERROR unexpected `...`
|
||||
let [_, ..., _] = [0, 1]; //~ ERROR unexpected `...`
|
||||
let _recovery_witness: () = 0; //~ ERROR mismatched types
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
error: unexpected `...`
|
||||
--> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:4:13
|
||||
|
|
||||
LL | let Foo(...) = Foo(0);
|
||||
| ^^^
|
||||
| |
|
||||
| not a valid pattern
|
||||
| help: for a rest pattern, use `..` instead of `...`
|
||||
|
||||
error: unexpected `...`
|
||||
--> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:5:13
|
||||
|
|
||||
LL | let [_, ..., _] = [0, 1];
|
||||
| ^^^
|
||||
| |
|
||||
| not a valid pattern
|
||||
| help: for a rest pattern, use `..` instead of `...`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-70388-recover-dotdotdot-rest-pat.rs:6:33
|
||||
|
|
||||
LL | let _recovery_witness: () = 0;
|
||||
| -- ^ expected `()`, found integer
|
||||
| |
|
||||
| expected due to this
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![allow(bare_trait_objects)]
|
||||
|
||||
auto trait Auto {}
|
||||
|
@ -1,23 +1,23 @@
|
||||
error[E0178]: expected a path on the left-hand side of `+`, not `((Auto))`
|
||||
--> $DIR/trait-object-bad-parens.rs:7:16
|
||||
--> $DIR/trait-object-bad-parens.rs:8:16
|
||||
|
|
||||
LL | let _: Box<((Auto)) + Auto>;
|
||||
| ^^^^^^^^^^^^^^^ expected a path
|
||||
|
||||
error[E0178]: expected a path on the left-hand side of `+`, not `(Auto + Auto)`
|
||||
--> $DIR/trait-object-bad-parens.rs:9:16
|
||||
--> $DIR/trait-object-bad-parens.rs:10:16
|
||||
|
|
||||
LL | let _: Box<(Auto + Auto) + Auto>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ expected a path
|
||||
|
||||
error[E0178]: expected a path on the left-hand side of `+`, not `(Auto)`
|
||||
--> $DIR/trait-object-bad-parens.rs:11:16
|
||||
--> $DIR/trait-object-bad-parens.rs:12:16
|
||||
|
|
||||
LL | let _: Box<(Auto +) + Auto>;
|
||||
| ^^^^^^^^^^^^^^^ expected a path
|
||||
|
||||
error[E0178]: expected a path on the left-hand side of `+`, not `(dyn Auto)`
|
||||
--> $DIR/trait-object-bad-parens.rs:13:16
|
||||
--> $DIR/trait-object-bad-parens.rs:14:16
|
||||
|
|
||||
LL | let _: Box<(dyn Auto) + Auto>;
|
||||
| ^^^^^^^^^^^^^^^^^ expected a path
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
pub trait Tr {
|
||||
fn f();
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
#[allow(private_in_public)]
|
||||
mod m {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: trait `m::PrivNonPrincipal` is private
|
||||
--> $DIR/private-in-public-non-principal-2.rs:11:5
|
||||
--> $DIR/private-in-public-non-principal-2.rs:12:5
|
||||
|
|
||||
LL | m::leak_dyn_nonprincipal();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ private trait
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
pub trait PubPrincipal {}
|
||||
auto trait PrivNonPrincipal {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
warning: private trait `PrivNonPrincipal` in public interface (error E0445)
|
||||
--> $DIR/private-in-public-non-principal.rs:6:1
|
||||
--> $DIR/private-in-public-non-principal.rs:7:1
|
||||
|
|
||||
LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -9,13 +9,13 @@ LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal>
|
||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||
|
||||
error: missing documentation for an associated function
|
||||
--> $DIR/private-in-public-non-principal.rs:13:9
|
||||
--> $DIR/private-in-public-non-principal.rs:14:9
|
||||
|
|
||||
LL | pub fn check_doc_lint() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/private-in-public-non-principal.rs:10:8
|
||||
--> $DIR/private-in-public-non-principal.rs:11:8
|
||||
|
|
||||
LL | #[deny(missing_docs)]
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(specialization)]
|
||||
|
||||
struct S;
|
||||
@ -8,8 +8,9 @@ default impl S {} //~ ERROR inherent impls cannot be `default`
|
||||
|
||||
default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default
|
||||
default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default
|
||||
//~^ ERROR negative impls cannot be default impls
|
||||
|
||||
trait Tr {}
|
||||
default impl !Tr for S {} //~ ERROR invalid negative impl
|
||||
default impl !Tr for S {} //~ ERROR negative impls cannot be default impls
|
||||
|
||||
fn main() {}
|
||||
|
@ -24,14 +24,18 @@ LL | default impl !Send for Z {}
|
||||
| |
|
||||
| default because of this
|
||||
|
||||
error[E0192]: invalid negative impl
|
||||
--> $DIR/validation.rs:13:14
|
||||
error[E0750]: negative impls cannot be default impls
|
||||
--> $DIR/validation.rs:10:14
|
||||
|
|
||||
LL | default impl !Send for Z {}
|
||||
| ^^^^^^^ ^
|
||||
|
||||
error[E0750]: negative impls cannot be default impls
|
||||
--> $DIR/validation.rs:14:14
|
||||
|
|
||||
LL | default impl !Tr for S {}
|
||||
| ^^^
|
||||
|
|
||||
= note: negative impls are only allowed for auto traits, like `Send` and `Sync`
|
||||
| ^^^^^^^ ^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0192`.
|
||||
For more information about this error, try `rustc --explain E0750`.
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(specialization)]
|
||||
|
||||
trait MyTrait {}
|
||||
@ -6,6 +6,6 @@ trait MyTrait {}
|
||||
struct TestType<T>(::std::marker::PhantomData<T>);
|
||||
|
||||
unsafe impl<T: Clone> Send for TestType<T> {}
|
||||
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR E0119
|
||||
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR E0748
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0119]: conflicting implementations of trait `std::marker::Send` for type `TestType<_>`:
|
||||
error[E0748]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`:
|
||||
--> $DIR/specialization-overlap-negative.rs:9:1
|
||||
|
|
||||
LL | unsafe impl<T: Clone> Send for TestType<T> {}
|
||||
| ------------------------------------------ first implementation here
|
||||
| ------------------------------------------ positive implementation here
|
||||
LL | impl<T: MyTrait> !Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
For more information about this error, try `rustc --explain E0748`.
|
||||
|
@ -1,16 +1,17 @@
|
||||
// Make sure specialization cannot change impl polarity
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(specialization)]
|
||||
|
||||
auto trait Foo {}
|
||||
|
||||
impl<T> Foo for T {}
|
||||
impl !Foo for u8 {} //~ ERROR E0119
|
||||
impl !Foo for u8 {} //~ ERROR E0748
|
||||
|
||||
auto trait Bar {}
|
||||
|
||||
impl<T> !Bar for T {}
|
||||
impl Bar for u8 {} //~ ERROR E0119
|
||||
impl Bar for u8 {} //~ ERROR E0748
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,19 +1,19 @@
|
||||
error[E0119]: conflicting implementations of trait `Foo` for type `u8`:
|
||||
--> $DIR/specialization-polarity.rs:9:1
|
||||
error[E0748]: found both positive and negative implementation of trait `Foo` for type `u8`:
|
||||
--> $DIR/specialization-polarity.rs:10:1
|
||||
|
|
||||
LL | impl<T> Foo for T {}
|
||||
| ----------------- first implementation here
|
||||
| ----------------- positive implementation here
|
||||
LL | impl !Foo for u8 {}
|
||||
| ^^^^^^^^^^^^^^^^ conflicting implementation for `u8`
|
||||
| ^^^^^^^^^^^^^^^^ negative implementation here
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Bar` for type `u8`:
|
||||
--> $DIR/specialization-polarity.rs:14:1
|
||||
error[E0748]: found both positive and negative implementation of trait `Bar` for type `u8`:
|
||||
--> $DIR/specialization-polarity.rs:15:1
|
||||
|
|
||||
LL | impl<T> !Bar for T {}
|
||||
| ------------------ first implementation here
|
||||
| ------------------ negative implementation here
|
||||
LL | impl Bar for u8 {}
|
||||
| ^^^^^^^^^^^^^^^ conflicting implementation for `u8`
|
||||
| ^^^^^^^^^^^^^^^ positive implementation here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
For more information about this error, try `rustc --explain E0748`.
|
||||
|
@ -4,8 +4,8 @@ error[E0658]: negative trait bounds are not yet fully implemented; use marker ty
|
||||
LL | impl !Send for TestType {}
|
||||
| ^^^^^
|
||||
|
|
||||
= note: see issue #13231 <https://github.com/rust-lang/rust/issues/13231> for more information
|
||||
= help: add `#![feature(optin_builtin_traits)]` to the crate attributes to enable
|
||||
= note: see issue #68318 <https://github.com/rust-lang/rust/issues/68318> for more information
|
||||
= help: add `#![feature(negative_impls)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
||||
@ -12,7 +12,6 @@ trait TestTrait {}
|
||||
unsafe impl !Send for TestType {}
|
||||
//~^ ERROR negative impls cannot be unsafe
|
||||
impl !TestTrait for TestType {}
|
||||
//~^ ERROR invalid negative impl
|
||||
|
||||
struct TestType2<T>(T);
|
||||
|
||||
@ -22,6 +21,5 @@ impl<T> !TestType2<T> {}
|
||||
unsafe impl<T> !Send for TestType2<T> {}
|
||||
//~^ ERROR negative impls cannot be unsafe
|
||||
impl<T> !TestTrait for TestType2<T> {}
|
||||
//~^ ERROR invalid negative impl
|
||||
|
||||
fn main() {}
|
||||
|
@ -16,7 +16,7 @@ LL | unsafe impl !Send for TestType {}
|
||||
| unsafe because of this
|
||||
|
||||
error: inherent impls cannot be negative
|
||||
--> $DIR/syntax-trait-polarity.rs:19:10
|
||||
--> $DIR/syntax-trait-polarity.rs:18:10
|
||||
|
|
||||
LL | impl<T> !TestType2<T> {}
|
||||
| -^^^^^^^^^^^^ inherent impl for this type
|
||||
@ -24,7 +24,7 @@ LL | impl<T> !TestType2<T> {}
|
||||
| negative because of this
|
||||
|
||||
error[E0198]: negative impls cannot be unsafe
|
||||
--> $DIR/syntax-trait-polarity.rs:22:16
|
||||
--> $DIR/syntax-trait-polarity.rs:21:16
|
||||
|
|
||||
LL | unsafe impl<T> !Send for TestType2<T> {}
|
||||
| ------ -^^^^
|
||||
@ -32,23 +32,6 @@ LL | unsafe impl<T> !Send for TestType2<T> {}
|
||||
| | negative because of this
|
||||
| unsafe because of this
|
||||
|
||||
error[E0192]: invalid negative impl
|
||||
--> $DIR/syntax-trait-polarity.rs:14:6
|
||||
|
|
||||
LL | impl !TestTrait for TestType {}
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: negative impls are only allowed for auto traits, like `Send` and `Sync`
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
error[E0192]: invalid negative impl
|
||||
--> $DIR/syntax-trait-polarity.rs:24:9
|
||||
|
|
||||
LL | impl<T> !TestTrait for TestType2<T> {}
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: negative impls are only allowed for auto traits, like `Send` and `Sync`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0192, E0198.
|
||||
For more information about an error, try `rustc --explain E0192`.
|
||||
For more information about this error, try `rustc --explain E0198`.
|
||||
|
@ -1,6 +1,7 @@
|
||||
// run-pass
|
||||
#![allow(unused_doc_comments)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
auto trait Auto {}
|
||||
unsafe auto trait AutoUnsafe {}
|
||||
|
@ -0,0 +1,6 @@
|
||||
#![feature(negative_impls)]
|
||||
|
||||
pub trait ForeignTrait {}
|
||||
|
||||
impl ForeignTrait for u32 {}
|
||||
impl !ForeignTrait for String {}
|
@ -0,0 +1,3 @@
|
||||
trait MyTrait {}
|
||||
impl !MyTrait for u32 {} //~ ERROR negative trait bounds are not yet fully implemented
|
||||
fn main() {}
|
@ -0,0 +1,12 @@
|
||||
error[E0658]: negative trait bounds are not yet fully implemented; use marker types for now
|
||||
--> $DIR/feature-gate-negative_impls.rs:2:6
|
||||
|
|
||||
LL | impl !MyTrait for u32 {}
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: see issue #68318 <https://github.com/rust-lang/rust/issues/68318> for more information
|
||||
= help: add `#![feature(negative_impls)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -3,7 +3,7 @@
|
||||
// errors are not reported. This way, we make sure that, for each function, different
|
||||
// typeck phases are involved and all errors are reported.
|
||||
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0277]: `dummy::TestType` cannot be sent between threads safely
|
||||
--> $DIR/traits-negative-impls.rs:23:11
|
||||
--> $DIR/negated-auto-traits-error.rs:23:11
|
||||
|
|
||||
LL | struct Outer<T: Send>(T);
|
||||
| ------------------------- required by `Outer`
|
||||
@ -10,7 +10,7 @@ LL | Outer(TestType);
|
||||
= help: the trait `std::marker::Send` is not implemented for `dummy::TestType`
|
||||
|
||||
error[E0277]: `dummy::TestType` cannot be sent between threads safely
|
||||
--> $DIR/traits-negative-impls.rs:23:5
|
||||
--> $DIR/negated-auto-traits-error.rs:23:5
|
||||
|
|
||||
LL | struct Outer<T: Send>(T);
|
||||
| ------------------------- required by `Outer`
|
||||
@ -21,7 +21,7 @@ LL | Outer(TestType);
|
||||
= help: the trait `std::marker::Send` is not implemented for `dummy::TestType`
|
||||
|
||||
error[E0277]: `dummy1b::TestType` cannot be sent between threads safely
|
||||
--> $DIR/traits-negative-impls.rs:32:13
|
||||
--> $DIR/negated-auto-traits-error.rs:32:13
|
||||
|
|
||||
LL | fn is_send<T: Send>(_: T) {}
|
||||
| ------- ---- required by this bound in `is_send`
|
||||
@ -32,7 +32,7 @@ LL | is_send(TestType);
|
||||
= help: the trait `std::marker::Send` is not implemented for `dummy1b::TestType`
|
||||
|
||||
error[E0277]: `dummy1c::TestType` cannot be sent between threads safely
|
||||
--> $DIR/traits-negative-impls.rs:40:13
|
||||
--> $DIR/negated-auto-traits-error.rs:40:13
|
||||
|
|
||||
LL | fn is_send<T: Send>(_: T) {}
|
||||
| ------- ---- required by this bound in `is_send`
|
||||
@ -44,7 +44,7 @@ LL | is_send((8, TestType));
|
||||
= note: required because it appears within the type `({integer}, dummy1c::TestType)`
|
||||
|
||||
error[E0277]: `dummy2::TestType` cannot be sent between threads safely
|
||||
--> $DIR/traits-negative-impls.rs:48:13
|
||||
--> $DIR/negated-auto-traits-error.rs:48:13
|
||||
|
|
||||
LL | fn is_send<T: Send>(_: T) {}
|
||||
| ------- ---- required by this bound in `is_send`
|
||||
@ -60,7 +60,7 @@ LL | is_send(Box::new(TestType));
|
||||
= note: required because it appears within the type `std::boxed::Box<dummy2::TestType>`
|
||||
|
||||
error[E0277]: `dummy3::TestType` cannot be sent between threads safely
|
||||
--> $DIR/traits-negative-impls.rs:56:13
|
||||
--> $DIR/negated-auto-traits-error.rs:56:13
|
||||
|
|
||||
LL | fn is_send<T: Send>(_: T) {}
|
||||
| ------- ---- required by this bound in `is_send`
|
||||
@ -74,7 +74,7 @@ LL | is_send(Box::new(Outer2(TestType)));
|
||||
= note: required because it appears within the type `std::boxed::Box<Outer2<dummy3::TestType>>`
|
||||
|
||||
error[E0277]: `main::TestType` cannot be sent between threads safely
|
||||
--> $DIR/traits-negative-impls.rs:66:13
|
||||
--> $DIR/negated-auto-traits-error.rs:66:13
|
||||
|
|
||||
LL | fn is_sync<T: Sync>(_: T) {}
|
||||
| ------- ---- required by this bound in `is_sync`
|
@ -1,6 +1,6 @@
|
||||
// run-pass
|
||||
#![allow(unused_variables)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(negative_impls)]
|
||||
|
||||
use std::marker::Send;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user