Rollup merge of #142693 - fmease:unbound-bettering, r=compiler-errors

More robustly deal with relaxed bounds and improve their diagnostics

Scaffolding for https://github.com/rust-lang/rust/issues/135229 (CC https://github.com/rust-lang/rust/pull/135331)

Fixes https://github.com/rust-lang/rust/issues/136944 (6th commit).
Fixes https://github.com/rust-lang/rust/issues/142718 (8th commit).
This commit is contained in:
Matthias Krüger
2025-07-18 19:14:43 +02:00
committed by GitHub
65 changed files with 772 additions and 819 deletions

View File

@@ -127,9 +127,6 @@ ast_lowering_misplaced_impl_trait =
`impl Trait` is not allowed in {$position}
.note = `impl Trait` is only allowed in arguments and return types of functions and methods
ast_lowering_misplaced_relax_trait_bound =
`?Trait` bounds are only permitted at the point where a type parameter is declared
ast_lowering_never_pattern_with_body =
a never pattern is always unreachable
.label = this will never be executed

View File

@@ -324,13 +324,6 @@ pub(crate) struct MisplacedDoubleDot {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_misplaced_relax_trait_bound)]
pub(crate) struct MisplacedRelaxTraitBound {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_match_arm_with_no_body)]
pub(crate) struct MatchArmWithNoBody {

View File

@@ -16,14 +16,11 @@ use smallvec::{SmallVec, smallvec};
use thin_vec::ThinVec;
use tracing::instrument;
use super::errors::{
InvalidAbi, InvalidAbiSuggestion, MisplacedRelaxTraitBound, TupleStructWithDefault,
UnionWithDefault,
};
use super::errors::{InvalidAbi, InvalidAbiSuggestion, TupleStructWithDefault, UnionWithDefault};
use super::stability::{enabled_names, gate_unstable_abi};
use super::{
AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
ResolverAstLoweringExt,
RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt,
};
pub(super) struct ItemLowerer<'a, 'hir> {
@@ -435,6 +432,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|this| {
let bounds = this.lower_param_bounds(
bounds,
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::SuperTrait),
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
);
let items = this.arena.alloc_from_iter(
@@ -455,6 +453,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|this| {
this.lower_param_bounds(
bounds,
RelaxedBoundPolicy::Allowed,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
)
},
@@ -940,6 +939,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::TraitItemKind::Type(
this.lower_param_bounds(
bounds,
RelaxedBoundPolicy::Allowed,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
ty,
@@ -1677,61 +1677,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
assert!(self.impl_trait_defs.is_empty());
assert!(self.impl_trait_bounds.is_empty());
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
// these into hir when we lower thee where clauses), but this makes it quite difficult to
// keep track of the Span info. Now, `<dyn HirTyLowerer>::add_implicit_sized_bound`
// checks both param bounds and where clauses for `?Sized`.
for pred in &generics.where_clause.predicates {
let WherePredicateKind::BoundPredicate(bound_pred) = &pred.kind else {
continue;
};
let compute_is_param = || {
// Check if the where clause type is a plain type parameter.
match self
.resolver
.get_partial_res(bound_pred.bounded_ty.id)
.and_then(|r| r.full_res())
{
Some(Res::Def(DefKind::TyParam, def_id))
if bound_pred.bound_generic_params.is_empty() =>
{
generics
.params
.iter()
.any(|p| def_id == self.local_def_id(p.id).to_def_id())
}
// Either the `bounded_ty` is not a plain type parameter, or
// it's not found in the generic type parameters list.
_ => false,
}
};
// We only need to compute this once per `WherePredicate`, but don't
// need to compute this at all unless there is a Maybe bound.
let mut is_param: Option<bool> = None;
for bound in &bound_pred.bounds {
if !matches!(
*bound,
GenericBound::Trait(PolyTraitRef {
modifiers: TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. },
..
})
) {
continue;
}
let is_param = *is_param.get_or_insert_with(compute_is_param);
if !is_param && !self.tcx.features().more_maybe_bounds() {
self.tcx
.sess
.create_feature_err(
MisplacedRelaxTraitBound { span: bound.span() },
sym::more_maybe_bounds,
)
.emit();
}
}
}
let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new();
predicates.extend(generics.params.iter().filter_map(|param| {
self.lower_generic_bound_predicate(
@@ -1741,6 +1686,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&param.bounds,
param.colon_span,
generics.span,
RelaxedBoundPolicy::Allowed,
itctx,
PredicateOrigin::GenericParam,
)
@@ -1750,7 +1696,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
.where_clause
.predicates
.iter()
.map(|predicate| self.lower_where_predicate(predicate)),
.map(|predicate| self.lower_where_predicate(predicate, &generics.params)),
);
let mut params: SmallVec<[hir::GenericParam<'hir>; 4]> = self
@@ -1827,6 +1773,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
bounds: &[GenericBound],
colon_span: Option<Span>,
parent_span: Span,
rbp: RelaxedBoundPolicy<'_>,
itctx: ImplTraitContext,
origin: PredicateOrigin,
) -> Option<hir::WherePredicate<'hir>> {
@@ -1835,7 +1782,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
return None;
}
let bounds = self.lower_param_bounds(bounds, itctx);
let bounds = self.lower_param_bounds(bounds, rbp, itctx);
let param_span = ident.span;
@@ -1887,7 +1834,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(hir::WherePredicate { hir_id, span, kind })
}
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
fn lower_where_predicate(
&mut self,
pred: &WherePredicate,
params: &[ast::GenericParam],
) -> hir::WherePredicate<'hir> {
let hir_id = self.lower_node_id(pred.id);
let span = self.lower_span(pred.span);
self.lower_attrs(hir_id, &pred.attrs, span);
@@ -1896,17 +1847,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
bound_generic_params,
bounded_ty,
bounds,
}) => hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
bound_generic_params: self
.lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
bounded_ty: self
.lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
}) => {
let rbp = if bound_generic_params.is_empty() {
RelaxedBoundPolicy::AllowedIfOnTyParam(bounded_ty.id, params)
} else {
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::LateBoundVarsInScope)
};
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
bound_generic_params: self.lower_generic_params(
bound_generic_params,
hir::GenericParamSource::Binder,
),
bounded_ty: self.lower_ty(
bounded_ty,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
bounds: self.lower_param_bounds(
bounds,
rbp,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
origin: PredicateOrigin::WhereClause,
}),
})
}
WherePredicateKind::RegionPredicate(WhereRegionPredicate { lifetime, bounds }) => {
hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
lifetime: self.lower_lifetime(
@@ -1916,6 +1879,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
),
bounds: self.lower_param_bounds(
bounds,
RelaxedBoundPolicy::Allowed,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
in_where_clause: true,

View File

@@ -53,8 +53,8 @@ use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};
use rustc_hir::lints::DelayedLint;
use rustc_hir::{
self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LangItem,
LifetimeSource, LifetimeSyntax, ParamName, TraitCandidate,
self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,
LifetimeSyntax, ParamName, TraitCandidate,
};
use rustc_index::{Idx, IndexSlice, IndexVec};
use rustc_macros::extension;
@@ -281,6 +281,24 @@ impl ResolverAstLowering {
}
}
/// How relaxed bounds `?Trait` should be treated.
///
/// Relaxed bounds should only be allowed in places where we later
/// (namely during HIR ty lowering) perform *sized elaboration*.
#[derive(Clone, Copy, Debug)]
enum RelaxedBoundPolicy<'a> {
Allowed,
AllowedIfOnTyParam(NodeId, &'a [ast::GenericParam]),
Forbidden(RelaxedBoundForbiddenReason),
}
#[derive(Clone, Copy, Debug)]
enum RelaxedBoundForbiddenReason {
TraitObjectTy,
SuperTrait,
LateBoundVarsInScope,
}
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
/// and if so, what meaning it has.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -1084,10 +1102,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
} else {
// Desugar `AssocTy: Bounds` into an assoc type binding where the
// later desugars into a trait predicate.
let bounds = self.lower_param_bounds(bounds, itctx);
// FIXME(#135229): These should be forbidden!
let bounds =
self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx);
hir::AssocItemConstraintKind::Bound { bounds }
}
}
@@ -1216,6 +1233,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
span: t.span,
parens: ast::Parens::No,
},
RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitObjectTy),
itctx,
);
let bounds = this.arena.alloc_from_iter([bound]);
@@ -1271,7 +1289,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
parenthesized: hir::GenericArgsParentheses::No,
span_ext: span,
});
let path = self.make_lang_item_qpath(LangItem::Pin, span, Some(args));
let path = self.make_lang_item_qpath(hir::LangItem::Pin, span, Some(args));
hir::TyKind::Path(path)
}
TyKind::FnPtr(f) => {
@@ -1332,7 +1350,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// takes care of rejecting invalid modifier combinations and
// const trait bounds in trait object types.
GenericBound::Trait(ty) => {
let trait_ref = this.lower_poly_trait_ref(ty, itctx);
let trait_ref = this.lower_poly_trait_ref(
ty,
RelaxedBoundPolicy::Forbidden(
RelaxedBoundForbiddenReason::TraitObjectTy,
),
itctx,
);
Some(trait_ref)
}
GenericBound::Outlives(lifetime) => {
@@ -1387,9 +1411,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
path
}
ImplTraitContext::InBinding => {
hir::TyKind::TraitAscription(self.lower_param_bounds(bounds, itctx))
}
ImplTraitContext::InBinding => hir::TyKind::TraitAscription(
self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx),
),
ImplTraitContext::FeatureGated(position, feature) => {
let guar = self
.tcx
@@ -1505,7 +1529,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
this.lower_param_bounds(bounds, itctx)
this.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx)
})
}
@@ -1799,10 +1823,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_param_bound(
&mut self,
tpb: &GenericBound,
rbp: RelaxedBoundPolicy<'_>,
itctx: ImplTraitContext,
) -> hir::GenericBound<'hir> {
match tpb {
GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
GenericBound::Trait(p) => {
hir::GenericBound::Trait(self.lower_poly_trait_ref(p, rbp, itctx))
}
GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(
lifetime,
LifetimeSource::OutlivesBound,
@@ -2017,21 +2044,93 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
#[instrument(level = "debug", skip(self))]
fn lower_poly_trait_ref(
&mut self,
p: &PolyTraitRef,
PolyTraitRef { bound_generic_params, modifiers, trait_ref, span, parens: _ }: &PolyTraitRef,
rbp: RelaxedBoundPolicy<'_>,
itctx: ImplTraitContext,
) -> hir::PolyTraitRef<'hir> {
let bound_generic_params =
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
self.lower_lifetime_binder(trait_ref.ref_id, bound_generic_params);
let trait_ref = self.lower_trait_ref(*modifiers, trait_ref, itctx);
let modifiers = self.lower_trait_bound_modifiers(*modifiers);
if let ast::BoundPolarity::Maybe(_) = modifiers.polarity {
self.validate_relaxed_bound(trait_ref, *span, rbp);
}
hir::PolyTraitRef {
bound_generic_params,
modifiers,
trait_ref,
span: self.lower_span(p.span),
span: self.lower_span(*span),
}
}
fn validate_relaxed_bound(
&self,
trait_ref: hir::TraitRef<'_>,
span: Span,
rbp: RelaxedBoundPolicy<'_>,
) {
// Even though feature `more_maybe_bounds` bypasses the given policy and (currently) enables
// relaxed bounds in every conceivable position[^1], we don't want to advertise it to the user
// (via a feature gate) since it's super internal. Besides this, it'd be quite distracting.
//
// [^1]: Strictly speaking, this is incorrect (at the very least for `Sized`) because it's
// no longer fully consistent with default trait elaboration in HIR ty lowering.
match rbp {
RelaxedBoundPolicy::Allowed => return,
RelaxedBoundPolicy::AllowedIfOnTyParam(id, params) => {
if let Some(res) = self.resolver.get_partial_res(id).and_then(|r| r.full_res())
&& let Res::Def(DefKind::TyParam, def_id) = res
&& params.iter().any(|p| def_id == self.local_def_id(p.id).to_def_id())
{
return;
}
if self.tcx.features().more_maybe_bounds() {
return;
}
}
RelaxedBoundPolicy::Forbidden(reason) => {
if self.tcx.features().more_maybe_bounds() {
return;
}
match reason {
RelaxedBoundForbiddenReason::TraitObjectTy => {
self.dcx().span_err(
span,
"relaxed bounds are not permitted in trait object types",
);
return;
}
RelaxedBoundForbiddenReason::SuperTrait => {
let mut diag = self.dcx().struct_span_err(
span,
"relaxed bounds are not permitted in supertrait bounds",
);
if let Some(def_id) = trait_ref.trait_def_id()
&& self.tcx.is_lang_item(def_id, hir::LangItem::Sized)
{
diag.note("traits are `?Sized` by default");
}
diag.emit();
return;
}
RelaxedBoundForbiddenReason::LateBoundVarsInScope => {}
};
}
}
self.dcx()
.struct_span_err(span, "this relaxed bound is not permitted here")
.with_note(
"in this context, relaxed bounds are only allowed on \
type parameters defined by the closest item",
)
.emit();
}
fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
}
@@ -2040,17 +2139,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_param_bounds(
&mut self,
bounds: &[GenericBound],
rbp: RelaxedBoundPolicy<'_>,
itctx: ImplTraitContext,
) -> hir::GenericBounds<'hir> {
self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, rbp, itctx))
}
fn lower_param_bounds_mut(
&mut self,
bounds: &[GenericBound],
rbp: RelaxedBoundPolicy<'_>,
itctx: ImplTraitContext,
) -> impl Iterator<Item = hir::GenericBound<'hir>> {
bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
bounds.iter().map(move |bound| self.lower_param_bound(bound, rbp, itctx))
}
#[instrument(level = "debug", skip(self), ret)]
@@ -2084,6 +2185,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
bounds,
/* colon_span */ None,
span,
RelaxedBoundPolicy::Allowed,
ImplTraitContext::Universal,
hir::PredicateOrigin::ImplTrait,
);

View File

@@ -212,11 +212,6 @@ ast_passes_nomangle_ascii = `#[no_mangle]` requires ASCII identifier
ast_passes_obsolete_auto = `impl Trait for .. {"{}"}` is an obsolete syntax
.help = use `auto trait Trait {"{}"}` instead
ast_passes_optional_trait_object = `?Trait` is not permitted in trait object types
ast_passes_optional_trait_supertrait = `?Trait` is not permitted in supertraits
.note = traits are `?{$path_str}` by default
ast_passes_out_of_order_params = {$param_ord} parameters must be declared prior to {$max_param} parameters
.suggestion = reorder the parameters: lifetimes, then consts and types

View File

@@ -1381,29 +1381,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
match bound {
GenericBound::Trait(trait_ref) => {
match (ctxt, trait_ref.modifiers.constness, trait_ref.modifiers.polarity) {
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_))
if !self.features.more_maybe_bounds() =>
{
self.sess
.create_feature_err(
errors::OptionalTraitSupertrait {
span: trait_ref.span,
path_str: pprust::path_to_string(&trait_ref.trait_ref.path),
},
sym::more_maybe_bounds,
)
.emit();
}
(BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_))
if !self.features.more_maybe_bounds() =>
{
self.sess
.create_feature_err(
errors::OptionalTraitObject { span: trait_ref.span },
sym::more_maybe_bounds,
)
.emit();
}
(
BoundKind::TraitObject,
BoundConstness::Always(_),

View File

@@ -566,22 +566,6 @@ pub(crate) struct NestedLifetimes {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_passes_optional_trait_supertrait)]
#[note]
pub(crate) struct OptionalTraitSupertrait {
#[primary_span]
pub span: Span,
pub path_str: String,
}
#[derive(Diagnostic)]
#[diag(ast_passes_optional_trait_object)]
pub(crate) struct OptionalTraitObject {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_passes_const_bound_trait_object)]
pub(crate) struct ConstBoundTraitObject {

View File

@@ -1,15 +1,15 @@
Having multiple relaxed default bounds is unsupported.
Having duplicate relaxed default bounds is unsupported.
Erroneous code example:
```compile_fail,E0203
struct Bad<T: ?Sized + ?Send>{
inner: T
struct Bad<T: ?Sized + ?Sized>{
inner: T,
}
```
Here the type `T` cannot have a relaxed bound for multiple default traits
(`Sized` and `Send`). This can be fixed by only using one relaxed bound.
Here the type parameter `T` cannot have duplicate relaxed bounds for default
trait `Sized`. This can be fixed by only using one relaxed bound:
```
struct Good<T: ?Sized>{

View File

@@ -371,9 +371,6 @@ hir_analysis_missing_type_params =
*[other] parameters
} must be specified on the object type
hir_analysis_multiple_relaxed_default_bounds =
type parameter has more than one relaxed default bound, only one is supported
hir_analysis_must_be_name_of_associated_function = must be a name of an associated function
hir_analysis_must_implement_not_function = not a function
@@ -448,8 +445,6 @@ hir_analysis_parenthesized_fn_trait_expansion =
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
.label = not allowed in type signatures
hir_analysis_pointee_sized_trait_object = `PointeeSized` cannot be used with trait objects
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
.label = `Self` is not a generic argument, but an alias to the type of the {$what}

View File

@@ -267,20 +267,16 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
match predicate.kind {
hir::WherePredicateKind::BoundPredicate(bound_pred) => {
let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
let bound_vars = tcx.late_bound_vars(predicate.hir_id);
// Keep the type around in a dummy predicate, in case of no bounds.
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
// is still checked for WF.
// This is a `where Ty:` (sic!).
if bound_pred.bounds.is_empty() {
if let ty::Param(_) = ty.kind() {
// This is a `where T:`, which can be in the HIR from the
// transformation that moves `?Sized` to `T`'s declaration.
// We can skip the predicate because type parameters are
// trivially WF, but also we *should*, to avoid exposing
// users who never wrote `where Type:,` themselves, to
// compiler/tooling bugs from not handling WF predicates.
// We can skip the predicate because type parameters are trivially WF.
} else {
// Keep the type around in a dummy predicate. That way, it's not a complete
// noop (see #53696) and `Ty` is still checked for WF.
let span = bound_pred.bounded_ty.span;
let predicate = ty::Binder::bind_with_vars(
ty::ClauseKind::WellFormed(ty.into()),

View File

@@ -279,13 +279,6 @@ pub(crate) struct CopyImplOnTypeWithDtor {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_multiple_relaxed_default_bounds, code = E0203)]
pub(crate) struct MultipleRelaxedDefaultBounds {
#[primary_span]
pub spans: Vec<Span>,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_copy_impl_on_non_adt, code = E0206)]
pub(crate) struct CopyImplOnNonAdt {
@@ -319,13 +312,6 @@ pub(crate) struct TraitObjectDeclaredWithNoTraits {
pub trait_alias_span: Option<Span>,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_pointee_sized_trait_object)]
pub(crate) struct PointeeSizedTraitObject {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_ambiguous_lifetime_bound, code = E0227)]
pub(crate) struct AmbiguousLifetimeBound {

View File

@@ -6,7 +6,7 @@ use rustc_errors::struct_span_code_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_hir::{AmbigArg, LangItem, PolyTraitRef};
use rustc_hir::{AmbigArg, PolyTraitRef};
use rustc_middle::bug;
use rustc_middle::ty::{
self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@@ -85,17 +85,17 @@ fn search_bounds_for<'tcx>(
}
}
fn collect_unbounds<'tcx>(
fn collect_relaxed_bounds<'tcx>(
hir_bounds: &'tcx [hir::GenericBound<'tcx>],
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
) -> SmallVec<[&'tcx PolyTraitRef<'tcx>; 1]> {
let mut unbounds: SmallVec<[_; 1]> = SmallVec::new();
let mut relaxed_bounds: SmallVec<[_; 1]> = SmallVec::new();
search_bounds_for(hir_bounds, self_ty_where_predicates, |ptr| {
if matches!(ptr.modifiers.polarity, hir::BoundPolarity::Maybe(_)) {
unbounds.push(ptr);
relaxed_bounds.push(ptr);
}
});
unbounds
relaxed_bounds
}
fn collect_bounds<'a, 'tcx>(
@@ -124,13 +124,13 @@ fn collect_sizedness_bounds<'tcx>(
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
span: Span,
) -> CollectedSizednessBounds {
let sized_did = tcx.require_lang_item(LangItem::Sized, span);
let sized_did = tcx.require_lang_item(hir::LangItem::Sized, span);
let sized = collect_bounds(hir_bounds, self_ty_where_predicates, sized_did);
let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span);
let meta_sized_did = tcx.require_lang_item(hir::LangItem::MetaSized, span);
let meta_sized = collect_bounds(hir_bounds, self_ty_where_predicates, meta_sized_did);
let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, span);
let pointee_sized_did = tcx.require_lang_item(hir::LangItem::PointeeSized, span);
let pointee_sized = collect_bounds(hir_bounds, self_ty_where_predicates, pointee_sized_did);
CollectedSizednessBounds { sized, meta_sized, pointee_sized }
@@ -151,24 +151,6 @@ fn add_trait_bound<'tcx>(
}
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Skip `PointeeSized` bounds.
///
/// `PointeeSized` is a "fake bound" insofar as anywhere a `PointeeSized` bound exists, there
/// is actually the absence of any bounds. This avoids limitations around non-global where
/// clauses being preferred over item bounds (where `PointeeSized` bounds would be
/// proven) - which can result in errors when a `PointeeSized` supertrait/bound/predicate is
/// added to some items.
pub(crate) fn should_skip_sizedness_bound<'hir>(
&self,
bound: &'hir hir::GenericBound<'tcx>,
) -> bool {
bound
.trait_ref()
.and_then(|tr| tr.trait_def_id())
.map(|did| self.tcx().is_lang_item(did, LangItem::PointeeSized))
.unwrap_or(false)
}
/// Adds sizedness bounds to a trait, trait alias, parameter, opaque type or associated type.
///
/// - On parameters, opaque type and associated types, add default `Sized` bound if no explicit
@@ -193,8 +175,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
return;
}
let meta_sized_did = tcx.require_lang_item(LangItem::MetaSized, span);
let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, span);
let meta_sized_did = tcx.require_lang_item(hir::LangItem::MetaSized, span);
let pointee_sized_did = tcx.require_lang_item(hir::LangItem::PointeeSized, span);
// If adding sizedness bounds to a trait, then there are some relevant early exits
if let Some(trait_did) = trait_did {
@@ -209,9 +191,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
return;
}
} else {
// Report invalid unbounds on sizedness-bounded generic parameters.
let unbounds = collect_unbounds(hir_bounds, self_ty_where_predicates);
self.check_and_report_invalid_unbounds_on_param(unbounds);
// Report invalid relaxed bounds.
// FIXME: Since we only call this validation function here in this function, we only
// fully validate relaxed bounds in contexts where we perform
// "sized elaboration". In most cases that doesn't matter because we *usually*
// reject such relaxed bounds outright during AST lowering.
// However, this can easily get out of sync! Ideally, we would perform this step
// where we are guaranteed to catch *all* bounds like in
// `Self::lower_poly_trait_ref`. List of concrete issues:
// FIXME(more_maybe_bounds): We don't call this for e.g., trait object tys or
// supertrait bounds!
// FIXME(trait_alias, #143122): We don't call it for the RHS. Arguably however,
// AST lowering should reject them outright.
// FIXME(associated_type_bounds): We don't call this for them. However, AST
// lowering should reject them outright (#135229).
let bounds = collect_relaxed_bounds(hir_bounds, self_ty_where_predicates);
self.check_and_report_invalid_relaxed_bounds(bounds);
}
let collected = collect_sizedness_bounds(tcx, hir_bounds, self_ty_where_predicates, span);
@@ -231,7 +226,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
} else {
// If there are no explicit sizedness bounds on a parameter then add a default
// `Sized` bound.
let sized_did = tcx.require_lang_item(LangItem::Sized, span);
let sized_did = tcx.require_lang_item(hir::LangItem::Sized, span);
add_trait_bound(tcx, bounds, self_ty, sized_did, span);
}
}
@@ -463,10 +458,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
'tcx: 'hir,
{
for hir_bound in hir_bounds {
if self.should_skip_sizedness_bound(hir_bound) {
continue;
}
// In order to avoid cycles, when we're lowering `SelfTraitThatDefines`,
// we skip over any traits that don't define the given associated type.
if let PredicateFilter::SelfTraitThatDefines(assoc_ident) = predicate_filter {
@@ -482,12 +473,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
match hir_bound {
hir::GenericBound::Trait(poly_trait_ref) => {
let hir::TraitBoundModifiers { constness, polarity } = poly_trait_ref.modifiers;
let _ = self.lower_poly_trait_ref(
&poly_trait_ref.trait_ref,
poly_trait_ref.span,
constness,
polarity,
poly_trait_ref,
param_ty,
bounds,
predicate_filter,

View File

@@ -2,7 +2,6 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::struct_span_code_err;
use rustc_hir as hir;
use rustc_hir::LangItem;
use rustc_hir::def::{DefKind, Res};
use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
use rustc_middle::ty::elaborate::ClauseWithSupertraitSpan;
@@ -18,9 +17,7 @@ use tracing::{debug, instrument};
use super::HirTyLowerer;
use crate::errors::SelfInTypeAlias;
use crate::hir_ty_lowering::{
GenericArgCountMismatch, GenericArgCountResult, PredicateFilter, RegionInferReason,
};
use crate::hir_ty_lowering::{GenericArgCountMismatch, PredicateFilter, RegionInferReason};
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Lower a trait object type from the HIR to our internal notion of a type.
@@ -38,24 +35,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let mut user_written_bounds = Vec::new();
let mut potential_assoc_types = Vec::new();
for trait_bound in hir_bounds.iter() {
if let hir::BoundPolarity::Maybe(_) = trait_bound.modifiers.polarity {
continue;
}
if let GenericArgCountResult {
correct:
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
..
} = self.lower_poly_trait_ref(
&trait_bound.trait_ref,
trait_bound.span,
trait_bound.modifiers.constness,
hir::BoundPolarity::Positive,
for poly_trait_ref in hir_bounds.iter() {
let result = self.lower_poly_trait_ref(
poly_trait_ref,
dummy_self,
&mut user_written_bounds,
PredicateFilter::SelfOnly,
) {
potential_assoc_types.extend(cur_potential_assoc_types);
);
if let Err(GenericArgCountMismatch { invalid_args, .. }) = result.correct {
potential_assoc_types.extend(invalid_args);
}
}
@@ -81,13 +69,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let guar = self.report_trait_object_addition_traits(&regular_traits);
return Ty::new_error(tcx, guar);
}
// We don't support `PointeeSized` principals
let pointee_sized_did = tcx.require_lang_item(LangItem::PointeeSized, span);
if regular_traits.iter().any(|(pred, _)| pred.def_id() == pointee_sized_did) {
let guar = self.report_pointee_sized_trait_object(span);
return Ty::new_error(tcx, guar);
}
// Don't create a dyn trait if we have errors in the principal.
if let Err(guar) = regular_traits.error_reported() {
return Ty::new_error(tcx, guar);

View File

@@ -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, LangItem, PolyTraitRef};
use rustc_hir::{self as hir, HirId, PolyTraitRef};
use rustc_middle::bug;
use rustc_middle::ty::fast_reject::{TreatParams, simplify_type};
use rustc_middle::ty::print::{PrintPolyTraitRefExt as _, PrintTraitRefExt as _};
@@ -29,59 +29,54 @@ use tracing::debug;
use super::InherentAssocCandidate;
use crate::errors::{
self, AssocItemConstraintsNotAllowedHere, ManualImplementation, MissingTypeParams,
ParenthesizedFnTraitExpansion, PointeeSizedTraitObject, TraitObjectDeclaredWithNoTraits,
ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,
};
use crate::fluent_generated as fluent;
use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer};
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Check for multiple relaxed default bounds and relaxed bounds of non-sizedness traits.
pub(crate) fn check_and_report_invalid_unbounds_on_param(
/// Check for duplicate relaxed bounds and relaxed bounds of non-default traits.
pub(crate) fn check_and_report_invalid_relaxed_bounds(
&self,
unbounds: SmallVec<[&PolyTraitRef<'_>; 1]>,
relaxed_bounds: SmallVec<[&PolyTraitRef<'_>; 1]>,
) {
let tcx = self.tcx();
let sized_did = tcx.require_lang_item(LangItem::Sized, DUMMY_SP);
let mut grouped_bounds = FxIndexMap::<_, Vec<_>>::default();
let mut unique_bounds = FxIndexSet::default();
let mut seen_repeat = false;
for unbound in &unbounds {
if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res {
seen_repeat |= !unique_bounds.insert(unbound_def_id);
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);
}
}
if unbounds.len() > 1 {
let err = errors::MultipleRelaxedDefaultBounds {
spans: unbounds.iter().map(|ptr| ptr.span).collect(),
};
if seen_repeat {
tcx.dcx().emit_err(err);
} else if !tcx.features().more_maybe_bounds() {
tcx.sess.create_feature_err(err, sym::more_maybe_bounds).emit();
};
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();
}
}
for unbound in unbounds {
if let Res::Def(DefKind::Trait, did) = unbound.trait_ref.path.res
&& ((did == sized_did) || tcx.is_default_trait(did))
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;
}
let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds {
true => "`?Sized` and `experimental_default_bounds`",
false => "`?Sized`",
};
self.dcx().span_err(
unbound.span,
format!(
"relaxing a default bound only does something for {}; all other traits are \
not bound by default",
unbound_traits
),
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`"
},
);
}
}
@@ -1410,10 +1405,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self.dcx().emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span })
}
pub(super) fn report_pointee_sized_trait_object(&self, span: Span) -> ErrorGuaranteed {
self.dcx().emit_err(PointeeSizedTraitObject { span })
}
}
/// Emit an error for the given associated item constraint.

View File

@@ -747,18 +747,46 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
/// where `'a` is a bound region at depth 0. Similarly, the `trait_ref` would be `Bar<'a>`.
/// The lowered poly-trait-ref will track this binder explicitly, however.
#[instrument(level = "debug", skip(self, span, constness, bounds))]
#[instrument(level = "debug", skip(self, bounds))]
pub(crate) fn lower_poly_trait_ref(
&self,
trait_ref: &hir::TraitRef<'tcx>,
span: Span,
constness: hir::BoundConstness,
polarity: hir::BoundPolarity,
poly_trait_ref: &hir::PolyTraitRef<'tcx>,
self_ty: Ty<'tcx>,
bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
predicate_filter: PredicateFilter,
) -> GenericArgCountResult {
let tcx = self.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 } =
*poly_trait_ref;
let hir::TraitBoundModifiers { constness, polarity } = modifiers;
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
// Relaxed bounds `?Trait` and `PointeeSized` bounds aren't represented in the `middle::ty` IR
// as they denote the *absence* of a default bound. However, we can't bail out early here since
// we still need to perform several validation steps (see below). Instead, simply "pour" all
// resulting bounds "down the drain", i.e., into a new `Vec` that just gets dropped at the end.
let (polarity, bounds) = match polarity {
rustc_ast::BoundPolarity::Positive
if tcx.is_lang_item(trait_def_id, hir::LangItem::PointeeSized) =>
{
// To elaborate on the comment directly above, regarding `PointeeSized` specifically,
// we don't "reify" such bounds to avoid trait system limitations -- namely,
// non-global where-clauses being preferred over item bounds (where `PointeeSized`
// bounds would be proven) -- which can result in errors when a `PointeeSized`
// supertrait / bound / predicate is added to some items.
(ty::PredicatePolarity::Positive, &mut Vec::new())
}
rustc_ast::BoundPolarity::Positive => (ty::PredicatePolarity::Positive, bounds),
rustc_ast::BoundPolarity::Negative(_) => (ty::PredicatePolarity::Negative, bounds),
rustc_ast::BoundPolarity::Maybe(_) => {
(ty::PredicatePolarity::Positive, &mut Vec::new())
}
};
let trait_segment = trait_ref.path.segments.last().unwrap();
let _ = self.prohibit_generic_args(
@@ -775,7 +803,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
Some(self_ty),
);
let tcx = self.tcx();
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
debug!(?bound_vars);
@@ -786,27 +813,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
debug!(?poly_trait_ref);
let polarity = match polarity {
rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
rustc_ast::BoundPolarity::Maybe(_) => {
// Validate associated type at least. We may want to reject these
// outright in the future...
for constraint in trait_segment.args().constraints {
let _ = self.lower_assoc_item_constraint(
trait_ref.hir_ref_id,
poly_trait_ref,
constraint,
&mut Default::default(),
&mut Default::default(),
constraint.span,
predicate_filter,
);
}
return arg_count;
}
};
// We deal with const conditions later.
match predicate_filter {
PredicateFilter::All
@@ -909,7 +915,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// Don't register any associated item constraints for negative bounds,
// since we should have emitted an error for them earlier, and they
// would not be well-formed!
if polarity != ty::PredicatePolarity::Positive {
if polarity == ty::PredicatePolarity::Negative {
self.dcx().span_delayed_bug(
constraint.span,
"negative trait bounds should not have assoc item constraints",

View File

@@ -1,8 +1,7 @@
// Regression test for <https://github.com/rust-lang/rust/issues/137554>.
fn main() -> dyn Iterator + ?Iterator::advance_by(usize) {
//~^ ERROR `?Trait` is not permitted in trait object types
//~| ERROR expected trait, found associated function `Iterator::advance_by`
//~| ERROR the value of the associated type `Item` in `Iterator` must be specified
//~^ ERROR expected trait, found associated function `Iterator::advance_by`
//~| ERROR relaxed bounds are not permitted in trait object types
todo!()
}

View File

@@ -1,25 +1,15 @@
error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/missing-associated_item_or_field_def_ids.rs:3:29
|
LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0404]: expected trait, found associated function `Iterator::advance_by`
--> $DIR/missing-associated_item_or_field_def_ids.rs:3:30
|
LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a trait
error[E0191]: the value of the associated type `Item` in `Iterator` must be specified
--> $DIR/missing-associated_item_or_field_def_ids.rs:3:18
error: relaxed bounds are not permitted in trait object types
--> $DIR/missing-associated_item_or_field_def_ids.rs:3:29
|
LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) {
| ^^^^^^^^ help: specify the associated type: `Iterator<Item = Type>`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0191, E0404, E0658.
For more information about an error, try `rustc --explain E0191`.
For more information about this error, try `rustc --explain E0404`.

View File

@@ -6,7 +6,6 @@ trait Tr {
fn main() {
let _: dyn Tr + ?Foo<Assoc = ()>;
//~^ ERROR: `?Trait` is not permitted in trait object types
//~| ERROR: cannot find trait `Foo` in this scope
//~| ERROR: the value of the associated type `Item` in `Tr` must be specified
//~^ ERROR: cannot find trait `Foo` in this scope
//~| ERROR: relaxed bounds are not permitted in trait object types
}

View File

@@ -1,28 +1,15 @@
error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:21
|
LL | let _: dyn Tr + ?Foo<Assoc = ()>;
| ^^^^^^^^^^^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0405]: cannot find trait `Foo` in this scope
--> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:22
|
LL | let _: dyn Tr + ?Foo<Assoc = ()>;
| ^^^ not found in this scope
error[E0191]: the value of the associated type `Item` in `Tr` must be specified
--> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:16
error: relaxed bounds are not permitted in trait object types
--> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:21
|
LL | type Item;
| --------- `Item` defined here
...
LL | let _: dyn Tr + ?Foo<Assoc = ()>;
| ^^ help: specify the associated type: `Tr<Item = Type>`
| ^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0191, E0405, E0658.
For more information about an error, try `rustc --explain E0191`.
For more information about this error, try `rustc --explain E0405`.

View File

@@ -2,23 +2,13 @@
trait Trait1 {}
auto trait Trait2 {}
trait Trait3: ?Trait1 {}
//~^ ERROR `?Trait` is not permitted in supertraits
trait Trait4 where Self: ?Trait1 {}
//~^ ERROR ?Trait` bounds are only permitted at the point where a type parameter is declared
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
fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
//~^ ERROR `?Trait` is not permitted in trait object types
//~^ ERROR relaxed bounds are not permitted in trait object types
fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
trait Trait {}
// Do not suggest `#![feature(more_maybe_bounds)]` for repetitions
fn baz<T: ?Trait + ?Trait>(_ : T) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~^ ERROR bound modifier `?` can only be applied to `Sized`
//~| ERROR bound modifier `?` can only be applied to `Sized`
fn main() {}

View File

@@ -1,71 +1,34 @@
error[E0658]: `?Trait` is not permitted in supertraits
error: relaxed bounds are not permitted in supertrait bounds
--> $DIR/feature-gate-more-maybe-bounds.rs:5:15
|
LL | trait Trait3: ?Trait1 {}
| ^^^^^^^
|
= note: traits are `?Trait1` by default
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/feature-gate-more-maybe-bounds.rs:10:28
|
LL | fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
| ^^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/feature-gate-more-maybe-bounds.rs:7:26
error: this relaxed bound is not permitted here
--> $DIR/feature-gate-more-maybe-bounds.rs:6:26
|
LL | trait Trait4 where Self: ?Trait1 {}
| ^^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
--> $DIR/feature-gate-more-maybe-bounds.rs:12:11
error: relaxed bounds are not permitted in trait object types
--> $DIR/feature-gate-more-maybe-bounds.rs:8:28
|
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
| ^^^^^^^ ^^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
LL | fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
| ^^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/feature-gate-more-maybe-bounds.rs:12:11
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/feature-gate-more-maybe-bounds.rs:10:11
|
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
| ^^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/feature-gate-more-maybe-bounds.rs:12:21
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/feature-gate-more-maybe-bounds.rs:10:21
|
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
| ^^^^^^^
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
--> $DIR/feature-gate-more-maybe-bounds.rs:19:11
|
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
| ^^^^^^ ^^^^^^
error: aborting due to 5 previous errors
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/feature-gate-more-maybe-bounds.rs:19:11
|
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
| ^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/feature-gate-more-maybe-bounds.rs:19:20
|
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
| ^^^^^^
error: aborting due to 9 previous errors
Some errors have detailed explanations: E0203, E0658.
For more information about an error, try `rustc --explain E0203`.

View File

@@ -3,8 +3,8 @@
use std::future::Future;
fn foo() -> impl ?Future<Output = impl Send> {
//~^ ERROR: relaxing a default bound only does something for `?Sized`
//~| ERROR: relaxing a default bound only does something for `?Sized`
//~^ ERROR: bound modifier `?` can only be applied to `Sized`
//~| ERROR: bound modifier `?` can only be applied to `Sized`
()
}

View File

@@ -1,10 +1,10 @@
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/opt-out-bound-not-satisfied.rs:5:18
|
LL | fn foo() -> impl ?Future<Output = impl Send> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/opt-out-bound-not-satisfied.rs:5:18
|
LL | fn foo() -> impl ?Future<Output = impl Send> {

View File

@@ -1,5 +1,5 @@
struct Foo<T: ?Hash> {}
//~^ ERROR expected trait, found derive macro `Hash`
//~| ERROR relaxing a default bound only does something for `?Sized`
//~| ERROR bound modifier `?` can only be applied to `Sized`
fn main() {}

View File

@@ -9,7 +9,7 @@ help: consider importing this trait instead
LL + use std::hash::Hash;
|
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/issue-37534.rs:1:15
|
LL | struct Foo<T: ?Hash> {}

View File

@@ -6,12 +6,12 @@
// Check that these function definitions only emit warnings, not errors
fn arg<T: ?Send>(_: T) {}
//~^ ERROR: relaxing a default bound only does something for `?Sized`
//~^ ERROR: bound modifier `?` can only be applied to `Sized`
fn ref_arg<T: ?Send>(_: &T) {}
//~^ ERROR: relaxing a default bound only does something for `?Sized`
//~^ ERROR: bound modifier `?` can only be applied to `Sized`
fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
//~^ ERROR: relaxing a default bound only does something for `?Sized`
//~| ERROR: relaxing a default bound only does something for `?Sized`
//~^ ERROR: bound modifier `?` can only be applied to `Sized`
//~| ERROR: bound modifier `?` can only be applied to `Sized`
// Check that there's no `?Sized` relaxation!
fn main() {

View File

@@ -1,22 +1,22 @@
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/issue-87199.rs:8:11
|
LL | fn arg<T: ?Send>(_: T) {}
| ^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/issue-87199.rs:10:15
|
LL | fn ref_arg<T: ?Send>(_: &T) {}
| ^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/issue-87199.rs:12:40
|
LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
| ^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/issue-87199.rs:12:40
|
LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }

View File

@@ -6,17 +6,17 @@ fn f<T: (Copy) + (?Sized) + (for<'a> Trait<'a>)>() {}
fn main() {
let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
//~^ ERROR `?Trait` is not permitted in trait object types
//~^ ERROR relaxed bounds are not permitted in trait object types
//~| ERROR only auto traits can be used as additional traits
//~| WARN trait objects without an explicit `dyn` are deprecated
//~| WARN this is accepted in the current edition
let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
//~^ ERROR `?Trait` is not permitted in trait object types
//~^ ERROR relaxed bounds are not permitted in trait object types
//~| ERROR only auto traits can be used as additional traits
//~| WARN trait objects without an explicit `dyn` are deprecated
//~| WARN this is accepted in the current edition
let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
//~^ ERROR `?Trait` is not permitted in trait object types
//~^ ERROR relaxed bounds are not permitted in trait object types
//~| ERROR only auto traits can be used as additional traits
//~| WARN trait objects without an explicit `dyn` are deprecated
//~| WARN this is accepted in the current edition

View File

@@ -1,29 +1,20 @@
error[E0658]: `?Trait` is not permitted in trait object types
error: relaxed bounds are not permitted in trait object types
--> $DIR/trait-object-trait-parens.rs:8:24
|
LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
| ^^^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in trait object types
error: relaxed bounds are not permitted in trait object types
--> $DIR/trait-object-trait-parens.rs:13:16
|
LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in trait object types
error: relaxed bounds are not permitted in trait object types
--> $DIR/trait-object-trait-parens.rs:18:44
|
LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
| ^^^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/trait-object-trait-parens.rs:8:16
@@ -100,5 +91,4 @@ LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
error: aborting due to 6 previous errors; 3 warnings emitted
Some errors have detailed explanations: E0225, E0658.
For more information about an error, try `rustc --explain E0225`.
For more information about this error, try `rustc --explain E0225`.

View File

@@ -14,13 +14,13 @@ fn neg_sized<T: ?Sized>() {}
fn metasized<T: MetaSized>() {}
fn neg_metasized<T: ?MetaSized>() {}
//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~^ ERROR bound modifier `?` can only be applied to `Sized`
fn pointeesized<T: PointeeSized>() { }
fn neg_pointeesized<T: ?PointeeSized>() { }
//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~^ ERROR bound modifier `?` can only be applied to `Sized`
fn main() {

View File

@@ -1,10 +1,10 @@
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/default-bound.rs:16:21
|
LL | fn neg_metasized<T: ?MetaSized>() {}
| ^^^^^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/default-bound.rs:22:24
|
LL | fn neg_pointeesized<T: ?PointeeSized>() { }

View File

@@ -6,18 +6,18 @@ use std::marker::{MetaSized, PointeeSized};
trait Sized_: Sized { }
trait NegSized: ?Sized { }
//~^ ERROR `?Trait` is not permitted in supertraits
//~^ ERROR relaxed bounds are not permitted in supertrait bounds
trait MetaSized_: MetaSized { }
trait NegMetaSized: ?MetaSized { }
//~^ ERROR `?Trait` is not permitted in supertraits
//~^ ERROR relaxed bounds are not permitted in supertrait bounds
trait PointeeSized_: PointeeSized { }
trait NegPointeeSized: ?PointeeSized { }
//~^ ERROR `?Trait` is not permitted in supertraits
//~^ ERROR relaxed bounds are not permitted in supertrait bounds
trait Bare {}

View File

@@ -1,32 +1,22 @@
error[E0658]: `?Trait` is not permitted in supertraits
error: relaxed bounds are not permitted in supertrait bounds
--> $DIR/default-supertrait.rs:8:17
|
LL | trait NegSized: ?Sized { }
| ^^^^^^
|
= note: traits are `?Sized` by default
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in supertraits
error: relaxed bounds are not permitted in supertrait bounds
--> $DIR/default-supertrait.rs:13:21
|
LL | trait NegMetaSized: ?MetaSized { }
| ^^^^^^^^^^
|
= note: traits are `?MetaSized` by default
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in supertraits
error: relaxed bounds are not permitted in supertrait bounds
--> $DIR/default-supertrait.rs:19:24
|
LL | trait NegPointeeSized: ?PointeeSized { }
| ^^^^^^^^^^^^^
|
= note: traits are `?PointeeSized` by default
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0277]: the size for values of type `T` cannot be known
--> $DIR/default-supertrait.rs:52:38
@@ -121,5 +111,4 @@ LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() {
error: aborting due to 9 previous errors
Some errors have detailed explanations: E0277, E0658.
For more information about an error, try `rustc --explain E0277`.
For more information about this error, try `rustc --explain E0277`.

View File

@@ -0,0 +1,20 @@
// Test that despite us dropping `PointeeSized` bounds during HIR ty lowering
// we still validate it first.
// issue: <https://github.com/rust-lang/rust/issues/142718>
#![feature(sized_hierarchy)]
use std::marker::PointeeSized;
struct T where (): PointeeSized<(), Undefined = ()>;
//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
//~| ERROR associated type `Undefined` not found for `PointeeSized`
const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {}
//~^ ERROR `const` can only be applied to `const` traits
//~| ERROR `const` can only be applied to `const` traits
//~| ERROR const trait impls are experimental
//~| ERROR `[const]` can only be applied to `const` traits
//~| ERROR `[const]` can only be applied to `const` traits
//~| ERROR const trait impls are experimental
fn main() {}

View File

@@ -0,0 +1,76 @@
error[E0658]: const trait impls are experimental
--> $DIR/pointee-validation.rs:12:32
|
LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {}
| ^^^^^
|
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: const trait impls are experimental
--> $DIR/pointee-validation.rs:12:55
|
LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {}
| ^^^^^^^
|
= note: see issue #143874 <https://github.com/rust-lang/rust/issues/143874> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/pointee-validation.rs:8:20
|
LL | struct T where (): PointeeSized<(), Undefined = ()>;
| ^^^^^^^^^^^^-------------------- help: remove the unnecessary generics
| |
| expected 0 generic arguments
error[E0220]: associated type `Undefined` not found for `PointeeSized`
--> $DIR/pointee-validation.rs:8:37
|
LL | struct T where (): PointeeSized<(), Undefined = ()>;
| ^^^^^^^^^ associated type `Undefined` not found
error: `const` can only be applied to `const` traits
--> $DIR/pointee-validation.rs:12:32
|
LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {}
| ^^^^^ can't be applied to `PointeeSized`
|
note: `PointeeSized` can't be used with `const` because it isn't `const`
--> $SRC_DIR/core/src/marker.rs:LL:COL
error: `[const]` can only be applied to `const` traits
--> $DIR/pointee-validation.rs:12:55
|
LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {}
| ^^^^^^^ can't be applied to `PointeeSized`
|
note: `PointeeSized` can't be used with `[const]` because it isn't `const`
--> $SRC_DIR/core/src/marker.rs:LL:COL
error: `const` can only be applied to `const` traits
--> $DIR/pointee-validation.rs:12:32
|
LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {}
| ^^^^^ can't be applied to `PointeeSized`
|
note: `PointeeSized` can't be used with `const` because it isn't `const`
--> $SRC_DIR/core/src/marker.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `[const]` can only be applied to `const` traits
--> $DIR/pointee-validation.rs:12:55
|
LL | const fn test<T, U>() where T: const PointeeSized, U: [const] PointeeSized {}
| ^^^^^^^ can't be applied to `PointeeSized`
|
note: `PointeeSized` can't be used with `[const]` because it isn't `const`
--> $SRC_DIR/core/src/marker.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0107, E0220, E0658.
For more information about an error, try `rustc --explain E0107`.

View File

@@ -3,7 +3,7 @@
use std::marker::PointeeSized;
type Foo = dyn PointeeSized;
//~^ ERROR `PointeeSized` cannot be used with trait objects
//~^ ERROR at least one trait is required for an object type
fn foo(f: &Foo) {}
@@ -12,5 +12,5 @@ fn main() {
let x = main;
let y: Box<dyn PointeeSized> = x;
//~^ ERROR `PointeeSized` cannot be used with trait objects
//~^ ERROR at least one trait is required for an object type
}

View File

@@ -1,10 +1,10 @@
error: `PointeeSized` cannot be used with trait objects
error[E0224]: at least one trait is required for an object type
--> $DIR/reject-dyn-pointeesized.rs:5:12
|
LL | type Foo = dyn PointeeSized;
| ^^^^^^^^^^^^^^^^
error: `PointeeSized` cannot be used with trait objects
error[E0224]: at least one trait is required for an object type
--> $DIR/reject-dyn-pointeesized.rs:14:16
|
LL | let y: Box<dyn PointeeSized> = x;
@@ -12,3 +12,4 @@ LL | let y: Box<dyn PointeeSized> = x;
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0224`.

View File

@@ -0,0 +1,22 @@
fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {}
//~^ ERROR duplicate relaxed `Sized` bounds
//~| ERROR duplicate relaxed `Iterator` bounds
//~| ERROR bound modifier `?` can only be applied to `Sized`
//~| ERROR bound modifier `?` can only be applied to `Sized`
trait Trait {
// We used to say "type parameter has more than one relaxed default bound"
// even on *associated types* like here. Test that we no longer do that.
type Type: ?Sized + ?Sized;
//~^ ERROR duplicate relaxed `Sized` bounds
//~| ERROR duplicate relaxed `Sized` bounds
}
// We used to emit an additional error about "multiple relaxed default bounds".
// However, multiple relaxed bounds are actually *fine* if they're distinct.
// Ultimately, we still reject this because `Sized` is
// the only (stable) default trait, so we're fine.
fn not_dupes<T: ?Sized + ?Iterator>() {}
//~^ ERROR bound modifier `?` can only be applied to `Sized`
fn main() {}

View File

@@ -0,0 +1,47 @@
error[E0203]: duplicate relaxed `Sized` bounds
--> $DIR/duplicate-relaxed-bounds.rs:1:13
|
LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {}
| ^^^^^^ ^^^^^^
error[E0203]: duplicate relaxed `Iterator` bounds
--> $DIR/duplicate-relaxed-bounds.rs:1:31
|
LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {}
| ^^^^^^^^^ ^^^^^^^^^
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/duplicate-relaxed-bounds.rs:1:31
|
LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {}
| ^^^^^^^^^
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/duplicate-relaxed-bounds.rs:1:43
|
LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {}
| ^^^^^^^^^
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/duplicate-relaxed-bounds.rs:19:26
|
LL | fn not_dupes<T: ?Sized + ?Iterator>() {}
| ^^^^^^^^^
error[E0203]: duplicate relaxed `Sized` bounds
--> $DIR/duplicate-relaxed-bounds.rs:10:16
|
LL | type Type: ?Sized + ?Sized;
| ^^^^^^ ^^^^^^
error[E0203]: duplicate relaxed `Sized` bounds
--> $DIR/duplicate-relaxed-bounds.rs:10:16
|
LL | type Type: ?Sized + ?Sized;
| ^^^^^^ ^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0203`.

View File

@@ -1,39 +1,38 @@
// Regression test for #127441
// Tests that we make the correct suggestion
// in case there are more than one `?Sized`
// bounds on a function parameter
// Test that we emit a correct structured suggestions for dynamically sized ("maybe unsized")
// function parameters.
// We used to emit a butchered suggestion if duplicate relaxed `Sized` bounds were present.
// issue: <https://github.com/rust-lang/rust/issues/127441>.
use std::fmt::Debug;
fn foo1<T: ?Sized>(a: T) {}
//~^ ERROR he size for values of type `T` cannot be known at compilation time
//~^ ERROR the size for values of type `T` cannot be known at compilation time
fn foo2<T: ?Sized + ?Sized>(a: T) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~^ ERROR duplicate relaxed `Sized` bounds
//~| ERROR the size for values of type `T` cannot be known at compilation time
fn foo3<T: ?Sized + ?Sized + Debug>(a: T) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~| ERROR he size for values of type `T` cannot be known at compilation time
//~^ ERROR duplicate relaxed `Sized` bounds
//~| ERROR the size for values of type `T` cannot be known at compilation time
fn foo4<T: ?Sized + Debug + ?Sized >(a: T) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~^ ERROR duplicate relaxed `Sized` bounds
//~| ERROR the size for values of type `T` cannot be known at compilation time
fn foo5(_: impl ?Sized) {}
//~^ ERROR the size for values of type `impl ?Sized` cannot be known at compilation time
fn foo6(_: impl ?Sized + ?Sized) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~^ ERROR duplicate relaxed `Sized` bounds
//~| ERROR the size for values of type `impl ?Sized + ?Sized` cannot be known at compilation tim
fn foo7(_: impl ?Sized + ?Sized + Debug) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~^ ERROR duplicate relaxed `Sized` bounds
//~| ERROR the size for values of type `impl ?Sized + ?Sized + Debug` cannot be known at compilation time
fn foo8(_: impl ?Sized + Debug + ?Sized ) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~^ ERROR duplicate relaxed `Sized` bounds
//~| ERROR the size for values of type `impl ?Sized + Debug + ?Sized` cannot be known at compilation time
fn main() {}

View File

@@ -1,41 +1,41 @@
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:12:12
error[E0203]: duplicate relaxed `Sized` bounds
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:11:12
|
LL | fn foo2<T: ?Sized + ?Sized>(a: T) {}
| ^^^^^^ ^^^^^^
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:16:12
error[E0203]: duplicate relaxed `Sized` bounds
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:15:12
|
LL | fn foo3<T: ?Sized + ?Sized + Debug>(a: T) {}
| ^^^^^^ ^^^^^^
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:20:12
error[E0203]: duplicate relaxed `Sized` bounds
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:19:12
|
LL | fn foo4<T: ?Sized + Debug + ?Sized >(a: T) {}
| ^^^^^^ ^^^^^^
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:27:17
error[E0203]: duplicate relaxed `Sized` bounds
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:26:17
|
LL | fn foo6(_: impl ?Sized + ?Sized) {}
| ^^^^^^ ^^^^^^
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:31:17
error[E0203]: duplicate relaxed `Sized` bounds
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:30:17
|
LL | fn foo7(_: impl ?Sized + ?Sized + Debug) {}
| ^^^^^^ ^^^^^^
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:35:17
error[E0203]: duplicate relaxed `Sized` bounds
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:34:17
|
LL | fn foo8(_: impl ?Sized + Debug + ?Sized ) {}
| ^^^^^^ ^^^^^^
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:9:23
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:8:23
|
LL | fn foo1<T: ?Sized>(a: T) {}
| - ^ doesn't have a size known at compile-time
@@ -54,7 +54,7 @@ LL | fn foo1<T: ?Sized>(a: &T) {}
| +
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:12:32
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:11:32
|
LL | fn foo2<T: ?Sized + ?Sized>(a: T) {}
| - ^ doesn't have a size known at compile-time
@@ -73,7 +73,7 @@ LL | fn foo2<T: ?Sized + ?Sized>(a: &T) {}
| +
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:16:40
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:15:40
|
LL | fn foo3<T: ?Sized + ?Sized + Debug>(a: T) {}
| - ^ doesn't have a size known at compile-time
@@ -92,7 +92,7 @@ LL | fn foo3<T: ?Sized + ?Sized + Debug>(a: &T) {}
| +
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:20:41
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:19:41
|
LL | fn foo4<T: ?Sized + Debug + ?Sized >(a: T) {}
| - ^ doesn't have a size known at compile-time
@@ -111,7 +111,7 @@ LL | fn foo4<T: ?Sized + Debug + ?Sized >(a: &T) {}
| +
error[E0277]: the size for values of type `impl ?Sized` cannot be known at compilation time
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:24:12
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:23:12
|
LL | fn foo5(_: impl ?Sized) {}
| ^^^^^^^^^^^
@@ -131,7 +131,7 @@ LL | fn foo5(_: &impl ?Sized) {}
| +
error[E0277]: the size for values of type `impl ?Sized + ?Sized` cannot be known at compilation time
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:27:12
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:26:12
|
LL | fn foo6(_: impl ?Sized + ?Sized) {}
| ^^^^^^^^^^^^^^^^^^^^
@@ -151,7 +151,7 @@ LL | fn foo6(_: &impl ?Sized + ?Sized) {}
| +
error[E0277]: the size for values of type `impl ?Sized + ?Sized + Debug` cannot be known at compilation time
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:31:12
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:30:12
|
LL | fn foo7(_: impl ?Sized + ?Sized + Debug) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -171,7 +171,7 @@ LL | fn foo7(_: &impl ?Sized + ?Sized + Debug) {}
| +
error[E0277]: the size for values of type `impl ?Sized + Debug + ?Sized` cannot be known at compilation time
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:35:12
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:34:12
|
LL | fn foo8(_: impl ?Sized + Debug + ?Sized ) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -2,6 +2,6 @@ trait Trait {}
fn test<T: ?self::<i32>::Trait>() {}
//~^ ERROR type arguments are not allowed on module `maybe_bound_has_path_args`
//~| ERROR relaxing a default bound only does something for `?Sized`
//~| ERROR bound modifier `?` can only be applied to `Sized`
fn main() {}

View File

@@ -1,4 +1,4 @@
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/maybe-bound-has-path-args.rs:3:12
|
LL | fn test<T: ?self::<i32>::Trait>() {}

View File

@@ -2,11 +2,11 @@ trait HasAssoc {
type Assoc;
}
fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
//~^ ERROR relaxing a default bound
//~^ ERROR bound modifier `?` can only be applied to `Sized`
trait NoAssoc {}
fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
//~^ ERROR relaxing a default bound
//~^ ERROR bound modifier `?` can only be applied to `Sized`
//~| ERROR associated type `Missing` not found for `NoAssoc`
fn main() {}

View File

@@ -1,10 +1,10 @@
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/maybe-bound-with-assoc.rs:4:16
|
LL | fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
| ^^^^^^^^^^^^^^^^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/maybe-bound-with-assoc.rs:8:15
|
LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}

View File

@@ -0,0 +1,29 @@
// 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 and trait object types 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 {}
trait Trait4 where Self: Trait1 {}
// FIXME: `?Trait2` should be rejected, `Trait2` isn't marked `#[lang = "default_traitN"]`.
fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}
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`
struct S;
impl !Trait2 for S {}
impl Trait1 for S {}
impl Trait3 for S {}
fn main() {
foo(Box::new(S));
bar(&S);
}

View File

@@ -0,0 +1,20 @@
error: bound modifier `?` can only be applied to default traits like `Sized`
--> $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: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:16:40
|
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
| ^^^^^^^
error: aborting due to 3 previous errors

View File

@@ -2,9 +2,12 @@
const fn maybe_const_maybe<T: [const] ?Sized>() {}
//~^ ERROR `[const]` trait not allowed with `?` trait polarity modifier
//~| ERROR `[const]` can only be applied to `const` traits
//~| ERROR `[const]` can only be applied to `const` traits
fn const_maybe<T: const ?Sized>() {}
//~^ ERROR `const` trait not allowed with `?` trait polarity modifier
//~| ERROR `const` can only be applied to `const` traits
const fn maybe_const_negative<T: [const] !Trait>() {}
//~^ ERROR `[const]` trait not allowed with `!` trait polarity modifier

View File

@@ -7,7 +7,7 @@ LL | const fn maybe_const_maybe<T: [const] ?Sized>() {}
| there is not a well-defined meaning for a `[const] ?` trait
error: `const` trait not allowed with `?` trait polarity modifier
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:6:25
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:8:25
|
LL | fn const_maybe<T: const ?Sized>() {}
| ----- ^
@@ -15,7 +15,7 @@ LL | fn const_maybe<T: const ?Sized>() {}
| there is not a well-defined meaning for a `const ?` trait
error: `[const]` trait not allowed with `!` trait polarity modifier
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:42
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:12:42
|
LL | const fn maybe_const_negative<T: [const] !Trait>() {}
| ------- ^
@@ -23,7 +23,7 @@ LL | const fn maybe_const_negative<T: [const] !Trait>() {}
| there is not a well-defined meaning for a `[const] !` trait
error: `const` trait not allowed with `!` trait polarity modifier
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:16:28
|
LL | fn const_negative<T: const !Trait>() {}
| ----- ^
@@ -31,16 +31,44 @@ LL | fn const_negative<T: const !Trait>() {}
| there is not a well-defined meaning for a `const !` trait
error: negative bounds are not supported
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:9:42
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:12:42
|
LL | const fn maybe_const_negative<T: [const] !Trait>() {}
| ^
error: negative bounds are not supported
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:13:28
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:16:28
|
LL | fn const_negative<T: const !Trait>() {}
| ^
error: aborting due to 6 previous errors
error: `[const]` can only be applied to `const` traits
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:3:31
|
LL | const fn maybe_const_maybe<T: [const] ?Sized>() {}
| ^^^^^^^ can't be applied to `Sized`
|
note: `Sized` can't be used with `[const]` because it isn't `const`
--> $SRC_DIR/core/src/marker.rs:LL:COL
error: `[const]` can only be applied to `const` traits
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:3:31
|
LL | const fn maybe_const_maybe<T: [const] ?Sized>() {}
| ^^^^^^^ can't be applied to `Sized`
|
note: `Sized` can't be used with `[const]` because it isn't `const`
--> $SRC_DIR/core/src/marker.rs:LL:COL
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `const` can only be applied to `const` traits
--> $DIR/mutually-exclusive-trait-bound-modifiers.rs:8:19
|
LL | fn const_maybe<T: const ?Sized>() {}
| ^^^^^ can't be applied to `Sized`
|
note: `Sized` can't be used with `const` because it isn't `const`
--> $SRC_DIR/core/src/marker.rs:LL:COL
error: aborting due to 9 previous errors

View File

@@ -64,4 +64,8 @@ fn main() {
x.leak_foo();
//~^ ERROR the trait bound `dyn Trait: Leak` is not satisfied
x.maybe_leak_foo();
// Ensure that we validate the generic args of relaxed bounds in trait object types.
let _: dyn Trait + ?Leak<(), Undefined = ()>;
//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
//~| ERROR associated type `Undefined` not found for `Leak`
}

View File

@@ -18,6 +18,27 @@ note: required by a bound in `Trait::leak_foo`
LL | fn leak_foo(&self) {}
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait::leak_foo`
error: aborting due to 2 previous errors
error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
--> $DIR/maybe-bounds-in-dyn-traits.rs:68:25
|
LL | let _: dyn Trait + ?Leak<(), Undefined = ()>;
| ^^^^-------------------- help: remove the unnecessary generics
| |
| expected 0 generic arguments
|
note: trait defined here, with 0 generic parameters
--> $DIR/maybe-bounds-in-dyn-traits.rs:44:12
|
LL | auto trait Leak {}
| ^^^^
For more information about this error, try `rustc --explain E0277`.
error[E0220]: associated type `Undefined` not found for `Leak`
--> $DIR/maybe-bounds-in-dyn-traits.rs:68:34
|
LL | let _: dyn Trait + ?Leak<(), Undefined = ()>;
| ^^^^^^^^^ associated type `Undefined` not found
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0107, E0220, E0277.
For more information about an error, try `rustc --explain E0107`.

View File

@@ -1,25 +0,0 @@
#![feature(auto_traits)]
#![feature(more_maybe_bounds)]
#![feature(negative_impls)]
trait Trait1 {}
auto trait Trait2 {}
trait Trait3 : ?Trait1 {}
trait Trait4 where Self: Trait1 {}
fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}
fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
//~^ ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
struct S;
impl !Trait2 for S {}
impl Trait1 for S {}
impl Trait3 for S {}
fn main() {
foo(Box::new(S));
bar(&S);
}

View File

@@ -1,20 +0,0 @@
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-pass.rs:12:20
|
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
| ^^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-pass.rs:12:30
|
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
| ^^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-pass.rs:12:40
|
LL | fn bar<T: ?Sized + ?Trait2 + ?Trait1 + ?Trait4>(_: &T) {}
| ^^^^^^^
error: aborting due to 3 previous errors

View File

@@ -1,9 +0,0 @@
#![feature(more_maybe_bounds)]
trait Trait {}
fn foo<T: ?Trait + ?Trait>(_: T) {}
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
//~| ERROR relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
fn main() {}

View File

@@ -1,21 +0,0 @@
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
--> $DIR/maybe-polarity-repeated.rs:4:11
|
LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
| ^^^^^^ ^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-repeated.rs:4:11
|
LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
| ^^^^^^
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-polarity-repeated.rs:4:20
|
LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
| ^^^^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0203`.

View File

@@ -1,18 +0,0 @@
//! Test that ?Trait bounds are forbidden in supertraits and trait object types.
//!
//! While `?Sized` and other maybe bounds are allowed in type parameter bounds and where clauses,
//! they are explicitly forbidden in certain syntactic positions:
//! - As supertraits in trait definitions
//! - In trait object type expressions
//!
//! See https://github.com/rust-lang/rust/issues/20503
trait Tr: ?Sized {}
//~^ ERROR `?Trait` is not permitted in supertraits
type A1 = dyn Tr + (?Sized);
//~^ ERROR `?Trait` is not permitted in trait object types
type A2 = dyn for<'a> Tr + (?Sized);
//~^ ERROR `?Trait` is not permitted in trait object types
fn main() {}

View File

@@ -1,31 +0,0 @@
error[E0658]: `?Trait` is not permitted in supertraits
--> $DIR/maybe-trait-bounds-forbidden-locations.rs:10:11
|
LL | trait Tr: ?Sized {}
| ^^^^^^
|
= note: traits are `?Sized` by default
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-trait-bounds-forbidden-locations.rs:13:20
|
LL | type A1 = dyn Tr + (?Sized);
| ^^^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-trait-bounds-forbidden-locations.rs:15:28
|
LL | type A2 = dyn for<'a> Tr + (?Sized);
| ^^^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@@ -1,18 +0,0 @@
// Test that `dyn ... + ?Sized + ...` is okay (though `?Sized` has no effect in trait objects).
trait Foo {}
type _0 = dyn ?Sized + Foo;
//~^ ERROR `?Trait` is not permitted in trait object types
type _1 = dyn Foo + ?Sized;
//~^ ERROR `?Trait` is not permitted in trait object types
type _2 = dyn Foo + ?Sized + ?Sized;
//~^ ERROR `?Trait` is not permitted in trait object types
//~| ERROR `?Trait` is not permitted in trait object types
type _3 = dyn ?Sized + Foo;
//~^ ERROR `?Trait` is not permitted in trait object types
fn main() {}

View File

@@ -1,48 +0,0 @@
error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bound.rs:5:15
|
LL | type _0 = dyn ?Sized + Foo;
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bound.rs:8:21
|
LL | type _1 = dyn Foo + ?Sized;
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bound.rs:11:21
|
LL | type _2 = dyn Foo + ?Sized + ?Sized;
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bound.rs:11:30
|
LL | type _2 = dyn Foo + ?Sized + ?Sized;
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` is not permitted in trait object types
--> $DIR/maybe-bound.rs:15:15
|
LL | type _3 = dyn ?Sized + Foo;
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@@ -2,6 +2,6 @@
type _0 = dyn ?Sized;
//~^ ERROR at least one trait is required for an object type [E0224]
//~| ERROR ?Trait` is not permitted in trait object types
//~| ERROR relaxed bounds are not permitted in trait object types
fn main() {}

View File

@@ -1,11 +1,8 @@
error[E0658]: `?Trait` is not permitted in trait object types
error: relaxed bounds are not permitted in trait object types
--> $DIR/only-maybe-bound.rs:3:15
|
LL | type _0 = dyn ?Sized;
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0224]: at least one trait is required for an object type
--> $DIR/only-maybe-bound.rs:3:11
@@ -15,5 +12,4 @@ LL | type _0 = dyn ?Sized;
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0224, E0658.
For more information about an error, try `rustc --explain E0224`.
For more information about this error, try `rustc --explain E0224`.

View File

@@ -1,28 +0,0 @@
struct S1<T>(T) where (T): ?Sized;
//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
struct S2<T>(T) where u8: ?Sized;
//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
struct S3<T>(T) where &'static T: ?Sized;
//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
trait Trait<'a> {}
struct S4<T>(T) where for<'a> T: ?Trait<'a>;
//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
//~| ERROR relaxing a default bound only does something for `?Sized`
struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
//~^ ERROR type parameter has more than one relaxed default bound
//~| ERROR relaxing a default bound only does something for `?Sized`
impl<T> S1<T> {
fn f() where T: ?Sized {}
//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
}
fn main() {
let u = vec![1, 2, 3];
let _s: S5<[u8]> = S5(&u[..]); // OK
}

View File

@@ -1,70 +0,0 @@
error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:1:28
|
LL | struct S1<T>(T) where (T): ?Sized;
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:4:27
|
LL | struct S2<T>(T) where u8: ?Sized;
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:7:35
|
LL | struct S3<T>(T) where &'static T: ?Sized;
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:12:34
|
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
| ^^^^^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:21:21
|
LL | fn f() where T: ?Sized {}
| ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bounds-where.rs:12:34
|
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
| ^^^^^^^^^^
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
--> $DIR/maybe-bounds-where.rs:16:33
|
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
| ^^^^^^^^^^^^^^^ ^^^^^^
|
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
--> $DIR/maybe-bounds-where.rs:16:33
|
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
| ^^^^^^^^^^^^^^^
error: aborting due to 8 previous errors
Some errors have detailed explanations: E0203, E0658.
For more information about an error, try `rustc --explain E0203`.

View File

@@ -0,0 +1,34 @@
// Test various places where relaxed bounds are not permitted.
//
// Relaxed bounds are only permitted inside impl-Trait, assoc ty item bounds and
// on type params defined by the closest item.
struct S1<T>(T) where (T): ?Sized; //~ ERROR this relaxed bound is not permitted here
struct S2<T>(T) where u8: ?Sized; //~ ERROR this relaxed bound is not permitted here
struct S3<T>(T) where &'static T: ?Sized; //~ ERROR this relaxed bound is not permitted here
trait Trait<'a> {}
struct S4<T>(T) where for<'a> T: ?Trait<'a>;
//~^ ERROR this relaxed bound is not permitted here
//~| ERROR bound modifier `?` can only be applied to `Sized`
struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
//~^ ERROR bound modifier `?` can only be applied to `Sized`
impl<T> S1<T> {
fn f() where T: ?Sized {} //~ ERROR this relaxed bound is not permitted here
}
trait Tr: ?Sized {} //~ ERROR relaxed bounds are not permitted in supertrait bounds
// Test that relaxed `Sized` bounds are rejected in trait object types:
type O1 = dyn Tr + ?Sized; //~ ERROR relaxed bounds are not permitted in trait object types
type O2 = dyn ?Sized + ?Sized + Tr;
//~^ ERROR relaxed bounds are not permitted in trait object types
//~| ERROR relaxed bounds are not permitted in trait object types
fn main() {}

View File

@@ -0,0 +1,80 @@
error: this relaxed bound is not permitted here
--> $DIR/relaxed-bounds-invalid-places.rs:6:28
|
LL | struct S1<T>(T) where (T): ?Sized;
| ^^^^^^
|
= note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
error: this relaxed bound is not permitted here
--> $DIR/relaxed-bounds-invalid-places.rs:8:27
|
LL | struct S2<T>(T) where u8: ?Sized;
| ^^^^^^
|
= note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
error: this relaxed bound is not permitted here
--> $DIR/relaxed-bounds-invalid-places.rs:10:35
|
LL | struct S3<T>(T) where &'static T: ?Sized;
| ^^^^^^
|
= note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
error: this relaxed bound is not permitted here
--> $DIR/relaxed-bounds-invalid-places.rs:14:34
|
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
| ^^^^^^^^^^
|
= note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
error: this relaxed bound is not permitted here
--> $DIR/relaxed-bounds-invalid-places.rs:22:21
|
LL | fn f() where T: ?Sized {}
| ^^^^^^
|
= note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item
error: relaxed bounds are not permitted in supertrait bounds
--> $DIR/relaxed-bounds-invalid-places.rs:25:11
|
LL | trait Tr: ?Sized {}
| ^^^^^^
|
= note: traits are `?Sized` by default
error: relaxed bounds are not permitted in trait object types
--> $DIR/relaxed-bounds-invalid-places.rs:29:20
|
LL | type O1 = dyn Tr + ?Sized;
| ^^^^^^
error: relaxed bounds are not permitted in trait object types
--> $DIR/relaxed-bounds-invalid-places.rs:30:15
|
LL | type O2 = dyn ?Sized + ?Sized + Tr;
| ^^^^^^
error: relaxed bounds are not permitted in trait object types
--> $DIR/relaxed-bounds-invalid-places.rs:30:24
|
LL | type O2 = dyn ?Sized + ?Sized + Tr;
| ^^^^^^
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/relaxed-bounds-invalid-places.rs:14:34
|
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
| ^^^^^^^^^^
error: bound modifier `?` can only be applied to `Sized`
--> $DIR/relaxed-bounds-invalid-places.rs:18:33
|
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
| ^^^^^^^^^^^^^^^
error: aborting due to 11 previous errors