Move trait bound modifiers into ast::PolyTraitRef
This commit is contained in:
parent
7500e09b8b
commit
95dba280b9
17 changed files with 118 additions and 103 deletions
|
@ -308,7 +308,7 @@ impl TraitBoundModifiers {
|
||||||
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum GenericBound {
|
pub enum GenericBound {
|
||||||
Trait(PolyTraitRef, TraitBoundModifiers),
|
Trait(PolyTraitRef),
|
||||||
Outlives(Lifetime),
|
Outlives(Lifetime),
|
||||||
/// Precise capturing syntax: `impl Sized + use<'a>`
|
/// Precise capturing syntax: `impl Sized + use<'a>`
|
||||||
Use(ThinVec<PreciseCapturingArg>, Span),
|
Use(ThinVec<PreciseCapturingArg>, Span),
|
||||||
|
@ -1213,10 +1213,12 @@ impl Expr {
|
||||||
|
|
||||||
pub fn to_bound(&self) -> Option<GenericBound> {
|
pub fn to_bound(&self) -> Option<GenericBound> {
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
ExprKind::Path(None, path) => Some(GenericBound::Trait(
|
ExprKind::Path(None, path) => Some(GenericBound::Trait(PolyTraitRef::new(
|
||||||
PolyTraitRef::new(ThinVec::new(), path.clone(), self.span),
|
ThinVec::new(),
|
||||||
|
path.clone(),
|
||||||
TraitBoundModifiers::NONE,
|
TraitBoundModifiers::NONE,
|
||||||
)),
|
self.span,
|
||||||
|
))),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2965,6 +2967,9 @@ pub struct PolyTraitRef {
|
||||||
/// The `'a` in `for<'a> Foo<&'a T>`.
|
/// The `'a` in `for<'a> Foo<&'a T>`.
|
||||||
pub bound_generic_params: ThinVec<GenericParam>,
|
pub bound_generic_params: ThinVec<GenericParam>,
|
||||||
|
|
||||||
|
// Optional constness, asyncness, or polarity.
|
||||||
|
pub modifiers: TraitBoundModifiers,
|
||||||
|
|
||||||
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
|
/// The `Foo<&'a T>` in `<'a> Foo<&'a T>`.
|
||||||
pub trait_ref: TraitRef,
|
pub trait_ref: TraitRef,
|
||||||
|
|
||||||
|
@ -2972,9 +2977,15 @@ pub struct PolyTraitRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PolyTraitRef {
|
impl PolyTraitRef {
|
||||||
pub fn new(generic_params: ThinVec<GenericParam>, path: Path, span: Span) -> Self {
|
pub fn new(
|
||||||
|
generic_params: ThinVec<GenericParam>,
|
||||||
|
path: Path,
|
||||||
|
modifiers: TraitBoundModifiers,
|
||||||
|
span: Span,
|
||||||
|
) -> Self {
|
||||||
PolyTraitRef {
|
PolyTraitRef {
|
||||||
bound_generic_params: generic_params,
|
bound_generic_params: generic_params,
|
||||||
|
modifiers,
|
||||||
trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
|
trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID },
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
|
|
|
@ -913,7 +913,7 @@ fn walk_fn_ret_ty<T: MutVisitor>(vis: &mut T, fn_ret_ty: &mut FnRetTy) {
|
||||||
|
|
||||||
fn walk_param_bound<T: MutVisitor>(vis: &mut T, pb: &mut GenericBound) {
|
fn walk_param_bound<T: MutVisitor>(vis: &mut T, pb: &mut GenericBound) {
|
||||||
match pb {
|
match pb {
|
||||||
GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty),
|
GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref),
|
||||||
GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime),
|
GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime),
|
||||||
GenericBound::Use(args, span) => {
|
GenericBound::Use(args, span) => {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
|
@ -1034,7 +1034,7 @@ fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut Tr
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
|
fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
|
||||||
let PolyTraitRef { bound_generic_params, trait_ref, span } = p;
|
let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span } = p;
|
||||||
bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
|
bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
|
||||||
vis.visit_trait_ref(trait_ref);
|
vis.visit_trait_ref(trait_ref);
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
|
|
|
@ -263,7 +263,7 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
|
||||||
|
|
||||||
ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds) => {
|
ast::TyKind::TraitObject(bounds, _) | ast::TyKind::ImplTrait(_, bounds) => {
|
||||||
match bounds.last() {
|
match bounds.last() {
|
||||||
Some(ast::GenericBound::Trait(bound, _)) => {
|
Some(ast::GenericBound::Trait(bound)) => {
|
||||||
match path_return_type(&bound.trait_ref.path) {
|
match path_return_type(&bound.trait_ref.path) {
|
||||||
Some(trailing_ty) => ty = trailing_ty,
|
Some(trailing_ty) => ty = trailing_ty,
|
||||||
None => break None,
|
None => break None,
|
||||||
|
|
|
@ -329,7 +329,7 @@ pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef)
|
||||||
where
|
where
|
||||||
V: Visitor<'a>,
|
V: Visitor<'a>,
|
||||||
{
|
{
|
||||||
let PolyTraitRef { bound_generic_params, trait_ref, span: _ } = trait_ref;
|
let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span: _ } = trait_ref;
|
||||||
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
walk_list!(visitor, visit_generic_param, bound_generic_params);
|
||||||
visitor.visit_trait_ref(trait_ref)
|
visitor.visit_trait_ref(trait_ref)
|
||||||
}
|
}
|
||||||
|
@ -720,7 +720,7 @@ impl WalkItemKind for ForeignItemKind {
|
||||||
|
|
||||||
pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result {
|
pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result {
|
||||||
match bound {
|
match bound {
|
||||||
GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ),
|
GenericBound::Trait(trait_ref) => visitor.visit_poly_trait_ref(trait_ref),
|
||||||
GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
|
GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound),
|
||||||
GenericBound::Use(args, _span) => {
|
GenericBound::Use(args, _span) => {
|
||||||
walk_list!(visitor, visit_precise_capturing_arg, args);
|
walk_list!(visitor, visit_precise_capturing_arg, args);
|
||||||
|
|
|
@ -1504,8 +1504,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
for bound in &bound_pred.bounds {
|
for bound in &bound_pred.bounds {
|
||||||
if !matches!(
|
if !matches!(
|
||||||
*bound,
|
*bound,
|
||||||
GenericBound::Trait(_, TraitBoundModifiers {
|
GenericBound::Trait(PolyTraitRef {
|
||||||
polarity: BoundPolarity::Maybe(_),
|
modifiers: TraitBoundModifiers { polarity: BoundPolarity::Maybe(_), .. },
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1219,11 +1219,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
let bound = this.lower_poly_trait_ref(
|
let bound = this.lower_poly_trait_ref(
|
||||||
&PolyTraitRef {
|
&PolyTraitRef {
|
||||||
bound_generic_params: ThinVec::new(),
|
bound_generic_params: ThinVec::new(),
|
||||||
|
modifiers: TraitBoundModifiers::NONE,
|
||||||
trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
|
trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
|
||||||
span: t.span,
|
span: t.span,
|
||||||
},
|
},
|
||||||
itctx,
|
itctx,
|
||||||
TraitBoundModifiers::NONE,
|
|
||||||
);
|
);
|
||||||
let bounds = this.arena.alloc_from_iter([bound]);
|
let bounds = this.arena.alloc_from_iter([bound]);
|
||||||
let lifetime_bound = this.elided_dyn_bound(t.span);
|
let lifetime_bound = this.elided_dyn_bound(t.span);
|
||||||
|
@ -1325,8 +1325,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// We can safely ignore constness here since AST validation
|
// We can safely ignore constness here since AST validation
|
||||||
// takes care of rejecting invalid modifier combinations and
|
// takes care of rejecting invalid modifier combinations and
|
||||||
// const trait bounds in trait object types.
|
// const trait bounds in trait object types.
|
||||||
GenericBound::Trait(ty, modifiers) => {
|
GenericBound::Trait(ty) => {
|
||||||
let trait_ref = this.lower_poly_trait_ref(ty, itctx, *modifiers);
|
let trait_ref = this.lower_poly_trait_ref(ty, itctx);
|
||||||
Some(trait_ref)
|
Some(trait_ref)
|
||||||
}
|
}
|
||||||
GenericBound::Outlives(lifetime) => {
|
GenericBound::Outlives(lifetime) => {
|
||||||
|
@ -1974,9 +1974,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
itctx: ImplTraitContext,
|
itctx: ImplTraitContext,
|
||||||
) -> hir::GenericBound<'hir> {
|
) -> hir::GenericBound<'hir> {
|
||||||
match tpb {
|
match tpb {
|
||||||
GenericBound::Trait(p, modifiers) => {
|
GenericBound::Trait(p) => hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx)),
|
||||||
hir::GenericBound::Trait(self.lower_poly_trait_ref(p, itctx, *modifiers))
|
|
||||||
}
|
|
||||||
GenericBound::Outlives(lifetime) => {
|
GenericBound::Outlives(lifetime) => {
|
||||||
hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
|
hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
|
||||||
}
|
}
|
||||||
|
@ -2180,12 +2178,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
&mut self,
|
&mut self,
|
||||||
p: &PolyTraitRef,
|
p: &PolyTraitRef,
|
||||||
itctx: ImplTraitContext,
|
itctx: ImplTraitContext,
|
||||||
modifiers: ast::TraitBoundModifiers,
|
|
||||||
) -> hir::PolyTraitRef<'hir> {
|
) -> hir::PolyTraitRef<'hir> {
|
||||||
let bound_generic_params =
|
let bound_generic_params =
|
||||||
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
|
self.lower_lifetime_binder(p.trait_ref.ref_id, &p.bound_generic_params);
|
||||||
let trait_ref = self.lower_trait_ref(modifiers, &p.trait_ref, itctx);
|
let trait_ref = self.lower_trait_ref(p.modifiers, &p.trait_ref, itctx);
|
||||||
let modifiers = self.lower_trait_bound_modifiers(modifiers);
|
let modifiers = self.lower_trait_bound_modifiers(p.modifiers);
|
||||||
hir::PolyTraitRef {
|
hir::PolyTraitRef {
|
||||||
bound_generic_params,
|
bound_generic_params,
|
||||||
modifiers,
|
modifiers,
|
||||||
|
|
|
@ -1260,7 +1260,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
if !bound_pred.bound_generic_params.is_empty() {
|
if !bound_pred.bound_generic_params.is_empty() {
|
||||||
for bound in &bound_pred.bounds {
|
for bound in &bound_pred.bounds {
|
||||||
match bound {
|
match bound {
|
||||||
GenericBound::Trait(t, _) => {
|
GenericBound::Trait(t) => {
|
||||||
if !t.bound_generic_params.is_empty() {
|
if !t.bound_generic_params.is_empty() {
|
||||||
self.dcx()
|
self.dcx()
|
||||||
.emit_err(errors::NestedLifetimes { span: t.span });
|
.emit_err(errors::NestedLifetimes { span: t.span });
|
||||||
|
@ -1280,8 +1280,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
|
|
||||||
fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
|
fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
|
||||||
match bound {
|
match bound {
|
||||||
GenericBound::Trait(trait_ref, modifiers) => {
|
GenericBound::Trait(trait_ref) => {
|
||||||
match (ctxt, modifiers.constness, modifiers.polarity) {
|
match (ctxt, trait_ref.modifiers.constness, trait_ref.modifiers.polarity) {
|
||||||
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_))
|
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_))
|
||||||
if !self.features.more_maybe_bounds =>
|
if !self.features.more_maybe_bounds =>
|
||||||
{
|
{
|
||||||
|
@ -1321,7 +1321,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Negative trait bounds are not allowed to have associated constraints
|
// Negative trait bounds are not allowed to have associated constraints
|
||||||
if let BoundPolarity::Negative(_) = modifiers.polarity
|
if let BoundPolarity::Negative(_) = trait_ref.modifiers.polarity
|
||||||
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
||||||
{
|
{
|
||||||
match segment.args.as_deref() {
|
match segment.args.as_deref() {
|
||||||
|
@ -1669,7 +1669,9 @@ fn deny_equality_constraints(
|
||||||
}),
|
}),
|
||||||
) {
|
) {
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
if let GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound {
|
if let GenericBound::Trait(poly) = bound
|
||||||
|
&& poly.modifiers == TraitBoundModifiers::NONE
|
||||||
|
{
|
||||||
if full_path.segments[..full_path.segments.len() - 1]
|
if full_path.segments[..full_path.segments.len() - 1]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|segment| segment.ident.name)
|
.map(|segment| segment.ident.name)
|
||||||
|
@ -1697,7 +1699,9 @@ fn deny_equality_constraints(
|
||||||
) {
|
) {
|
||||||
if ident == potential_param.ident {
|
if ident == potential_param.ident {
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
if let ast::GenericBound::Trait(poly, TraitBoundModifiers::NONE) = bound {
|
if let ast::GenericBound::Trait(poly) = bound
|
||||||
|
&& poly.modifiers == TraitBoundModifiers::NONE
|
||||||
|
{
|
||||||
suggest(poly, potential_assoc, predicate);
|
suggest(poly, potential_assoc, predicate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ mod item;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use ast::TraitBoundModifiers;
|
|
||||||
use rustc_ast::attr::AttrIdGenerator;
|
use rustc_ast::attr::AttrIdGenerator;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{
|
use rustc_ast::token::{
|
||||||
|
@ -1253,6 +1252,27 @@ impl<'a> State<'a> {
|
||||||
|
|
||||||
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
|
fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) {
|
||||||
self.print_formal_generic_params(&t.bound_generic_params);
|
self.print_formal_generic_params(&t.bound_generic_params);
|
||||||
|
|
||||||
|
let ast::TraitBoundModifiers { constness, asyncness, polarity } = t.modifiers;
|
||||||
|
match constness {
|
||||||
|
ast::BoundConstness::Never => {}
|
||||||
|
ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => {
|
||||||
|
self.word_space(constness.as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match asyncness {
|
||||||
|
ast::BoundAsyncness::Normal => {}
|
||||||
|
ast::BoundAsyncness::Async(_) => {
|
||||||
|
self.word_space(asyncness.as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match polarity {
|
||||||
|
ast::BoundPolarity::Positive => {}
|
||||||
|
ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => {
|
||||||
|
self.word(polarity.as_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.print_trait_ref(&t.trait_ref)
|
self.print_trait_ref(&t.trait_ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1740,31 +1760,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match bound {
|
match bound {
|
||||||
GenericBound::Trait(
|
GenericBound::Trait(tref) => {
|
||||||
tref,
|
|
||||||
TraitBoundModifiers { constness, asyncness, polarity },
|
|
||||||
) => {
|
|
||||||
match constness {
|
|
||||||
ast::BoundConstness::Never => {}
|
|
||||||
ast::BoundConstness::Always(_) | ast::BoundConstness::Maybe(_) => {
|
|
||||||
self.word_space(constness.as_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match asyncness {
|
|
||||||
ast::BoundAsyncness::Normal => {}
|
|
||||||
ast::BoundAsyncness::Async(_) => {
|
|
||||||
self.word_space(asyncness.as_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match polarity {
|
|
||||||
ast::BoundPolarity::Positive => {}
|
|
||||||
ast::BoundPolarity::Negative(_) | ast::BoundPolarity::Maybe(_) => {
|
|
||||||
self.word(polarity.as_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.print_poly_trait_ref(tref);
|
self.print_poly_trait_ref(tref);
|
||||||
}
|
}
|
||||||
GenericBound::Outlives(lt) => self.print_lifetime(*lt),
|
GenericBound::Outlives(lt) => self.print_lifetime(*lt),
|
||||||
|
|
|
@ -333,12 +333,12 @@ fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee:
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_maybe_sized_bound(bound: &GenericBound) -> bool {
|
fn is_maybe_sized_bound(bound: &GenericBound) -> bool {
|
||||||
if let GenericBound::Trait(
|
if let GenericBound::Trait(trait_ref) = bound
|
||||||
trait_ref,
|
&& let TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. } =
|
||||||
TraitBoundModifiers { polarity: ast::BoundPolarity::Maybe(_), .. },
|
trait_ref.modifiers
|
||||||
) = bound
|
&& is_sized_marker(&trait_ref.trait_ref.path)
|
||||||
{
|
{
|
||||||
is_sized_marker(&trait_ref.trait_ref.path)
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,24 +143,25 @@ impl<'a> ExtCtxt<'a> {
|
||||||
ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID }
|
ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef {
|
pub fn poly_trait_ref(&self, span: Span, path: ast::Path, is_const: bool) -> ast::PolyTraitRef {
|
||||||
ast::PolyTraitRef {
|
ast::PolyTraitRef {
|
||||||
bound_generic_params: ThinVec::new(),
|
bound_generic_params: ThinVec::new(),
|
||||||
|
modifiers: ast::TraitBoundModifiers {
|
||||||
|
polarity: ast::BoundPolarity::Positive,
|
||||||
|
constness: if is_const {
|
||||||
|
ast::BoundConstness::Maybe(DUMMY_SP)
|
||||||
|
} else {
|
||||||
|
ast::BoundConstness::Never
|
||||||
|
},
|
||||||
|
asyncness: ast::BoundAsyncness::Normal,
|
||||||
|
},
|
||||||
trait_ref: self.trait_ref(path),
|
trait_ref: self.trait_ref(path),
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trait_bound(&self, path: ast::Path, is_const: bool) -> ast::GenericBound {
|
pub fn trait_bound(&self, path: ast::Path, is_const: bool) -> ast::GenericBound {
|
||||||
ast::GenericBound::Trait(self.poly_trait_ref(path.span, path), ast::TraitBoundModifiers {
|
ast::GenericBound::Trait(self.poly_trait_ref(path.span, path, is_const))
|
||||||
polarity: ast::BoundPolarity::Positive,
|
|
||||||
constness: if is_const {
|
|
||||||
ast::BoundConstness::Maybe(DUMMY_SP)
|
|
||||||
} else {
|
|
||||||
ast::BoundConstness::Never
|
|
||||||
},
|
|
||||||
asyncness: ast::BoundAsyncness::Normal,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime {
|
pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime {
|
||||||
|
|
|
@ -2113,7 +2113,7 @@ impl<'a> Parser<'a> {
|
||||||
&& let Some(poly) = bounds
|
&& let Some(poly) = bounds
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|bound| match bound {
|
.filter_map(|bound| match bound {
|
||||||
ast::GenericBound::Trait(poly, _) => Some(poly),
|
ast::GenericBound::Trait(poly) => Some(poly),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.last()
|
.last()
|
||||||
|
|
|
@ -948,8 +948,8 @@ impl<'a> Parser<'a> {
|
||||||
{
|
{
|
||||||
return Ok((false, seg.ident, seg.args.as_deref().cloned()));
|
return Ok((false, seg.ident, seg.args.as_deref().cloned()));
|
||||||
} else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind
|
} else if let ast::TyKind::TraitObject(bounds, ast::TraitObjectSyntax::None) = &ty.kind
|
||||||
&& let [ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE)] =
|
&& let [ast::GenericBound::Trait(trait_ref)] = bounds.as_slice()
|
||||||
bounds.as_slice()
|
&& trait_ref.modifiers == ast::TraitBoundModifiers::NONE
|
||||||
&& let [seg] = trait_ref.trait_ref.path.segments.as_slice()
|
&& let [seg] = trait_ref.trait_ref.path.segments.as_slice()
|
||||||
{
|
{
|
||||||
return Ok((true, seg.ident, seg.args.as_deref().cloned()));
|
return Ok((true, seg.ident, seg.args.as_deref().cloned()));
|
||||||
|
|
|
@ -419,8 +419,13 @@ impl<'a> Parser<'a> {
|
||||||
lo: Span,
|
lo: Span,
|
||||||
parse_plus: bool,
|
parse_plus: bool,
|
||||||
) -> PResult<'a, TyKind> {
|
) -> PResult<'a, TyKind> {
|
||||||
let poly_trait_ref = PolyTraitRef::new(generic_params, path, lo.to(self.prev_token.span));
|
let poly_trait_ref = PolyTraitRef::new(
|
||||||
let bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifiers::NONE)];
|
generic_params,
|
||||||
|
path,
|
||||||
|
TraitBoundModifiers::NONE,
|
||||||
|
lo.to(self.prev_token.span),
|
||||||
|
);
|
||||||
|
let bounds = vec![GenericBound::Trait(poly_trait_ref)];
|
||||||
self.parse_remaining_bounds(bounds, parse_plus)
|
self.parse_remaining_bounds(bounds, parse_plus)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1085,8 +1090,9 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_token.span));
|
let poly_trait =
|
||||||
Ok(GenericBound::Trait(poly_trait, modifiers))
|
PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span));
|
||||||
|
Ok(GenericBound::Trait(poly_trait))
|
||||||
}
|
}
|
||||||
|
|
||||||
// recovers a `Fn(..)` parenthesized-style path from `fn(..)`
|
// recovers a `Fn(..)` parenthesized-style path from `fn(..)`
|
||||||
|
|
|
@ -519,11 +519,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifiers::NONE) = bound
|
let ast::GenericBound::Trait(trait_ref) = bound else {
|
||||||
else {
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if base_error.span == trait_ref.span {
|
if trait_ref.modifiers == ast::TraitBoundModifiers::NONE
|
||||||
|
&& base_error.span == trait_ref.span
|
||||||
|
{
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
constraint.ident.span.between(trait_ref.span),
|
constraint.ident.span.between(trait_ref.span),
|
||||||
"you might have meant to write a path instead of an associated type bound",
|
"you might have meant to write a path instead of an associated type bound",
|
||||||
|
@ -837,7 +838,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
);
|
);
|
||||||
if bounds.iter().all(|bound| match bound {
|
if bounds.iter().all(|bound| match bound {
|
||||||
ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true,
|
ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true,
|
||||||
ast::GenericBound::Trait(tr, _) => tr.span == base_error.span,
|
ast::GenericBound::Trait(tr) => tr.span == base_error.span,
|
||||||
}) {
|
}) {
|
||||||
let mut sugg = vec![];
|
let mut sugg = vec![];
|
||||||
if base_error.span != start_span {
|
if base_error.span != start_span {
|
||||||
|
@ -1210,7 +1211,8 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
let param = generics.params.iter().find_map(|param| {
|
let param = generics.params.iter().find_map(|param| {
|
||||||
// Only consider type params with exactly one trait bound.
|
// Only consider type params with exactly one trait bound.
|
||||||
if let [bound] = &*param.bounds
|
if let [bound] = &*param.bounds
|
||||||
&& let ast::GenericBound::Trait(tref, ast::TraitBoundModifiers::NONE) = bound
|
&& let ast::GenericBound::Trait(tref) = bound
|
||||||
|
&& tref.modifiers == ast::TraitBoundModifiers::NONE
|
||||||
&& tref.span == span
|
&& tref.span == span
|
||||||
&& param.ident.span.eq_ctxt(span)
|
&& param.ident.span.eq_ctxt(span)
|
||||||
{
|
{
|
||||||
|
@ -1333,8 +1335,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
}
|
}
|
||||||
if let (
|
if let (
|
||||||
[ast::PathSegment { args: None, .. }],
|
[ast::PathSegment { args: None, .. }],
|
||||||
[ast::GenericBound::Trait(poly_trait_ref, ast::TraitBoundModifiers::NONE)],
|
[ast::GenericBound::Trait(poly_trait_ref)],
|
||||||
) = (&type_param_path.segments[..], &bounds[..])
|
) = (&type_param_path.segments[..], &bounds[..])
|
||||||
|
&& poly_trait_ref.modifiers == ast::TraitBoundModifiers::NONE
|
||||||
{
|
{
|
||||||
if let [ast::PathSegment { ident, args: None, .. }] =
|
if let [ast::PathSegment { ident, args: None, .. }] =
|
||||||
&poly_trait_ref.trait_ref.path.segments[..]
|
&poly_trait_ref.trait_ref.path.segments[..]
|
||||||
|
@ -2814,7 +2817,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
&& bounded_ty.id == binder
|
&& bounded_ty.id == binder
|
||||||
{
|
{
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
if let ast::GenericBound::Trait(poly_trait_ref, _) = bound
|
if let ast::GenericBound::Trait(poly_trait_ref) = bound
|
||||||
&& let span = poly_trait_ref
|
&& let span = poly_trait_ref
|
||||||
.span
|
.span
|
||||||
.with_hi(poly_trait_ref.trait_ref.path.span.lo())
|
.with_hi(poly_trait_ref.trait_ref.path.span.lo())
|
||||||
|
@ -3233,7 +3236,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
let mut lt_finder =
|
let mut lt_finder =
|
||||||
LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] };
|
LifetimeFinder { lifetime: lt.span, found: None, seen: vec![] };
|
||||||
for bound in arg_refs {
|
for bound in arg_refs {
|
||||||
if let ast::GenericBound::Trait(trait_ref, _) = bound {
|
if let ast::GenericBound::Trait(trait_ref) = bound {
|
||||||
lt_finder.visit_trait_ref(&trait_ref.trait_ref);
|
lt_finder.visit_trait_ref(&trait_ref.trait_ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3444,17 +3447,15 @@ fn mk_where_bound_predicate(
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
bound_generic_params: ThinVec::new(),
|
bound_generic_params: ThinVec::new(),
|
||||||
bounded_ty: ast::ptr::P(ty.clone()),
|
bounded_ty: ast::ptr::P(ty.clone()),
|
||||||
bounds: vec![ast::GenericBound::Trait(
|
bounds: vec![ast::GenericBound::Trait(ast::PolyTraitRef {
|
||||||
ast::PolyTraitRef {
|
bound_generic_params: ThinVec::new(),
|
||||||
bound_generic_params: ThinVec::new(),
|
modifiers: ast::TraitBoundModifiers::NONE,
|
||||||
trait_ref: ast::TraitRef {
|
trait_ref: ast::TraitRef {
|
||||||
path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None },
|
path: ast::Path { segments: modified_segments, span: DUMMY_SP, tokens: None },
|
||||||
ref_id: DUMMY_NODE_ID,
|
ref_id: DUMMY_NODE_ID,
|
||||||
},
|
|
||||||
span: DUMMY_SP,
|
|
||||||
},
|
},
|
||||||
ast::TraitBoundModifiers::NONE,
|
span: DUMMY_SP,
|
||||||
)],
|
})],
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(new_where_bound_predicate)
|
Some(new_where_bound_predicate)
|
||||||
|
|
|
@ -783,7 +783,8 @@ pub fn eq_str_lit(l: &StrLit, r: &StrLit) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eq_poly_ref_trait(l: &PolyTraitRef, r: &PolyTraitRef) -> bool {
|
pub fn eq_poly_ref_trait(l: &PolyTraitRef, r: &PolyTraitRef) -> bool {
|
||||||
eq_path(&l.trait_ref.path, &r.trait_ref.path)
|
l.modifiers == r.modifiers
|
||||||
|
&& eq_path(&l.trait_ref.path, &r.trait_ref.path)
|
||||||
&& over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
|
&& over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
|
||||||
eq_generic_param(l, r)
|
eq_generic_param(l, r)
|
||||||
})
|
})
|
||||||
|
@ -817,7 +818,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {
|
||||||
pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool {
|
pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool {
|
||||||
use GenericBound::*;
|
use GenericBound::*;
|
||||||
match (l, r) {
|
match (l, r) {
|
||||||
(Trait(ptr1, tbm1), Trait(ptr2, tbm2)) => tbm1 == tbm2 && eq_poly_ref_trait(ptr1, ptr2),
|
(Trait(ptr1), Trait(ptr2)) => eq_poly_ref_trait(ptr1, ptr2),
|
||||||
(Outlives(l), Outlives(r)) => eq_id(l.ident, r.ident),
|
(Outlives(l), Outlives(r)) => eq_id(l.ident, r.ident),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ impl Spanned for ast::GenericArg {
|
||||||
impl Spanned for ast::GenericBound {
|
impl Spanned for ast::GenericBound {
|
||||||
fn span(&self) -> Span {
|
fn span(&self) -> Span {
|
||||||
match *self {
|
match *self {
|
||||||
ast::GenericBound::Trait(ref ptr, _) => ptr.span,
|
ast::GenericBound::Trait(ref ptr) => ptr.span,
|
||||||
ast::GenericBound::Outlives(ref l) => l.ident.span,
|
ast::GenericBound::Outlives(ref l) => l.ident.span,
|
||||||
ast::GenericBound::Use(_, span) => span,
|
ast::GenericBound::Use(_, span) => span,
|
||||||
}
|
}
|
||||||
|
|
|
@ -610,16 +610,14 @@ impl Rewrite for ast::GenericBound {
|
||||||
|
|
||||||
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
|
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
|
||||||
match *self {
|
match *self {
|
||||||
ast::GenericBound::Trait(
|
ast::GenericBound::Trait(ref poly_trait_ref) => {
|
||||||
ref poly_trait_ref,
|
let snippet = context.snippet(self.span());
|
||||||
ast::TraitBoundModifiers {
|
let has_paren = snippet.starts_with('(') && snippet.ends_with(')');
|
||||||
|
let ast::TraitBoundModifiers {
|
||||||
constness,
|
constness,
|
||||||
asyncness,
|
asyncness,
|
||||||
polarity,
|
polarity,
|
||||||
},
|
} = poly_trait_ref.modifiers;
|
||||||
) => {
|
|
||||||
let snippet = context.snippet(self.span());
|
|
||||||
let has_paren = snippet.starts_with('(') && snippet.ends_with(')');
|
|
||||||
let mut constness = constness.as_str().to_string();
|
let mut constness = constness.as_str().to_string();
|
||||||
if !constness.is_empty() {
|
if !constness.is_empty() {
|
||||||
constness.push(' ');
|
constness.push(' ');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue