More robustly reject relaxing non-default trait bounds
This commit is contained in:
@@ -204,7 +204,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
// FIXME(more_maybe_bounds): We don't call this for trait object tys, supertrait
|
||||
// bounds, trait alias bounds, assoc type bounds (ATB)!
|
||||
let bounds = collect_relaxed_bounds(hir_bounds, self_ty_where_predicates);
|
||||
self.check_and_report_invalid_relaxed_bounds(bounds);
|
||||
self.reject_duplicate_relaxed_bounds(bounds);
|
||||
}
|
||||
|
||||
let collected = collect_sizedness_bounds(tcx, hir_bounds, self_ty_where_predicates, span);
|
||||
@@ -308,6 +308,53 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
!self.tcx().has_attr(CRATE_DEF_ID, sym::rustc_no_implicit_bounds) && !collected.any()
|
||||
}
|
||||
|
||||
fn reject_duplicate_relaxed_bounds(&self, relaxed_bounds: SmallVec<[&PolyTraitRef<'_>; 1]>) {
|
||||
let tcx = self.tcx();
|
||||
|
||||
let mut grouped_bounds = FxIndexMap::<_, Vec<_>>::default();
|
||||
|
||||
for bound in &relaxed_bounds {
|
||||
if let Res::Def(DefKind::Trait, trait_def_id) = bound.trait_ref.path.res {
|
||||
grouped_bounds.entry(trait_def_id).or_default().push(bound.span);
|
||||
}
|
||||
}
|
||||
|
||||
for (trait_def_id, spans) in grouped_bounds {
|
||||
if spans.len() > 1 {
|
||||
let name = tcx.item_name(trait_def_id);
|
||||
self.dcx()
|
||||
.struct_span_err(spans, format!("duplicate relaxed `{name}` bounds"))
|
||||
.with_code(E0203)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn require_bound_to_relax_default_trait(
|
||||
&self,
|
||||
trait_ref: hir::TraitRef<'_>,
|
||||
span: Span,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
|
||||
if let Res::Def(DefKind::Trait, def_id) = trait_ref.path.res
|
||||
&& (tcx.is_lang_item(def_id, hir::LangItem::Sized) || tcx.is_default_trait(def_id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.dcx().span_err(
|
||||
span,
|
||||
if tcx.sess.opts.unstable_opts.experimental_default_bounds
|
||||
|| tcx.features().more_maybe_bounds()
|
||||
{
|
||||
"bound modifier `?` can only be applied to default traits"
|
||||
} else {
|
||||
"bound modifier `?` can only be applied to `Sized`"
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Lower HIR bounds into `bounds` given the self type `param_ty` and the overarching late-bound vars if any.
|
||||
///
|
||||
/// ### Examples
|
||||
|
||||
@@ -8,7 +8,7 @@ use rustc_errors::{
|
||||
};
|
||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{self as hir, HirId, PolyTraitRef};
|
||||
use rustc_hir::{self as hir, HirId};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
|
||||
use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
|
||||
@@ -35,52 +35,6 @@ use crate::fluent_generated as fluent;
|
||||
use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer};
|
||||
|
||||
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
/// Check for duplicate relaxed bounds and relaxed bounds of non-default traits.
|
||||
pub(crate) fn check_and_report_invalid_relaxed_bounds(
|
||||
&self,
|
||||
relaxed_bounds: SmallVec<[&PolyTraitRef<'_>; 1]>,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
|
||||
let mut grouped_bounds = FxIndexMap::<_, Vec<_>>::default();
|
||||
|
||||
for bound in &relaxed_bounds {
|
||||
if let Res::Def(DefKind::Trait, trait_def_id) = bound.trait_ref.path.res {
|
||||
grouped_bounds.entry(trait_def_id).or_default().push(bound.span);
|
||||
}
|
||||
}
|
||||
|
||||
for (trait_def_id, spans) in grouped_bounds {
|
||||
if spans.len() > 1 {
|
||||
let name = tcx.item_name(trait_def_id);
|
||||
self.dcx()
|
||||
.struct_span_err(spans, format!("duplicate relaxed `{name}` bounds"))
|
||||
.with_code(E0203)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
||||
let sized_def_id = tcx.require_lang_item(hir::LangItem::Sized, DUMMY_SP);
|
||||
|
||||
for bound in relaxed_bounds {
|
||||
if let Res::Def(DefKind::Trait, def_id) = bound.trait_ref.path.res
|
||||
&& (def_id == sized_def_id || tcx.is_default_trait(def_id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
self.dcx().span_err(
|
||||
bound.span,
|
||||
if tcx.sess.opts.unstable_opts.experimental_default_bounds
|
||||
|| tcx.features().more_maybe_bounds()
|
||||
{
|
||||
"bound modifier `?` can only be applied to default traits like `Sized`"
|
||||
} else {
|
||||
"bound modifier `?` can only be applied to `Sized`"
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// On missing type parameters, emit an E0393 error and provide a structured suggestion using
|
||||
/// the type parameter's name as a placeholder.
|
||||
pub(crate) fn report_missing_type_params(
|
||||
|
||||
@@ -767,7 +767,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
|
||||
// We use the *resolved* bound vars later instead of the HIR ones since the former
|
||||
// also include the bound vars of the overarching predicate if applicable.
|
||||
let hir::PolyTraitRef { bound_generic_params: _, modifiers, ref trait_ref, span } =
|
||||
let hir::PolyTraitRef { bound_generic_params: _, modifiers, trait_ref, span } =
|
||||
*poly_trait_ref;
|
||||
let hir::TraitBoundModifiers { constness, polarity } = modifiers;
|
||||
|
||||
@@ -791,6 +791,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
rustc_ast::BoundPolarity::Positive => (ty::PredicatePolarity::Positive, bounds),
|
||||
rustc_ast::BoundPolarity::Negative(_) => (ty::PredicatePolarity::Negative, bounds),
|
||||
rustc_ast::BoundPolarity::Maybe(_) => {
|
||||
self.require_bound_to_relax_default_trait(trait_ref, span);
|
||||
|
||||
(ty::PredicatePolarity::Positive, &mut Vec::new())
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1782,9 +1782,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
|
||||
pub fn is_default_trait(self, def_id: DefId) -> bool {
|
||||
self.default_traits()
|
||||
.iter()
|
||||
.any(|&default_trait| self.lang_items().get(default_trait) == Some(def_id))
|
||||
self.default_traits().iter().any(|&default_trait| self.is_lang_item(def_id, default_trait))
|
||||
}
|
||||
|
||||
/// Returns a range of the start/end indices specified with the
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
#![feature(auto_traits)]
|
||||
#![feature(auto_traits, lang_items)]
|
||||
|
||||
trait Trait1 {}
|
||||
auto trait Trait2 {}
|
||||
trait Trait3: ?Trait1 {} //~ ERROR relaxed bounds are not permitted in supertrait bounds
|
||||
trait Trait4 where Self: ?Trait1 {} //~ ERROR this relaxed bound is not permitted here
|
||||
#[lang = "default_trait1"] trait Trait1 {}
|
||||
#[lang = "default_trait2"] auto trait Trait2 {}
|
||||
|
||||
trait Trait3: ?Trait1 {}
|
||||
//~^ ERROR relaxed bounds are not permitted in supertrait bounds
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
|
||||
fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
|
||||
//~^ ERROR relaxed bounds are not permitted in trait object types
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
|
||||
//~^ ERROR bound modifier `?` can only be applied to `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
|
||||
@@ -1,34 +1,54 @@
|
||||
error: relaxed bounds are not permitted in supertrait bounds
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:5:15
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:6:15
|
||||
|
|
||||
LL | trait Trait3: ?Trait1 {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: this relaxed bound is not permitted here
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:6:26
|
||||
|
|
||||
LL | trait Trait4 where Self: ?Trait1 {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item
|
||||
|
||||
error: relaxed bounds are not permitted in trait object types
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:8:28
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:12:28
|
||||
|
|
||||
LL | fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:10:11
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:6:15
|
||||
|
|
||||
LL | trait Trait3: ?Trait1 {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:6:15
|
||||
|
|
||||
LL | trait Trait3: ?Trait1 {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:6:15
|
||||
|
|
||||
LL | trait Trait3: ?Trait1 {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:12:28
|
||||
|
|
||||
LL | fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:15:11
|
||||
|
|
||||
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:10:21
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:15:21
|
||||
|
|
||||
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
||||
@@ -12,12 +12,17 @@ trait MetaSized_: MetaSized { }
|
||||
|
||||
trait NegMetaSized: ?MetaSized { }
|
||||
//~^ ERROR relaxed bounds are not permitted in supertrait bounds
|
||||
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
|
||||
trait PointeeSized_: PointeeSized { }
|
||||
|
||||
trait NegPointeeSized: ?PointeeSized { }
|
||||
//~^ ERROR relaxed bounds are not permitted in supertrait bounds
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
|
||||
trait Bare {}
|
||||
|
||||
|
||||
@@ -13,19 +13,63 @@ LL | trait NegMetaSized: ?MetaSized { }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: relaxed bounds are not permitted in supertrait bounds
|
||||
--> $DIR/default-supertrait.rs:19:24
|
||||
--> $DIR/default-supertrait.rs:21:24
|
||||
|
|
||||
LL | trait NegPointeeSized: ?PointeeSized { }
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/default-supertrait.rs:13:21
|
||||
|
|
||||
LL | trait NegMetaSized: ?MetaSized { }
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/default-supertrait.rs:13:21
|
||||
|
|
||||
LL | trait NegMetaSized: ?MetaSized { }
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/default-supertrait.rs:13:21
|
||||
|
|
||||
LL | trait NegMetaSized: ?MetaSized { }
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/default-supertrait.rs:21:24
|
||||
|
|
||||
LL | trait NegPointeeSized: ?PointeeSized { }
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/default-supertrait.rs:21:24
|
||||
|
|
||||
LL | trait NegPointeeSized: ?PointeeSized { }
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/default-supertrait.rs:21:24
|
||||
|
|
||||
LL | trait NegPointeeSized: ?PointeeSized { }
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known
|
||||
--> $DIR/default-supertrait.rs:52:38
|
||||
--> $DIR/default-supertrait.rs:57:38
|
||||
|
|
||||
LL | fn with_bare_trait<T: PointeeSized + Bare>() {
|
||||
| ^^^^ doesn't have a known size
|
||||
|
|
||||
note: required by a bound in `Bare`
|
||||
--> $DIR/default-supertrait.rs:22:1
|
||||
--> $DIR/default-supertrait.rs:27:1
|
||||
|
|
||||
LL | trait Bare {}
|
||||
| ^^^^^^^^^^^^^ required by this bound in `Bare`
|
||||
@@ -35,7 +79,7 @@ LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() {
|
||||
| ++++++++++++++++++++++++
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/default-supertrait.rs:35:22
|
||||
--> $DIR/default-supertrait.rs:40:22
|
||||
|
|
||||
LL | fn with_metasized_supertrait<T: PointeeSized + MetaSized_>() {
|
||||
| - this type parameter needs to be `Sized`
|
||||
@@ -43,13 +87,13 @@ LL | requires_sized::<T>();
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
note: required by a bound in `requires_sized`
|
||||
--> $DIR/default-supertrait.rs:24:22
|
||||
--> $DIR/default-supertrait.rs:29:22
|
||||
|
|
||||
LL | fn requires_sized<T: Sized>() {}
|
||||
| ^^^^^ required by this bound in `requires_sized`
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/default-supertrait.rs:43:22
|
||||
--> $DIR/default-supertrait.rs:48:22
|
||||
|
|
||||
LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_>() {
|
||||
| - this type parameter needs to be `Sized`
|
||||
@@ -57,19 +101,19 @@ LL | requires_sized::<T>();
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
note: required by a bound in `requires_sized`
|
||||
--> $DIR/default-supertrait.rs:24:22
|
||||
--> $DIR/default-supertrait.rs:29:22
|
||||
|
|
||||
LL | fn requires_sized<T: Sized>() {}
|
||||
| ^^^^^ required by this bound in `requires_sized`
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known
|
||||
--> $DIR/default-supertrait.rs:45:26
|
||||
--> $DIR/default-supertrait.rs:50:26
|
||||
|
|
||||
LL | requires_metasized::<T>();
|
||||
| ^ doesn't have a known size
|
||||
|
|
||||
note: required by a bound in `requires_metasized`
|
||||
--> $DIR/default-supertrait.rs:25:26
|
||||
--> $DIR/default-supertrait.rs:30:26
|
||||
|
|
||||
LL | fn requires_metasized<T: MetaSized>() {}
|
||||
| ^^^^^^^^^ required by this bound in `requires_metasized`
|
||||
@@ -79,7 +123,7 @@ LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_ + std::mark
|
||||
| ++++++++++++++++++++++++
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
||||
--> $DIR/default-supertrait.rs:54:22
|
||||
--> $DIR/default-supertrait.rs:59:22
|
||||
|
|
||||
LL | fn with_bare_trait<T: PointeeSized + Bare>() {
|
||||
| - this type parameter needs to be `Sized`
|
||||
@@ -88,19 +132,19 @@ LL | requires_sized::<T>();
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
note: required by a bound in `requires_sized`
|
||||
--> $DIR/default-supertrait.rs:24:22
|
||||
--> $DIR/default-supertrait.rs:29:22
|
||||
|
|
||||
LL | fn requires_sized<T: Sized>() {}
|
||||
| ^^^^^ required by this bound in `requires_sized`
|
||||
|
||||
error[E0277]: the size for values of type `T` cannot be known
|
||||
--> $DIR/default-supertrait.rs:56:26
|
||||
--> $DIR/default-supertrait.rs:61:26
|
||||
|
|
||||
LL | requires_metasized::<T>();
|
||||
| ^ doesn't have a known size
|
||||
|
|
||||
note: required by a bound in `requires_metasized`
|
||||
--> $DIR/default-supertrait.rs:25:26
|
||||
--> $DIR/default-supertrait.rs:30:26
|
||||
|
|
||||
LL | fn requires_metasized<T: MetaSized>() {}
|
||||
| ^^^^^^^^^ required by this bound in `requires_metasized`
|
||||
@@ -109,6 +153,6 @@ help: consider further restricting type parameter `T` with unstable trait `MetaS
|
||||
LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() {
|
||||
| ++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error: aborting due to 15 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
struct Foo<T: ?Hash> {}
|
||||
//~^ ERROR expected trait, found derive macro `Hash`
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
// issue: <https://github.com/rust-lang/rust/issues/37534>
|
||||
|
||||
struct Foo<T: ?Hash> {} //~ ERROR expected trait, found derive macro `Hash`
|
||||
|
||||
fn main() {}
|
||||
|
||||
// https://github.com/rust-lang/rust/issues/37534
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error[E0404]: expected trait, found derive macro `Hash`
|
||||
--> $DIR/relaxing-default-bound-error-37534.rs:1:16
|
||||
--> $DIR/relaxing-default-bound-error-37534.rs:3:16
|
||||
|
|
||||
LL | struct Foo<T: ?Hash> {}
|
||||
| ^^^^ not a trait
|
||||
@@ -9,12 +9,6 @@ help: consider importing this trait instead
|
||||
LL + use std::hash::Hash;
|
||||
|
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/relaxing-default-bound-error-37534.rs:1:15
|
||||
|
|
||||
LL | struct Foo<T: ?Hash> {}
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0404`.
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
// FIXME(more_maybe_bounds): Even under `more_maybe_bounds` / `-Zexperimental-default-bounds`,
|
||||
// trying to relax non-default bounds should still be an error in all contexts! As you can see
|
||||
// there are places like supertrait bounds, trait object types or associated type bounds (ATB)
|
||||
// where we currently don't perform this check.
|
||||
#![feature(auto_traits, more_maybe_bounds, negative_impls)]
|
||||
|
||||
trait Trait1 {}
|
||||
auto trait Trait2 {}
|
||||
|
||||
// FIXME: `?Trait1` should be rejected, `Trait1` isn't marked `#[lang = "default_traitN"]`.
|
||||
trait Trait3: ?Trait1 {}
|
||||
//~^ ERROR bound modifier `?` can only be applied to default traits
|
||||
//~| ERROR bound modifier `?` can only be applied to default traits
|
||||
//~| ERROR bound modifier `?` can only be applied to default traits
|
||||
trait Trait4 where Self: Trait1 {}
|
||||
|
||||
// FIXME: `?Trait2` should be rejected, `Trait2` isn't marked `#[lang = "default_traitN"]`.
|
||||
|
||||
fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}
|
||||
//~^ ERROR bound modifier `?` can only be applied to default traits
|
||||
|
||||
fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
|
||||
//~^ ERROR bound modifier `?` can only be applied to default traits like `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to default traits like `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to default traits like `Sized`
|
||||
//~^ ERROR bound modifier `?` can only be applied to default traits
|
||||
//~| ERROR bound modifier `?` can only be applied to default traits
|
||||
//~| ERROR bound modifier `?` can only be applied to default traits
|
||||
|
||||
// FIXME: `?Trait1` should be rejected, `Trait1` isn't marked `#[lang = "default_traitN"]`.
|
||||
fn baz<T>() where T: Iterator<Item: ?Trait1> {}
|
||||
//~^ ERROR this relaxed bound is not permitted here
|
||||
//~| ERROR bound modifier `?` can only be applied to default traits
|
||||
|
||||
struct S1<T>(T);
|
||||
|
||||
impl<T> S1<T> {
|
||||
fn f() where T: ?Trait1 {}
|
||||
//~^ ERROR this relaxed bound is not permitted here
|
||||
//~| ERROR bound modifier `?` can only be applied to default traits
|
||||
}
|
||||
|
||||
trait Trait5<'a> {}
|
||||
|
||||
struct S2<T>(T) where for<'a> T: ?Trait5<'a>;
|
||||
//~^ ERROR this relaxed bound is not permitted here
|
||||
//~| ERROR bound modifier `?` can only be applied to default traits like `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to default traits
|
||||
|
||||
struct S;
|
||||
impl !Trait2 for S {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
error: this relaxed bound is not permitted here
|
||||
--> $DIR/more_maybe_bounds.rs:23:37
|
||||
--> $DIR/more_maybe_bounds.rs:21:37
|
||||
|
|
||||
LL | fn baz<T>() where T: Iterator<Item: ?Trait1> {}
|
||||
| ^^^^^^^
|
||||
@@ -7,7 +7,7 @@ LL | fn baz<T>() where T: Iterator<Item: ?Trait1> {}
|
||||
= note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item
|
||||
|
||||
error: this relaxed bound is not permitted here
|
||||
--> $DIR/more_maybe_bounds.rs:29:21
|
||||
--> $DIR/more_maybe_bounds.rs:28:21
|
||||
|
|
||||
LL | fn f() where T: ?Trait1 {}
|
||||
| ^^^^^^^
|
||||
@@ -22,29 +22,69 @@ LL | struct S2<T>(T) where for<'a> T: ?Trait5<'a>;
|
||||
|
|
||||
= note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item
|
||||
|
||||
error: bound modifier `?` can only be applied to default traits like `Sized`
|
||||
--> $DIR/more_maybe_bounds.rs:17:20
|
||||
error: bound modifier `?` can only be applied to default traits
|
||||
--> $DIR/more_maybe_bounds.rs:6:15
|
||||
|
|
||||
LL | trait Trait3: ?Trait1 {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to default traits
|
||||
--> $DIR/more_maybe_bounds.rs:6:15
|
||||
|
|
||||
LL | trait Trait3: ?Trait1 {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: bound modifier `?` can only be applied to default traits
|
||||
--> $DIR/more_maybe_bounds.rs:6:15
|
||||
|
|
||||
LL | trait Trait3: ?Trait1 {}
|
||||
| ^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: bound modifier `?` can only be applied to default traits
|
||||
--> $DIR/more_maybe_bounds.rs:13:29
|
||||
|
|
||||
LL | fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to default traits
|
||||
--> $DIR/more_maybe_bounds.rs:16:20
|
||||
|
|
||||
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to default traits like `Sized`
|
||||
--> $DIR/more_maybe_bounds.rs:17:30
|
||||
error: bound modifier `?` can only be applied to default traits
|
||||
--> $DIR/more_maybe_bounds.rs:16:30
|
||||
|
|
||||
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to default traits like `Sized`
|
||||
--> $DIR/more_maybe_bounds.rs:17:40
|
||||
error: bound modifier `?` can only be applied to default traits
|
||||
--> $DIR/more_maybe_bounds.rs:16:40
|
||||
|
|
||||
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to default traits like `Sized`
|
||||
error: bound modifier `?` can only be applied to default traits
|
||||
--> $DIR/more_maybe_bounds.rs:21:37
|
||||
|
|
||||
LL | fn baz<T>() where T: Iterator<Item: ?Trait1> {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to default traits
|
||||
--> $DIR/more_maybe_bounds.rs:35:34
|
||||
|
|
||||
LL | struct S2<T>(T) where for<'a> T: ?Trait5<'a>;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: bound modifier `?` can only be applied to default traits
|
||||
--> $DIR/more_maybe_bounds.rs:28:21
|
||||
|
|
||||
LL | fn f() where T: ?Trait1 {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
|
||||
Reference in New Issue
Block a user