mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #119354 - fmease:negative_bounds-fixes, r=compiler-errors
Make `negative_bounds` internal & fix some of its issues r? compiler-errors
This commit is contained in:
commit
ea6129084e
@ -188,6 +188,9 @@ ast_passes_module_nonascii = trying to load file for module `{$name}` with non-a
|
|||||||
ast_passes_negative_bound_not_supported =
|
ast_passes_negative_bound_not_supported =
|
||||||
negative bounds are not supported
|
negative bounds are not supported
|
||||||
|
|
||||||
|
ast_passes_negative_bound_with_parenthetical_notation =
|
||||||
|
parenthetical notation may not be used for negative bounds
|
||||||
|
|
||||||
ast_passes_nested_impl_trait = nested `impl Trait` is not allowed
|
ast_passes_nested_impl_trait = nested `impl Trait` is not allowed
|
||||||
.outer = outer `impl Trait`
|
.outer = outer `impl Trait`
|
||||||
.inner = nested `impl Trait` here
|
.inner = nested `impl Trait` here
|
||||||
|
@ -1312,13 +1312,24 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
if let GenericBound::Trait(trait_ref, modifiers) = bound
|
if let GenericBound::Trait(trait_ref, modifiers) = bound
|
||||||
&& let BoundPolarity::Negative(_) = modifiers.polarity
|
&& let BoundPolarity::Negative(_) = modifiers.polarity
|
||||||
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
||||||
&& let Some(ast::GenericArgs::AngleBracketed(args)) = segment.args.as_deref()
|
|
||||||
{
|
{
|
||||||
for arg in &args.args {
|
match segment.args.as_deref() {
|
||||||
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
|
Some(ast::GenericArgs::AngleBracketed(args)) => {
|
||||||
self.dcx()
|
for arg in &args.args {
|
||||||
.emit_err(errors::ConstraintOnNegativeBound { span: constraint.span });
|
if let ast::AngleBracketedArg::Constraint(constraint) = arg {
|
||||||
|
self.dcx().emit_err(errors::ConstraintOnNegativeBound {
|
||||||
|
span: constraint.span,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// The lowered form of parenthesized generic args contains a type binding.
|
||||||
|
Some(ast::GenericArgs::Parenthesized(args)) => {
|
||||||
|
self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation {
|
||||||
|
span: args.span,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,6 +763,13 @@ pub struct ConstraintOnNegativeBound {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(ast_passes_negative_bound_with_parenthetical_notation)]
|
||||||
|
pub struct NegativeBoundWithParentheticalNotation {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(ast_passes_invalid_unnamed_field_ty)]
|
#[diag(ast_passes_invalid_unnamed_field_ty)]
|
||||||
pub struct InvalidUnnamedFieldTy {
|
pub struct InvalidUnnamedFieldTy {
|
||||||
|
@ -210,7 +210,7 @@ declare_features! (
|
|||||||
/// Allows the `multiple_supertrait_upcastable` lint.
|
/// Allows the `multiple_supertrait_upcastable` lint.
|
||||||
(unstable, multiple_supertrait_upcastable, "1.69.0", None),
|
(unstable, multiple_supertrait_upcastable, "1.69.0", None),
|
||||||
/// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!
|
/// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!
|
||||||
(incomplete, negative_bounds, "1.71.0", None),
|
(internal, negative_bounds, "1.71.0", None),
|
||||||
/// Allows using `#[omit_gdb_pretty_printer_section]`.
|
/// Allows using `#[omit_gdb_pretty_printer_section]`.
|
||||||
(internal, omit_gdb_pretty_printer_section, "1.5.0", None),
|
(internal, omit_gdb_pretty_printer_section, "1.5.0", None),
|
||||||
/// Allows using `#[prelude_import]` on glob `use` items.
|
/// Allows using `#[prelude_import]` on glob `use` items.
|
||||||
|
@ -26,23 +26,36 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
let sized_def_id = tcx.lang_items().sized_trait();
|
||||||
|
let mut seen_negative_sized_bound = false;
|
||||||
|
|
||||||
// Try to find an unbound in bounds.
|
// Try to find an unbound in bounds.
|
||||||
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
|
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
|
||||||
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
||||||
for ab in ast_bounds {
|
for ab in ast_bounds {
|
||||||
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
|
let hir::GenericBound::Trait(ptr, modifier) = ab else {
|
||||||
unbounds.push(ptr)
|
continue;
|
||||||
|
};
|
||||||
|
match modifier {
|
||||||
|
hir::TraitBoundModifier::Maybe => unbounds.push(ptr),
|
||||||
|
hir::TraitBoundModifier::Negative => {
|
||||||
|
if let Some(sized_def_id) = sized_def_id
|
||||||
|
&& ptr.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
|
||||||
|
{
|
||||||
|
seen_negative_sized_bound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
search_bounds(ast_bounds);
|
search_bounds(ast_bounds);
|
||||||
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
|
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
|
||||||
for clause in where_clause {
|
for clause in where_clause {
|
||||||
if let hir::WherePredicate::BoundPredicate(pred) = clause {
|
if let hir::WherePredicate::BoundPredicate(pred) = clause
|
||||||
if pred.is_param_bound(self_ty.to_def_id()) {
|
&& pred.is_param_bound(self_ty.to_def_id())
|
||||||
search_bounds(pred.bounds);
|
{
|
||||||
}
|
search_bounds(pred.bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,15 +66,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let sized_def_id = tcx.lang_items().sized_trait();
|
|
||||||
|
|
||||||
let mut seen_sized_unbound = false;
|
let mut seen_sized_unbound = false;
|
||||||
for unbound in unbounds {
|
for unbound in unbounds {
|
||||||
if let Some(sized_def_id) = sized_def_id {
|
if let Some(sized_def_id) = sized_def_id
|
||||||
if unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id) {
|
&& unbound.trait_ref.path.res == Res::Def(DefKind::Trait, sized_def_id)
|
||||||
seen_sized_unbound = true;
|
{
|
||||||
continue;
|
seen_sized_unbound = true;
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
// There was a `?Trait` bound, but it was not `?Sized`; warn.
|
// There was a `?Trait` bound, but it was not `?Sized`; warn.
|
||||||
tcx.dcx().span_warn(
|
tcx.dcx().span_warn(
|
||||||
@ -71,15 +82,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the above loop finished there was no `?Sized` bound; add implicitly sized if `Sized` is available.
|
if seen_sized_unbound || seen_negative_sized_bound {
|
||||||
if sized_def_id.is_none() {
|
// There was in fact a `?Sized` or `!Sized` bound;
|
||||||
// No lang item for `Sized`, so we can't add it as a bound.
|
// we don't need to do anything.
|
||||||
return;
|
} else if sized_def_id.is_some() {
|
||||||
}
|
// There was no `?Sized` or `!Sized` bound;
|
||||||
if seen_sized_unbound {
|
// add `Sized` if it's available.
|
||||||
// There was in fact a `?Sized` bound, return without doing anything
|
|
||||||
} else {
|
|
||||||
// There was no `?Sized` bound; add implicitly sized if `Sized` is available.
|
|
||||||
bounds.push_sized(tcx, self_ty, span);
|
bounds.push_sized(tcx, self_ty, span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -912,7 +912,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
|
|
||||||
let mut traits = FxIndexMap::default();
|
let mut traits = FxIndexMap::default();
|
||||||
let mut fn_traits = FxIndexMap::default();
|
let mut fn_traits = FxIndexMap::default();
|
||||||
let mut is_sized = false;
|
let mut has_sized_bound = false;
|
||||||
|
let mut has_negative_sized_bound = false;
|
||||||
let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new();
|
let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new();
|
||||||
|
|
||||||
for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) {
|
for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) {
|
||||||
@ -922,13 +923,24 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
ty::ClauseKind::Trait(pred) => {
|
ty::ClauseKind::Trait(pred) => {
|
||||||
let trait_ref = bound_predicate.rebind(pred.trait_ref);
|
let trait_ref = bound_predicate.rebind(pred.trait_ref);
|
||||||
|
|
||||||
// Don't print + Sized, but rather + ?Sized if absent.
|
// Don't print `+ Sized`, but rather `+ ?Sized` if absent.
|
||||||
if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() {
|
if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() {
|
||||||
is_sized = true;
|
match pred.polarity {
|
||||||
continue;
|
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => {
|
||||||
|
has_sized_bound = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ty::ImplPolarity::Negative => has_negative_sized_bound = true,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.insert_trait_and_projection(trait_ref, None, &mut traits, &mut fn_traits);
|
self.insert_trait_and_projection(
|
||||||
|
trait_ref,
|
||||||
|
pred.polarity,
|
||||||
|
None,
|
||||||
|
&mut traits,
|
||||||
|
&mut fn_traits,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
ty::ClauseKind::Projection(pred) => {
|
ty::ClauseKind::Projection(pred) => {
|
||||||
let proj_ref = bound_predicate.rebind(pred);
|
let proj_ref = bound_predicate.rebind(pred);
|
||||||
@ -939,6 +951,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
|
|
||||||
self.insert_trait_and_projection(
|
self.insert_trait_and_projection(
|
||||||
trait_ref,
|
trait_ref,
|
||||||
|
ty::ImplPolarity::Positive,
|
||||||
Some(proj_ty),
|
Some(proj_ty),
|
||||||
&mut traits,
|
&mut traits,
|
||||||
&mut fn_traits,
|
&mut fn_traits,
|
||||||
@ -955,7 +968,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
|
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
// Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
|
// Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
|
||||||
let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !is_sized;
|
let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !has_sized_bound;
|
||||||
|
|
||||||
for (fn_once_trait_ref, entry) in fn_traits {
|
for (fn_once_trait_ref, entry) in fn_traits {
|
||||||
write!(self, "{}", if first { "" } else { " + " })?;
|
write!(self, "{}", if first { "" } else { " + " })?;
|
||||||
@ -1002,18 +1015,21 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
// trait_refs we collected in the OpaqueFnEntry as normal trait refs.
|
// trait_refs we collected in the OpaqueFnEntry as normal trait refs.
|
||||||
_ => {
|
_ => {
|
||||||
if entry.has_fn_once {
|
if entry.has_fn_once {
|
||||||
traits.entry(fn_once_trait_ref).or_default().extend(
|
traits
|
||||||
// Group the return ty with its def id, if we had one.
|
.entry((fn_once_trait_ref, ty::ImplPolarity::Positive))
|
||||||
entry
|
.or_default()
|
||||||
.return_ty
|
.extend(
|
||||||
.map(|ty| (tcx.require_lang_item(LangItem::FnOnce, None), ty)),
|
// Group the return ty with its def id, if we had one.
|
||||||
);
|
entry.return_ty.map(|ty| {
|
||||||
|
(tcx.require_lang_item(LangItem::FnOnce, None), ty)
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if let Some(trait_ref) = entry.fn_mut_trait_ref {
|
if let Some(trait_ref) = entry.fn_mut_trait_ref {
|
||||||
traits.entry(trait_ref).or_default();
|
traits.entry((trait_ref, ty::ImplPolarity::Positive)).or_default();
|
||||||
}
|
}
|
||||||
if let Some(trait_ref) = entry.fn_trait_ref {
|
if let Some(trait_ref) = entry.fn_trait_ref {
|
||||||
traits.entry(trait_ref).or_default();
|
traits.entry((trait_ref, ty::ImplPolarity::Positive)).or_default();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1023,11 +1039,15 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Print the rest of the trait types (that aren't Fn* family of traits)
|
// Print the rest of the trait types (that aren't Fn* family of traits)
|
||||||
for (trait_ref, assoc_items) in traits {
|
for ((trait_ref, polarity), assoc_items) in traits {
|
||||||
write!(self, "{}", if first { "" } else { " + " })?;
|
write!(self, "{}", if first { "" } else { " + " })?;
|
||||||
|
|
||||||
self.wrap_binder(&trait_ref, |trait_ref, cx| {
|
self.wrap_binder(&trait_ref, |trait_ref, cx| {
|
||||||
define_scoped_cx!(cx);
|
define_scoped_cx!(cx);
|
||||||
|
|
||||||
|
if polarity == ty::ImplPolarity::Negative {
|
||||||
|
p!("!");
|
||||||
|
}
|
||||||
p!(print(trait_ref.print_only_trait_name()));
|
p!(print(trait_ref.print_only_trait_name()));
|
||||||
|
|
||||||
let generics = tcx.generics_of(trait_ref.def_id);
|
let generics = tcx.generics_of(trait_ref.def_id);
|
||||||
@ -1094,9 +1114,15 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !is_sized {
|
let add_sized = has_sized_bound && (first || has_negative_sized_bound);
|
||||||
write!(self, "{}?Sized", if first { "" } else { " + " })?;
|
let add_maybe_sized = !has_sized_bound && !has_negative_sized_bound;
|
||||||
} else if first {
|
if add_sized || add_maybe_sized {
|
||||||
|
if !first {
|
||||||
|
write!(self, " + ")?;
|
||||||
|
}
|
||||||
|
if add_maybe_sized {
|
||||||
|
write!(self, "?")?;
|
||||||
|
}
|
||||||
write!(self, "Sized")?;
|
write!(self, "Sized")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1128,9 +1154,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
fn insert_trait_and_projection(
|
fn insert_trait_and_projection(
|
||||||
&mut self,
|
&mut self,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
|
polarity: ty::ImplPolarity,
|
||||||
proj_ty: Option<(DefId, ty::Binder<'tcx, Term<'tcx>>)>,
|
proj_ty: Option<(DefId, ty::Binder<'tcx, Term<'tcx>>)>,
|
||||||
traits: &mut FxIndexMap<
|
traits: &mut FxIndexMap<
|
||||||
ty::PolyTraitRef<'tcx>,
|
(ty::PolyTraitRef<'tcx>, ty::ImplPolarity),
|
||||||
FxIndexMap<DefId, ty::Binder<'tcx, Term<'tcx>>>,
|
FxIndexMap<DefId, ty::Binder<'tcx, Term<'tcx>>>,
|
||||||
>,
|
>,
|
||||||
fn_traits: &mut FxIndexMap<ty::PolyTraitRef<'tcx>, OpaqueFnEntry<'tcx>>,
|
fn_traits: &mut FxIndexMap<ty::PolyTraitRef<'tcx>, OpaqueFnEntry<'tcx>>,
|
||||||
@ -1139,7 +1166,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
|
|
||||||
// If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce
|
// If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce
|
||||||
// super-trait ref and record it there.
|
// super-trait ref and record it there.
|
||||||
if let Some(fn_once_trait) = self.tcx().lang_items().fn_once_trait() {
|
// We skip negative Fn* bounds since they can't use parenthetical notation anyway.
|
||||||
|
if polarity == ty::ImplPolarity::Positive
|
||||||
|
&& let Some(fn_once_trait) = self.tcx().lang_items().fn_once_trait()
|
||||||
|
{
|
||||||
// If we have a FnOnce, then insert it into
|
// If we have a FnOnce, then insert it into
|
||||||
if trait_def_id == fn_once_trait {
|
if trait_def_id == fn_once_trait {
|
||||||
let entry = fn_traits.entry(trait_ref).or_default();
|
let entry = fn_traits.entry(trait_ref).or_default();
|
||||||
@ -1167,7 +1197,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, just group our traits and projection types.
|
// Otherwise, just group our traits and projection types.
|
||||||
traits.entry(trait_ref).or_default().extend(proj_ty);
|
traits.entry((trait_ref, polarity)).or_default().extend(proj_ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pretty_print_inherent_projection(
|
fn pretty_print_inherent_projection(
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#![feature(negative_bounds, associated_type_bounds)]
|
#![feature(negative_bounds, associated_type_bounds)]
|
||||||
//~^ WARN the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
|
|
||||||
trait Trait {
|
trait Trait {
|
||||||
type Assoc;
|
type Assoc;
|
||||||
@ -17,4 +16,7 @@ fn test3<T: !Trait<Assoc: Send>>() {}
|
|||||||
fn test4<T>() where T: !Trait<Assoc: Send> {}
|
fn test4<T>() where T: !Trait<Assoc: Send> {}
|
||||||
//~^ ERROR associated type constraints not allowed on negative bounds
|
//~^ ERROR associated type constraints not allowed on negative bounds
|
||||||
|
|
||||||
|
fn test5<T>() where T: !Fn() -> i32 {}
|
||||||
|
//~^ ERROR parenthetical notation may not be used for negative bounds
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,34 +1,32 @@
|
|||||||
error: associated type constraints not allowed on negative bounds
|
error: associated type constraints not allowed on negative bounds
|
||||||
--> $DIR/associated-constraints.rs:8:19
|
--> $DIR/associated-constraints.rs:7:19
|
||||||
|
|
|
|
||||||
LL | fn test<T: !Trait<Assoc = i32>>() {}
|
LL | fn test<T: !Trait<Assoc = i32>>() {}
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: associated type constraints not allowed on negative bounds
|
error: associated type constraints not allowed on negative bounds
|
||||||
--> $DIR/associated-constraints.rs:11:31
|
--> $DIR/associated-constraints.rs:10:31
|
||||||
|
|
|
|
||||||
LL | fn test2<T>() where T: !Trait<Assoc = i32> {}
|
LL | fn test2<T>() where T: !Trait<Assoc = i32> {}
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: associated type constraints not allowed on negative bounds
|
error: associated type constraints not allowed on negative bounds
|
||||||
--> $DIR/associated-constraints.rs:14:20
|
--> $DIR/associated-constraints.rs:13:20
|
||||||
|
|
|
|
||||||
LL | fn test3<T: !Trait<Assoc: Send>>() {}
|
LL | fn test3<T: !Trait<Assoc: Send>>() {}
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: associated type constraints not allowed on negative bounds
|
error: associated type constraints not allowed on negative bounds
|
||||||
--> $DIR/associated-constraints.rs:17:31
|
--> $DIR/associated-constraints.rs:16:31
|
||||||
|
|
|
|
||||||
LL | fn test4<T>() where T: !Trait<Assoc: Send> {}
|
LL | fn test4<T>() where T: !Trait<Assoc: Send> {}
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
warning: the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes
|
error: parenthetical notation may not be used for negative bounds
|
||||||
--> $DIR/associated-constraints.rs:1:12
|
--> $DIR/associated-constraints.rs:19:25
|
||||||
|
|
|
|
||||||
LL | #![feature(negative_bounds, associated_type_bounds)]
|
LL | fn test5<T>() where T: !Fn() -> i32 {}
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors; 1 warning emitted
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
// compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
#![feature(negative_bounds, negative_impls)]
|
||||||
|
|
||||||
|
trait Trait {}
|
||||||
|
impl !Trait for () {}
|
||||||
|
|
||||||
|
fn produce() -> impl !Trait {}
|
||||||
|
fn consume(_: impl Trait) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
consume(produce()); //~ ERROR the trait bound `impl !Trait: Trait` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
fn weird0() -> impl Sized + !Sized {}
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| ERROR type mismatch resolving `() == impl !Sized + Sized`
|
||||||
|
fn weird1() -> impl !Sized + Sized {}
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| ERROR type mismatch resolving `() == impl !Sized + Sized`
|
||||||
|
fn weird2() -> impl !Sized {}
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| ERROR type mismatch resolving `() == impl !Sized`
|
@ -0,0 +1,69 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:15:36
|
||||||
|
|
|
||||||
|
LL | fn weird0() -> impl Sized + !Sized {}
|
||||||
|
| ------------------- ^^ types differ
|
||||||
|
| |
|
||||||
|
| the expected opaque type
|
||||||
|
|
|
||||||
|
= note: expected opaque type `impl !Sized + Sized`
|
||||||
|
found unit type `()`
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `() == impl !Sized + Sized`
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:15:16
|
||||||
|
|
|
||||||
|
LL | fn weird0() -> impl Sized + !Sized {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:18:36
|
||||||
|
|
|
||||||
|
LL | fn weird1() -> impl !Sized + Sized {}
|
||||||
|
| ------------------- ^^ types differ
|
||||||
|
| |
|
||||||
|
| the expected opaque type
|
||||||
|
|
|
||||||
|
= note: expected opaque type `impl !Sized + Sized`
|
||||||
|
found unit type `()`
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `() == impl !Sized + Sized`
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:18:16
|
||||||
|
|
|
||||||
|
LL | fn weird1() -> impl !Sized + Sized {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:21:28
|
||||||
|
|
|
||||||
|
LL | fn weird2() -> impl !Sized {}
|
||||||
|
| ----------- ^^ types differ
|
||||||
|
| |
|
||||||
|
| the expected opaque type
|
||||||
|
|
|
||||||
|
= note: expected opaque type `impl !Sized`
|
||||||
|
found unit type `()`
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `() == impl !Sized`
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:21:16
|
||||||
|
|
|
||||||
|
LL | fn weird2() -> impl !Sized {}
|
||||||
|
| ^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:12:13
|
||||||
|
|
|
||||||
|
LL | consume(produce());
|
||||||
|
| ------- ^^^^^^^^^ the trait `Trait` is not implemented for `impl !Trait`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
note: required by a bound in `consume`
|
||||||
|
--> $DIR/opaque-type-unsatisfied-bound.rs:9:20
|
||||||
|
|
|
||||||
|
LL | fn consume(_: impl Trait) {}
|
||||||
|
| ^^^^^ required by this bound in `consume`
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0271, E0277, E0308.
|
||||||
|
For more information about an error, try `rustc --explain E0271`.
|
@ -0,0 +1,9 @@
|
|||||||
|
// compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
#![feature(negative_bounds, unboxed_closures)]
|
||||||
|
|
||||||
|
fn produce() -> impl !Fn<(u32,)> {}
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
//~| ERROR type mismatch resolving `() == impl !Fn<(u32,)>`
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,21 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
|
||||||
|
|
|
||||||
|
LL | fn produce() -> impl !Fn<(u32,)> {}
|
||||||
|
| ---------------- ^^ types differ
|
||||||
|
| |
|
||||||
|
| the expected opaque type
|
||||||
|
|
|
||||||
|
= note: expected opaque type `impl !Fn<(u32,)>`
|
||||||
|
found unit type `()`
|
||||||
|
|
||||||
|
error[E0271]: type mismatch resolving `() == impl !Fn<(u32,)>`
|
||||||
|
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
|
||||||
|
|
|
||||||
|
LL | fn produce() -> impl !Fn<(u32,)> {}
|
||||||
|
| ^^^^^^^^^^^^^^^^ types differ
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0271, E0308.
|
||||||
|
For more information about an error, try `rustc --explain E0271`.
|
@ -1,5 +1,4 @@
|
|||||||
#![feature(negative_bounds, negative_impls)]
|
#![feature(negative_bounds, negative_impls)]
|
||||||
//~^ WARN the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
|
|
||||||
fn not_copy<T: !Copy>() {}
|
fn not_copy<T: !Copy>() {}
|
||||||
|
|
||||||
|
@ -1,44 +1,36 @@
|
|||||||
warning: the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/simple.rs:1:12
|
|
||||||
|
|
|
||||||
LL | #![feature(negative_bounds, negative_impls)]
|
|
||||||
| ^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `T: !Copy` is not satisfied
|
error[E0277]: the trait bound `T: !Copy` is not satisfied
|
||||||
--> $DIR/simple.rs:11:16
|
--> $DIR/simple.rs:10:16
|
||||||
|
|
|
|
||||||
LL | not_copy::<T>();
|
LL | not_copy::<T>();
|
||||||
| ^ the trait `!Copy` is not implemented for `T`
|
| ^ the trait `!Copy` is not implemented for `T`
|
||||||
|
|
|
|
||||||
note: required by a bound in `not_copy`
|
note: required by a bound in `not_copy`
|
||||||
--> $DIR/simple.rs:4:16
|
--> $DIR/simple.rs:3:16
|
||||||
|
|
|
|
||||||
LL | fn not_copy<T: !Copy>() {}
|
LL | fn not_copy<T: !Copy>() {}
|
||||||
| ^^^^^ required by this bound in `not_copy`
|
| ^^^^^ required by this bound in `not_copy`
|
||||||
|
|
||||||
error[E0277]: the trait bound `T: !Copy` is not satisfied
|
error[E0277]: the trait bound `T: !Copy` is not satisfied
|
||||||
--> $DIR/simple.rs:16:16
|
--> $DIR/simple.rs:15:16
|
||||||
|
|
|
|
||||||
LL | not_copy::<T>();
|
LL | not_copy::<T>();
|
||||||
| ^ the trait `!Copy` is not implemented for `T`
|
| ^ the trait `!Copy` is not implemented for `T`
|
||||||
|
|
|
|
||||||
note: required by a bound in `not_copy`
|
note: required by a bound in `not_copy`
|
||||||
--> $DIR/simple.rs:4:16
|
--> $DIR/simple.rs:3:16
|
||||||
|
|
|
|
||||||
LL | fn not_copy<T: !Copy>() {}
|
LL | fn not_copy<T: !Copy>() {}
|
||||||
| ^^^^^ required by this bound in `not_copy`
|
| ^^^^^ required by this bound in `not_copy`
|
||||||
|
|
||||||
error[E0277]: the trait bound `Copyable: !Copy` is not satisfied
|
error[E0277]: the trait bound `Copyable: !Copy` is not satisfied
|
||||||
--> $DIR/simple.rs:31:16
|
--> $DIR/simple.rs:30:16
|
||||||
|
|
|
|
||||||
LL | not_copy::<Copyable>();
|
LL | not_copy::<Copyable>();
|
||||||
| ^^^^^^^^ the trait `!Copy` is not implemented for `Copyable`
|
| ^^^^^^^^ the trait `!Copy` is not implemented for `Copyable`
|
||||||
|
|
|
|
||||||
= help: the trait `Copy` is implemented for `Copyable`
|
= help: the trait `Copy` is implemented for `Copyable`
|
||||||
note: required by a bound in `not_copy`
|
note: required by a bound in `not_copy`
|
||||||
--> $DIR/simple.rs:4:16
|
--> $DIR/simple.rs:3:16
|
||||||
|
|
|
|
||||||
LL | fn not_copy<T: !Copy>() {}
|
LL | fn not_copy<T: !Copy>() {}
|
||||||
| ^^^^^ required by this bound in `not_copy`
|
| ^^^^^ required by this bound in `not_copy`
|
||||||
@ -49,13 +41,13 @@ LL | struct Copyable;
|
|||||||
|
|
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `NotNecessarilyCopyable: !Copy` is not satisfied
|
error[E0277]: the trait bound `NotNecessarilyCopyable: !Copy` is not satisfied
|
||||||
--> $DIR/simple.rs:38:16
|
--> $DIR/simple.rs:37:16
|
||||||
|
|
|
|
||||||
LL | not_copy::<NotNecessarilyCopyable>();
|
LL | not_copy::<NotNecessarilyCopyable>();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `!Copy` is not implemented for `NotNecessarilyCopyable`
|
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `!Copy` is not implemented for `NotNecessarilyCopyable`
|
||||||
|
|
|
|
||||||
note: required by a bound in `not_copy`
|
note: required by a bound in `not_copy`
|
||||||
--> $DIR/simple.rs:4:16
|
--> $DIR/simple.rs:3:16
|
||||||
|
|
|
|
||||||
LL | fn not_copy<T: !Copy>() {}
|
LL | fn not_copy<T: !Copy>() {}
|
||||||
| ^^^^^ required by this bound in `not_copy`
|
| ^^^^^ required by this bound in `not_copy`
|
||||||
@ -65,6 +57,6 @@ LL + #[derive(Copy)]
|
|||||||
LL | struct NotNecessarilyCopyable;
|
LL | struct NotNecessarilyCopyable;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors; 1 warning emitted
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
#![feature(negative_bounds)]
|
#![feature(negative_bounds)]
|
||||||
//~^ WARN the feature `negative_bounds` is incomplete
|
|
||||||
|
|
||||||
trait A: !B {}
|
trait A: !B {}
|
||||||
trait B: !A {}
|
trait B: !A {}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
warning: the feature `negative_bounds` is incomplete and may not be safe to use and/or cause compiler crashes
|
|
||||||
--> $DIR/supertrait.rs:3:12
|
|
||||||
|
|
|
||||||
LL | #![feature(negative_bounds)]
|
|
||||||
| ^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
|
||||||
|
|
||||||
warning: 1 warning emitted
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user