提交 2fbb0752 编写于 作者: B bors

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
# `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 @@ fn clone(&self) -> Self {
}
}
// 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 @@ fn clone(&self) -> Self {
*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 @@ impl<T: ?Sized> Copy for *const T {}
#[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 @@ fn deref(&self) -> &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 @@ fn univariant_uninterned(
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 @@ fn univariant_uninterned(
// 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 @@ fn layout_raw_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<
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 @@ fn check_expr_within_pat(&self, expr: &Expr, allow_paths: bool) {
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 @@ fn visit_item(&mut self, i: &'a ast::Item) {
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 @@ fn visit_item(&mut self, i: &'a ast::Item) {
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 @@ fn visit_item(&mut self, i: &'a ast::Item) {
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 @@
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 @@
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 @@
// 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,
......
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.
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.
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 @@ fn print_error_count(&mut self, registry: &Registry) {
));
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 @@ pub fn set(&self, features: &mut Features, span: Span) {
// 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 @@ fn before_access_global(
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 @@ fn before_access_global(
_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 @@ fn before_access_global(
_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 @@ fn before_access_global(
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 @@ fn parse_pat_with_range_pat(
// 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 @@ fn parse_pat_with_range_pat(
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 @@
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 visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
_ => 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 @@ fn try_index_step(
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 @@ fn check_block_with_expected(
err.span_label(
fn_span,
"implicitly returns `()` as its body has no tail or `return` \
expression",
expression",
);
}
},
......@@ -5577,11 +5598,14 @@ pub fn instantiate_value_path(
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)]
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
// pp-exact
......
#![crate_name = "foo"]
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
pub struct Foo;
......
// aux-build:rustdoc-impl-parts-crosscrate.rs
// ignore-cross-compile
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
extern crate rustdoc_impl_parts_crosscrate;
......
#![feature(negative_impls)]
#![feature(optin_builtin_traits)]
pub auto trait AnOibit {}
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
// @has issue_55321/struct.A.html
// @has - '//*[@id="implementations-list"]/*[@class="impl"]//code' "impl !Send for A"
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
#![crate_name = "foo"]
pub struct Foo;
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
// @matches negative_impl/struct.Alpha.html '//pre' "pub struct Alpha"
pub struct Alpha;
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
// edition:2018
// This tests the the specialized async-await-specific error when futures don't implement an
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
// edition:2018
// This tests the the specialized async-await-specific error when futures don't implement an
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
// edition:2018
// This tests the the unspecialized async-await-specific error when futures don't implement an
......
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`
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
fn main() {
struct Foo;
......
#![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> {}
......
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`.
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
auto trait MySafeTrait {}
......
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 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......
#![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.
......
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
......
#![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.
......
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
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
use std::marker::Copy;
......
#![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() {}
#![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;
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
use std::marker::Send;
......
// aux-build:coherence_orphan_lib.rs
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
extern crate coherence_orphan_lib as lib;
......
#![feature(optin_builtin_traits)]
trait Trait {
type Bar;
}
struct Foo;
impl !Trait for Foo { } //~ ERROR E0192
fn main() {
}
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`.
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
struct Foo;
......
#![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
......
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);
| ^^^^^^^^^^^^^^^
......
#![feature(generators)]
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
auto trait Foo {}
......
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
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
use std::marker::Sync;
......
//~ ERROR
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
unsafe auto trait Trait {
type Output; //~ ERROR E0380
......
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
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
unsafe auto trait Trait {
fn method(&self) { //~ ERROR E0380
......
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
......
// check-pass
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
auto trait NotSame {}
......
#![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 {}
......
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`.
// 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;
......
// check-pass
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
#![feature(never_type)]
fn main() {
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
use std::marker::Send;
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
use std::marker::Send;
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
use std::marker::Sync;
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
use std::marker::Sync;
......
struct Foo(i32);
fn main() {
let Foo(...) = Foo(0); //~ ERROR unexpected `...`
let [_, ..., _] = [0, 1]; //~ ERROR unexpected `...`
let _recovery_witness: () = 0; //~ ERROR mismatched types
}
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`.
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
#![allow(bare_trait_objects)]
auto trait Auto {}
......
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
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
pub trait Tr {
fn f();
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
#[allow(private_in_public)]
mod m {
......
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
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
pub trait PubPrincipal {}
auto trait PrivNonPrincipal {}
......
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)]
| ^^^^^^^^^^^^
......
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
#![feature(specialization)]
struct S;
......@@ -8,8 +8,9 @@
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 !Tr for S {}
| ^^^
LL | default impl !Send for Z {}
| ^^^^^^^ ^
error[E0750]: negative impls cannot be default impls
--> $DIR/validation.rs:14:14
|
= note: negative impls are only allowed for auto traits, like `Send` and `Sync`
LL | default impl !Tr for S {}
| ^^^^^^^ ^
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`.
#![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() {}
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`.
// 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() {}
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
......
#![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[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
error: aborting due to 4 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`.
// run-pass
#![allow(unused_doc_comments)]
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
auto trait Auto {}
unsafe auto trait AutoUnsafe {}
......
#![feature(negative_impls)]
pub trait ForeignTrait {}
impl ForeignTrait for u32 {}
impl !ForeignTrait for String {}
trait MyTrait {}
impl !MyTrait for u32 {} //~ ERROR negative trait bounds are not yet fully implemented
fn main() {}
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;
......
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`
......
// run-pass
#![allow(unused_variables)]
#![feature(optin_builtin_traits)]
#![feature(negative_impls)]
use std::marker::Send;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册