AST lowering: More robustly deal with relaxed bounds
This commit is contained in:
parent
9788f59bbf
commit
1df99f22d3
16 changed files with 189 additions and 210 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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> {
|
|||
¶m.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)),
|
||||
bounds: self.lower_param_bounds(
|
||||
bounds,
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
|
||||
),
|
||||
origin: PredicateOrigin::WhereClause,
|
||||
}),
|
||||
}) => {
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -53,14 +53,14 @@ 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;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
|
||||
use rustc_session::parse::add_feature_diagnostics;
|
||||
use rustc_session::parse::{add_feature_diagnostics, feature_err};
|
||||
use rustc_span::symbol::{Ident, Symbol, kw, sym};
|
||||
use rustc_span::{DUMMY_SP, DesugaringKind, Span};
|
||||
use smallvec::SmallVec;
|
||||
|
|
@ -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,77 @@ 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<'_>,
|
||||
) {
|
||||
let err = |message| feature_err(&self.tcx.sess, sym::more_maybe_bounds, span, message);
|
||||
|
||||
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 => {
|
||||
err("`?Trait` is not permitted in trait object types").emit();
|
||||
return;
|
||||
}
|
||||
RelaxedBoundForbiddenReason::SuperTrait => {
|
||||
let mut diag = err("`?Trait` is not permitted in supertraits");
|
||||
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 => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
err("`?Trait` bounds are only permitted at the point where a type parameter is declared")
|
||||
.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 +2123,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 +2169,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
bounds,
|
||||
/* colon_span */ None,
|
||||
span,
|
||||
RelaxedBoundPolicy::Allowed,
|
||||
ImplTraitContext::Universal,
|
||||
hir::PredicateOrigin::ImplTrait,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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(_),
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 `?Trait` is not permitted in trait object types
|
||||
todo!()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
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[E0658]: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/missing-associated_item_or_field_def_ids.rs:3:29
|
||||
|
|
||||
|
|
@ -7,19 +13,7 @@ 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: aborting due to 2 previous errors
|
||||
|
||||
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
|
||||
|
|
||||
LL | fn main() -> dyn Iterator + ?Iterator::advance_by(usize) {
|
||||
| ^^^^^^^^ help: specify the associated type: `Iterator<Item = Type>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0191, E0404, E0658.
|
||||
For more information about an error, try `rustc --explain E0191`.
|
||||
Some errors have detailed explanations: E0404, E0658.
|
||||
For more information about an error, try `rustc --explain E0404`.
|
||||
|
|
|
|||
|
|
@ -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: `?Trait` is not permitted in trait object types
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
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[E0658]: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/avoid-getting-associated-items-of-undefined-trait.rs:8:21
|
||||
|
|
||||
|
|
@ -7,22 +13,7 @@ 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: aborting due to 2 previous errors
|
||||
|
||||
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
|
||||
|
|
||||
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
|
||||
|
||||
Some errors have detailed explanations: E0191, E0405, E0658.
|
||||
For more information about an error, try `rustc --explain E0191`.
|
||||
Some errors have detailed explanations: E0405, E0658.
|
||||
For more information about an error, try `rustc --explain E0405`.
|
||||
|
|
|
|||
|
|
@ -4,16 +4,6 @@ error[E0658]: `?Trait` is not permitted in supertraits
|
|||
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
|
||||
|
||||
|
|
@ -26,6 +16,15 @@ 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
|
||||
|
||||
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[E0203]: type parameter has more than one relaxed default bound, only one is supported
|
||||
--> $DIR/feature-gate-more-maybe-bounds.rs:12:11
|
||||
|
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ error[E0658]: `?Trait` is not permitted in supertraits
|
|||
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
|
||||
= note: traits are `?Sized` by default
|
||||
|
||||
error[E0658]: `?Trait` is not permitted in supertraits
|
||||
--> $DIR/default-supertrait.rs:13:21
|
||||
|
|
@ -14,7 +14,6 @@ error[E0658]: `?Trait` is not permitted in supertraits
|
|||
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
|
||||
|
||||
|
|
@ -24,7 +23,6 @@ error[E0658]: `?Trait` is not permitted in supertraits
|
|||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ error[E0658]: `?Trait` is not permitted in supertraits
|
|||
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
|
||||
= note: traits are `?Sized` by default
|
||||
|
||||
error[E0658]: `?Trait` is not permitted in trait object types
|
||||
--> $DIR/maybe-trait-bounds-forbidden-locations.rs:13:20
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// Test that relaxed bounds can only be placed on type parameters defined by the closest item
|
||||
// (ignoring relaxed bounds inside `impl Trait` and in associated type defs here).
|
||||
|
||||
struct S1<T>(T) where (T): ?Sized;
|
||||
//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0658]: `?Trait` bounds are only permitted at the point where a type parameter is declared
|
||||
--> $DIR/maybe-bounds-where.rs:1:28
|
||||
--> $DIR/relaxed-bounds-invalid-places.rs:4:28
|
||||
|
|
||||
LL | struct S1<T>(T) where (T): ?Sized;
|
||||
| ^^^^^^
|
||||
|
|
@ -8,7 +8,7 @@ LL | struct S1<T>(T) where (T): ?Sized;
|
|||
= 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
|
||||
--> $DIR/relaxed-bounds-invalid-places.rs:7:27
|
||||
|
|
||||
LL | struct S2<T>(T) where u8: ?Sized;
|
||||
| ^^^^^^
|
||||
|
|
@ -17,7 +17,7 @@ LL | struct S2<T>(T) where u8: ?Sized;
|
|||
= 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
|
||||
--> $DIR/relaxed-bounds-invalid-places.rs:10:35
|
||||
|
|
||||
LL | struct S3<T>(T) where &'static T: ?Sized;
|
||||
| ^^^^^^
|
||||
|
|
@ -26,7 +26,7 @@ LL | struct S3<T>(T) where &'static T: ?Sized;
|
|||
= 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
|
||||
--> $DIR/relaxed-bounds-invalid-places.rs:15:34
|
||||
|
|
||||
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
|
||||
| ^^^^^^^^^^
|
||||
|
|
@ -35,7 +35,7 @@ LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
|
|||
= 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
|
||||
--> $DIR/relaxed-bounds-invalid-places.rs:24:21
|
||||
|
|
||||
LL | fn f() where T: ?Sized {}
|
||||
| ^^^^^^
|
||||
|
|
@ -44,13 +44,13 @@ LL | fn f() where T: ?Sized {}
|
|||
= 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
|
||||
--> $DIR/relaxed-bounds-invalid-places.rs:15: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
|
||||
--> $DIR/relaxed-bounds-invalid-places.rs:19:33
|
||||
|
|
||||
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
||||
| ^^^^^^^^^^^^^^^ ^^^^^^
|
||||
|
|
@ -59,7 +59,7 @@ LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
|||
= 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
|
||||
--> $DIR/relaxed-bounds-invalid-places.rs:19:33
|
||||
|
|
||||
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
||||
| ^^^^^^^^^^^^^^^
|
||||
Loading…
Add table
Add a link
Reference in a new issue