mirror of https://github.com/rust-lang/rust.git
Rename HIR `TypeBinding` to `AssocItemConstraint` and related cleanup
This commit is contained in:
parent
0a59f11362
commit
34c56c45cf
|
@ -167,7 +167,7 @@ impl PathSegment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The arguments of a path segment.
|
/// The generic arguments and associated item constraints of a path segment.
|
||||||
///
|
///
|
||||||
/// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
|
/// E.g., `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)`.
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
@ -221,14 +221,13 @@ pub struct AngleBracketedArgs {
|
||||||
pub args: ThinVec<AngleBracketedArg>,
|
pub args: ThinVec<AngleBracketedArg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Either an argument for a parameter e.g., `'a`, `Vec<u8>`, `0`,
|
/// Either an argument for a generic parameter or a constraint on an associated item.
|
||||||
/// or a constraint on an associated item, e.g., `Item = String` or `Item: Bound`.
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum AngleBracketedArg {
|
pub enum AngleBracketedArg {
|
||||||
/// Argument for a generic parameter.
|
/// A generic argument for a generic parameter.
|
||||||
Arg(GenericArg),
|
Arg(GenericArg),
|
||||||
/// Constraint for an associated item.
|
/// A constraint on an associated item.
|
||||||
Constraint(AssocConstraint),
|
Constraint(AssocItemConstraint),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AngleBracketedArg {
|
impl AngleBracketedArg {
|
||||||
|
@ -418,7 +417,7 @@ impl Default for WhereClause {
|
||||||
/// A single predicate in a where-clause.
|
/// A single predicate in a where-clause.
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum WherePredicate {
|
pub enum WherePredicate {
|
||||||
/// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
|
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
|
||||||
BoundPredicate(WhereBoundPredicate),
|
BoundPredicate(WhereBoundPredicate),
|
||||||
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
|
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
|
||||||
RegionPredicate(WhereRegionPredicate),
|
RegionPredicate(WhereRegionPredicate),
|
||||||
|
@ -2034,18 +2033,25 @@ impl UintTy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A constraint on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
|
/// A constraint on an associated item.
|
||||||
/// `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`).
|
///
|
||||||
|
/// ### Examples
|
||||||
|
///
|
||||||
|
/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
|
||||||
|
/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
|
||||||
|
/// * the `A: Bound` in `Trait<A: Bound>`
|
||||||
|
/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
|
||||||
|
/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
|
||||||
|
/// * the `f(): Bound` in `Trait<f(): Bound>` (feature `return_type_notation`)
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub struct AssocConstraint {
|
pub struct AssocItemConstraint {
|
||||||
pub id: NodeId,
|
pub id: NodeId,
|
||||||
pub ident: Ident,
|
pub ident: Ident,
|
||||||
pub gen_args: Option<GenericArgs>,
|
pub gen_args: Option<GenericArgs>,
|
||||||
pub kind: AssocConstraintKind,
|
pub kind: AssocItemConstraintKind,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The kinds of an `AssocConstraint`.
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum Term {
|
pub enum Term {
|
||||||
Ty(P<Ty>),
|
Ty(P<Ty>),
|
||||||
|
@ -2064,12 +2070,17 @@ impl From<AnonConst> for Term {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The kinds of an `AssocConstraint`.
|
/// The kind of [associated item constraint][AssocItemConstraint].
|
||||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum AssocConstraintKind {
|
pub enum AssocItemConstraintKind {
|
||||||
/// E.g., `A = Bar`, `A = 3` in `Foo<A = Bar>` where A is an associated type.
|
/// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait<AssocTy = Ty>`).
|
||||||
|
///
|
||||||
|
/// Also known as an *associated item binding* (we *bind* an associated item to a term).
|
||||||
|
///
|
||||||
|
/// Furthermore, associated type equality constraints can also be referred to as *associated type
|
||||||
|
/// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
|
||||||
Equality { term: Term },
|
Equality { term: Term },
|
||||||
/// E.g. `A: TraitA + TraitB` in `Foo<A: TraitA + TraitB>`.
|
/// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
|
||||||
Bound { bounds: GenericBounds },
|
Bound { bounds: GenericBounds },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,8 +175,8 @@ pub trait MutVisitor: Sized {
|
||||||
noop_visit_lifetime(l, self);
|
noop_visit_lifetime(l, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_constraint(&mut self, t: &mut AssocConstraint) {
|
fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) {
|
||||||
noop_visit_constraint(t, self);
|
noop_visit_assoc_item_constraint(c, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) {
|
fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) {
|
||||||
|
@ -463,8 +463,8 @@ pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[
|
||||||
smallvec![arm]
|
smallvec![arm]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn noop_visit_constraint<T: MutVisitor>(
|
fn noop_visit_assoc_item_constraint<T: MutVisitor>(
|
||||||
AssocConstraint { id, ident, gen_args, kind, span }: &mut AssocConstraint,
|
AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint,
|
||||||
vis: &mut T,
|
vis: &mut T,
|
||||||
) {
|
) {
|
||||||
vis.visit_id(id);
|
vis.visit_id(id);
|
||||||
|
@ -473,11 +473,11 @@ fn noop_visit_constraint<T: MutVisitor>(
|
||||||
vis.visit_generic_args(gen_args);
|
vis.visit_generic_args(gen_args);
|
||||||
}
|
}
|
||||||
match kind {
|
match kind {
|
||||||
AssocConstraintKind::Equality { term } => match term {
|
AssocItemConstraintKind::Equality { term } => match term {
|
||||||
Term::Ty(ty) => vis.visit_ty(ty),
|
Term::Ty(ty) => vis.visit_ty(ty),
|
||||||
Term::Const(c) => vis.visit_anon_const(c),
|
Term::Const(c) => vis.visit_anon_const(c),
|
||||||
},
|
},
|
||||||
AssocConstraintKind::Bound { bounds } => visit_bounds(bounds, vis),
|
AssocItemConstraintKind::Bound { bounds } => visit_bounds(bounds, vis),
|
||||||
}
|
}
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
}
|
}
|
||||||
|
@ -607,7 +607,7 @@ fn noop_visit_angle_bracketed_parameter_data<T: MutVisitor>(
|
||||||
let AngleBracketedArgs { args, span } = data;
|
let AngleBracketedArgs { args, span } = data;
|
||||||
visit_thin_vec(args, |arg| match arg {
|
visit_thin_vec(args, |arg| match arg {
|
||||||
AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg),
|
AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg),
|
||||||
AngleBracketedArg::Constraint(constraint) => vis.visit_constraint(constraint),
|
AngleBracketedArg::Constraint(constraint) => vis.visit_assoc_item_constraint(constraint),
|
||||||
});
|
});
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,8 +246,11 @@ pub trait Visitor<'ast>: Sized {
|
||||||
fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result {
|
fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result {
|
||||||
walk_generic_arg(self, generic_arg)
|
walk_generic_arg(self, generic_arg)
|
||||||
}
|
}
|
||||||
fn visit_assoc_constraint(&mut self, constraint: &'ast AssocConstraint) -> Self::Result {
|
fn visit_assoc_item_constraint(
|
||||||
walk_assoc_constraint(self, constraint)
|
&mut self,
|
||||||
|
constraint: &'ast AssocItemConstraint,
|
||||||
|
) -> Self::Result {
|
||||||
|
walk_assoc_item_constraint(self, constraint)
|
||||||
}
|
}
|
||||||
fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result {
|
fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result {
|
||||||
walk_attribute(self, attr)
|
walk_attribute(self, attr)
|
||||||
|
@ -558,7 +561,7 @@ where
|
||||||
match arg {
|
match arg {
|
||||||
AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)),
|
AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)),
|
||||||
AngleBracketedArg::Constraint(c) => {
|
AngleBracketedArg::Constraint(c) => {
|
||||||
try_visit!(visitor.visit_assoc_constraint(c))
|
try_visit!(visitor.visit_assoc_item_constraint(c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -582,18 +585,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_assoc_constraint<'a, V: Visitor<'a>>(
|
pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>(
|
||||||
visitor: &mut V,
|
visitor: &mut V,
|
||||||
constraint: &'a AssocConstraint,
|
constraint: &'a AssocItemConstraint,
|
||||||
) -> V::Result {
|
) -> V::Result {
|
||||||
try_visit!(visitor.visit_ident(constraint.ident));
|
try_visit!(visitor.visit_ident(constraint.ident));
|
||||||
visit_opt!(visitor, visit_generic_args, &constraint.gen_args);
|
visit_opt!(visitor, visit_generic_args, &constraint.gen_args);
|
||||||
match &constraint.kind {
|
match &constraint.kind {
|
||||||
AssocConstraintKind::Equality { term } => match term {
|
AssocItemConstraintKind::Equality { term } => match term {
|
||||||
Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)),
|
Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)),
|
||||||
Term::Const(c) => try_visit!(visitor.visit_anon_const(c)),
|
Term::Const(c) => try_visit!(visitor.visit_anon_const(c)),
|
||||||
},
|
},
|
||||||
AssocConstraintKind::Bound { bounds } => {
|
AssocItemConstraintKind::Bound { bounds } => {
|
||||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
|
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -333,10 +333,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_assoc_type_binding(&mut self, type_binding: &'hir TypeBinding<'hir>) {
|
fn visit_assoc_item_constraint(&mut self, constraint: &'hir AssocItemConstraint<'hir>) {
|
||||||
self.insert(type_binding.span, type_binding.hir_id, Node::TypeBinding(type_binding));
|
self.insert(constraint.span, constraint.hir_id, Node::AssocItemConstraint(constraint));
|
||||||
self.with_parent(type_binding.hir_id, |this| {
|
self.with_parent(constraint.hir_id, |this| {
|
||||||
intravisit::walk_assoc_type_binding(this, type_binding)
|
intravisit::walk_assoc_item_constraint(this, constraint)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -961,24 +961,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() }
|
DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an associated type constraint like one of these:
|
/// Lower an associated item constraint.
|
||||||
///
|
#[instrument(level = "debug", skip_all)]
|
||||||
/// ```ignore (illustrative)
|
fn lower_assoc_item_constraint(
|
||||||
/// T: Iterator<Item: Debug>
|
|
||||||
/// ^^^^^^^^^^^
|
|
||||||
/// T: Iterator<Item = Debug>
|
|
||||||
/// ^^^^^^^^^^^^
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// returns a `hir::TypeBinding` representing `Item`.
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
|
||||||
fn lower_assoc_ty_constraint(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
constraint: &AssocConstraint,
|
constraint: &AssocItemConstraint,
|
||||||
itctx: ImplTraitContext,
|
itctx: ImplTraitContext,
|
||||||
) -> hir::TypeBinding<'hir> {
|
) -> hir::AssocItemConstraint<'hir> {
|
||||||
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
|
debug!(?constraint, ?itctx);
|
||||||
// lower generic arguments of identifier in constraint
|
// Lower the generic arguments for the associated item.
|
||||||
let gen_args = if let Some(gen_args) = &constraint.gen_args {
|
let gen_args = if let Some(gen_args) = &constraint.gen_args {
|
||||||
let gen_args_ctor = match gen_args {
|
let gen_args_ctor = match gen_args {
|
||||||
GenericArgs::AngleBracketed(data) => {
|
GenericArgs::AngleBracketed(data) => {
|
||||||
|
@ -994,7 +985,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
};
|
};
|
||||||
GenericArgsCtor {
|
GenericArgsCtor {
|
||||||
args: Default::default(),
|
args: Default::default(),
|
||||||
bindings: &[],
|
constraints: &[],
|
||||||
parenthesized,
|
parenthesized,
|
||||||
span: data.inputs_span,
|
span: data.inputs_span,
|
||||||
}
|
}
|
||||||
|
@ -1024,7 +1015,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
err.emit();
|
err.emit();
|
||||||
GenericArgsCtor {
|
GenericArgsCtor {
|
||||||
args: Default::default(),
|
args: Default::default(),
|
||||||
bindings: &[],
|
constraints: &[],
|
||||||
parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
|
parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
|
||||||
span: data.span,
|
span: data.span,
|
||||||
}
|
}
|
||||||
|
@ -1046,14 +1037,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.arena.alloc(hir::GenericArgs::none())
|
self.arena.alloc(hir::GenericArgs::none())
|
||||||
};
|
};
|
||||||
let kind = match &constraint.kind {
|
let kind = match &constraint.kind {
|
||||||
AssocConstraintKind::Equality { term } => {
|
AssocItemConstraintKind::Equality { term } => {
|
||||||
let term = match term {
|
let term = match term {
|
||||||
Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
|
Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
|
||||||
Term::Const(c) => self.lower_anon_const(c).into(),
|
Term::Const(c) => self.lower_anon_const(c).into(),
|
||||||
};
|
};
|
||||||
hir::TypeBindingKind::Equality { term }
|
hir::AssocItemConstraintKind::Equality { term }
|
||||||
}
|
}
|
||||||
AssocConstraintKind::Bound { bounds } => {
|
AssocItemConstraintKind::Bound { bounds } => {
|
||||||
// Disallow ATB in dyn types
|
// Disallow ATB in dyn types
|
||||||
if self.is_in_dyn_type {
|
if self.is_in_dyn_type {
|
||||||
let suggestion = match itctx {
|
let suggestion = match itctx {
|
||||||
|
@ -1077,18 +1068,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
});
|
});
|
||||||
let err_ty =
|
let err_ty =
|
||||||
&*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
|
&*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
|
||||||
hir::TypeBindingKind::Equality { term: err_ty.into() }
|
hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
|
||||||
} else {
|
} else {
|
||||||
// Desugar `AssocTy: Bounds` into a type binding where the
|
// Desugar `AssocTy: Bounds` into an assoc type binding where the
|
||||||
// later desugars into a trait predicate.
|
// later desugars into a trait predicate.
|
||||||
let bounds = self.lower_param_bounds(bounds, itctx);
|
let bounds = self.lower_param_bounds(bounds, itctx);
|
||||||
|
|
||||||
hir::TypeBindingKind::Constraint { bounds }
|
hir::AssocItemConstraintKind::Bound { bounds }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
hir::TypeBinding {
|
hir::AssocItemConstraint {
|
||||||
hir_id: self.lower_node_id(constraint.id),
|
hir_id: self.lower_node_id(constraint.id),
|
||||||
ident: self.lower_ident(constraint.ident),
|
ident: self.lower_ident(constraint.ident),
|
||||||
gen_args,
|
gen_args,
|
||||||
|
@ -2008,7 +1999,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
|
|
||||||
let bound_args = self.arena.alloc(hir::GenericArgs {
|
let bound_args = self.arena.alloc(hir::GenericArgs {
|
||||||
args: &[],
|
args: &[],
|
||||||
bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
|
constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
|
||||||
parenthesized: hir::GenericArgsParentheses::No,
|
parenthesized: hir::GenericArgsParentheses::No,
|
||||||
span_ext: DUMMY_SP,
|
span_ext: DUMMY_SP,
|
||||||
});
|
});
|
||||||
|
@ -2581,10 +2572,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper struct for delayed construction of GenericArgs.
|
/// Helper struct for the delayed construction of [`hir::GenericArgs`].
|
||||||
struct GenericArgsCtor<'hir> {
|
struct GenericArgsCtor<'hir> {
|
||||||
args: SmallVec<[hir::GenericArg<'hir>; 4]>,
|
args: SmallVec<[hir::GenericArg<'hir>; 4]>,
|
||||||
bindings: &'hir [hir::TypeBinding<'hir>],
|
constraints: &'hir [hir::AssocItemConstraint<'hir>],
|
||||||
parenthesized: hir::GenericArgsParentheses,
|
parenthesized: hir::GenericArgsParentheses,
|
||||||
span: Span,
|
span: Span,
|
||||||
}
|
}
|
||||||
|
@ -2664,14 +2655,14 @@ impl<'hir> GenericArgsCtor<'hir> {
|
||||||
|
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
self.args.is_empty()
|
self.args.is_empty()
|
||||||
&& self.bindings.is_empty()
|
&& self.constraints.is_empty()
|
||||||
&& self.parenthesized == hir::GenericArgsParentheses::No
|
&& self.parenthesized == hir::GenericArgsParentheses::No
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
|
fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
|
||||||
let ga = hir::GenericArgs {
|
let ga = hir::GenericArgs {
|
||||||
args: this.arena.alloc_from_iter(self.args),
|
args: this.arena.alloc_from_iter(self.args),
|
||||||
bindings: self.bindings,
|
constraints: self.constraints,
|
||||||
parenthesized: self.parenthesized,
|
parenthesized: self.parenthesized,
|
||||||
span_ext: this.lower_span(self.span),
|
span_ext: this.lower_span(self.span),
|
||||||
};
|
};
|
||||||
|
|
|
@ -281,7 +281,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
(
|
(
|
||||||
GenericArgsCtor {
|
GenericArgsCtor {
|
||||||
args: Default::default(),
|
args: Default::default(),
|
||||||
bindings: &[],
|
constraints: &[],
|
||||||
parenthesized: hir::GenericArgsParentheses::No,
|
parenthesized: hir::GenericArgsParentheses::No,
|
||||||
span: path_span.shrink_to_hi(),
|
span: path_span.shrink_to_hi(),
|
||||||
},
|
},
|
||||||
|
@ -390,13 +390,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
AngleBracketedArg::Constraint(_) => None,
|
AngleBracketedArg::Constraint(_) => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let bindings = self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg {
|
let constraints =
|
||||||
AngleBracketedArg::Constraint(c) => Some(self.lower_assoc_ty_constraint(c, itctx)),
|
self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg {
|
||||||
AngleBracketedArg::Arg(_) => None,
|
AngleBracketedArg::Constraint(c) => {
|
||||||
}));
|
Some(self.lower_assoc_item_constraint(c, itctx))
|
||||||
|
}
|
||||||
|
AngleBracketedArg::Arg(_) => None,
|
||||||
|
}));
|
||||||
let ctor = GenericArgsCtor {
|
let ctor = GenericArgsCtor {
|
||||||
args,
|
args,
|
||||||
bindings,
|
constraints,
|
||||||
parenthesized: hir::GenericArgsParentheses::No,
|
parenthesized: hir::GenericArgsParentheses::No,
|
||||||
span: data.span,
|
span: data.span,
|
||||||
};
|
};
|
||||||
|
@ -454,12 +457,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
Some(bound_modifier_allowed_features),
|
Some(bound_modifier_allowed_features),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let binding = self.assoc_ty_binding(sym::Output, output_span, output_ty);
|
let constraint = self.assoc_ty_binding(sym::Output, output_span, output_ty);
|
||||||
|
|
||||||
(
|
(
|
||||||
GenericArgsCtor {
|
GenericArgsCtor {
|
||||||
args,
|
args,
|
||||||
bindings: arena_vec![self; binding],
|
constraints: arena_vec![self; constraint],
|
||||||
parenthesized: hir::GenericArgsParentheses::ParenSugar,
|
parenthesized: hir::GenericArgsParentheses::ParenSugar,
|
||||||
span: data.inputs_span,
|
span: data.inputs_span,
|
||||||
},
|
},
|
||||||
|
@ -467,24 +470,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An associated type binding `$assoc_ty_name = $ty`.
|
/// An associated type binding (i.e., associated type equality constraint).
|
||||||
pub(crate) fn assoc_ty_binding(
|
pub(crate) fn assoc_ty_binding(
|
||||||
&mut self,
|
&mut self,
|
||||||
assoc_ty_name: rustc_span::Symbol,
|
assoc_ty_name: rustc_span::Symbol,
|
||||||
span: Span,
|
span: Span,
|
||||||
ty: &'hir hir::Ty<'hir>,
|
ty: &'hir hir::Ty<'hir>,
|
||||||
) -> hir::TypeBinding<'hir> {
|
) -> hir::AssocItemConstraint<'hir> {
|
||||||
let ident = Ident::with_dummy_span(assoc_ty_name);
|
let ident = Ident::with_dummy_span(assoc_ty_name);
|
||||||
let kind = hir::TypeBindingKind::Equality { term: ty.into() };
|
let kind = hir::AssocItemConstraintKind::Equality { term: ty.into() };
|
||||||
let args = arena_vec![self;];
|
let args = arena_vec![self;];
|
||||||
let bindings = arena_vec![self;];
|
let constraints = arena_vec![self;];
|
||||||
let gen_args = self.arena.alloc(hir::GenericArgs {
|
let gen_args = self.arena.alloc(hir::GenericArgs {
|
||||||
args,
|
args,
|
||||||
bindings,
|
constraints,
|
||||||
parenthesized: hir::GenericArgsParentheses::No,
|
parenthesized: hir::GenericArgsParentheses::No,
|
||||||
span_ext: DUMMY_SP,
|
span_ext: DUMMY_SP,
|
||||||
});
|
});
|
||||||
hir::TypeBinding {
|
hir::AssocItemConstraint {
|
||||||
hir_id: self.next_id(),
|
hir_id: self.next_id(),
|
||||||
gen_args,
|
gen_args,
|
||||||
span: self.lower_span(span),
|
span: self.lower_span(span),
|
||||||
|
|
|
@ -673,7 +673,7 @@ impl<'a> AstValidator<'a> {
|
||||||
let constraint_sugg = data.args.iter().filter_map(|a| match a {
|
let constraint_sugg = data.args.iter().filter_map(|a| match a {
|
||||||
AngleBracketedArg::Arg(_) => None,
|
AngleBracketedArg::Arg(_) => None,
|
||||||
AngleBracketedArg::Constraint(c) => {
|
AngleBracketedArg::Constraint(c) => {
|
||||||
Some(pprust::to_string(|s| s.print_assoc_constraint(c)))
|
Some(pprust::to_string(|s| s.print_assoc_item_constraint(c)))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
format!(
|
format!(
|
||||||
|
@ -1201,11 +1201,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
for arg in &data.args {
|
for arg in &data.args {
|
||||||
match arg {
|
match arg {
|
||||||
AngleBracketedArg::Arg(arg) => self.visit_generic_arg(arg),
|
AngleBracketedArg::Arg(arg) => self.visit_generic_arg(arg),
|
||||||
// Type bindings such as `Item = impl Debug` in `Iterator<Item = Debug>`
|
// Associated type bindings such as `Item = impl Debug` in
|
||||||
// are allowed to contain nested `impl Trait`.
|
// `Iterator<Item = Debug>` are allowed to contain nested `impl Trait`.
|
||||||
AngleBracketedArg::Constraint(constraint) => {
|
AngleBracketedArg::Constraint(constraint) => {
|
||||||
self.with_impl_trait(None, |this| {
|
self.with_impl_trait(None, |this| {
|
||||||
this.visit_assoc_constraint(constraint);
|
this.visit_assoc_item_constraint(constraint);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1365,7 +1365,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The lowered form of parenthesized generic args contains a type binding.
|
// The lowered form of parenthesized generic args contains an associated type binding.
|
||||||
Some(ast::GenericArgs::Parenthesized(args)) => {
|
Some(ast::GenericArgs::Parenthesized(args)) => {
|
||||||
self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation {
|
self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation {
|
||||||
span: args.span,
|
span: args.span,
|
||||||
|
@ -1591,11 +1591,13 @@ fn deny_equality_constraints(
|
||||||
let len = assoc_path.segments.len() - 1;
|
let len = assoc_path.segments.len() - 1;
|
||||||
let gen_args = args.as_deref().cloned();
|
let gen_args = args.as_deref().cloned();
|
||||||
// Build `<Bar = RhsTy>`.
|
// Build `<Bar = RhsTy>`.
|
||||||
let arg = AngleBracketedArg::Constraint(AssocConstraint {
|
let arg = AngleBracketedArg::Constraint(AssocItemConstraint {
|
||||||
id: rustc_ast::node_id::DUMMY_NODE_ID,
|
id: rustc_ast::node_id::DUMMY_NODE_ID,
|
||||||
ident: *ident,
|
ident: *ident,
|
||||||
gen_args,
|
gen_args,
|
||||||
kind: AssocConstraintKind::Equality { term: predicate.rhs_ty.clone().into() },
|
kind: AssocItemConstraintKind::Equality {
|
||||||
|
term: predicate.rhs_ty.clone().into(),
|
||||||
|
},
|
||||||
span: ident.span,
|
span: ident.span,
|
||||||
});
|
});
|
||||||
// Add `<Bar = RhsTy>` to `Foo`.
|
// Add `<Bar = RhsTy>` to `Foo`.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
|
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
|
||||||
use rustc_ast::{attr, AssocConstraint, AssocConstraintKind, NodeId};
|
use rustc_ast::{attr, AssocItemConstraint, AssocItemConstraintKind, NodeId};
|
||||||
use rustc_ast::{token, PatKind};
|
use rustc_ast::{token, PatKind};
|
||||||
use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP};
|
use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP};
|
||||||
use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
|
use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
|
||||||
|
@ -344,7 +344,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
for predicate in &g.where_clause.predicates {
|
for predicate in &g.where_clause.predicates {
|
||||||
match predicate {
|
match predicate {
|
||||||
ast::WherePredicate::BoundPredicate(bound_pred) => {
|
ast::WherePredicate::BoundPredicate(bound_pred) => {
|
||||||
// A type binding, eg `for<'c> Foo: Send+Clone+'c`
|
// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
|
||||||
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
|
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -445,21 +445,21 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||||
visit::walk_fn(self, fn_kind)
|
visit::walk_fn(self, fn_kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
|
fn visit_assoc_item_constraint(&mut self, constraint: &'a AssocItemConstraint) {
|
||||||
if let AssocConstraintKind::Bound { .. } = constraint.kind {
|
if let AssocItemConstraintKind::Bound { .. } = constraint.kind
|
||||||
if let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref()
|
&& let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref()
|
||||||
&& args.inputs.is_empty()
|
&& args.inputs.is_empty()
|
||||||
&& matches!(args.output, ast::FnRetTy::Default(..))
|
&& let ast::FnRetTy::Default(..) = args.output
|
||||||
{
|
{
|
||||||
gate!(
|
gate!(
|
||||||
&self,
|
&self,
|
||||||
return_type_notation,
|
return_type_notation,
|
||||||
constraint.span,
|
constraint.span,
|
||||||
"return type notation is experimental"
|
"return type notation is experimental"
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
visit::walk_assoc_constraint(self, constraint)
|
|
||||||
|
visit::walk_assoc_item_constraint(self, constraint)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
|
fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
|
||||||
|
|
|
@ -119,9 +119,9 @@ impl<'ast> Visitor<'ast> for NodeCounter {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
walk_generic_args(self, generic_args)
|
walk_generic_args(self, generic_args)
|
||||||
}
|
}
|
||||||
fn visit_assoc_constraint(&mut self, constraint: &AssocConstraint) {
|
fn visit_assoc_item_constraint(&mut self, constraint: &AssocItemConstraint) {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
walk_assoc_constraint(self, constraint)
|
walk_assoc_item_constraint(self, constraint)
|
||||||
}
|
}
|
||||||
fn visit_attribute(&mut self, _attr: &Attribute) {
|
fn visit_attribute(&mut self, _attr: &Attribute) {
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
|
|
|
@ -1045,7 +1045,7 @@ impl<'a> PrintState<'a> for State<'a> {
|
||||||
self.word("<");
|
self.word("<");
|
||||||
self.commasep(Inconsistent, &data.args, |s, arg| match arg {
|
self.commasep(Inconsistent, &data.args, |s, arg| match arg {
|
||||||
ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a),
|
ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a),
|
||||||
ast::AngleBracketedArg::Constraint(c) => s.print_assoc_constraint(c),
|
ast::AngleBracketedArg::Constraint(c) => s.print_assoc_item_constraint(c),
|
||||||
});
|
});
|
||||||
self.word(">")
|
self.word(">")
|
||||||
}
|
}
|
||||||
|
@ -1097,21 +1097,21 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocConstraint) {
|
pub fn print_assoc_item_constraint(&mut self, constraint: &ast::AssocItemConstraint) {
|
||||||
self.print_ident(constraint.ident);
|
self.print_ident(constraint.ident);
|
||||||
if let Some(args) = constraint.gen_args.as_ref() {
|
if let Some(args) = constraint.gen_args.as_ref() {
|
||||||
self.print_generic_args(args, false)
|
self.print_generic_args(args, false)
|
||||||
}
|
}
|
||||||
self.space();
|
self.space();
|
||||||
match &constraint.kind {
|
match &constraint.kind {
|
||||||
ast::AssocConstraintKind::Equality { term } => {
|
ast::AssocItemConstraintKind::Equality { term } => {
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
match term {
|
match term {
|
||||||
Term::Ty(ty) => self.print_type(ty),
|
Term::Ty(ty) => self.print_type(ty),
|
||||||
Term::Const(c) => self.print_expr_anon_const(c, &[]),
|
Term::Const(c) => self.print_expr_anon_const(c, &[]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::AssocConstraintKind::Bound { bounds } => {
|
ast::AssocItemConstraintKind::Bound { bounds } => {
|
||||||
if !bounds.is_empty() {
|
if !bounds.is_empty() {
|
||||||
self.word_nbsp(":");
|
self.word_nbsp(":");
|
||||||
self.print_type_bounds(bounds);
|
self.print_type_bounds(bounds);
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rustc_middle::ty::print::RegionHighlightMode;
|
||||||
use rustc_middle::ty::{self, RegionVid, Ty};
|
use rustc_middle::ty::{self, RegionVid, Ty};
|
||||||
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
|
||||||
use crate::{universal_regions::DefiningTy, MirBorrowckCtxt};
|
use crate::{universal_regions::DefiningTy, MirBorrowckCtxt};
|
||||||
|
@ -842,13 +842,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
}) = opaque_ty.kind
|
}) = opaque_ty.kind
|
||||||
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
||||||
&& let Some(args) = segment.args
|
&& let Some(args) = segment.args
|
||||||
&& let [
|
&& let [constraint] = args.constraints
|
||||||
hir::TypeBinding {
|
&& constraint.ident.name == sym::Output
|
||||||
ident: Ident { name: sym::Output, .. },
|
&& let Some(ty) = constraint.ty()
|
||||||
kind: hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
|
|
||||||
..
|
|
||||||
},
|
|
||||||
] = args.bindings
|
|
||||||
{
|
{
|
||||||
ty
|
ty
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
An associated type binding was done outside of the type parameter declaration
|
An associated item constraint was written in an unexpected context.
|
||||||
and `where` clause.
|
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
|
@ -16,12 +15,12 @@ impl Foo for isize {
|
||||||
fn boo(&self) -> usize { 42 }
|
fn boo(&self) -> usize { 42 }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
|
fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
// error: associated type bindings are not allowed here
|
// error: associated item constraint are not allowed here
|
||||||
```
|
```
|
||||||
|
|
||||||
To solve this error, please move the type bindings in the type parameter
|
To solve this error, please move the associated item constraints to the type
|
||||||
declaration:
|
parameter declaration:
|
||||||
|
|
||||||
```
|
```
|
||||||
# struct Bar;
|
# struct Bar;
|
||||||
|
@ -29,7 +28,7 @@ declaration:
|
||||||
fn baz<I: Foo<A=Bar>>(x: &<I as Foo>::A) {} // ok!
|
fn baz<I: Foo<A=Bar>>(x: &<I as Foo>::A) {} // ok!
|
||||||
```
|
```
|
||||||
|
|
||||||
Or in the `where` clause:
|
Or into the where-clause:
|
||||||
|
|
||||||
```
|
```
|
||||||
# struct Bar;
|
# struct Bar;
|
||||||
|
|
|
@ -300,23 +300,30 @@ impl GenericArg<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The generic arguments and associated item constraints of a path segment.
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub struct GenericArgs<'hir> {
|
pub struct GenericArgs<'hir> {
|
||||||
/// The generic arguments for this path segment.
|
/// The generic arguments for this path segment.
|
||||||
pub args: &'hir [GenericArg<'hir>],
|
pub args: &'hir [GenericArg<'hir>],
|
||||||
/// Bindings (equality constraints) on associated types, if present.
|
/// The associated item constraints for this path segment.
|
||||||
/// E.g., `Foo<A = Bar>`.
|
pub constraints: &'hir [AssocItemConstraint<'hir>],
|
||||||
pub bindings: &'hir [TypeBinding<'hir>],
|
/// Whether the arguments were written in parenthesized form (e.g., `Fn(T) -> U`).
|
||||||
/// Were arguments written in parenthesized form `Fn(T) -> U`?
|
///
|
||||||
/// This is required mostly for pretty-printing and diagnostics,
|
/// This is required mostly for pretty-printing and diagnostics,
|
||||||
/// but also for changing lifetime elision rules to be "function-like".
|
/// but also for changing lifetime elision rules to be "function-like".
|
||||||
pub parenthesized: GenericArgsParentheses,
|
pub parenthesized: GenericArgsParentheses,
|
||||||
/// The span encompassing arguments and the surrounding brackets `<>` or `()`
|
/// The span encompassing the arguments, constraints and the surrounding brackets (`<>` or `()`).
|
||||||
|
///
|
||||||
|
/// For example:
|
||||||
|
///
|
||||||
|
/// ```ignore (illustrative)
|
||||||
/// Foo<A, B, AssocTy = D> Fn(T, U, V) -> W
|
/// Foo<A, B, AssocTy = D> Fn(T, U, V) -> W
|
||||||
/// ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
|
/// ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// Note that this may be:
|
/// Note that this may be:
|
||||||
/// - empty, if there are no generic brackets (but there may be hidden lifetimes)
|
/// - empty, if there are no generic brackets (but there may be hidden lifetimes)
|
||||||
/// - dummy, if this was generated while desugaring
|
/// - dummy, if this was generated during desugaring
|
||||||
pub span_ext: Span,
|
pub span_ext: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,39 +331,63 @@ impl<'hir> GenericArgs<'hir> {
|
||||||
pub const fn none() -> Self {
|
pub const fn none() -> Self {
|
||||||
Self {
|
Self {
|
||||||
args: &[],
|
args: &[],
|
||||||
bindings: &[],
|
constraints: &[],
|
||||||
parenthesized: GenericArgsParentheses::No,
|
parenthesized: GenericArgsParentheses::No,
|
||||||
span_ext: DUMMY_SP,
|
span_ext: DUMMY_SP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inputs(&self) -> &[Ty<'hir>] {
|
/// Obtain the list of input types and the output type if the generic arguments are parenthesized.
|
||||||
if self.parenthesized == GenericArgsParentheses::ParenSugar {
|
///
|
||||||
for arg in self.args {
|
/// Returns the `Ty0, Ty1, ...` and the `RetTy` in `Trait(Ty0, Ty1, ...) -> RetTy`.
|
||||||
match arg {
|
/// Panics if the parenthesized arguments have an incorrect form (this shouldn't happen).
|
||||||
GenericArg::Lifetime(_) => {}
|
pub fn paren_sugar_inputs_output(&self) -> Option<(&[Ty<'hir>], &Ty<'hir>)> {
|
||||||
GenericArg::Type(ref ty) => {
|
if self.parenthesized != GenericArgsParentheses::ParenSugar {
|
||||||
if let TyKind::Tup(ref tys) = ty.kind {
|
return None;
|
||||||
return tys;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
GenericArg::Const(_) => {}
|
|
||||||
GenericArg::Infer(_) => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
panic!("GenericArgs::inputs: not a `Fn(T) -> U`");
|
|
||||||
|
let inputs = self
|
||||||
|
.args
|
||||||
|
.iter()
|
||||||
|
.find_map(|arg| {
|
||||||
|
let GenericArg::Type(ty) = arg else { return None };
|
||||||
|
let TyKind::Tup(tys) = &ty.kind else { return None };
|
||||||
|
Some(tys)
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Some((inputs, self.paren_sugar_output_inner()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_err(&self) -> bool {
|
/// Obtain the output type if the generic arguments are parenthesized.
|
||||||
self.args.iter().any(|arg| match arg {
|
///
|
||||||
GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err(_)),
|
/// Returns the `RetTy` in `Trait(Ty0, Ty1, ...) -> RetTy`.
|
||||||
_ => false,
|
/// Panics if the parenthesized arguments have an incorrect form (this shouldn't happen).
|
||||||
}) || self.bindings.iter().any(|arg| match arg.kind {
|
pub fn paren_sugar_output(&self) -> Option<&Ty<'hir>> {
|
||||||
TypeBindingKind::Equality { term: Term::Ty(ty) } => matches!(ty.kind, TyKind::Err(_)),
|
(self.parenthesized == GenericArgsParentheses::ParenSugar)
|
||||||
_ => false,
|
.then(|| self.paren_sugar_output_inner())
|
||||||
})
|
}
|
||||||
|
|
||||||
|
fn paren_sugar_output_inner(&self) -> &Ty<'hir> {
|
||||||
|
let [constraint] = self.constraints.try_into().unwrap();
|
||||||
|
debug_assert_eq!(constraint.ident.name, sym::Output);
|
||||||
|
constraint.ty().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_err(&self) -> Option<ErrorGuaranteed> {
|
||||||
|
self.args
|
||||||
|
.iter()
|
||||||
|
.find_map(|arg| {
|
||||||
|
let GenericArg::Type(ty) = arg else { return None };
|
||||||
|
let TyKind::Err(guar) = ty.kind else { return None };
|
||||||
|
Some(guar)
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.constraints.iter().find_map(|constraint| {
|
||||||
|
let TyKind::Err(guar) = constraint.ty()?.kind else { return None };
|
||||||
|
Some(guar)
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -383,9 +414,11 @@ impl<'hir> GenericArgs<'hir> {
|
||||||
.count()
|
.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The span encompassing the text inside the surrounding brackets.
|
/// The span encompassing the arguments and constraints[^1] inside the surrounding brackets.
|
||||||
/// It will also include bindings if they aren't in the form `-> Ret`
|
///
|
||||||
/// Returns `None` if the span is empty (e.g. no brackets) or dummy
|
/// Returns `None` if the span is empty (i.e., no brackets) or dummy.
|
||||||
|
///
|
||||||
|
/// [^1]: Unless of the form `-> Ty` (see [`GenericArgsParentheses`]).
|
||||||
pub fn span(&self) -> Option<Span> {
|
pub fn span(&self) -> Option<Span> {
|
||||||
let span_ext = self.span_ext()?;
|
let span_ext = self.span_ext()?;
|
||||||
Some(span_ext.with_lo(span_ext.lo() + BytePos(1)).with_hi(span_ext.hi() - BytePos(1)))
|
Some(span_ext.with_lo(span_ext.lo() + BytePos(1)).with_hi(span_ext.hi() - BytePos(1)))
|
||||||
|
@ -660,9 +693,7 @@ impl<'hir> Generics<'hir> {
|
||||||
|bound| {
|
|bound| {
|
||||||
let span_for_parentheses = if let Some(trait_ref) = bound.trait_ref()
|
let span_for_parentheses = if let Some(trait_ref) = bound.trait_ref()
|
||||||
&& let [.., segment] = trait_ref.path.segments
|
&& let [.., segment] = trait_ref.path.segments
|
||||||
&& segment.args().parenthesized == GenericArgsParentheses::ParenSugar
|
&& let Some(ret_ty) = segment.args().paren_sugar_output()
|
||||||
&& let [binding] = segment.args().bindings
|
|
||||||
&& let TypeBindingKind::Equality { term: Term::Ty(ret_ty) } = binding.kind
|
|
||||||
&& let ret_ty = ret_ty.peel_refs()
|
&& let ret_ty = ret_ty.peel_refs()
|
||||||
&& let TyKind::TraitObject(
|
&& let TyKind::TraitObject(
|
||||||
_,
|
_,
|
||||||
|
@ -748,7 +779,7 @@ impl<'hir> Generics<'hir> {
|
||||||
/// A single predicate in a where-clause.
|
/// A single predicate in a where-clause.
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub enum WherePredicate<'hir> {
|
pub enum WherePredicate<'hir> {
|
||||||
/// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
|
/// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
|
||||||
BoundPredicate(WhereBoundPredicate<'hir>),
|
BoundPredicate(WhereBoundPredicate<'hir>),
|
||||||
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
|
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
|
||||||
RegionPredicate(WhereRegionPredicate<'hir>),
|
RegionPredicate(WhereRegionPredicate<'hir>),
|
||||||
|
@ -2361,24 +2392,43 @@ pub enum ImplItemKind<'hir> {
|
||||||
Type(&'hir Ty<'hir>),
|
Type(&'hir Ty<'hir>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An associated item binding.
|
/// A constraint on an associated item.
|
||||||
///
|
///
|
||||||
/// ### Examples
|
/// ### Examples
|
||||||
///
|
///
|
||||||
/// * `Trait<A = Ty, B = Ty>`
|
/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
|
||||||
/// * `Trait<G<Ty> = Ty>`
|
/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
|
||||||
/// * `Trait<A: Bound>`
|
/// * the `A: Bound` in `Trait<A: Bound>`
|
||||||
/// * `Trait<C = { Ct }>` (under feature `associated_const_equality`)
|
/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
|
||||||
/// * `Trait<f(): Bound>` (under feature `return_type_notation`)
|
/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
|
||||||
|
/// * the `f(): Bound` in `Trait<f(): Bound>` (feature `return_type_notation`)
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub struct TypeBinding<'hir> {
|
pub struct AssocItemConstraint<'hir> {
|
||||||
pub hir_id: HirId,
|
pub hir_id: HirId,
|
||||||
pub ident: Ident,
|
pub ident: Ident,
|
||||||
pub gen_args: &'hir GenericArgs<'hir>,
|
pub gen_args: &'hir GenericArgs<'hir>,
|
||||||
pub kind: TypeBindingKind<'hir>,
|
pub kind: AssocItemConstraintKind<'hir>,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'hir> AssocItemConstraint<'hir> {
|
||||||
|
/// Obtain the type on the RHS of an assoc ty equality constraint if applicable.
|
||||||
|
pub fn ty(self) -> Option<&'hir Ty<'hir>> {
|
||||||
|
match self.kind {
|
||||||
|
AssocItemConstraintKind::Equality { term: Term::Ty(ty) } => Some(ty),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Obtain the const on the RHS of an assoc const equality constraint if applicable.
|
||||||
|
pub fn ct(self) -> Option<&'hir AnonConst> {
|
||||||
|
match self.kind {
|
||||||
|
AssocItemConstraintKind::Equality { term: Term::Const(ct) } => Some(ct),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub enum Term<'hir> {
|
pub enum Term<'hir> {
|
||||||
Ty(&'hir Ty<'hir>),
|
Ty(&'hir Ty<'hir>),
|
||||||
|
@ -2397,28 +2447,18 @@ impl<'hir> From<&'hir AnonConst> for Term<'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Represents the two kinds of type bindings.
|
/// The kind of [associated item constraint][AssocItemConstraint].
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub enum TypeBindingKind<'hir> {
|
pub enum AssocItemConstraintKind<'hir> {
|
||||||
/// E.g., `Foo<Bar: Send>`.
|
/// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait<AssocTy = Ty>`).
|
||||||
Constraint { bounds: &'hir [GenericBound<'hir>] },
|
///
|
||||||
/// E.g., `Foo<Bar = ()>`.
|
/// Also known as an *associated item binding* (we *bind* an associated item to a term).
|
||||||
|
///
|
||||||
|
/// Furthermore, associated type equality constraints can also be referred to as *associated type
|
||||||
|
/// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
|
||||||
Equality { term: Term<'hir> },
|
Equality { term: Term<'hir> },
|
||||||
}
|
/// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait<AssocTy: Bound>`).
|
||||||
|
Bound { bounds: &'hir [GenericBound<'hir>] },
|
||||||
impl TypeBinding<'_> {
|
|
||||||
pub fn ty(&self) -> &Ty<'_> {
|
|
||||||
match self.kind {
|
|
||||||
TypeBindingKind::Equality { term: Term::Ty(ref ty) } => ty,
|
|
||||||
_ => panic!("expected equality type binding for parenthesized generic args"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn opt_const(&self) -> Option<&'_ AnonConst> {
|
|
||||||
match self.kind {
|
|
||||||
TypeBindingKind::Equality { term: Term::Const(ref c) } => Some(c),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
|
@ -3615,7 +3655,7 @@ pub enum Node<'hir> {
|
||||||
Stmt(&'hir Stmt<'hir>),
|
Stmt(&'hir Stmt<'hir>),
|
||||||
PathSegment(&'hir PathSegment<'hir>),
|
PathSegment(&'hir PathSegment<'hir>),
|
||||||
Ty(&'hir Ty<'hir>),
|
Ty(&'hir Ty<'hir>),
|
||||||
TypeBinding(&'hir TypeBinding<'hir>),
|
AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
|
||||||
TraitRef(&'hir TraitRef<'hir>),
|
TraitRef(&'hir TraitRef<'hir>),
|
||||||
Pat(&'hir Pat<'hir>),
|
Pat(&'hir Pat<'hir>),
|
||||||
PatField(&'hir PatField<'hir>),
|
PatField(&'hir PatField<'hir>),
|
||||||
|
@ -3664,7 +3704,7 @@ impl<'hir> Node<'hir> {
|
||||||
| Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
|
| Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
|
||||||
Node::Lifetime(lt) => Some(lt.ident),
|
Node::Lifetime(lt) => Some(lt.ident),
|
||||||
Node::GenericParam(p) => Some(p.name.ident()),
|
Node::GenericParam(p) => Some(p.name.ident()),
|
||||||
Node::TypeBinding(b) => Some(b.ident),
|
Node::AssocItemConstraint(c) => Some(c.ident),
|
||||||
Node::PatField(f) => Some(f.ident),
|
Node::PatField(f) => Some(f.ident),
|
||||||
Node::ExprField(f) => Some(f.ident),
|
Node::ExprField(f) => Some(f.ident),
|
||||||
Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
|
Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
|
||||||
|
@ -3843,7 +3883,7 @@ impl<'hir> Node<'hir> {
|
||||||
expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
|
expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
|
||||||
expect_path_segment, &'hir PathSegment<'hir>, Node::PathSegment(n), n;
|
expect_path_segment, &'hir PathSegment<'hir>, Node::PathSegment(n), n;
|
||||||
expect_ty, &'hir Ty<'hir>, Node::Ty(n), n;
|
expect_ty, &'hir Ty<'hir>, Node::Ty(n), n;
|
||||||
expect_type_binding, &'hir TypeBinding<'hir>, Node::TypeBinding(n), n;
|
expect_assoc_item_constraint, &'hir AssocItemConstraint<'hir>, Node::AssocItemConstraint(n), n;
|
||||||
expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n;
|
expect_trait_ref, &'hir TraitRef<'hir>, Node::TraitRef(n), n;
|
||||||
expect_pat, &'hir Pat<'hir>, Node::Pat(n), n;
|
expect_pat, &'hir Pat<'hir>, Node::Pat(n), n;
|
||||||
expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
|
expect_pat_field, &'hir PatField<'hir>, Node::PatField(n), n;
|
||||||
|
|
|
@ -456,8 +456,11 @@ pub trait Visitor<'v>: Sized {
|
||||||
fn visit_generic_args(&mut self, generic_args: &'v GenericArgs<'v>) -> Self::Result {
|
fn visit_generic_args(&mut self, generic_args: &'v GenericArgs<'v>) -> Self::Result {
|
||||||
walk_generic_args(self, generic_args)
|
walk_generic_args(self, generic_args)
|
||||||
}
|
}
|
||||||
fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding<'v>) -> Self::Result {
|
fn visit_assoc_item_constraint(
|
||||||
walk_assoc_type_binding(self, type_binding)
|
&mut self,
|
||||||
|
constraint: &'v AssocItemConstraint<'v>,
|
||||||
|
) -> Self::Result {
|
||||||
|
walk_assoc_item_constraint(self, constraint)
|
||||||
}
|
}
|
||||||
fn visit_attribute(&mut self, _attr: &'v Attribute) -> Self::Result {
|
fn visit_attribute(&mut self, _attr: &'v Attribute) -> Self::Result {
|
||||||
Self::Result::output()
|
Self::Result::output()
|
||||||
|
@ -1259,23 +1262,25 @@ pub fn walk_generic_args<'v, V: Visitor<'v>>(
|
||||||
generic_args: &'v GenericArgs<'v>,
|
generic_args: &'v GenericArgs<'v>,
|
||||||
) -> V::Result {
|
) -> V::Result {
|
||||||
walk_list!(visitor, visit_generic_arg, generic_args.args);
|
walk_list!(visitor, visit_generic_arg, generic_args.args);
|
||||||
walk_list!(visitor, visit_assoc_type_binding, generic_args.bindings);
|
walk_list!(visitor, visit_assoc_item_constraint, generic_args.constraints);
|
||||||
V::Result::output()
|
V::Result::output()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(
|
pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>(
|
||||||
visitor: &mut V,
|
visitor: &mut V,
|
||||||
type_binding: &'v TypeBinding<'v>,
|
constraint: &'v AssocItemConstraint<'v>,
|
||||||
) -> V::Result {
|
) -> V::Result {
|
||||||
try_visit!(visitor.visit_id(type_binding.hir_id));
|
try_visit!(visitor.visit_id(constraint.hir_id));
|
||||||
try_visit!(visitor.visit_ident(type_binding.ident));
|
try_visit!(visitor.visit_ident(constraint.ident));
|
||||||
try_visit!(visitor.visit_generic_args(type_binding.gen_args));
|
try_visit!(visitor.visit_generic_args(constraint.gen_args));
|
||||||
match type_binding.kind {
|
match constraint.kind {
|
||||||
TypeBindingKind::Equality { ref term } => match term {
|
AssocItemConstraintKind::Equality { ref term } => match term {
|
||||||
Term::Ty(ref ty) => try_visit!(visitor.visit_ty(ty)),
|
Term::Ty(ref ty) => try_visit!(visitor.visit_ty(ty)),
|
||||||
Term::Const(ref c) => try_visit!(visitor.visit_anon_const(c)),
|
Term::Const(ref c) => try_visit!(visitor.visit_anon_const(c)),
|
||||||
},
|
},
|
||||||
TypeBindingKind::Constraint { bounds } => walk_list!(visitor, visit_param_bound, bounds),
|
AssocItemConstraintKind::Bound { bounds } => {
|
||||||
|
walk_list!(visitor, visit_param_bound, bounds)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
V::Result::output()
|
V::Result::output()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,10 @@ hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_
|
||||||
hir_analysis_ambiguous_lifetime_bound =
|
hir_analysis_ambiguous_lifetime_bound =
|
||||||
ambiguous lifetime bound, explicit lifetime bound required
|
ambiguous lifetime bound, explicit lifetime bound required
|
||||||
|
|
||||||
|
hir_analysis_assoc_item_constraints_not_allowed_here =
|
||||||
|
associated item constraints are not allowed here
|
||||||
|
.label = associated item constraint not allowed here
|
||||||
|
|
||||||
hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$ty_param_name}`
|
hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$ty_param_name}`
|
||||||
|
|
||||||
hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->
|
hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->
|
||||||
|
@ -24,10 +28,6 @@ hir_analysis_assoc_kind_mismatch = expected {$expected}, found {$got}
|
||||||
|
|
||||||
hir_analysis_assoc_kind_mismatch_wrap_in_braces_sugg = consider adding braces here
|
hir_analysis_assoc_kind_mismatch_wrap_in_braces_sugg = consider adding braces here
|
||||||
|
|
||||||
hir_analysis_assoc_type_binding_not_allowed =
|
|
||||||
associated type bindings are not allowed here
|
|
||||||
.label = associated type not allowed here
|
|
||||||
|
|
||||||
hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the associated type of a trait with uninferred generic parameters
|
hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the associated type of a trait with uninferred generic parameters
|
||||||
.suggestion = use a fully qualified path with inferred lifetimes
|
.suggestion = use a fully qualified path with inferred lifetimes
|
||||||
|
|
||||||
|
|
|
@ -1468,12 +1468,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
depth: usize,
|
depth: usize,
|
||||||
generic_args: &'tcx hir::GenericArgs<'tcx>,
|
generic_args: &'tcx hir::GenericArgs<'tcx>,
|
||||||
) {
|
) {
|
||||||
if generic_args.parenthesized == hir::GenericArgsParentheses::ParenSugar {
|
if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() {
|
||||||
self.visit_fn_like_elision(
|
self.visit_fn_like_elision(inputs, Some(output), false);
|
||||||
generic_args.inputs(),
|
|
||||||
Some(generic_args.bindings[0].ty()),
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1608,8 +1604,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hack: when resolving the type `XX` in binding like `dyn
|
// Hack: When resolving the type `XX` in an assoc ty binding like
|
||||||
// Foo<'b, Item = XX>`, the current object-lifetime default
|
// `dyn Foo<'b, Item = XX>`, the current object-lifetime default
|
||||||
// would be to examine the trait `Foo` to check whether it has
|
// would be to examine the trait `Foo` to check whether it has
|
||||||
// a lifetime bound declared on `Item`. e.g., if `Foo` is
|
// a lifetime bound declared on `Item`. e.g., if `Foo` is
|
||||||
// declared like so, then the default object lifetime bound in
|
// declared like so, then the default object lifetime bound in
|
||||||
|
@ -1637,7 +1633,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
|
|
||||||
// Resolve lifetimes found in the bindings, so either in the type `XX` in `Item = XX` or
|
// Resolve lifetimes found in the bindings, so either in the type `XX` in `Item = XX` or
|
||||||
// in the trait ref `YY<...>` in `Item: YY<...>`.
|
// in the trait ref `YY<...>` in `Item: YY<...>`.
|
||||||
for binding in generic_args.bindings {
|
for constraint in generic_args.constraints {
|
||||||
let scope = Scope::ObjectLifetimeDefault {
|
let scope = Scope::ObjectLifetimeDefault {
|
||||||
lifetime: if has_lifetime_parameter {
|
lifetime: if has_lifetime_parameter {
|
||||||
None
|
None
|
||||||
|
@ -1646,7 +1642,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
s: self.scope,
|
s: self.scope,
|
||||||
};
|
};
|
||||||
// If the binding is parenthesized, then this must be `feature(return_type_notation)`.
|
// If the args are parenthesized, then this must be `feature(return_type_notation)`.
|
||||||
// In that case, introduce a binder over all of the function's early and late bound vars.
|
// In that case, introduce a binder over all of the function's early and late bound vars.
|
||||||
//
|
//
|
||||||
// For example, given
|
// For example, given
|
||||||
|
@ -1659,13 +1655,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
// `for<'a> T::Trait<'a, x(): for<'b> Other<'b>>`
|
// `for<'a> T::Trait<'a, x(): for<'b> Other<'b>>`
|
||||||
// this is going to expand to something like:
|
// this is going to expand to something like:
|
||||||
// `for<'a> for<'r, T> <T as Trait<'a>>::x::<'r, T>::{opaque#0}: for<'b> Other<'b>`.
|
// `for<'a> for<'r, T> <T as Trait<'a>>::x::<'r, T>::{opaque#0}: for<'b> Other<'b>`.
|
||||||
if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation {
|
if constraint.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation
|
||||||
|
{
|
||||||
let bound_vars = if let Some(type_def_id) = type_def_id
|
let bound_vars = if let Some(type_def_id) = type_def_id
|
||||||
&& self.tcx.def_kind(type_def_id) == DefKind::Trait
|
&& self.tcx.def_kind(type_def_id) == DefKind::Trait
|
||||||
&& let Some((mut bound_vars, assoc_fn)) = BoundVarContext::supertrait_hrtb_vars(
|
&& let Some((mut bound_vars, assoc_fn)) = BoundVarContext::supertrait_hrtb_vars(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
type_def_id,
|
type_def_id,
|
||||||
binding.ident,
|
constraint.ident,
|
||||||
ty::AssocKind::Fn,
|
ty::AssocKind::Fn,
|
||||||
) {
|
) {
|
||||||
bound_vars.extend(self.tcx.generics_of(assoc_fn.def_id).own_params.iter().map(
|
bound_vars.extend(self.tcx.generics_of(assoc_fn.def_id).own_params.iter().map(
|
||||||
|
@ -1686,22 +1683,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
self.tcx
|
self.tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
.span_delayed_bug(binding.ident.span, "bad return type notation here");
|
.span_delayed_bug(constraint.ident.span, "bad return type notation here");
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
self.with(scope, |this| {
|
self.with(scope, |this| {
|
||||||
let scope = Scope::Supertrait { bound_vars, s: this.scope };
|
let scope = Scope::Supertrait { bound_vars, s: this.scope };
|
||||||
this.with(scope, |this| {
|
this.with(scope, |this| {
|
||||||
let (bound_vars, _) = this.poly_trait_ref_binder_info();
|
let (bound_vars, _) = this.poly_trait_ref_binder_info();
|
||||||
this.record_late_bound_vars(binding.hir_id, bound_vars);
|
this.record_late_bound_vars(constraint.hir_id, bound_vars);
|
||||||
this.visit_assoc_type_binding(binding)
|
this.visit_assoc_item_constraint(constraint)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if let Some(type_def_id) = type_def_id {
|
} else if let Some(type_def_id) = type_def_id {
|
||||||
let bound_vars = BoundVarContext::supertrait_hrtb_vars(
|
let bound_vars = BoundVarContext::supertrait_hrtb_vars(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
type_def_id,
|
type_def_id,
|
||||||
binding.ident,
|
constraint.ident,
|
||||||
ty::AssocKind::Type,
|
ty::AssocKind::Type,
|
||||||
)
|
)
|
||||||
.map(|(bound_vars, _)| bound_vars);
|
.map(|(bound_vars, _)| bound_vars);
|
||||||
|
@ -1710,10 +1707,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
bound_vars: bound_vars.unwrap_or_default(),
|
bound_vars: bound_vars.unwrap_or_default(),
|
||||||
s: this.scope,
|
s: this.scope,
|
||||||
};
|
};
|
||||||
this.with(scope, |this| this.visit_assoc_type_binding(binding));
|
this.with(scope, |this| this.visit_assoc_item_constraint(constraint));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.with(scope, |this| this.visit_assoc_type_binding(binding));
|
self.with(scope, |this| this.visit_assoc_item_constraint(constraint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,9 +220,10 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||||
.position(|arg| arg.hir_id() == hir_id)
|
.position(|arg| arg.hir_id() == hir_id)
|
||||||
.map(|index| (index, seg))
|
.map(|index| (index, seg))
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
args.bindings
|
args.constraints
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(TypeBinding::opt_const)
|
.copied()
|
||||||
|
.filter_map(AssocItemConstraint::ct)
|
||||||
.position(|ct| ct.hir_id == hir_id)
|
.position(|ct| ct.hir_id == hir_id)
|
||||||
.map(|idx| (idx, seg))
|
.map(|idx| (idx, seg))
|
||||||
})
|
})
|
||||||
|
|
|
@ -290,8 +290,8 @@ pub struct AmbiguousLifetimeBound {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_assoc_type_binding_not_allowed, code = E0229)]
|
#[diag(hir_analysis_assoc_item_constraints_not_allowed_here, code = E0229)]
|
||||||
pub struct AssocTypeBindingNotAllowed {
|
pub struct AssocItemConstraintsNotAllowedHere {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
#[label]
|
#[label]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
|
|
@ -230,32 +230,34 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
bounds
|
bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Lower an associated item binding from HIR into `bounds`.
|
/// Lower an associated item constraint from the HIR into `bounds`.
|
||||||
///
|
///
|
||||||
/// ### A Note on Binders
|
/// ### A Note on Binders
|
||||||
///
|
///
|
||||||
/// Given something like `T: for<'a> Iterator<Item = &'a u32>`,
|
/// Given something like `T: for<'a> Iterator<Item = &'a u32>`,
|
||||||
/// the `trait_ref` here will be `for<'a> T: Iterator`.
|
/// the `trait_ref` here will be `for<'a> T: Iterator`.
|
||||||
/// The `binding` data however is from *inside* the binder
|
/// The `constraint` data however is from *inside* the binder
|
||||||
/// (e.g., `&'a u32`) and hence may reference bound regions.
|
/// (e.g., `&'a u32`) and hence may reference bound regions.
|
||||||
#[instrument(level = "debug", skip(self, bounds, dup_bindings, path_span))]
|
#[instrument(level = "debug", skip(self, bounds, duplicates, path_span))]
|
||||||
pub(super) fn lower_assoc_item_binding(
|
pub(super) fn lower_assoc_item_constraint(
|
||||||
&self,
|
&self,
|
||||||
hir_ref_id: hir::HirId,
|
hir_ref_id: hir::HirId,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
binding: &hir::TypeBinding<'tcx>,
|
constraint: &hir::AssocItemConstraint<'tcx>,
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
dup_bindings: &mut FxIndexMap<DefId, Span>,
|
duplicates: &mut FxIndexMap<DefId, Span>,
|
||||||
path_span: Span,
|
path_span: Span,
|
||||||
only_self_bounds: OnlySelfBounds,
|
only_self_bounds: OnlySelfBounds,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
let assoc_kind = if binding.gen_args.parenthesized
|
let assoc_kind = if constraint.gen_args.parenthesized
|
||||||
== hir::GenericArgsParentheses::ReturnTypeNotation
|
== hir::GenericArgsParentheses::ReturnTypeNotation
|
||||||
{
|
{
|
||||||
ty::AssocKind::Fn
|
ty::AssocKind::Fn
|
||||||
} else if let hir::TypeBindingKind::Equality { term: hir::Term::Const(_) } = binding.kind {
|
} else if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(_) } =
|
||||||
|
constraint.kind
|
||||||
|
{
|
||||||
ty::AssocKind::Const
|
ty::AssocKind::Const
|
||||||
} else {
|
} else {
|
||||||
ty::AssocKind::Type
|
ty::AssocKind::Type
|
||||||
|
@ -272,7 +274,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let candidate = if self.probe_trait_that_defines_assoc_item(
|
let candidate = if self.probe_trait_that_defines_assoc_item(
|
||||||
trait_ref.def_id(),
|
trait_ref.def_id(),
|
||||||
assoc_kind,
|
assoc_kind,
|
||||||
binding.ident,
|
constraint.ident,
|
||||||
) {
|
) {
|
||||||
// Simple case: The assoc item is defined in the current trait.
|
// Simple case: The assoc item is defined in the current trait.
|
||||||
trait_ref
|
trait_ref
|
||||||
|
@ -284,14 +286,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
trait_ref.skip_binder().print_only_trait_name(),
|
trait_ref.skip_binder().print_only_trait_name(),
|
||||||
None,
|
None,
|
||||||
assoc_kind,
|
assoc_kind,
|
||||||
binding.ident,
|
constraint.ident,
|
||||||
path_span,
|
path_span,
|
||||||
Some(binding),
|
Some(constraint),
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let (assoc_ident, def_scope) =
|
let (assoc_ident, def_scope) =
|
||||||
tcx.adjust_ident_and_get_scope(binding.ident, candidate.def_id(), hir_ref_id);
|
tcx.adjust_ident_and_get_scope(constraint.ident, candidate.def_id(), hir_ref_id);
|
||||||
|
|
||||||
// We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
|
// We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
|
||||||
// instead of calling `filter_by_name_and_kind` which would needlessly normalize the
|
// instead of calling `filter_by_name_and_kind` which would needlessly normalize the
|
||||||
|
@ -306,26 +308,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let reported = tcx
|
let reported = tcx
|
||||||
.dcx()
|
.dcx()
|
||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
binding.span,
|
constraint.span,
|
||||||
format!("{} `{}` is private", assoc_item.kind, binding.ident),
|
format!("{} `{}` is private", assoc_item.kind, constraint.ident),
|
||||||
)
|
)
|
||||||
.with_span_label(binding.span, format!("private {}", assoc_item.kind))
|
.with_span_label(constraint.span, format!("private {}", assoc_item.kind))
|
||||||
.emit();
|
.emit();
|
||||||
self.set_tainted_by_errors(reported);
|
self.set_tainted_by_errors(reported);
|
||||||
}
|
}
|
||||||
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
|
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), constraint.span, None);
|
||||||
|
|
||||||
dup_bindings
|
duplicates
|
||||||
.entry(assoc_item.def_id)
|
.entry(assoc_item.def_id)
|
||||||
.and_modify(|prev_span| {
|
.and_modify(|prev_span| {
|
||||||
tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
|
tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
|
||||||
span: binding.span,
|
span: constraint.span,
|
||||||
prev_span: *prev_span,
|
prev_span: *prev_span,
|
||||||
item_name: binding.ident,
|
item_name: constraint.ident,
|
||||||
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
|
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.or_insert(binding.span);
|
.or_insert(constraint.span);
|
||||||
|
|
||||||
let projection_term = if let ty::AssocKind::Fn = assoc_kind {
|
let projection_term = if let ty::AssocKind::Fn = assoc_kind {
|
||||||
let mut emitted_bad_param_err = None;
|
let mut emitted_bad_param_err = None;
|
||||||
|
@ -384,7 +386,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
alias_ty.into()
|
alias_ty.into()
|
||||||
} else {
|
} else {
|
||||||
return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit {
|
return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit {
|
||||||
span: binding.span,
|
span: constraint.span,
|
||||||
ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output),
|
ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output),
|
||||||
fn_span: tcx.hir().span_if_local(assoc_item.def_id),
|
fn_span: tcx.hir().span_if_local(assoc_item.def_id),
|
||||||
note: (),
|
note: (),
|
||||||
|
@ -398,19 +400,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
|
let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
|
||||||
let instantiation_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args);
|
let instantiation_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args);
|
||||||
|
|
||||||
let bound_vars = tcx.late_bound_vars(binding.hir_id);
|
let bound_vars = tcx.late_bound_vars(constraint.hir_id);
|
||||||
ty::Binder::bind_with_vars(instantiation_output, bound_vars)
|
ty::Binder::bind_with_vars(instantiation_output, bound_vars)
|
||||||
} else {
|
} else {
|
||||||
// Create the generic arguments for the associated type or constant by joining the
|
// Create the generic arguments for the associated type or constant by joining the
|
||||||
// parent arguments (the arguments of the trait) and the own arguments (the ones of
|
// parent arguments (the arguments of the trait) and the own arguments (the ones of
|
||||||
// the associated item itself) and construct an alias type using them.
|
// the associated item itself) and construct an alias type using them.
|
||||||
let alias_ty = candidate.map_bound(|trait_ref| {
|
let alias_ty = candidate.map_bound(|trait_ref| {
|
||||||
let ident = Ident::new(assoc_item.name, binding.ident.span);
|
let ident = Ident::new(assoc_item.name, constraint.ident.span);
|
||||||
let item_segment = hir::PathSegment {
|
let item_segment = hir::PathSegment {
|
||||||
ident,
|
ident,
|
||||||
hir_id: binding.hir_id,
|
hir_id: constraint.hir_id,
|
||||||
res: Res::Err,
|
res: Res::Err,
|
||||||
args: Some(binding.gen_args),
|
args: Some(constraint.gen_args),
|
||||||
infer_args: false,
|
infer_args: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -426,26 +428,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Provide the resolved type of the associated constant to `type_of(AnonConst)`.
|
// Provide the resolved type of the associated constant to `type_of(AnonConst)`.
|
||||||
if let hir::TypeBindingKind::Equality { term: hir::Term::Const(anon_const) } =
|
if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(anon_const) } =
|
||||||
binding.kind
|
constraint.kind
|
||||||
{
|
{
|
||||||
let ty = alias_ty.map_bound(|ty| tcx.type_of(ty.def_id).instantiate(tcx, ty.args));
|
let ty = alias_ty.map_bound(|ty| tcx.type_of(ty.def_id).instantiate(tcx, ty.args));
|
||||||
let ty = check_assoc_const_binding_type(tcx, assoc_ident, ty, binding.hir_id);
|
let ty = check_assoc_const_binding_type(tcx, assoc_ident, ty, constraint.hir_id);
|
||||||
tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
|
tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
alias_ty
|
alias_ty
|
||||||
};
|
};
|
||||||
|
|
||||||
match binding.kind {
|
match constraint.kind {
|
||||||
hir::TypeBindingKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => {
|
hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => {
|
||||||
return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound {
|
return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationEqualityBound {
|
||||||
span: binding.span,
|
span: constraint.span,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
// Lower an equality constraint like `Item = u32` as found in HIR bound `T: Iterator<Item = u32>`
|
// Lower an equality constraint like `Item = u32` as found in HIR bound `T: Iterator<Item = u32>`
|
||||||
// to a projection predicate: `<T as Iterator>::Item = u32`.
|
// to a projection predicate: `<T as Iterator>::Item = u32`.
|
||||||
hir::TypeBindingKind::Equality { term } => {
|
hir::AssocItemConstraintKind::Equality { term } => {
|
||||||
let term = match term {
|
let term = match term {
|
||||||
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
|
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
|
||||||
hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
|
hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
|
||||||
|
@ -469,18 +471,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
||||||
// ---- ---- ^^^^^^^
|
// ---- ---- ^^^^^^^
|
||||||
// NOTE(associated_const_equality): This error should be impossible to trigger
|
// NOTE(associated_const_equality): This error should be impossible to trigger
|
||||||
// with associated const equality bounds.
|
// with associated const equality constraints.
|
||||||
self.validate_late_bound_regions(
|
self.validate_late_bound_regions(
|
||||||
late_bound_in_projection_ty,
|
late_bound_in_projection_ty,
|
||||||
late_bound_in_term,
|
late_bound_in_term,
|
||||||
|br_name| {
|
|br_name| {
|
||||||
struct_span_code_err!(
|
struct_span_code_err!(
|
||||||
tcx.dcx(),
|
tcx.dcx(),
|
||||||
binding.span,
|
constraint.span,
|
||||||
E0582,
|
E0582,
|
||||||
"binding for associated type `{}` references {}, \
|
"binding for associated type `{}` references {}, \
|
||||||
which does not appear in the trait input types",
|
which does not appear in the trait input types",
|
||||||
binding.ident,
|
constraint.ident,
|
||||||
br_name
|
br_name
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -492,12 +494,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
projection_term,
|
projection_term,
|
||||||
term,
|
term,
|
||||||
}),
|
}),
|
||||||
binding.span,
|
constraint.span,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
|
// Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
|
||||||
// to a bound involving a projection: `<T as Iterator>::Item: Debug`.
|
// to a bound involving a projection: `<T as Iterator>::Item: Debug`.
|
||||||
hir::TypeBindingKind::Constraint { bounds: hir_bounds } => {
|
hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => {
|
||||||
// NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into
|
// NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into
|
||||||
// a trait predicate, since we only want to add predicates for the `Self` type.
|
// a trait predicate, since we only want to add predicates for the `Self` type.
|
||||||
if !only_self_bounds.0 {
|
if !only_self_bounds.0 {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
|
self, AssocItemConstraintsNotAllowedHere, ManualImplementation, MissingTypeParams,
|
||||||
ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,
|
ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits,
|
||||||
};
|
};
|
||||||
use crate::fluent_generated as fluent;
|
use crate::fluent_generated as fluent;
|
||||||
|
@ -121,7 +121,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
assoc_kind: ty::AssocKind,
|
assoc_kind: ty::AssocKind,
|
||||||
assoc_name: Ident,
|
assoc_name: Ident,
|
||||||
span: Span,
|
span: Span,
|
||||||
binding: Option<&hir::TypeBinding<'tcx>>,
|
constraint: Option<&hir::AssocItemConstraint<'tcx>>,
|
||||||
) -> ErrorGuaranteed
|
) -> ErrorGuaranteed
|
||||||
where
|
where
|
||||||
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
||||||
|
@ -135,7 +135,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
.find(|item| tcx.hygienic_eq(assoc_name, item.ident(tcx), r.def_id()))
|
.find(|item| tcx.hygienic_eq(assoc_name, item.ident(tcx), r.def_id()))
|
||||||
}) {
|
}) {
|
||||||
return self.complain_about_assoc_kind_mismatch(
|
return self.complain_about_assoc_kind_mismatch(
|
||||||
assoc_item, assoc_kind, assoc_name, span, binding,
|
assoc_item, assoc_kind, assoc_name, span, constraint,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,18 +300,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
assoc_kind: ty::AssocKind,
|
assoc_kind: ty::AssocKind,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
span: Span,
|
span: Span,
|
||||||
binding: Option<&hir::TypeBinding<'tcx>>,
|
constraint: Option<&hir::AssocItemConstraint<'tcx>>,
|
||||||
) -> ErrorGuaranteed {
|
) -> ErrorGuaranteed {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
let bound_on_assoc_const_label = if let ty::AssocKind::Const = assoc_item.kind
|
let bound_on_assoc_const_label = if let ty::AssocKind::Const = assoc_item.kind
|
||||||
&& let Some(binding) = binding
|
&& let Some(constraint) = constraint
|
||||||
&& let hir::TypeBindingKind::Constraint { .. } = binding.kind
|
&& let hir::AssocItemConstraintKind::Bound { .. } = constraint.kind
|
||||||
{
|
{
|
||||||
let lo = if binding.gen_args.span_ext.is_dummy() {
|
let lo = if constraint.gen_args.span_ext.is_dummy() {
|
||||||
ident.span
|
ident.span
|
||||||
} else {
|
} else {
|
||||||
binding.gen_args.span_ext
|
constraint.gen_args.span_ext
|
||||||
};
|
};
|
||||||
Some(lo.between(span.shrink_to_hi()))
|
Some(lo.between(span.shrink_to_hi()))
|
||||||
} else {
|
} else {
|
||||||
|
@ -319,8 +319,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME(associated_const_equality): This has quite a few false positives and negatives.
|
// FIXME(associated_const_equality): This has quite a few false positives and negatives.
|
||||||
let wrap_in_braces_sugg = if let Some(binding) = binding
|
let wrap_in_braces_sugg = if let Some(constraint) = constraint
|
||||||
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind
|
&& let Some(hir_ty) = constraint.ty()
|
||||||
&& let ty = self.lower_ty(hir_ty)
|
&& let ty = self.lower_ty(hir_ty)
|
||||||
&& (ty.is_enum() || ty.references_error())
|
&& (ty.is_enum() || ty.references_error())
|
||||||
&& tcx.features().associated_const_equality
|
&& tcx.features().associated_const_equality
|
||||||
|
@ -333,10 +333,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
// For equality bounds, we want to blame the term (RHS) instead of the item (LHS) since
|
// For equality constraints, we want to blame the term (RHS) instead of the item (LHS) since
|
||||||
// one can argue that that's more “intuitive” to the user.
|
// one can argue that that's more “intuitive” to the user.
|
||||||
let (span, expected_because_label, expected, got) = if let Some(binding) = binding
|
let (span, expected_because_label, expected, got) = if let Some(constraint) = constraint
|
||||||
&& let hir::TypeBindingKind::Equality { term } = binding.kind
|
&& let hir::AssocItemConstraintKind::Equality { term } = constraint.kind
|
||||||
{
|
{
|
||||||
let span = match term {
|
let span = match term {
|
||||||
hir::Term::Ty(ty) => ty.span,
|
hir::Term::Ty(ty) => ty.span,
|
||||||
|
@ -791,8 +791,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let path = poly_trait_ref.trait_ref.path.segments.last()?;
|
let path = poly_trait_ref.trait_ref.path.segments.last()?;
|
||||||
let args = path.args?;
|
let args = path.args?;
|
||||||
|
|
||||||
Some(args.bindings.iter().filter_map(|binding| {
|
Some(args.constraints.iter().filter_map(|constraint| {
|
||||||
let ident = binding.ident;
|
let ident = constraint.ident;
|
||||||
let trait_def = path.res.def_id();
|
let trait_def = path.res.def_id();
|
||||||
let assoc_item = tcx.associated_items(trait_def).find_by_name_and_kind(
|
let assoc_item = tcx.associated_items(trait_def).find_by_name_and_kind(
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -1192,14 +1192,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emits an error regarding forbidden type binding associations
|
/// Emit an error for the given associated item constraint.
|
||||||
pub fn prohibit_assoc_item_binding(
|
pub fn prohibit_assoc_item_constraint(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
binding: &hir::TypeBinding<'_>,
|
constraint: &hir::AssocItemConstraint<'_>,
|
||||||
segment: Option<(DefId, &hir::PathSegment<'_>, Span)>,
|
segment: Option<(DefId, &hir::PathSegment<'_>, Span)>,
|
||||||
) -> ErrorGuaranteed {
|
) -> ErrorGuaranteed {
|
||||||
let mut err = tcx.dcx().create_err(AssocTypeBindingNotAllowed {
|
let mut err = tcx.dcx().create_err(AssocItemConstraintsNotAllowedHere {
|
||||||
span: binding.span,
|
span: constraint.span,
|
||||||
fn_trait_expansion: if let Some((_, segment, span)) = segment
|
fn_trait_expansion: if let Some((_, segment, span)) = segment
|
||||||
&& segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar
|
&& segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar
|
||||||
{
|
{
|
||||||
|
@ -1217,13 +1217,12 @@ pub fn prohibit_assoc_item_binding(
|
||||||
// otherwise suggest the removal of the binding.
|
// otherwise suggest the removal of the binding.
|
||||||
if let Some((def_id, segment, _)) = segment
|
if let Some((def_id, segment, _)) = segment
|
||||||
&& segment.args().parenthesized == hir::GenericArgsParentheses::No
|
&& segment.args().parenthesized == hir::GenericArgsParentheses::No
|
||||||
&& let hir::TypeBindingKind::Equality { term } = binding.kind
|
&& let hir::AssocItemConstraintKind::Equality { term } = constraint.kind
|
||||||
{
|
{
|
||||||
// Suggests removal of the offending binding
|
// Suggests removal of the offending binding
|
||||||
let suggest_removal = |e: &mut Diag<'_>| {
|
let suggest_removal = |e: &mut Diag<'_>| {
|
||||||
let bindings = segment.args().bindings;
|
let constraints = segment.args().constraints;
|
||||||
let args = segment.args().args;
|
let args = segment.args().args;
|
||||||
let binding_span = binding.span;
|
|
||||||
|
|
||||||
// Compute the span to remove based on the position
|
// Compute the span to remove based on the position
|
||||||
// of the binding. We do that as follows:
|
// of the binding. We do that as follows:
|
||||||
|
@ -1236,26 +1235,21 @@ pub fn prohibit_assoc_item_binding(
|
||||||
// the start of the next span or will simply be the
|
// the start of the next span or will simply be the
|
||||||
// span encomassing everything within the generics brackets
|
// span encomassing everything within the generics brackets
|
||||||
|
|
||||||
let Some(binding_index) = bindings.iter().position(|b| b.hir_id == binding.hir_id)
|
let Some(index) = constraints.iter().position(|b| b.hir_id == constraint.hir_id) else {
|
||||||
else {
|
|
||||||
bug!("a type binding exists but its HIR ID not found in generics");
|
bug!("a type binding exists but its HIR ID not found in generics");
|
||||||
};
|
};
|
||||||
|
|
||||||
let preceding_span = if binding_index > 0 {
|
let preceding_span = if index > 0 {
|
||||||
Some(bindings[binding_index - 1].span)
|
Some(constraints[index - 1].span)
|
||||||
} else {
|
} else {
|
||||||
args.last().map(|a| a.span())
|
args.last().map(|a| a.span())
|
||||||
};
|
};
|
||||||
|
|
||||||
let next_span = if binding_index < bindings.len() - 1 {
|
let next_span = constraints.get(index + 1).map(|constraint| constraint.span);
|
||||||
Some(bindings[binding_index + 1].span)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let removal_span = match (preceding_span, next_span) {
|
let removal_span = match (preceding_span, next_span) {
|
||||||
(Some(prec), _) => binding_span.with_lo(prec.hi()),
|
(Some(prec), _) => constraint.span.with_lo(prec.hi()),
|
||||||
(None, Some(next)) => binding_span.with_hi(next.lo()),
|
(None, Some(next)) => constraint.span.with_hi(next.lo()),
|
||||||
(None, None) => {
|
(None, None) => {
|
||||||
let Some(generics_span) = segment.args().span_ext() else {
|
let Some(generics_span) = segment.args().span_ext() else {
|
||||||
bug!("a type binding exists but generic span is empty");
|
bug!("a type binding exists but generic span is empty");
|
||||||
|
@ -1269,7 +1263,7 @@ pub fn prohibit_assoc_item_binding(
|
||||||
if let Ok(suggestion) = tcx.sess.source_map().span_to_snippet(removal_span) {
|
if let Ok(suggestion) = tcx.sess.source_map().span_to_snippet(removal_span) {
|
||||||
e.span_suggestion_verbose(
|
e.span_suggestion_verbose(
|
||||||
removal_span,
|
removal_span,
|
||||||
"consider removing this type binding",
|
"consider removing this associated item binding",
|
||||||
suggestion,
|
suggestion,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
|
@ -1281,7 +1275,7 @@ pub fn prohibit_assoc_item_binding(
|
||||||
let suggest_direct_use = |e: &mut Diag<'_>, sp: Span| {
|
let suggest_direct_use = |e: &mut Diag<'_>, sp: Span| {
|
||||||
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(sp) {
|
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(sp) {
|
||||||
e.span_suggestion_verbose(
|
e.span_suggestion_verbose(
|
||||||
binding.span,
|
constraint.span,
|
||||||
format!("to use `{snippet}` as a generic argument specify it directly"),
|
format!("to use `{snippet}` as a generic argument specify it directly"),
|
||||||
snippet,
|
snippet,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
|
@ -1289,11 +1283,11 @@ pub fn prohibit_assoc_item_binding(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if the type has a generic param with the
|
// Check if the type has a generic param with the same name
|
||||||
// same name as the assoc type name in type binding
|
// as the assoc type name in the associated item binding.
|
||||||
let generics = tcx.generics_of(def_id);
|
let generics = tcx.generics_of(def_id);
|
||||||
let matching_param =
|
let matching_param =
|
||||||
generics.own_params.iter().find(|p| p.name.as_str() == binding.ident.as_str());
|
generics.own_params.iter().find(|p| p.name.as_str() == constraint.ident.as_str());
|
||||||
|
|
||||||
// Now emit the appropriate suggestion
|
// Now emit the appropriate suggestion
|
||||||
if let Some(matching_param) = matching_param {
|
if let Some(matching_param) = matching_param {
|
||||||
|
@ -1322,8 +1316,7 @@ pub(crate) fn fn_trait_to_string(
|
||||||
) -> String {
|
) -> String {
|
||||||
let args = trait_segment
|
let args = trait_segment
|
||||||
.args
|
.args
|
||||||
.as_ref()
|
.and_then(|args| args.args.first())
|
||||||
.and_then(|args| args.args.get(0))
|
|
||||||
.and_then(|arg| match arg {
|
.and_then(|arg| match arg {
|
||||||
hir::GenericArg::Type(ty) => match ty.kind {
|
hir::GenericArg::Type(ty) => match ty.kind {
|
||||||
hir::TyKind::Tup(t) => t
|
hir::TyKind::Tup(t) => t
|
||||||
|
@ -1334,7 +1327,7 @@ pub(crate) fn fn_trait_to_string(
|
||||||
_ => tcx.sess.source_map().span_to_snippet(ty.span),
|
_ => tcx.sess.source_map().span_to_snippet(ty.span),
|
||||||
}
|
}
|
||||||
.map(|s| {
|
.map(|s| {
|
||||||
// `s.empty()` checks to see if the type is the unit tuple, if so we don't want a comma
|
// `is_empty()` checks to see if the type is the unit tuple, if so we don't want a comma
|
||||||
if parenthesized || s.is_empty() { format!("({s})") } else { format!("({s},)") }
|
if parenthesized || s.is_empty() { format!("({s})") } else { format!("({s},)") }
|
||||||
})
|
})
|
||||||
.ok(),
|
.ok(),
|
||||||
|
@ -1344,20 +1337,17 @@ pub(crate) fn fn_trait_to_string(
|
||||||
|
|
||||||
let ret = trait_segment
|
let ret = trait_segment
|
||||||
.args()
|
.args()
|
||||||
.bindings
|
.constraints
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|b| match (b.ident.name == sym::Output, &b.kind) {
|
.find_map(|c| {
|
||||||
(true, hir::TypeBindingKind::Equality { term }) => {
|
if c.ident.name == sym::Output
|
||||||
let span = match term {
|
&& let Some(ty) = c.ty()
|
||||||
hir::Term::Ty(ty) => ty.span,
|
&& ty.span != tcx.hir().span(trait_segment.hir_id)
|
||||||
hir::Term::Const(c) => tcx.hir().span(c.hir_id),
|
{
|
||||||
};
|
tcx.sess.source_map().span_to_snippet(ty.span).ok()
|
||||||
|
} else {
|
||||||
(span != tcx.hir().span(trait_segment.hir_id))
|
None
|
||||||
.then_some(tcx.sess.source_map().span_to_snippet(span).ok())
|
|
||||||
.flatten()
|
|
||||||
}
|
}
|
||||||
_ => None,
|
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| "()".to_string());
|
.unwrap_or_else(|| "()".to_string());
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::IsMethodCall;
|
use super::IsMethodCall;
|
||||||
use crate::hir_ty_lowering::{
|
use crate::hir_ty_lowering::{
|
||||||
errors::prohibit_assoc_item_binding, ExplicitLateBound, GenericArgCountMismatch,
|
errors::prohibit_assoc_item_constraint, ExplicitLateBound, GenericArgCountMismatch,
|
||||||
GenericArgCountResult, GenericArgPosition, GenericArgsLowerer,
|
GenericArgCountResult, GenericArgPosition, GenericArgsLowerer,
|
||||||
};
|
};
|
||||||
use crate::structured_errors::{GenericArgsInfo, StructuredDiag, WrongNumberOfGenericArgs};
|
use crate::structured_errors::{GenericArgsInfo, StructuredDiag, WrongNumberOfGenericArgs};
|
||||||
|
@ -452,9 +452,9 @@ pub(crate) fn check_generic_arg_count(
|
||||||
(gen_pos != GenericArgPosition::Type || seg.infer_args) && !gen_args.has_lifetime_params();
|
(gen_pos != GenericArgPosition::Type || seg.infer_args) && !gen_args.has_lifetime_params();
|
||||||
|
|
||||||
if gen_pos != GenericArgPosition::Type
|
if gen_pos != GenericArgPosition::Type
|
||||||
&& let Some(b) = gen_args.bindings.first()
|
&& let Some(c) = gen_args.constraints.first()
|
||||||
{
|
{
|
||||||
prohibit_assoc_item_binding(tcx, b, None);
|
prohibit_assoc_item_constraint(tcx, c, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let explicit_late_bound =
|
let explicit_late_bound =
|
||||||
|
@ -566,17 +566,19 @@ pub(crate) fn check_generic_arg_count(
|
||||||
|
|
||||||
debug!(?gen_args_info);
|
debug!(?gen_args_info);
|
||||||
|
|
||||||
let reported = WrongNumberOfGenericArgs::new(
|
let reported = gen_args.has_err().unwrap_or_else(|| {
|
||||||
tcx,
|
WrongNumberOfGenericArgs::new(
|
||||||
gen_args_info,
|
tcx,
|
||||||
seg,
|
gen_args_info,
|
||||||
gen_params,
|
seg,
|
||||||
params_offset,
|
gen_params,
|
||||||
gen_args,
|
params_offset,
|
||||||
def_id,
|
gen_args,
|
||||||
)
|
def_id,
|
||||||
.diagnostic()
|
)
|
||||||
.emit_unless(gen_args.has_err());
|
.diagnostic()
|
||||||
|
.emit()
|
||||||
|
});
|
||||||
|
|
||||||
Err(reported)
|
Err(reported)
|
||||||
};
|
};
|
||||||
|
|
|
@ -268,8 +268,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) {
|
fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) {
|
||||||
let mut parents = self.tcx().hir().parent_iter(self_ty.hir_id);
|
let mut parents = self.tcx().hir().parent_iter(self_ty.hir_id);
|
||||||
|
|
||||||
if let Some((_, hir::Node::TypeBinding(binding))) = parents.next()
|
if let Some((_, hir::Node::AssocItemConstraint(constraint))) = parents.next()
|
||||||
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(obj_ty) } = binding.kind
|
&& let Some(obj_ty) = constraint.ty()
|
||||||
{
|
{
|
||||||
if let Some((_, hir::Node::TraitRef(..))) = parents.next()
|
if let Some((_, hir::Node::TraitRef(..))) = parents.next()
|
||||||
&& let Some((_, hir::Node::Ty(ty))) = parents.next()
|
&& let Some((_, hir::Node::Ty(ty))) = parents.next()
|
||||||
|
@ -279,10 +279,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let lo = if binding.gen_args.span_ext.is_dummy() {
|
let lo = if constraint.gen_args.span_ext.is_dummy() {
|
||||||
binding.ident.span
|
constraint.ident.span
|
||||||
} else {
|
} else {
|
||||||
binding.gen_args.span_ext
|
constraint.gen_args.span_ext
|
||||||
};
|
};
|
||||||
let hi = obj_ty.span;
|
let hi = obj_ty.span;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ mod object_safety;
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::collect::HirPlaceholderCollector;
|
use crate::collect::HirPlaceholderCollector;
|
||||||
use crate::errors::{AmbiguousLifetimeBound, WildPatTy};
|
use crate::errors::{AmbiguousLifetimeBound, WildPatTy};
|
||||||
use crate::hir_ty_lowering::errors::{prohibit_assoc_item_binding, GenericsArgsErrExtend};
|
use crate::hir_ty_lowering::errors::{prohibit_assoc_item_constraint, GenericsArgsErrExtend};
|
||||||
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
|
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
|
||||||
use crate::middle::resolve_bound_vars as rbv;
|
use crate::middle::resolve_bound_vars as rbv;
|
||||||
use crate::require_c_abi_if_c_variadic;
|
use crate::require_c_abi_if_c_variadic;
|
||||||
|
@ -324,8 +324,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
None,
|
None,
|
||||||
ty::BoundConstness::NotConst,
|
ty::BoundConstness::NotConst,
|
||||||
);
|
);
|
||||||
if let Some(b) = item_segment.args().bindings.first() {
|
if let Some(c) = item_segment.args().constraints.first() {
|
||||||
prohibit_assoc_item_binding(self.tcx(), b, Some((def_id, item_segment, span)));
|
prohibit_assoc_item_constraint(self.tcx(), c, Some((def_id, item_segment, span)));
|
||||||
}
|
}
|
||||||
args
|
args
|
||||||
}
|
}
|
||||||
|
@ -335,7 +335,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
/// If this is a trait reference, you also need to pass the self type `self_ty`.
|
/// If this is a trait reference, you also need to pass the self type `self_ty`.
|
||||||
/// The lowering process may involve applying defaulted type parameters.
|
/// The lowering process may involve applying defaulted type parameters.
|
||||||
///
|
///
|
||||||
/// Associated item bindings are not handled here!
|
/// Associated item constraints are not handled here! They are either lowered via
|
||||||
|
/// `lower_assoc_item_constraint` or rejected via `prohibit_assoc_item_constraint`.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
///
|
///
|
||||||
|
@ -349,7 +350,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
/// which will have been resolved to a `def_id`
|
/// which will have been resolved to a `def_id`
|
||||||
/// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type
|
/// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type
|
||||||
/// parameters are returned in the `GenericArgsRef`
|
/// parameters are returned in the `GenericArgsRef`
|
||||||
/// 4. Associated type bindings like `Output = u32` are contained in `generic_args.bindings`.
|
/// 4. Associated item constraints like `Output = u32` are contained in `generic_args.constraints`.
|
||||||
///
|
///
|
||||||
/// Note that the type listing given here is *exactly* what the user provided.
|
/// Note that the type listing given here is *exactly* what the user provided.
|
||||||
///
|
///
|
||||||
|
@ -411,8 +412,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
|
|
||||||
// Skip processing if type has no generic parameters.
|
// Skip processing if type has no generic parameters.
|
||||||
// Traits always have `Self` as a generic parameter, which means they will not return early
|
// Traits always have `Self` as a generic parameter, which means they will not return early
|
||||||
// here and so associated type bindings will be handled regardless of whether there are any
|
// here and so associated item constraints will be handled regardless of whether there are
|
||||||
// non-`Self` generic parameters.
|
// any non-`Self` generic parameters.
|
||||||
if generics.is_own_empty() {
|
if generics.is_own_empty() {
|
||||||
return (tcx.mk_args(parent_args), arg_count);
|
return (tcx.mk_args(parent_args), arg_count);
|
||||||
}
|
}
|
||||||
|
@ -621,8 +622,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
None,
|
None,
|
||||||
ty::BoundConstness::NotConst,
|
ty::BoundConstness::NotConst,
|
||||||
);
|
);
|
||||||
if let Some(b) = item_segment.args().bindings.first() {
|
if let Some(c) = item_segment.args().constraints.first() {
|
||||||
prohibit_assoc_item_binding(self.tcx(), b, Some((item_def_id, item_segment, span)));
|
prohibit_assoc_item_constraint(self.tcx(), c, Some((item_def_id, item_segment, span)));
|
||||||
}
|
}
|
||||||
args
|
args
|
||||||
}
|
}
|
||||||
|
@ -654,13 +655,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
///
|
///
|
||||||
/// *Polymorphic* in the sense that it may bind late-bound vars.
|
/// *Polymorphic* in the sense that it may bind late-bound vars.
|
||||||
///
|
///
|
||||||
/// This may generate auxiliary bounds if the trait reference contains associated item bindings.
|
/// This may generate auxiliary bounds iff the trait reference contains associated item constraints.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
///
|
///
|
||||||
/// Given the trait ref `Iterator<Item = u32>` and the self type `Ty`, this will add the
|
/// Given the trait ref `Iterator<Item = u32>` and the self type `Ty`, this will add the
|
||||||
///
|
///
|
||||||
/// 1. *trait predicate* `<Ty as Iterator>` (known as `Foo: Iterator` in surface syntax) and the
|
/// 1. *trait predicate* `<Ty as Iterator>` (known as `Ty: Iterator` in the surface syntax) and the
|
||||||
/// 2. *projection predicate* `<Ty as Iterator>::Item = u32`
|
/// 2. *projection predicate* `<Ty as Iterator>::Item = u32`
|
||||||
///
|
///
|
||||||
/// to `bounds`.
|
/// to `bounds`.
|
||||||
|
@ -714,27 +715,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
debug!(?poly_trait_ref);
|
debug!(?poly_trait_ref);
|
||||||
bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
|
bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
|
||||||
|
|
||||||
let mut dup_bindings = FxIndexMap::default();
|
let mut dup_constraints = FxIndexMap::default();
|
||||||
for binding in trait_segment.args().bindings {
|
for constraint in trait_segment.args().constraints {
|
||||||
// Don't register additional associated type bounds for negative bounds,
|
// Don't register any associated item constraints for negative bounds,
|
||||||
// since we should have emitten an error for them earlier, and they will
|
// since we should have emitted an error for them earlier, and they
|
||||||
// not be well-formed!
|
// would not be well-formed!
|
||||||
if polarity != ty::PredicatePolarity::Positive {
|
if polarity != ty::PredicatePolarity::Positive {
|
||||||
assert!(
|
assert!(
|
||||||
self.tcx().dcx().has_errors().is_some(),
|
self.tcx().dcx().has_errors().is_some(),
|
||||||
"negative trait bounds should not have bindings",
|
"negative trait bounds should not have assoc item constraints",
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify type to assert that error was already reported in `Err` case.
|
// Specify type to assert that error was already reported in `Err` case.
|
||||||
let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_binding(
|
let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_constraint(
|
||||||
trait_ref.hir_ref_id,
|
trait_ref.hir_ref_id,
|
||||||
poly_trait_ref,
|
poly_trait_ref,
|
||||||
binding,
|
constraint,
|
||||||
bounds,
|
bounds,
|
||||||
&mut dup_bindings,
|
&mut dup_constraints,
|
||||||
binding.span,
|
constraint.span,
|
||||||
only_self_bounds,
|
only_self_bounds,
|
||||||
);
|
);
|
||||||
// Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
|
// Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
|
||||||
|
@ -766,8 +767,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
Some(self_ty),
|
Some(self_ty),
|
||||||
constness,
|
constness,
|
||||||
);
|
);
|
||||||
if let Some(b) = trait_segment.args().bindings.first() {
|
if let Some(c) = trait_segment.args().constraints.first() {
|
||||||
prohibit_assoc_item_binding(self.tcx(), b, Some((trait_def_id, trait_segment, span)));
|
prohibit_assoc_item_constraint(
|
||||||
|
self.tcx(),
|
||||||
|
c,
|
||||||
|
Some((trait_def_id, trait_segment, span)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
ty::TraitRef::new(self.tcx(), trait_def_id, generic_args)
|
ty::TraitRef::new(self.tcx(), trait_def_id, generic_args)
|
||||||
}
|
}
|
||||||
|
@ -849,7 +854,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
///
|
///
|
||||||
/// This fails if there is no such bound in the list of candidates or if there are multiple
|
/// This fails if there is no such bound in the list of candidates or if there are multiple
|
||||||
/// candidates in which case it reports ambiguity.
|
/// candidates in which case it reports ambiguity.
|
||||||
#[instrument(level = "debug", skip(self, all_candidates, ty_param_name, binding), ret)]
|
#[instrument(level = "debug", skip(self, all_candidates, ty_param_name, constraint), ret)]
|
||||||
fn probe_single_bound_for_assoc_item<I>(
|
fn probe_single_bound_for_assoc_item<I>(
|
||||||
&self,
|
&self,
|
||||||
all_candidates: impl Fn() -> I,
|
all_candidates: impl Fn() -> I,
|
||||||
|
@ -858,7 +863,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
assoc_kind: ty::AssocKind,
|
assoc_kind: ty::AssocKind,
|
||||||
assoc_name: Ident,
|
assoc_name: Ident,
|
||||||
span: Span,
|
span: Span,
|
||||||
binding: Option<&hir::TypeBinding<'tcx>>,
|
constraint: Option<&hir::AssocItemConstraint<'tcx>>,
|
||||||
) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
|
) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
|
||||||
where
|
where
|
||||||
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
||||||
|
@ -877,7 +882,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
assoc_kind,
|
assoc_kind,
|
||||||
assoc_name,
|
assoc_name,
|
||||||
span,
|
span,
|
||||||
binding,
|
constraint,
|
||||||
);
|
);
|
||||||
self.set_tainted_by_errors(reported);
|
self.set_tainted_by_errors(reported);
|
||||||
return Err(reported);
|
return Err(reported);
|
||||||
|
@ -897,8 +902,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
});
|
});
|
||||||
// Provide a more specific error code index entry for equality bindings.
|
// Provide a more specific error code index entry for equality bindings.
|
||||||
err.code(
|
err.code(
|
||||||
if let Some(binding) = binding
|
if let Some(constraint) = constraint
|
||||||
&& let hir::TypeBindingKind::Equality { .. } = binding.kind
|
&& let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind
|
||||||
{
|
{
|
||||||
E0222
|
E0222
|
||||||
} else {
|
} else {
|
||||||
|
@ -906,7 +911,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// FIXME(#97583): Resugar equality bounds to type/const bindings.
|
// FIXME(#97583): Print associated item bindings properly (i.e., not as equality predicates!).
|
||||||
// FIXME: Turn this into a structured, translateable & more actionable suggestion.
|
// FIXME: Turn this into a structured, translateable & more actionable suggestion.
|
||||||
let mut where_bounds = vec![];
|
let mut where_bounds = vec![];
|
||||||
for bound in [bound, bound2].into_iter().chain(matching_candidates) {
|
for bound in [bound, bound2].into_iter().chain(matching_candidates) {
|
||||||
|
@ -921,9 +926,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
bound_span,
|
bound_span,
|
||||||
format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),),
|
format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),),
|
||||||
);
|
);
|
||||||
if let Some(binding) = binding {
|
if let Some(constraint) = constraint {
|
||||||
match binding.kind {
|
match constraint.kind {
|
||||||
hir::TypeBindingKind::Equality { term } => {
|
hir::AssocItemConstraintKind::Equality { term } => {
|
||||||
let term: ty::Term<'_> = match term {
|
let term: ty::Term<'_> = match term {
|
||||||
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
|
hir::Term::Ty(ty) => self.lower_ty(ty).into(),
|
||||||
hir::Term::Const(ct) => {
|
hir::Term::Const(ct) => {
|
||||||
|
@ -937,7 +942,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
// FIXME: Provide a suggestion.
|
// FIXME: Provide a suggestion.
|
||||||
hir::TypeBindingKind::Constraint { bounds: _ } => {}
|
hir::AssocItemConstraintKind::Bound { bounds: _ } => {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
|
@ -1545,8 +1550,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
|
|
||||||
for segment in segments {
|
for segment in segments {
|
||||||
// Only emit the first error to avoid overloading the user with error messages.
|
// Only emit the first error to avoid overloading the user with error messages.
|
||||||
if let Some(b) = segment.args().bindings.first() {
|
if let Some(c) = segment.args().constraints.first() {
|
||||||
return Err(prohibit_assoc_item_binding(self.tcx(), b, None));
|
return Err(prohibit_assoc_item_constraint(self.tcx(), c, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -489,7 +489,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||||
.in_definition_order()
|
.in_definition_order()
|
||||||
.filter(|item| item.kind == AssocKind::Type)
|
.filter(|item| item.kind == AssocKind::Type)
|
||||||
.filter(|item| {
|
.filter(|item| {
|
||||||
!self.gen_args.bindings.iter().any(|binding| binding.ident.name == item.name)
|
!self
|
||||||
|
.gen_args
|
||||||
|
.constraints
|
||||||
|
.iter()
|
||||||
|
.any(|constraint| constraint.ident.name == item.name)
|
||||||
})
|
})
|
||||||
.map(|item| item.name.to_ident_string())
|
.map(|item| item.name.to_ident_string())
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -679,11 +683,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||||
(last_lt.span().shrink_to_hi(), false)
|
(last_lt.span().shrink_to_hi(), false)
|
||||||
};
|
};
|
||||||
let has_non_lt_args = self.num_provided_type_or_const_args() != 0;
|
let has_non_lt_args = self.num_provided_type_or_const_args() != 0;
|
||||||
let has_bindings = !self.gen_args.bindings.is_empty();
|
let has_constraints = !self.gen_args.constraints.is_empty();
|
||||||
|
|
||||||
let sugg_prefix = if is_first { "" } else { ", " };
|
let sugg_prefix = if is_first { "" } else { ", " };
|
||||||
let sugg_suffix =
|
let sugg_suffix =
|
||||||
if is_first && (has_non_lt_args || has_bindings) { ", " } else { "" };
|
if is_first && (has_non_lt_args || has_constraints) { ", " } else { "" };
|
||||||
|
|
||||||
let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
|
let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
|
||||||
debug!("sugg: {:?}", sugg);
|
debug!("sugg: {:?}", sugg);
|
||||||
|
@ -741,7 +745,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||||
|
|
||||||
let sugg_prefix = if is_first { "" } else { ", " };
|
let sugg_prefix = if is_first { "" } else { ", " };
|
||||||
let sugg_suffix =
|
let sugg_suffix =
|
||||||
if is_first && !self.gen_args.bindings.is_empty() { ", " } else { "" };
|
if is_first && !self.gen_args.constraints.is_empty() { ", " } else { "" };
|
||||||
|
|
||||||
let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
|
let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}");
|
||||||
debug!("sugg: {:?}", sugg);
|
debug!("sugg: {:?}", sugg);
|
||||||
|
|
|
@ -90,7 +90,7 @@ impl<'a> State<'a> {
|
||||||
Node::Stmt(a) => self.print_stmt(a),
|
Node::Stmt(a) => self.print_stmt(a),
|
||||||
Node::PathSegment(a) => self.print_path_segment(a),
|
Node::PathSegment(a) => self.print_path_segment(a),
|
||||||
Node::Ty(a) => self.print_type(a),
|
Node::Ty(a) => self.print_type(a),
|
||||||
Node::TypeBinding(a) => self.print_type_binding(a),
|
Node::AssocItemConstraint(a) => self.print_assoc_item_constraint(a),
|
||||||
Node::TraitRef(a) => self.print_trait_ref(a),
|
Node::TraitRef(a) => self.print_trait_ref(a),
|
||||||
Node::Pat(a) => self.print_pat(a),
|
Node::Pat(a) => self.print_pat(a),
|
||||||
Node::PatField(a) => self.print_patfield(a),
|
Node::PatField(a) => self.print_patfield(a),
|
||||||
|
@ -1136,7 +1136,7 @@ impl<'a> State<'a> {
|
||||||
self.print_ident(segment.ident);
|
self.print_ident(segment.ident);
|
||||||
|
|
||||||
let generic_args = segment.args();
|
let generic_args = segment.args();
|
||||||
if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
|
if !generic_args.args.is_empty() || !generic_args.constraints.is_empty() {
|
||||||
self.print_generic_args(generic_args, true);
|
self.print_generic_args(generic_args, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1677,9 +1677,9 @@ impl<'a> State<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for binding in generic_args.bindings {
|
for constraint in generic_args.constraints {
|
||||||
start_or_comma(self);
|
start_or_comma(self);
|
||||||
self.print_type_binding(binding);
|
self.print_assoc_item_constraint(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !empty.get() {
|
if !empty.get() {
|
||||||
|
@ -1687,13 +1687,15 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::GenericArgsParentheses::ParenSugar => {
|
hir::GenericArgsParentheses::ParenSugar => {
|
||||||
|
let (inputs, output) = generic_args.paren_sugar_inputs_output().unwrap();
|
||||||
|
|
||||||
self.word("(");
|
self.word("(");
|
||||||
self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(ty));
|
self.commasep(Inconsistent, inputs, |s, ty| s.print_type(ty));
|
||||||
self.word(")");
|
self.word(")");
|
||||||
|
|
||||||
self.space_if_not_bol();
|
self.space_if_not_bol();
|
||||||
self.word_space("->");
|
self.word_space("->");
|
||||||
self.print_type(generic_args.bindings[0].ty());
|
self.print_type(output);
|
||||||
}
|
}
|
||||||
hir::GenericArgsParentheses::ReturnTypeNotation => {
|
hir::GenericArgsParentheses::ReturnTypeNotation => {
|
||||||
self.word("(..)");
|
self.word("(..)");
|
||||||
|
@ -1701,19 +1703,19 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) {
|
fn print_assoc_item_constraint(&mut self, constraint: &hir::AssocItemConstraint<'_>) {
|
||||||
self.print_ident(binding.ident);
|
self.print_ident(constraint.ident);
|
||||||
self.print_generic_args(binding.gen_args, false);
|
self.print_generic_args(constraint.gen_args, false);
|
||||||
self.space();
|
self.space();
|
||||||
match binding.kind {
|
match constraint.kind {
|
||||||
hir::TypeBindingKind::Equality { ref term } => {
|
hir::AssocItemConstraintKind::Equality { ref term } => {
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
match term {
|
match term {
|
||||||
Term::Ty(ty) => self.print_type(ty),
|
Term::Ty(ty) => self.print_type(ty),
|
||||||
Term::Const(ref c) => self.print_anon_const(c),
|
Term::Const(ref c) => self.print_anon_const(c),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::TypeBindingKind::Constraint { bounds } => {
|
hir::AssocItemConstraintKind::Bound { bounds } => {
|
||||||
self.print_bounds(":", bounds);
|
self.print_bounds(":", bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -848,19 +848,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
&& let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds
|
&& let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds
|
||||||
&& let Some(hir::PathSegment { args: Some(generic_args), .. }) =
|
&& let Some(hir::PathSegment { args: Some(generic_args), .. }) =
|
||||||
trait_ref.trait_ref.path.segments.last()
|
trait_ref.trait_ref.path.segments.last()
|
||||||
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
|
&& let [constraint] = generic_args.constraints
|
||||||
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } =
|
&& let Some(ty) = constraint.ty()
|
||||||
ty_binding.kind
|
|
||||||
{
|
{
|
||||||
// Check if async function's return type was omitted.
|
// Check if async function's return type was omitted.
|
||||||
// Don't emit suggestions if the found type is `impl Future<...>`.
|
// Don't emit suggestions if the found type is `impl Future<...>`.
|
||||||
debug!(?found);
|
debug!(?found);
|
||||||
if found.is_suggestable(self.tcx, false) {
|
if found.is_suggestable(self.tcx, false) {
|
||||||
if term.span.is_empty() {
|
if ty.span.is_empty() {
|
||||||
err.subdiagnostic(
|
err.subdiagnostic(
|
||||||
self.dcx(),
|
self.dcx(),
|
||||||
errors::AddReturnTypeSuggestion::Add {
|
errors::AddReturnTypeSuggestion::Add {
|
||||||
span: term.span,
|
span: ty.span,
|
||||||
found: found.to_string(),
|
found: found.to_string(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -868,10 +867,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
err.subdiagnostic(
|
err.subdiagnostic(
|
||||||
self.dcx(),
|
self.dcx(),
|
||||||
errors::ExpectedReturnTypeLabel::Other {
|
errors::ExpectedReturnTypeLabel::Other { span: ty.span, expected },
|
||||||
span: term.span,
|
|
||||||
expected,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -901,7 +901,7 @@ impl<'hir> Map<'hir> {
|
||||||
.with_hi(seg.args.map_or_else(|| ident_span.hi(), |args| args.span_ext.hi()))
|
.with_hi(seg.args.map_or_else(|| ident_span.hi(), |args| args.span_ext.hi()))
|
||||||
}
|
}
|
||||||
Node::Ty(ty) => ty.span,
|
Node::Ty(ty) => ty.span,
|
||||||
Node::TypeBinding(tb) => tb.span,
|
Node::AssocItemConstraint(constraint) => constraint.span,
|
||||||
Node::TraitRef(tr) => tr.path.span,
|
Node::TraitRef(tr) => tr.path.span,
|
||||||
Node::Pat(pat) => pat.span,
|
Node::Pat(pat) => pat.span,
|
||||||
Node::PatField(field) => field.span,
|
Node::PatField(field) => field.span,
|
||||||
|
@ -1167,7 +1167,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
|
||||||
Node::Stmt(_) => node_str("stmt"),
|
Node::Stmt(_) => node_str("stmt"),
|
||||||
Node::PathSegment(_) => node_str("path segment"),
|
Node::PathSegment(_) => node_str("path segment"),
|
||||||
Node::Ty(_) => node_str("type"),
|
Node::Ty(_) => node_str("type"),
|
||||||
Node::TypeBinding(_) => node_str("type binding"),
|
Node::AssocItemConstraint(_) => node_str("assoc item constraint"),
|
||||||
Node::TraitRef(_) => node_str("trait ref"),
|
Node::TraitRef(_) => node_str("trait ref"),
|
||||||
Node::Pat(_) => node_str("pat"),
|
Node::Pat(_) => node_str("pat"),
|
||||||
Node::PatField(_) => node_str("pattern field"),
|
Node::PatField(_) => node_str("pattern field"),
|
||||||
|
|
|
@ -7,8 +7,8 @@ use ast::token::IdentIsRaw;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
||||||
use rustc_ast::{
|
use rustc_ast::{
|
||||||
self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocConstraint,
|
self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocItemConstraint,
|
||||||
AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
|
AssocItemConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
|
||||||
Path, PathSegment, QSelf,
|
Path, PathSegment, QSelf,
|
||||||
};
|
};
|
||||||
use rustc_errors::{Applicability, Diag, PResult};
|
use rustc_errors::{Applicability, Diag, PResult};
|
||||||
|
@ -720,10 +720,7 @@ impl<'a> Parser<'a> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let kind = if self.eat(&token::Colon) {
|
let kind = if self.eat(&token::Colon) {
|
||||||
// Parse associated type constraint bound.
|
AssocItemConstraintKind::Bound { bounds: self.parse_generic_bounds()? }
|
||||||
|
|
||||||
let bounds = self.parse_generic_bounds()?;
|
|
||||||
AssocConstraintKind::Bound { bounds }
|
|
||||||
} else if self.eat(&token::Eq) {
|
} else if self.eat(&token::Eq) {
|
||||||
self.parse_assoc_equality_term(
|
self.parse_assoc_equality_term(
|
||||||
ident,
|
ident,
|
||||||
|
@ -735,17 +732,17 @@ impl<'a> Parser<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let span = lo.to(self.prev_token.span);
|
let span = lo.to(self.prev_token.span);
|
||||||
// Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
|
|
||||||
if let AssocConstraintKind::Bound { .. } = kind {
|
if let AssocItemConstraintKind::Bound { .. } = kind
|
||||||
if let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args
|
&& let Some(ast::GenericArgs::Parenthesized(args)) = &gen_args
|
||||||
&& args.inputs.is_empty()
|
&& args.inputs.is_empty()
|
||||||
&& matches!(args.output, ast::FnRetTy::Default(..))
|
&& let ast::FnRetTy::Default(..) = args.output
|
||||||
{
|
{
|
||||||
self.psess.gated_spans.gate(sym::return_type_notation, span);
|
self.psess.gated_spans.gate(sym::return_type_notation, span);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let constraint =
|
let constraint =
|
||||||
AssocConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span };
|
AssocItemConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span };
|
||||||
Ok(Some(AngleBracketedArg::Constraint(constraint)))
|
Ok(Some(AngleBracketedArg::Constraint(constraint)))
|
||||||
} else {
|
} else {
|
||||||
// we only want to suggest `:` and `=` in contexts where the previous token
|
// we only want to suggest `:` and `=` in contexts where the previous token
|
||||||
|
@ -772,7 +769,7 @@ impl<'a> Parser<'a> {
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
gen_args: Option<&GenericArgs>,
|
gen_args: Option<&GenericArgs>,
|
||||||
eq: Span,
|
eq: Span,
|
||||||
) -> PResult<'a, AssocConstraintKind> {
|
) -> PResult<'a, AssocItemConstraintKind> {
|
||||||
let arg = self.parse_generic_arg(None)?;
|
let arg = self.parse_generic_arg(None)?;
|
||||||
let span = ident.span.to(self.prev_token.span);
|
let span = ident.span.to(self.prev_token.span);
|
||||||
let term = match arg {
|
let term = match arg {
|
||||||
|
@ -820,7 +817,7 @@ impl<'a> Parser<'a> {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(AssocConstraintKind::Equality { term })
|
Ok(AssocItemConstraintKind::Equality { term })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We do not permit arbitrary expressions as const arguments. They must be one of:
|
/// We do not permit arbitrary expressions as const arguments. They must be one of:
|
||||||
|
@ -941,7 +938,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a arg inside of generics, we try to destructure it as if it were the LHS in
|
/// Given a arg inside of generics, we try to destructure it as if it were the LHS in
|
||||||
/// `LHS = ...`, i.e. an associated type binding.
|
/// `LHS = ...`, i.e. an associated item binding.
|
||||||
/// This returns a bool indicating if there are any `for<'a, 'b>` binder args, the
|
/// This returns a bool indicating if there are any `for<'a, 'b>` binder args, the
|
||||||
/// identifier, and any GAT arguments.
|
/// identifier, and any GAT arguments.
|
||||||
fn get_ident_from_generic_arg(
|
fn get_ident_from_generic_arg(
|
||||||
|
|
|
@ -477,9 +477,9 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
hir_visit::walk_generic_args(self, ga)
|
hir_visit::walk_generic_args(self, ga)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_assoc_type_binding(&mut self, type_binding: &'v hir::TypeBinding<'v>) {
|
fn visit_assoc_item_constraint(&mut self, constraint: &'v hir::AssocItemConstraint<'v>) {
|
||||||
self.record("TypeBinding", Id::Node(type_binding.hir_id), type_binding);
|
self.record("AssocItemConstraint", Id::Node(constraint.hir_id), constraint);
|
||||||
hir_visit::walk_assoc_type_binding(self, type_binding)
|
hir_visit::walk_assoc_item_constraint(self, constraint)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
|
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
|
||||||
|
@ -688,7 +688,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
ast_visit::walk_path_segment(self, path_segment)
|
ast_visit::walk_path_segment(self, path_segment)
|
||||||
}
|
}
|
||||||
|
|
||||||
// `GenericArgs` has one inline use (in `ast::AssocConstraint::gen_args`) and one
|
// `GenericArgs` has one inline use (in `ast::AssocItemConstraint::gen_args`) and one
|
||||||
// non-inline use (in `ast::PathSegment::args`). The latter case is more
|
// non-inline use (in `ast::PathSegment::args`). The latter case is more
|
||||||
// common, so we implement `visit_generic_args` and tolerate the double
|
// common, so we implement `visit_generic_args` and tolerate the double
|
||||||
// counting in the former case.
|
// counting in the former case.
|
||||||
|
|
|
@ -1148,7 +1148,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||||
self.diag_metadata.currently_processing_generic_args = prev;
|
self.diag_metadata.currently_processing_generic_args = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_assoc_constraint(&mut self, constraint: &'ast AssocConstraint) {
|
fn visit_assoc_item_constraint(&mut self, constraint: &'ast AssocItemConstraint) {
|
||||||
self.visit_ident(constraint.ident);
|
self.visit_ident(constraint.ident);
|
||||||
if let Some(ref gen_args) = constraint.gen_args {
|
if let Some(ref gen_args) = constraint.gen_args {
|
||||||
// Forbid anonymous lifetimes in GAT parameters until proper semantics are decided.
|
// Forbid anonymous lifetimes in GAT parameters until proper semantics are decided.
|
||||||
|
@ -1157,13 +1157,13 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
match constraint.kind {
|
match constraint.kind {
|
||||||
AssocConstraintKind::Equality { ref term } => match term {
|
AssocItemConstraintKind::Equality { ref term } => match term {
|
||||||
Term::Ty(ty) => self.visit_ty(ty),
|
Term::Ty(ty) => self.visit_ty(ty),
|
||||||
Term::Const(c) => {
|
Term::Const(c) => {
|
||||||
self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))
|
self.resolve_anon_const(c, AnonConstKind::ConstArg(IsRepeatExpr::No))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
AssocConstraintKind::Bound { ref bounds } => {
|
AssocItemConstraintKind::Bound { ref bounds } => {
|
||||||
self.record_lifetime_params_for_impl_trait(constraint.id);
|
self.record_lifetime_params_for_impl_trait(constraint.id);
|
||||||
walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);
|
walk_list!(self, visit_param_bound, bounds, BoundKind::Bound);
|
||||||
}
|
}
|
||||||
|
|
|
@ -508,7 +508,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
|
||||||
let ast::AngleBracketedArg::Constraint(constraint) = param else {
|
let ast::AngleBracketedArg::Constraint(constraint) = param else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let ast::AssocConstraintKind::Bound { bounds } = &constraint.kind else {
|
let ast::AssocItemConstraintKind::Bound { bounds } = &constraint.kind else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
|
@ -3390,11 +3390,11 @@ fn mk_where_bound_predicate(
|
||||||
};
|
};
|
||||||
let mut segments = ThinVec::from(preceding);
|
let mut segments = ThinVec::from(preceding);
|
||||||
|
|
||||||
let added_constraint = ast::AngleBracketedArg::Constraint(ast::AssocConstraint {
|
let added_constraint = ast::AngleBracketedArg::Constraint(ast::AssocItemConstraint {
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
ident: last.ident,
|
ident: last.ident,
|
||||||
gen_args: None,
|
gen_args: None,
|
||||||
kind: ast::AssocConstraintKind::Equality {
|
kind: ast::AssocItemConstraintKind::Equality {
|
||||||
term: ast::Term::Ty(ast::ptr::P(ast::Ty {
|
term: ast::Term::Ty(ast::ptr::P(ast::Ty {
|
||||||
kind: ast::TyKind::Path(None, poly_trait_ref.trait_ref.path.clone()),
|
kind: ast::TyKind::Path(None, poly_trait_ref.trait_ref.path.clone()),
|
||||||
id: DUMMY_NODE_ID,
|
id: DUMMY_NODE_ID,
|
||||||
|
|
|
@ -450,7 +450,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When after several dereferencing, the reference satisfies the trait
|
/// When after several dereferencing, the reference satisfies the trait
|
||||||
/// binding. This function provides dereference suggestion for this
|
/// bound. This function provides dereference suggestion for this
|
||||||
/// specific situation.
|
/// specific situation.
|
||||||
fn suggest_dereferences(
|
fn suggest_dereferences(
|
||||||
&self,
|
&self,
|
||||||
|
@ -777,7 +777,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We tried to apply the bound to an `fn` or closure. Check whether calling it would
|
/// We tried to apply the bound to an `fn` or closure. Check whether calling it would
|
||||||
/// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling
|
/// evaluate to a type that *would* satisfy the trait bound. If it would, suggest calling
|
||||||
/// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`.
|
/// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`.
|
||||||
fn suggest_fn_call(
|
fn suggest_fn_call(
|
||||||
&self,
|
&self,
|
||||||
|
@ -1241,7 +1241,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
|
|
||||||
let param_env = obligation.param_env;
|
let param_env = obligation.param_env;
|
||||||
|
|
||||||
// Try to apply the original trait binding obligation by borrowing.
|
// Try to apply the original trait bound by borrowing.
|
||||||
let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>,
|
let mut try_borrowing = |old_pred: ty::PolyTraitPredicate<'tcx>,
|
||||||
blacklist: &[DefId]|
|
blacklist: &[DefId]|
|
||||||
-> bool {
|
-> bool {
|
||||||
|
@ -4908,14 +4908,12 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
|
||||||
// `async fn` should always lower to a single bound... but don't ICE.
|
// `async fn` should always lower to a single bound... but don't ICE.
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Some(hir::PathSegment { args: Some(generics), .. }) =
|
let Some(hir::PathSegment { args: Some(args), .. }) = trait_ref.trait_ref.path.segments.last()
|
||||||
trait_ref.trait_ref.path.segments.last()
|
|
||||||
else {
|
else {
|
||||||
// desugaring to a single path segment for `Future<...>`.
|
// desugaring to a single path segment for `Future<...>`.
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) =
|
let Some(future_output_ty) = args.constraints.first().and_then(|constraint| constraint.ty())
|
||||||
generics.bindings.get(0).map(|binding| binding.kind)
|
|
||||||
else {
|
else {
|
||||||
// Also should never happen.
|
// Also should never happen.
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -11,7 +11,7 @@ use thin_vec::ThinVec;
|
||||||
|
|
||||||
use crate::clean::{self, simplify, Lifetime};
|
use crate::clean::{self, simplify, Lifetime};
|
||||||
use crate::clean::{
|
use crate::clean::{
|
||||||
clean_generic_param_def, clean_middle_ty, clean_predicate, clean_trait_ref_with_bindings,
|
clean_generic_param_def, clean_middle_ty, clean_predicate, clean_trait_ref_with_constraints,
|
||||||
clean_ty_generics,
|
clean_ty_generics,
|
||||||
};
|
};
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
|
@ -121,7 +121,7 @@ fn synthesize_auto_trait_impl<'tcx>(
|
||||||
kind: Box::new(clean::ImplItem(Box::new(clean::Impl {
|
kind: Box::new(clean::ImplItem(Box::new(clean::Impl {
|
||||||
safety: hir::Safety::Safe,
|
safety: hir::Safety::Safe,
|
||||||
generics,
|
generics,
|
||||||
trait_: Some(clean_trait_ref_with_bindings(cx, trait_ref, ThinVec::new())),
|
trait_: Some(clean_trait_ref_with_constraints(cx, trait_ref, ThinVec::new())),
|
||||||
for_: clean_middle_ty(ty::Binder::dummy(ty), cx, None, None),
|
for_: clean_middle_ty(ty::Binder::dummy(ty), cx, None, None),
|
||||||
items: Vec::new(),
|
items: Vec::new(),
|
||||||
polarity,
|
polarity,
|
||||||
|
|
|
@ -10,7 +10,7 @@ use thin_vec::ThinVec;
|
||||||
|
|
||||||
use crate::clean;
|
use crate::clean;
|
||||||
use crate::clean::{
|
use crate::clean::{
|
||||||
clean_middle_assoc_item, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty_generics,
|
clean_middle_assoc_item, clean_middle_ty, clean_trait_ref_with_constraints, clean_ty_generics,
|
||||||
};
|
};
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ pub(crate) fn synthesize_blanket_impls(
|
||||||
),
|
),
|
||||||
// FIXME(eddyb) compute both `trait_` and `for_` from
|
// FIXME(eddyb) compute both `trait_` and `for_` from
|
||||||
// the post-inference `trait_ref`, as it's more accurate.
|
// the post-inference `trait_ref`, as it's more accurate.
|
||||||
trait_: Some(clean_trait_ref_with_bindings(
|
trait_: Some(clean_trait_ref_with_constraints(
|
||||||
cx,
|
cx,
|
||||||
ty::Binder::dummy(trait_ref.instantiate_identity()),
|
ty::Binder::dummy(trait_ref.instantiate_identity()),
|
||||||
ThinVec::new(),
|
ThinVec::new(),
|
||||||
|
|
|
@ -20,7 +20,7 @@ use rustc_span::symbol::{kw, sym, Symbol};
|
||||||
|
|
||||||
use crate::clean::{
|
use crate::clean::{
|
||||||
self, clean_bound_vars, clean_generics, clean_impl_item, clean_middle_assoc_item,
|
self, clean_bound_vars, clean_generics, clean_impl_item, clean_middle_assoc_item,
|
||||||
clean_middle_field, clean_middle_ty, clean_poly_fn_sig, clean_trait_ref_with_bindings,
|
clean_middle_field, clean_middle_ty, clean_poly_fn_sig, clean_trait_ref_with_constraints,
|
||||||
clean_ty, clean_ty_alias_inner_type, clean_ty_generics, clean_variant_def, utils, Attributes,
|
clean_ty, clean_ty_alias_inner_type, clean_ty_generics, clean_variant_def, utils, Attributes,
|
||||||
AttributesExt, ImplKind, ItemId, Type,
|
AttributesExt, ImplKind, ItemId, Type,
|
||||||
};
|
};
|
||||||
|
@ -566,7 +566,7 @@ pub(crate) fn build_impl(
|
||||||
};
|
};
|
||||||
let polarity = tcx.impl_polarity(did);
|
let polarity = tcx.impl_polarity(did);
|
||||||
let trait_ = associated_trait
|
let trait_ = associated_trait
|
||||||
.map(|t| clean_trait_ref_with_bindings(cx, ty::Binder::dummy(t), ThinVec::new()));
|
.map(|t| clean_trait_ref_with_constraints(cx, ty::Binder::dummy(t), ThinVec::new()));
|
||||||
if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
|
if trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() {
|
||||||
super::build_deref_target_impls(cx, &trait_items, ret);
|
super::build_deref_target_impls(cx, &trait_items, ret);
|
||||||
}
|
}
|
||||||
|
@ -688,7 +688,7 @@ fn build_module_items(
|
||||||
name: prim_ty.as_sym(),
|
name: prim_ty.as_sym(),
|
||||||
args: clean::GenericArgs::AngleBracketed {
|
args: clean::GenericArgs::AngleBracketed {
|
||||||
args: Default::default(),
|
args: Default::default(),
|
||||||
bindings: ThinVec::new(),
|
constraints: ThinVec::new(),
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
|
|
@ -231,10 +231,10 @@ fn clean_generic_bound<'tcx>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
|
pub(crate) fn clean_trait_ref_with_constraints<'tcx>(
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
bindings: ThinVec<TypeBinding>,
|
constraints: ThinVec<AssocItemConstraint>,
|
||||||
) -> Path {
|
) -> Path {
|
||||||
let kind = cx.tcx.def_kind(trait_ref.def_id()).into();
|
let kind = cx.tcx.def_kind(trait_ref.def_id()).into();
|
||||||
if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) {
|
if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) {
|
||||||
|
@ -245,7 +245,7 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
|
||||||
cx,
|
cx,
|
||||||
trait_ref.def_id(),
|
trait_ref.def_id(),
|
||||||
true,
|
true,
|
||||||
bindings,
|
constraints,
|
||||||
trait_ref.map_bound(|tr| tr.args),
|
trait_ref.map_bound(|tr| tr.args),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -254,14 +254,14 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>(
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_poly_trait_ref_with_bindings<'tcx>(
|
fn clean_poly_trait_ref_with_constraints<'tcx>(
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
poly_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
bindings: ThinVec<TypeBinding>,
|
constraints: ThinVec<AssocItemConstraint>,
|
||||||
) -> GenericBound {
|
) -> GenericBound {
|
||||||
GenericBound::TraitBound(
|
GenericBound::TraitBound(
|
||||||
PolyTrait {
|
PolyTrait {
|
||||||
trait_: clean_trait_ref_with_bindings(cx, poly_trait_ref, bindings),
|
trait_: clean_trait_ref_with_constraints(cx, poly_trait_ref, constraints),
|
||||||
generic_params: clean_bound_vars(poly_trait_ref.bound_vars()),
|
generic_params: clean_bound_vars(poly_trait_ref.bound_vars()),
|
||||||
},
|
},
|
||||||
hir::TraitBoundModifier::None,
|
hir::TraitBoundModifier::None,
|
||||||
|
@ -395,7 +395,7 @@ fn clean_poly_trait_predicate<'tcx>(
|
||||||
let poly_trait_ref = pred.map_bound(|pred| pred.trait_ref);
|
let poly_trait_ref = pred.map_bound(|pred| pred.trait_ref);
|
||||||
Some(WherePredicate::BoundPredicate {
|
Some(WherePredicate::BoundPredicate {
|
||||||
ty: clean_middle_ty(poly_trait_ref.self_ty(), cx, None, None),
|
ty: clean_middle_ty(poly_trait_ref.self_ty(), cx, None, None),
|
||||||
bounds: vec![clean_poly_trait_ref_with_bindings(cx, poly_trait_ref, ThinVec::new())],
|
bounds: vec![clean_poly_trait_ref_with_constraints(cx, poly_trait_ref, ThinVec::new())],
|
||||||
bound_params: Vec::new(),
|
bound_params: Vec::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -481,8 +481,11 @@ fn clean_projection<'tcx>(
|
||||||
return clean_middle_opaque_bounds(cx, bounds);
|
return clean_middle_opaque_bounds(cx, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
let trait_ =
|
let trait_ = clean_trait_ref_with_constraints(
|
||||||
clean_trait_ref_with_bindings(cx, ty.map_bound(|ty| ty.trait_ref(cx.tcx)), ThinVec::new());
|
cx,
|
||||||
|
ty.map_bound(|ty| ty.trait_ref(cx.tcx)),
|
||||||
|
ThinVec::new(),
|
||||||
|
);
|
||||||
let self_type = clean_middle_ty(ty.map_bound(|ty| ty.self_ty()), cx, None, None);
|
let self_type = clean_middle_ty(ty.map_bound(|ty| ty.self_ty()), cx, None, None);
|
||||||
let self_def_id = if let Some(def_id) = def_id {
|
let self_def_id = if let Some(def_id) = def_id {
|
||||||
cx.tcx.opt_parent(def_id).or(Some(def_id))
|
cx.tcx.opt_parent(def_id).or(Some(def_id))
|
||||||
|
@ -522,7 +525,7 @@ fn projection_to_path_segment<'tcx>(
|
||||||
def_id,
|
def_id,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
bindings: Default::default(),
|
constraints: Default::default(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1453,8 +1456,8 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
|
||||||
_ => return true,
|
_ => return true,
|
||||||
}
|
}
|
||||||
match &assoc.args {
|
match &assoc.args {
|
||||||
GenericArgs::AngleBracketed { args, bindings } => {
|
GenericArgs::AngleBracketed { args, constraints } => {
|
||||||
if !bindings.is_empty()
|
if !constraints.is_empty()
|
||||||
|| generics
|
|| generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -2135,7 +2138,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||||
|
|
||||||
let bindings = obj
|
let bindings = obj
|
||||||
.projection_bounds()
|
.projection_bounds()
|
||||||
.map(|pb| TypeBinding {
|
.map(|pb| AssocItemConstraint {
|
||||||
assoc: projection_to_path_segment(
|
assoc: projection_to_path_segment(
|
||||||
pb.map_bound(|pb| {
|
pb.map_bound(|pb| {
|
||||||
pb
|
pb
|
||||||
|
@ -2149,7 +2152,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||||
}),
|
}),
|
||||||
cx,
|
cx,
|
||||||
),
|
),
|
||||||
kind: TypeBindingKind::Equality {
|
kind: AssocItemConstraintKind::Equality {
|
||||||
term: clean_middle_term(pb.map_bound(|pb| pb.term), cx),
|
term: clean_middle_term(pb.map_bound(|pb| pb.term), cx),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -2198,7 +2201,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||||
def_id,
|
def_id,
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
bindings: Default::default(),
|
constraints: Default::default(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
should_show_cast: false,
|
should_show_cast: false,
|
||||||
|
@ -2304,14 +2307,14 @@ fn clean_middle_opaque_bounds<'tcx>(
|
||||||
.filter_map(|bound| {
|
.filter_map(|bound| {
|
||||||
if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() {
|
if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() {
|
||||||
if proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder() {
|
if proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder() {
|
||||||
Some(TypeBinding {
|
Some(AssocItemConstraint {
|
||||||
assoc: projection_to_path_segment(
|
assoc: projection_to_path_segment(
|
||||||
// FIXME: This needs to be made resilient for `AliasTerm`s that
|
// FIXME: This needs to be made resilient for `AliasTerm`s that
|
||||||
// are associated consts.
|
// are associated consts.
|
||||||
bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)),
|
bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)),
|
||||||
cx,
|
cx,
|
||||||
),
|
),
|
||||||
kind: TypeBindingKind::Equality {
|
kind: AssocItemConstraintKind::Equality {
|
||||||
term: clean_middle_term(bound.kind().rebind(proj.term), cx),
|
term: clean_middle_term(bound.kind().rebind(proj.term), cx),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -2324,7 +2327,7 @@ fn clean_middle_opaque_bounds<'tcx>(
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, bindings))
|
Some(clean_poly_trait_ref_with_constraints(cx, trait_ref, bindings))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -2505,11 +2508,12 @@ fn clean_generic_args<'tcx>(
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
) -> GenericArgs {
|
) -> GenericArgs {
|
||||||
// FIXME(return_type_notation): Fix RTN parens rendering
|
// FIXME(return_type_notation): Fix RTN parens rendering
|
||||||
if generic_args.parenthesized == hir::GenericArgsParentheses::ParenSugar {
|
if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() {
|
||||||
let output = clean_ty(generic_args.bindings[0].ty(), cx);
|
let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect::<Vec<_>>().into();
|
||||||
let output = if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None };
|
let output = match output.kind {
|
||||||
let inputs =
|
hir::TyKind::Tup(&[]) => None,
|
||||||
generic_args.inputs().iter().map(|x| clean_ty(x, cx)).collect::<Vec<_>>().into();
|
_ => Some(Box::new(clean_ty(output, cx))),
|
||||||
|
};
|
||||||
GenericArgs::Parenthesized { inputs, output }
|
GenericArgs::Parenthesized { inputs, output }
|
||||||
} else {
|
} else {
|
||||||
let args = generic_args
|
let args = generic_args
|
||||||
|
@ -2536,9 +2540,12 @@ fn clean_generic_args<'tcx>(
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into();
|
.into();
|
||||||
let bindings =
|
let constraints = generic_args
|
||||||
generic_args.bindings.iter().map(|x| clean_type_binding(x, cx)).collect::<ThinVec<_>>();
|
.constraints
|
||||||
GenericArgs::AngleBracketed { args, bindings }
|
.iter()
|
||||||
|
.map(|c| clean_assoc_item_constraint(c, cx))
|
||||||
|
.collect::<ThinVec<_>>();
|
||||||
|
GenericArgs::AngleBracketed { args, constraints }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3107,20 +3114,20 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_type_binding<'tcx>(
|
fn clean_assoc_item_constraint<'tcx>(
|
||||||
type_binding: &hir::TypeBinding<'tcx>,
|
constraint: &hir::AssocItemConstraint<'tcx>,
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
) -> TypeBinding {
|
) -> AssocItemConstraint {
|
||||||
TypeBinding {
|
AssocItemConstraint {
|
||||||
assoc: PathSegment {
|
assoc: PathSegment {
|
||||||
name: type_binding.ident.name,
|
name: constraint.ident.name,
|
||||||
args: clean_generic_args(type_binding.gen_args, cx),
|
args: clean_generic_args(constraint.gen_args, cx),
|
||||||
},
|
},
|
||||||
kind: match type_binding.kind {
|
kind: match constraint.kind {
|
||||||
hir::TypeBindingKind::Equality { ref term } => {
|
hir::AssocItemConstraintKind::Equality { ref term } => {
|
||||||
TypeBindingKind::Equality { term: clean_hir_term(term, cx) }
|
AssocItemConstraintKind::Equality { term: clean_hir_term(term, cx) }
|
||||||
}
|
}
|
||||||
hir::TypeBindingKind::Constraint { bounds } => TypeBindingKind::Constraint {
|
hir::AssocItemConstraintKind::Bound { bounds } => AssocItemConstraintKind::Bound {
|
||||||
bounds: bounds.iter().filter_map(|b| clean_generic_bound(b, cx)).collect(),
|
bounds: bounds.iter().filter_map(|b| clean_generic_bound(b, cx)).collect(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -90,10 +90,10 @@ pub(crate) fn merge_bounds(
|
||||||
let last = trait_ref.trait_.segments.last_mut().expect("segments were empty");
|
let last = trait_ref.trait_.segments.last_mut().expect("segments were empty");
|
||||||
|
|
||||||
match last.args {
|
match last.args {
|
||||||
PP::AngleBracketed { ref mut bindings, .. } => {
|
PP::AngleBracketed { ref mut constraints, .. } => {
|
||||||
bindings.push(clean::TypeBinding {
|
constraints.push(clean::AssocItemConstraint {
|
||||||
assoc: assoc.clone(),
|
assoc: assoc.clone(),
|
||||||
kind: clean::TypeBindingKind::Equality { term: rhs.clone() },
|
kind: clean::AssocItemConstraintKind::Equality { term: rhs.clone() },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
PP::Parenthesized { ref mut output, .. } => match output {
|
PP::Parenthesized { ref mut output, .. } => match output {
|
||||||
|
|
|
@ -1627,9 +1627,9 @@ impl Type {
|
||||||
if let Type::ImplTrait(mut v) = self
|
if let Type::ImplTrait(mut v) = self
|
||||||
&& let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _)) = v.pop()
|
&& let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _)) = v.pop()
|
||||||
&& let Some(segment) = trait_.segments.pop()
|
&& let Some(segment) = trait_.segments.pop()
|
||||||
&& let GenericArgs::AngleBracketed { mut bindings, .. } = segment.args
|
&& let GenericArgs::AngleBracketed { mut constraints, .. } = segment.args
|
||||||
&& let Some(binding) = bindings.pop()
|
&& let Some(constraint) = constraints.pop()
|
||||||
&& let TypeBindingKind::Equality { term } = binding.kind
|
&& let AssocItemConstraintKind::Equality { term } = constraint.kind
|
||||||
&& let Term::Type(ty) = term
|
&& let Term::Type(ty) = term
|
||||||
{
|
{
|
||||||
ty
|
ty
|
||||||
|
@ -2259,34 +2259,38 @@ impl GenericArg {
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub(crate) enum GenericArgs {
|
pub(crate) enum GenericArgs {
|
||||||
AngleBracketed { args: Box<[GenericArg]>, bindings: ThinVec<TypeBinding> },
|
AngleBracketed { args: Box<[GenericArg]>, constraints: ThinVec<AssocItemConstraint> },
|
||||||
Parenthesized { inputs: Box<[Type]>, output: Option<Box<Type>> },
|
Parenthesized { inputs: Box<[Type]>, output: Option<Box<Type>> },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenericArgs {
|
impl GenericArgs {
|
||||||
pub(crate) fn is_empty(&self) -> bool {
|
pub(crate) fn is_empty(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
GenericArgs::AngleBracketed { args, bindings } => {
|
GenericArgs::AngleBracketed { args, constraints } => {
|
||||||
args.is_empty() && bindings.is_empty()
|
args.is_empty() && constraints.is_empty()
|
||||||
}
|
}
|
||||||
GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(),
|
GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn bindings<'a>(&'a self) -> Box<dyn Iterator<Item = TypeBinding> + 'a> {
|
pub(crate) fn constraints<'a>(&'a self) -> Box<dyn Iterator<Item = AssocItemConstraint> + 'a> {
|
||||||
match self {
|
match self {
|
||||||
GenericArgs::AngleBracketed { bindings, .. } => Box::new(bindings.iter().cloned()),
|
GenericArgs::AngleBracketed { constraints, .. } => {
|
||||||
|
Box::new(constraints.iter().cloned())
|
||||||
|
}
|
||||||
GenericArgs::Parenthesized { output, .. } => Box::new(
|
GenericArgs::Parenthesized { output, .. } => Box::new(
|
||||||
output
|
output
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|ty| TypeBinding {
|
.map(|ty| AssocItemConstraint {
|
||||||
assoc: PathSegment {
|
assoc: PathSegment {
|
||||||
name: sym::Output,
|
name: sym::Output,
|
||||||
args: GenericArgs::AngleBracketed {
|
args: GenericArgs::AngleBracketed {
|
||||||
args: Vec::new().into_boxed_slice(),
|
args: Vec::new().into_boxed_slice(),
|
||||||
bindings: ThinVec::new(),
|
constraints: ThinVec::new(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kind: TypeBindingKind::Equality { term: Term::Type((**ty).clone()) },
|
kind: AssocItemConstraintKind::Equality {
|
||||||
|
term: Term::Type((**ty).clone()),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.into_iter(),
|
.into_iter(),
|
||||||
),
|
),
|
||||||
|
@ -2545,18 +2549,27 @@ pub(crate) struct ProcMacro {
|
||||||
pub(crate) helpers: Vec<Symbol>,
|
pub(crate) helpers: Vec<Symbol>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An type binding on an associated type (e.g., `A = Bar` in `Foo<A = Bar>` or
|
/// A constraint on an associated item.
|
||||||
/// `A: Send + Sync` in `Foo<A: Send + Sync>`).
|
///
|
||||||
|
/// ### Examples
|
||||||
|
///
|
||||||
|
/// * the `A = Ty` and `B = Ty` in `Trait<A = Ty, B = Ty>`
|
||||||
|
/// * the `G<Ty> = Ty` in `Trait<G<Ty> = Ty>`
|
||||||
|
/// * the `A: Bound` in `Trait<A: Bound>`
|
||||||
|
/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
|
||||||
|
/// * the `C = { Ct }` in `Trait<C = { Ct }>` (feature `associated_const_equality`)
|
||||||
|
/// * the `f(): Bound` in `Trait<f(): Bound>` (feature `return_type_notation`)
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub(crate) struct TypeBinding {
|
pub(crate) struct AssocItemConstraint {
|
||||||
pub(crate) assoc: PathSegment,
|
pub(crate) assoc: PathSegment,
|
||||||
pub(crate) kind: TypeBindingKind,
|
pub(crate) kind: AssocItemConstraintKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The kind of [associated item constraint][AssocItemConstraint].
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||||
pub(crate) enum TypeBindingKind {
|
pub(crate) enum AssocItemConstraintKind {
|
||||||
Equality { term: Term },
|
Equality { term: Term },
|
||||||
Constraint { bounds: Vec<GenericBound> },
|
Bound { bounds: Vec<GenericBound> },
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
|
||||||
|
|
|
@ -2,9 +2,10 @@ use crate::clean::auto_trait::synthesize_auto_trait_impls;
|
||||||
use crate::clean::blanket_impl::synthesize_blanket_impls;
|
use crate::clean::blanket_impl::synthesize_blanket_impls;
|
||||||
use crate::clean::render_macro_matchers::render_macro_matcher;
|
use crate::clean::render_macro_matchers::render_macro_matcher;
|
||||||
use crate::clean::{
|
use crate::clean::{
|
||||||
clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, Crate,
|
clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline,
|
||||||
ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path,
|
AssocItemConstraint, AssocItemConstraintKind, Crate, ExternalCrate, Generic, GenericArg,
|
||||||
PathSegment, Primitive, PrimitiveType, Term, Type, TypeBinding, TypeBindingKind,
|
GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path, PathSegment, Primitive,
|
||||||
|
PrimitiveType, Term, Type,
|
||||||
};
|
};
|
||||||
use crate::core::DocContext;
|
use crate::core::DocContext;
|
||||||
use crate::html::format::visibility_to_src_with_space;
|
use crate::html::format::visibility_to_src_with_space;
|
||||||
|
@ -200,11 +201,11 @@ fn can_elide_generic_arg<'tcx>(
|
||||||
actual.skip_binder() == default.skip_binder()
|
actual.skip_binder() == default.skip_binder()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_middle_generic_args_with_bindings<'tcx>(
|
fn clean_middle_generic_args_with_constraints<'tcx>(
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
did: DefId,
|
did: DefId,
|
||||||
has_self: bool,
|
has_self: bool,
|
||||||
bindings: ThinVec<TypeBinding>,
|
constraints: ThinVec<AssocItemConstraint>,
|
||||||
ty_args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
|
ty_args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
|
||||||
) -> GenericArgs {
|
) -> GenericArgs {
|
||||||
let args = clean_middle_generic_args(cx, ty_args.map_bound(|args| &args[..]), has_self, did);
|
let args = clean_middle_generic_args(cx, ty_args.map_bound(|args| &args[..]), has_self, did);
|
||||||
|
@ -219,17 +220,19 @@ fn clean_middle_generic_args_with_bindings<'tcx>(
|
||||||
// The trait's first substitution is the one after self, if there is one.
|
// The trait's first substitution is the one after self, if there is one.
|
||||||
match ty.skip_binder().kind() {
|
match ty.skip_binder().kind() {
|
||||||
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None, None)).collect::<Vec<_>>().into(),
|
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None, None)).collect::<Vec<_>>().into(),
|
||||||
_ => return GenericArgs::AngleBracketed { args: args.into(), bindings },
|
_ => return GenericArgs::AngleBracketed { args: args.into(), constraints },
|
||||||
};
|
};
|
||||||
let output = bindings.into_iter().next().and_then(|binding| match binding.kind {
|
let output = constraints.into_iter().next().and_then(|binding| match binding.kind {
|
||||||
TypeBindingKind::Equality { term: Term::Type(ty) } if ty != Type::Tuple(Vec::new()) => {
|
AssocItemConstraintKind::Equality { term: Term::Type(ty) }
|
||||||
|
if ty != Type::Tuple(Vec::new()) =>
|
||||||
|
{
|
||||||
Some(Box::new(ty))
|
Some(Box::new(ty))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
GenericArgs::Parenthesized { inputs, output }
|
GenericArgs::Parenthesized { inputs, output }
|
||||||
} else {
|
} else {
|
||||||
GenericArgs::AngleBracketed { args: args.into(), bindings }
|
GenericArgs::AngleBracketed { args: args.into(), constraints }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +240,7 @@ pub(super) fn clean_middle_path<'tcx>(
|
||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
did: DefId,
|
did: DefId,
|
||||||
has_self: bool,
|
has_self: bool,
|
||||||
bindings: ThinVec<TypeBinding>,
|
constraints: ThinVec<AssocItemConstraint>,
|
||||||
args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
|
args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
|
||||||
) -> Path {
|
) -> Path {
|
||||||
let def_kind = cx.tcx.def_kind(did);
|
let def_kind = cx.tcx.def_kind(did);
|
||||||
|
@ -246,7 +249,7 @@ pub(super) fn clean_middle_path<'tcx>(
|
||||||
res: Res::Def(def_kind, did),
|
res: Res::Def(def_kind, did),
|
||||||
segments: thin_vec![PathSegment {
|
segments: thin_vec![PathSegment {
|
||||||
name,
|
name,
|
||||||
args: clean_middle_generic_args_with_bindings(cx, did, has_self, bindings, args),
|
args: clean_middle_generic_args_with_constraints(cx, did, has_self, constraints, args),
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,8 +420,8 @@ impl clean::GenericArgs {
|
||||||
fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
|
fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
|
||||||
display_fn(move |f| {
|
display_fn(move |f| {
|
||||||
match self {
|
match self {
|
||||||
clean::GenericArgs::AngleBracketed { args, bindings } => {
|
clean::GenericArgs::AngleBracketed { args, constraints } => {
|
||||||
if !args.is_empty() || !bindings.is_empty() {
|
if !args.is_empty() || !constraints.is_empty() {
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
f.write_str("<")?;
|
f.write_str("<")?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -439,15 +439,15 @@ impl clean::GenericArgs {
|
||||||
write!(f, "{}", arg.print(cx))?;
|
write!(f, "{}", arg.print(cx))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for binding in bindings.iter() {
|
for constraint in constraints.iter() {
|
||||||
if comma {
|
if comma {
|
||||||
f.write_str(", ")?;
|
f.write_str(", ")?;
|
||||||
}
|
}
|
||||||
comma = true;
|
comma = true;
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
write!(f, "{:#}", binding.print(cx))?;
|
write!(f, "{:#}", constraint.print(cx))?;
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}", binding.print(cx))?;
|
write!(f, "{}", constraint.print(cx))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
|
@ -1699,7 +1699,7 @@ impl clean::ImportSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl clean::TypeBinding {
|
impl clean::AssocItemConstraint {
|
||||||
pub(crate) fn print<'a, 'tcx: 'a>(
|
pub(crate) fn print<'a, 'tcx: 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
cx: &'a Context<'tcx>,
|
cx: &'a Context<'tcx>,
|
||||||
|
@ -1708,11 +1708,11 @@ impl clean::TypeBinding {
|
||||||
f.write_str(self.assoc.name.as_str())?;
|
f.write_str(self.assoc.name.as_str())?;
|
||||||
self.assoc.args.print(cx).fmt(f)?;
|
self.assoc.args.print(cx).fmt(f)?;
|
||||||
match self.kind {
|
match self.kind {
|
||||||
clean::TypeBindingKind::Equality { ref term } => {
|
clean::AssocItemConstraintKind::Equality { ref term } => {
|
||||||
f.write_str(" = ")?;
|
f.write_str(" = ")?;
|
||||||
term.print(cx).fmt(f)?;
|
term.print(cx).fmt(f)?;
|
||||||
}
|
}
|
||||||
clean::TypeBindingKind::Constraint { ref bounds } => {
|
clean::AssocItemConstraintKind::Bound { ref bounds } => {
|
||||||
if !bounds.is_empty() {
|
if !bounds.is_empty() {
|
||||||
f.write_str(": ")?;
|
f.write_str(": ")?;
|
||||||
print_generic_bounds(bounds, cx).fmt(f)?;
|
print_generic_bounds(bounds, cx).fmt(f)?;
|
||||||
|
|
|
@ -727,7 +727,7 @@ pub(crate) fn get_function_type_for_search<'tcx>(
|
||||||
name: *name,
|
name: *name,
|
||||||
args: clean::GenericArgs::AngleBracketed {
|
args: clean::GenericArgs::AngleBracketed {
|
||||||
args: Vec::new().into_boxed_slice(),
|
args: Vec::new().into_boxed_slice(),
|
||||||
bindings: ThinVec::new(),
|
constraints: ThinVec::new(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
|
@ -1049,7 +1049,7 @@ fn simplify_fn_type<'tcx, 'a>(
|
||||||
// So in here, we can add it directly and look for its own type parameters (so for `Option`,
|
// So in here, we can add it directly and look for its own type parameters (so for `Option`,
|
||||||
// we will look for them but not for `T`).
|
// we will look for them but not for `T`).
|
||||||
let mut ty_generics = Vec::new();
|
let mut ty_generics = Vec::new();
|
||||||
let mut ty_bindings = Vec::new();
|
let mut ty_constraints = Vec::new();
|
||||||
if let Some(arg_generics) = arg.generic_args() {
|
if let Some(arg_generics) = arg.generic_args() {
|
||||||
for ty in arg_generics.into_iter().filter_map(|gen| match gen {
|
for ty in arg_generics.into_iter().filter_map(|gen| match gen {
|
||||||
clean::GenericArg::Type(ty) => Some(ty),
|
clean::GenericArg::Type(ty) => Some(ty),
|
||||||
|
@ -1067,14 +1067,14 @@ fn simplify_fn_type<'tcx, 'a>(
|
||||||
cache,
|
cache,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for binding in arg_generics.bindings() {
|
for constraint in arg_generics.constraints() {
|
||||||
simplify_fn_binding(
|
simplify_fn_constraint(
|
||||||
self_,
|
self_,
|
||||||
generics,
|
generics,
|
||||||
&binding,
|
&constraint,
|
||||||
tcx,
|
tcx,
|
||||||
recurse + 1,
|
recurse + 1,
|
||||||
&mut ty_bindings,
|
&mut ty_constraints,
|
||||||
rgen,
|
rgen,
|
||||||
is_return,
|
is_return,
|
||||||
cache,
|
cache,
|
||||||
|
@ -1137,7 +1137,7 @@ fn simplify_fn_type<'tcx, 'a>(
|
||||||
*stored_bounds = type_bounds;
|
*stored_bounds = type_bounds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty_bindings.push((
|
ty_constraints.push((
|
||||||
RenderTypeId::AssociatedType(name),
|
RenderTypeId::AssociatedType(name),
|
||||||
vec![RenderType {
|
vec![RenderType {
|
||||||
id: Some(RenderTypeId::Index(idx)),
|
id: Some(RenderTypeId::Index(idx)),
|
||||||
|
@ -1152,17 +1152,17 @@ fn simplify_fn_type<'tcx, 'a>(
|
||||||
if id.is_some() || !ty_generics.is_empty() {
|
if id.is_some() || !ty_generics.is_empty() {
|
||||||
res.push(RenderType {
|
res.push(RenderType {
|
||||||
id,
|
id,
|
||||||
bindings: if ty_bindings.is_empty() { None } else { Some(ty_bindings) },
|
bindings: if ty_constraints.is_empty() { None } else { Some(ty_constraints) },
|
||||||
generics: if ty_generics.is_empty() { None } else { Some(ty_generics) },
|
generics: if ty_generics.is_empty() { None } else { Some(ty_generics) },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn simplify_fn_binding<'tcx, 'a>(
|
fn simplify_fn_constraint<'tcx, 'a>(
|
||||||
self_: Option<&'a Type>,
|
self_: Option<&'a Type>,
|
||||||
generics: &Generics,
|
generics: &Generics,
|
||||||
binding: &'a clean::TypeBinding,
|
constraint: &'a clean::AssocItemConstraint,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
recurse: usize,
|
recurse: usize,
|
||||||
res: &mut Vec<(RenderTypeId, Vec<RenderType>)>,
|
res: &mut Vec<(RenderTypeId, Vec<RenderType>)>,
|
||||||
|
@ -1170,9 +1170,9 @@ fn simplify_fn_binding<'tcx, 'a>(
|
||||||
is_return: bool,
|
is_return: bool,
|
||||||
cache: &Cache,
|
cache: &Cache,
|
||||||
) {
|
) {
|
||||||
let mut ty_binding_constraints = Vec::new();
|
let mut ty_constraints = Vec::new();
|
||||||
let ty_binding_assoc = RenderTypeId::AssociatedType(binding.assoc.name);
|
let ty_constrained_assoc = RenderTypeId::AssociatedType(constraint.assoc.name);
|
||||||
for gen in &binding.assoc.args {
|
for gen in &constraint.assoc.args {
|
||||||
match gen {
|
match gen {
|
||||||
clean::GenericArg::Type(arg) => simplify_fn_type(
|
clean::GenericArg::Type(arg) => simplify_fn_type(
|
||||||
self_,
|
self_,
|
||||||
|
@ -1180,7 +1180,7 @@ fn simplify_fn_binding<'tcx, 'a>(
|
||||||
&arg,
|
&arg,
|
||||||
tcx,
|
tcx,
|
||||||
recurse + 1,
|
recurse + 1,
|
||||||
&mut ty_binding_constraints,
|
&mut ty_constraints,
|
||||||
rgen,
|
rgen,
|
||||||
is_return,
|
is_return,
|
||||||
cache,
|
cache,
|
||||||
|
@ -1190,11 +1190,11 @@ fn simplify_fn_binding<'tcx, 'a>(
|
||||||
| clean::GenericArg::Infer => {}
|
| clean::GenericArg::Infer => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for binding in binding.assoc.args.bindings() {
|
for constraint in constraint.assoc.args.constraints() {
|
||||||
simplify_fn_binding(
|
simplify_fn_constraint(
|
||||||
self_,
|
self_,
|
||||||
generics,
|
generics,
|
||||||
&binding,
|
&constraint,
|
||||||
tcx,
|
tcx,
|
||||||
recurse + 1,
|
recurse + 1,
|
||||||
res,
|
res,
|
||||||
|
@ -1203,8 +1203,8 @@ fn simplify_fn_binding<'tcx, 'a>(
|
||||||
cache,
|
cache,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
match &binding.kind {
|
match &constraint.kind {
|
||||||
clean::TypeBindingKind::Equality { term } => {
|
clean::AssocItemConstraintKind::Equality { term } => {
|
||||||
if let clean::Term::Type(arg) = &term {
|
if let clean::Term::Type(arg) = &term {
|
||||||
simplify_fn_type(
|
simplify_fn_type(
|
||||||
self_,
|
self_,
|
||||||
|
@ -1212,14 +1212,14 @@ fn simplify_fn_binding<'tcx, 'a>(
|
||||||
arg,
|
arg,
|
||||||
tcx,
|
tcx,
|
||||||
recurse + 1,
|
recurse + 1,
|
||||||
&mut ty_binding_constraints,
|
&mut ty_constraints,
|
||||||
rgen,
|
rgen,
|
||||||
is_return,
|
is_return,
|
||||||
cache,
|
cache,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clean::TypeBindingKind::Constraint { bounds } => {
|
clean::AssocItemConstraintKind::Bound { bounds } => {
|
||||||
for bound in &bounds[..] {
|
for bound in &bounds[..] {
|
||||||
if let Some(path) = bound.get_trait_path() {
|
if let Some(path) = bound.get_trait_path() {
|
||||||
let ty = Type::Path { path };
|
let ty = Type::Path { path };
|
||||||
|
@ -1229,7 +1229,7 @@ fn simplify_fn_binding<'tcx, 'a>(
|
||||||
&ty,
|
&ty,
|
||||||
tcx,
|
tcx,
|
||||||
recurse + 1,
|
recurse + 1,
|
||||||
&mut ty_binding_constraints,
|
&mut ty_constraints,
|
||||||
rgen,
|
rgen,
|
||||||
is_return,
|
is_return,
|
||||||
cache,
|
cache,
|
||||||
|
@ -1238,7 +1238,7 @@ fn simplify_fn_binding<'tcx, 'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res.push((ty_binding_assoc, ty_binding_constraints));
|
res.push((ty_constrained_assoc, ty_constraints));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the full list of types when bounds have been resolved.
|
/// Return the full list of types when bounds have been resolved.
|
||||||
|
|
|
@ -153,9 +153,9 @@ impl FromWithTcx<clean::GenericArgs> for GenericArgs {
|
||||||
fn from_tcx(args: clean::GenericArgs, tcx: TyCtxt<'_>) -> Self {
|
fn from_tcx(args: clean::GenericArgs, tcx: TyCtxt<'_>) -> Self {
|
||||||
use clean::GenericArgs::*;
|
use clean::GenericArgs::*;
|
||||||
match args {
|
match args {
|
||||||
AngleBracketed { args, bindings } => GenericArgs::AngleBracketed {
|
AngleBracketed { args, constraints } => GenericArgs::AngleBracketed {
|
||||||
args: args.into_vec().into_tcx(tcx),
|
args: args.into_vec().into_tcx(tcx),
|
||||||
bindings: bindings.into_tcx(tcx),
|
bindings: constraints.into_tcx(tcx),
|
||||||
},
|
},
|
||||||
Parenthesized { inputs, output } => GenericArgs::Parenthesized {
|
Parenthesized { inputs, output } => GenericArgs::Parenthesized {
|
||||||
inputs: inputs.into_vec().into_tcx(tcx),
|
inputs: inputs.into_vec().into_tcx(tcx),
|
||||||
|
@ -187,22 +187,22 @@ impl FromWithTcx<clean::Constant> for Constant {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromWithTcx<clean::TypeBinding> for TypeBinding {
|
impl FromWithTcx<clean::AssocItemConstraint> for TypeBinding {
|
||||||
fn from_tcx(binding: clean::TypeBinding, tcx: TyCtxt<'_>) -> Self {
|
fn from_tcx(constraint: clean::AssocItemConstraint, tcx: TyCtxt<'_>) -> Self {
|
||||||
TypeBinding {
|
TypeBinding {
|
||||||
name: binding.assoc.name.to_string(),
|
name: constraint.assoc.name.to_string(),
|
||||||
args: binding.assoc.args.into_tcx(tcx),
|
args: constraint.assoc.args.into_tcx(tcx),
|
||||||
binding: binding.kind.into_tcx(tcx),
|
binding: constraint.kind.into_tcx(tcx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromWithTcx<clean::TypeBindingKind> for TypeBindingKind {
|
impl FromWithTcx<clean::AssocItemConstraintKind> for TypeBindingKind {
|
||||||
fn from_tcx(kind: clean::TypeBindingKind, tcx: TyCtxt<'_>) -> Self {
|
fn from_tcx(kind: clean::AssocItemConstraintKind, tcx: TyCtxt<'_>) -> Self {
|
||||||
use clean::TypeBindingKind::*;
|
use clean::AssocItemConstraintKind::*;
|
||||||
match kind {
|
match kind {
|
||||||
Equality { term } => TypeBindingKind::Equality(term.into_tcx(tcx)),
|
Equality { term } => TypeBindingKind::Equality(term.into_tcx(tcx)),
|
||||||
Constraint { bounds } => TypeBindingKind::Constraint(bounds.into_tcx(tcx)),
|
Bound { bounds } => TypeBindingKind::Constraint(bounds.into_tcx(tcx)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use clippy_utils::source::snippet;
|
||||||
use rustc_errors::{Applicability, SuggestionStyle};
|
use rustc_errors::{Applicability, SuggestionStyle};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, TypeBinding,
|
GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, AssocItemConstraint,
|
||||||
WherePredicate,
|
WherePredicate,
|
||||||
};
|
};
|
||||||
use rustc_hir_analysis::lower_ty;
|
use rustc_hir_analysis::lower_ty;
|
||||||
|
@ -54,9 +54,9 @@ fn emit_lint(
|
||||||
poly_trait: &rustc_hir::PolyTraitRef<'_>,
|
poly_trait: &rustc_hir::PolyTraitRef<'_>,
|
||||||
bounds: GenericBounds<'_>,
|
bounds: GenericBounds<'_>,
|
||||||
index: usize,
|
index: usize,
|
||||||
// The bindings that were implied, used for suggestion purposes since removing a bound with associated types
|
// The constraints that were implied, used for suggestion purposes since removing a bound with
|
||||||
// means we might need to then move it to a different bound
|
// associated types means we might need to then move it to a different bound.
|
||||||
implied_bindings: &[TypeBinding<'_>],
|
implied_constraints: &[AssocItemConstraint<'_>],
|
||||||
bound: &ImplTraitBound<'_>,
|
bound: &ImplTraitBound<'_>,
|
||||||
) {
|
) {
|
||||||
let implied_by = snippet(cx, bound.span, "..");
|
let implied_by = snippet(cx, bound.span, "..");
|
||||||
|
@ -83,29 +83,29 @@ fn emit_lint(
|
||||||
|
|
||||||
let mut sugg = vec![(implied_span_extended, String::new())];
|
let mut sugg = vec![(implied_span_extended, String::new())];
|
||||||
|
|
||||||
// We also might need to include associated type binding that were specified in the implied bound,
|
// We also might need to include associated item constraints that were specified in the implied bound,
|
||||||
// but omitted in the implied-by bound:
|
// but omitted in the implied-by bound:
|
||||||
// `fn f() -> impl Deref<Target = u8> + DerefMut`
|
// `fn f() -> impl Deref<Target = u8> + DerefMut`
|
||||||
// If we're going to suggest removing `Deref<..>`, we'll need to put `<Target = u8>` on `DerefMut`
|
// If we're going to suggest removing `Deref<..>`, we'll need to put `<Target = u8>` on `DerefMut`
|
||||||
let omitted_assoc_tys: Vec<_> = implied_bindings
|
let omitted_constraints: Vec<_> = implied_constraints
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|binding| !bound.bindings.iter().any(|b| b.ident == binding.ident))
|
.filter(|constraint| !bound.constraints.iter().any(|c| c.ident == constraint.ident))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if !omitted_assoc_tys.is_empty() {
|
if !omitted_constraints.is_empty() {
|
||||||
// `<>` needs to be added if there aren't yet any generic arguments or bindings
|
// `<>` needs to be added if there aren't yet any generic arguments or constraints
|
||||||
let needs_angle_brackets = bound.args.is_empty() && bound.bindings.is_empty();
|
let needs_angle_brackets = bound.args.is_empty() && bound.constraints.is_empty();
|
||||||
let insert_span = match (bound.args, bound.bindings) {
|
let insert_span = match (bound.args, bound.constraints) {
|
||||||
([.., arg], [.., binding]) => arg.span().max(binding.span).shrink_to_hi(),
|
([.., arg], [.., constraint]) => arg.span().max(constraint.span).shrink_to_hi(),
|
||||||
([.., arg], []) => arg.span().shrink_to_hi(),
|
([.., arg], []) => arg.span().shrink_to_hi(),
|
||||||
([], [.., binding]) => binding.span.shrink_to_hi(),
|
([], [.., constraint]) => constraint.span.shrink_to_hi(),
|
||||||
([], []) => bound.span.shrink_to_hi(),
|
([], []) => bound.span.shrink_to_hi(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut associated_tys_sugg = if needs_angle_brackets {
|
let mut constraints_sugg = if needs_angle_brackets {
|
||||||
"<".to_owned()
|
"<".to_owned()
|
||||||
} else {
|
} else {
|
||||||
// If angle brackets aren't needed (i.e., there are already generic arguments or bindings),
|
// If angle brackets aren't needed (i.e., there are already generic arguments or constraints),
|
||||||
// we need to add a comma:
|
// we need to add a comma:
|
||||||
// `impl A<B, C >`
|
// `impl A<B, C >`
|
||||||
// ^ if we insert `Assoc=i32` without a comma here, that'd be invalid syntax:
|
// ^ if we insert `Assoc=i32` without a comma here, that'd be invalid syntax:
|
||||||
|
@ -113,16 +113,16 @@ fn emit_lint(
|
||||||
", ".to_owned()
|
", ".to_owned()
|
||||||
};
|
};
|
||||||
|
|
||||||
for (index, binding) in omitted_assoc_tys.into_iter().enumerate() {
|
for (index, constraint) in omitted_constraints.into_iter().enumerate() {
|
||||||
if index > 0 {
|
if index > 0 {
|
||||||
associated_tys_sugg += ", ";
|
constraints_sugg += ", ";
|
||||||
}
|
}
|
||||||
associated_tys_sugg += &snippet(cx, binding.span, "..");
|
constraints_sugg += &snippet(cx, constraint.span, "..");
|
||||||
}
|
}
|
||||||
if needs_angle_brackets {
|
if needs_angle_brackets {
|
||||||
associated_tys_sugg += ">";
|
constraints_sugg += ">";
|
||||||
}
|
}
|
||||||
sugg.push((insert_span, associated_tys_sugg));
|
sugg.push((insert_span, constraints_sugg));
|
||||||
}
|
}
|
||||||
|
|
||||||
diag.multipart_suggestion_with_style(
|
diag.multipart_suggestion_with_style(
|
||||||
|
@ -229,8 +229,8 @@ struct ImplTraitBound<'tcx> {
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
/// The generic arguments on the `impl Trait` bound
|
/// The generic arguments on the `impl Trait` bound
|
||||||
args: &'tcx [GenericArg<'tcx>],
|
args: &'tcx [GenericArg<'tcx>],
|
||||||
/// The associated types on this bound
|
/// The associated item constraints of this bound
|
||||||
bindings: &'tcx [TypeBinding<'tcx>],
|
constraints: &'tcx [AssocItemConstraint<'tcx>],
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an `impl Trait` type, gets all the supertraits from each bound ("implied bounds").
|
/// Given an `impl Trait` type, gets all the supertraits from each bound ("implied bounds").
|
||||||
|
@ -253,7 +253,7 @@ fn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds
|
||||||
Some(ImplTraitBound {
|
Some(ImplTraitBound {
|
||||||
predicates,
|
predicates,
|
||||||
args: path.args.map_or([].as_slice(), |p| p.args),
|
args: path.args.map_or([].as_slice(), |p| p.args),
|
||||||
bindings: path.args.map_or([].as_slice(), |p| p.bindings),
|
constraints: path.args.map_or([].as_slice(), |p| p.constraints),
|
||||||
trait_def_id,
|
trait_def_id,
|
||||||
span: bound.span(),
|
span: bound.span(),
|
||||||
})
|
})
|
||||||
|
@ -310,20 +310,20 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
|
||||||
if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
|
if let GenericBound::Trait(poly_trait, TraitBoundModifier::None) = bound
|
||||||
&& let [.., path] = poly_trait.trait_ref.path.segments
|
&& let [.., path] = poly_trait.trait_ref.path.segments
|
||||||
&& let implied_args = path.args.map_or([].as_slice(), |a| a.args)
|
&& let implied_args = path.args.map_or([].as_slice(), |a| a.args)
|
||||||
&& let implied_bindings = path.args.map_or([].as_slice(), |a| a.bindings)
|
&& let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints)
|
||||||
&& let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id()
|
&& let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id()
|
||||||
&& let Some(bound) = find_bound_in_supertraits(cx, def_id, implied_args, &supertraits)
|
&& let Some(bound) = find_bound_in_supertraits(cx, def_id, implied_args, &supertraits)
|
||||||
// If the implied bound has a type binding that also exists in the implied-by trait,
|
// If the implied bound has a type binding that also exists in the implied-by trait,
|
||||||
// then we shouldn't lint. See #11880 for an example.
|
// then we shouldn't lint. See #11880 for an example.
|
||||||
&& let assocs = cx.tcx.associated_items(bound.trait_def_id)
|
&& let assocs = cx.tcx.associated_items(bound.trait_def_id)
|
||||||
&& !implied_bindings.iter().any(|binding| {
|
&& !implied_constraints.iter().any(|constraint| {
|
||||||
assocs
|
assocs
|
||||||
.filter_by_name_unhygienic(binding.ident.name)
|
.filter_by_name_unhygienic(constraint.ident.name)
|
||||||
.next()
|
.next()
|
||||||
.is_some_and(|assoc| assoc.kind == ty::AssocKind::Type)
|
.is_some_and(|assoc| assoc.kind == ty::AssocKind::Type)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
emit_lint(cx, poly_trait, bounds, index, implied_bindings, bound);
|
emit_lint(cx, poly_trait, bounds, index, implied_constraints, bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_hir::def_id::{DefId, DefIdSet};
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind,
|
AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind,
|
||||||
ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatKind, PathSegment, PrimTy, QPath,
|
ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatKind, PathSegment, PrimTy, QPath,
|
||||||
TraitItemRef, TyKind, TypeBindingKind,
|
TraitItemRef, TyKind,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
|
use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
|
||||||
|
@ -307,17 +307,12 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&
|
||||||
&& let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
|
&& let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
|
||||||
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
||||||
&& let Some(generic_args) = segment.args
|
&& let Some(generic_args) = segment.args
|
||||||
&& generic_args.bindings.len() == 1
|
&& let [constraint] = generic_args.constraints
|
||||||
&& let TypeBindingKind::Equality {
|
&& let Some(ty) = constraint.ty()
|
||||||
term:
|
&& let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
|
||||||
rustc_hir::Term::Ty(rustc_hir::Ty {
|
&& let [segment] = path.segments
|
||||||
kind: TyKind::Path(QPath::Resolved(_, path)),
|
|
||||||
..
|
|
||||||
}),
|
|
||||||
} = &generic_args.bindings[0].kind
|
|
||||||
&& path.segments.len() == 1
|
|
||||||
{
|
{
|
||||||
return Some(&path.segments[0]);
|
return Some(segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
|
|
@ -4,8 +4,7 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
|
Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
|
||||||
FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, Term, TraitRef, Ty, TyKind,
|
FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, TraitRef, Ty, TyKind,
|
||||||
TypeBindingKind,
|
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_session::declare_lint_pass;
|
use rustc_session::declare_lint_pass;
|
||||||
|
@ -138,10 +137,9 @@ fn future_trait_ref<'tcx>(
|
||||||
fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'tcx>> {
|
fn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'tcx>> {
|
||||||
if let Some(segment) = trait_ref.path.segments.last()
|
if let Some(segment) = trait_ref.path.segments.last()
|
||||||
&& let Some(args) = segment.args
|
&& let Some(args) = segment.args
|
||||||
&& args.bindings.len() == 1
|
&& let [constraint] = args.constraints
|
||||||
&& let binding = &args.bindings[0]
|
&& constraint.ident.name == sym::Output
|
||||||
&& binding.ident.name == sym::Output
|
&& let Some(output) = constraint.ty()
|
||||||
&& let TypeBindingKind::Equality { term: Term::Ty(output) } = binding.kind
|
|
||||||
{
|
{
|
||||||
return Some(output);
|
return Some(output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ pub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool {
|
||||||
pub fn eq_angle_arg(l: &AngleBracketedArg, r: &AngleBracketedArg) -> bool {
|
pub fn eq_angle_arg(l: &AngleBracketedArg, r: &AngleBracketedArg) -> bool {
|
||||||
match (l, r) {
|
match (l, r) {
|
||||||
(AngleBracketedArg::Arg(l), AngleBracketedArg::Arg(r)) => eq_generic_arg(l, r),
|
(AngleBracketedArg::Arg(l), AngleBracketedArg::Arg(r)) => eq_generic_arg(l, r),
|
||||||
(AngleBracketedArg::Constraint(l), AngleBracketedArg::Constraint(r)) => eq_assoc_constraint(l, r),
|
(AngleBracketedArg::Constraint(l), AngleBracketedArg::Constraint(r)) => eq_assoc_item_constraint(l, r),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -802,8 +802,8 @@ fn eq_term(l: &Term, r: &Term) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eq_assoc_constraint(l: &AssocConstraint, r: &AssocConstraint) -> bool {
|
pub fn eq_assoc_item_constraint(l: &AssocItemConstraint, r: &AssocItemConstraint) -> bool {
|
||||||
use AssocConstraintKind::*;
|
use AssocItemConstraintKind::*;
|
||||||
eq_id(l.ident, r.ident)
|
eq_id(l.ident, r.ident)
|
||||||
&& match (&l.kind, &r.kind) {
|
&& match (&l.kind, &r.kind) {
|
||||||
(Equality { term: l }, Equality { term: r }) => eq_term(l, r),
|
(Equality { term: l }, Equality { term: r }) => eq_term(l, r),
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_hir::MatchSource::TryDesugar;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
ArrayLen, BinOpKind, BindingMode, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
|
ArrayLen, BinOpKind, BindingMode, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
|
||||||
GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
|
GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
|
||||||
PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
|
PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, AssocItemConstraint,
|
||||||
};
|
};
|
||||||
use rustc_lexer::{tokenize, TokenKind};
|
use rustc_lexer::{tokenize, TokenKind};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
|
@ -486,7 +486,7 @@ impl HirEqInterExpr<'_, '_, '_> {
|
||||||
fn eq_path_parameters(&mut self, left: &GenericArgs<'_>, right: &GenericArgs<'_>) -> bool {
|
fn eq_path_parameters(&mut self, left: &GenericArgs<'_>, right: &GenericArgs<'_>) -> bool {
|
||||||
if left.parenthesized == right.parenthesized {
|
if left.parenthesized == right.parenthesized {
|
||||||
over(left.args, right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work
|
over(left.args, right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work
|
||||||
&& over(left.bindings, right.bindings, |l, r| self.eq_type_binding(l, r))
|
&& over(left.constraints, right.constraints, |l, r| self.eq_assoc_type_binding(l, r))
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -518,8 +518,8 @@ impl HirEqInterExpr<'_, '_, '_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eq_type_binding(&mut self, left: &TypeBinding<'_>, right: &TypeBinding<'_>) -> bool {
|
fn eq_assoc_type_binding(&mut self, left: &AssocItemConstraint<'_>, right: &AssocItemConstraint<'_>) -> bool {
|
||||||
left.ident.name == right.ident.name && self.eq_ty(left.ty(), right.ty())
|
left.ident.name == right.ident.name && self.eq_ty(left.ty().expect("expected assoc type binding"), right.ty().expect("expected assoc type binding"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_ctxt(&mut self, left: SyntaxContext, right: SyntaxContext) -> bool {
|
fn check_ctxt(&mut self, left: SyntaxContext, right: SyntaxContext) -> bool {
|
||||||
|
|
|
@ -140,7 +140,7 @@ pub(crate) enum SegmentParam<'a> {
|
||||||
Const(&'a ast::AnonConst),
|
Const(&'a ast::AnonConst),
|
||||||
LifeTime(&'a ast::Lifetime),
|
LifeTime(&'a ast::Lifetime),
|
||||||
Type(&'a ast::Ty),
|
Type(&'a ast::Ty),
|
||||||
Binding(&'a ast::AssocConstraint),
|
Binding(&'a ast::AssocItemConstraint),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SegmentParam<'a> {
|
impl<'a> SegmentParam<'a> {
|
||||||
|
@ -175,9 +175,9 @@ impl<'a> Rewrite for SegmentParam<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rewrite for ast::AssocConstraint {
|
impl Rewrite for ast::AssocItemConstraint {
|
||||||
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
||||||
use ast::AssocConstraintKind::{Bound, Equality};
|
use ast::AssocItemConstraintKind::{Bound, Equality};
|
||||||
|
|
||||||
let mut result = String::with_capacity(128);
|
let mut result = String::with_capacity(128);
|
||||||
result.push_str(rewrite_ident(context, self.ident));
|
result.push_str(rewrite_ident(context, self.ident));
|
||||||
|
@ -205,14 +205,14 @@ impl Rewrite for ast::AssocConstraint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rewrite for ast::AssocConstraintKind {
|
impl Rewrite for ast::AssocItemConstraintKind {
|
||||||
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
||||||
match self {
|
match self {
|
||||||
ast::AssocConstraintKind::Equality { term } => match term {
|
ast::AssocItemConstraintKind::Equality { term } => match term {
|
||||||
Term::Ty(ty) => ty.rewrite(context, shape),
|
Term::Ty(ty) => ty.rewrite(context, shape),
|
||||||
Term::Const(c) => c.rewrite(context, shape),
|
Term::Const(c) => c.rewrite(context, shape),
|
||||||
},
|
},
|
||||||
ast::AssocConstraintKind::Bound { bounds } => bounds.rewrite(context, shape),
|
ast::AssocItemConstraintKind::Bound { bounds } => bounds.rewrite(context, shape),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
trait T {
|
trait T {
|
||||||
type A: S<C<X = 0i32> = 34>;
|
type A: S<C<X = 0i32> = 34>;
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
|
|
||||||
trait S {
|
trait S {
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/invalid_associated_const.rs:4:17
|
--> $DIR/invalid_associated_const.rs:4:17
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/invalid_associated_const.rs:4:17
|
--> $DIR/invalid_associated_const.rs:4:17
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
|
|
||||||
trait T {
|
trait T {
|
||||||
type A: S<C<X = 0i32> = 34>;
|
type A: S<C<X = 0i32> = 34>;
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
|
|
||||||
trait S {
|
trait S {
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-102467.rs:7:17
|
--> $DIR/issue-102467.rs:7:17
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-102467.rs:7:17
|
--> $DIR/issue-102467.rs:7:17
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
trait T {
|
trait T {
|
||||||
type A: S<C<X = 0i32> = 34>;
|
type A: S<C<X = 0i32> = 34>;
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
|
|
||||||
trait S {
|
trait S {
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-102335-const.rs:4:17
|
--> $DIR/issue-102335-const.rs:4:17
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-102335-const.rs:4:17
|
--> $DIR/issue-102335-const.rs:4:17
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<X = 0i32> = 34>;
|
LL | type A: S<C<X = 0i32> = 34>;
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
trait T {
|
trait T {
|
||||||
type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
|
type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
|
|
||||||
trait T2 {
|
trait T2 {
|
||||||
type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
|
type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Q {}
|
trait Q {}
|
||||||
|
|
|
@ -1,45 +1,45 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-102335-ty.rs:2:17
|
--> $DIR/issue-102335-ty.rs:2:17
|
||||||
|
|
|
|
||||||
LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
|
LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
|
||||||
| ^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
|
LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
|
||||||
| ~~~~~~~~~~~
|
| ~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-102335-ty.rs:2:17
|
--> $DIR/issue-102335-ty.rs:2:17
|
||||||
|
|
|
|
||||||
LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
|
LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
|
||||||
| ^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
|
LL | type A: S<C<i32 = u32> = ()>; // Just one erroneous equality constraint
|
||||||
| ~~~~~~~~~~~
|
| ~~~~~~~~~~~
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-102335-ty.rs:8:17
|
--> $DIR/issue-102335-ty.rs:8:17
|
||||||
|
|
|
|
||||||
LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
|
LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
|
||||||
| ^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
|
LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-102335-ty.rs:8:17
|
--> $DIR/issue-102335-ty.rs:8:17
|
||||||
|
|
|
|
||||||
LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
|
LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
|
||||||
| ^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
|
LL | type A: S<C<i32 = u32, X = i32> = ()>; // More than one erroneous equality constraints
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
|
|
@ -4,7 +4,7 @@ pub trait Iter {
|
||||||
type Item<'a>: 'a where Self: 'a;
|
type Item<'a>: 'a where Self: 'a;
|
||||||
|
|
||||||
fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>;
|
fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>;
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iter for () {
|
impl Iter for () {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/no-gat-position.rs:6:56
|
--> $DIR/no-gat-position.rs:6:56
|
||||||
|
|
|
|
||||||
LL | fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>;
|
LL | fn next<'a>(&'a mut self) -> Option<Self::Item<'a, As1: Copy>>;
|
||||||
| ^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,14 @@ impl Tr1 for isize {
|
||||||
// Test for when the assoc type is
|
// Test for when the assoc type is
|
||||||
// specified as an equality constraint
|
// specified as an equality constraint
|
||||||
impl Tr1<A = usize> for usize {
|
impl Tr1<A = usize> for usize {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR not all trait items implemented, missing: `A`
|
//~| ERROR not all trait items implemented, missing: `A`
|
||||||
fn boo(&self) -> usize { 42 }
|
fn boo(&self) -> usize { 42 }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for a wronngly used equality constraint in a func arg
|
// Test for a wronngly used equality constraint in a func arg
|
||||||
fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {}
|
fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {}
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,28 +38,28 @@ trait Tr2<T1, T2, T3> {
|
||||||
// (Note: E0229 is emitted only for the first erroneous equality
|
// (Note: E0229 is emitted only for the first erroneous equality
|
||||||
// constraint (T2) not for any subequent ones (e.g. T3))
|
// constraint (T2) not for any subequent ones (e.g. T3))
|
||||||
impl Tr2<i32, T2 = Qux, T3 = usize> for Bar {
|
impl Tr2<i32, T2 = Qux, T3 = usize> for Bar {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
|
//~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for when equality constraint's ident matches a
|
// Test for when equality constraint's ident matches a
|
||||||
// generic param's ident but has different case
|
// generic param's ident but has different case
|
||||||
impl Tr2<i32, t2 = Qux, T3 = usize> for Qux {
|
impl Tr2<i32, t2 = Qux, T3 = usize> for Qux {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
|
//~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for when equality constraint's ident
|
// Test for when equality constraint's ident
|
||||||
// matches none of the generic param idents
|
// matches none of the generic param idents
|
||||||
impl Tr2<i32, X = Qux, Y = usize> for Bar {
|
impl Tr2<i32, X = Qux, Y = usize> for Bar {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
|
//~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for when the term in equality constraint is itself generic
|
// Test for when the term in equality constraint is itself generic
|
||||||
struct GenericTerm<T> { _t: T }
|
struct GenericTerm<T> { _t: T }
|
||||||
impl Tr2<i32, Qux, T3 = GenericTerm<i32>> for Bar {
|
impl Tr2<i32, Qux, T3 = GenericTerm<i32>> for Bar {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR trait takes 3 generic arguments but 2 generic arguments were supplied
|
//~| ERROR trait takes 3 generic arguments but 2 generic arguments were supplied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ trait Tr3<const N: i32, T2, T3> {
|
||||||
// (Deliberately spread over multiple lines to test that
|
// (Deliberately spread over multiple lines to test that
|
||||||
// our suggestion spans are kosher in the face of such formatting)
|
// our suggestion spans are kosher in the face of such formatting)
|
||||||
impl Tr3<N
|
impl Tr3<N
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated const equality is incomplete
|
//~| ERROR associated const equality is incomplete
|
||||||
//~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
|
//~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
|
||||||
= 42, T2 = Qux, T3 = usize> for Bar {
|
= 42, T2 = Qux, T3 = usize> for Bar {
|
||||||
|
@ -83,7 +83,7 @@ impl Tr3<N
|
||||||
// Test for when equality constraint's ident
|
// Test for when equality constraint's ident
|
||||||
// matches the const param's ident but has a different case
|
// matches the const param's ident but has a different case
|
||||||
impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
|
impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated const equality is incomplete
|
//~| ERROR associated const equality is incomplete
|
||||||
//~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
|
//~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
|
||||||
}
|
}
|
||||||
|
@ -91,14 +91,14 @@ impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
|
||||||
// Test for when equality constraint's ident
|
// Test for when equality constraint's ident
|
||||||
// matches the const param ident but the constraint is a type arg
|
// matches the const param ident but the constraint is a type arg
|
||||||
impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar {
|
impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
|
//~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for when equality constraint's ident
|
// Test for when equality constraint's ident
|
||||||
// matches a type param ident but the constraint is a const arg
|
// matches a type param ident but the constraint is a const arg
|
||||||
impl Tr3<42, T2 = 42, T3 = usize> for Bar {
|
impl Tr3<42, T2 = 42, T3 = usize> for Bar {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated const equality is incomplete
|
//~| ERROR associated const equality is incomplete
|
||||||
//~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
|
//~| ERROR trait takes 3 generic arguments but 1 generic argument was supplied
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ impl Tr3<42, T2 = 42, T3 = usize> for Bar {
|
||||||
// Test for when equality constraint's ident
|
// Test for when equality constraint's ident
|
||||||
// matches none of the param idents
|
// matches none of the param idents
|
||||||
impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
|
impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated const equality is incomplete
|
//~| ERROR associated const equality is incomplete
|
||||||
//~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
|
//~| ERROR trait takes 3 generic arguments but 0 generic arguments were supplied
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
|
||||||
struct St<'a, T> { v: &'a T }
|
struct St<'a, T> { v: &'a T }
|
||||||
|
|
||||||
impl<'a, T> St<'a , T = Qux> {
|
impl<'a, T> St<'a , T = Qux> {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR struct takes 1 generic argument but 0 generic arguments were supplied
|
//~| ERROR struct takes 1 generic argument but 0 generic arguments were supplied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,13 +43,13 @@ LL | impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
|
||||||
= help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
|
= help: add `#![feature(associated_const_equality)]` 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: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:20:10
|
--> $DIR/associated-types-eq-2.rs:20:10
|
||||||
|
|
|
|
||||||
LL | impl Tr1<A = usize> for usize {
|
LL | impl Tr1<A = usize> for usize {
|
||||||
| ^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | impl Tr1<A = usize> for usize {
|
LL | impl Tr1<A = usize> for usize {
|
||||||
| ~~~~~~~~~~~
|
| ~~~~~~~~~~~
|
||||||
|
@ -63,13 +63,13 @@ LL | type A;
|
||||||
LL | impl Tr1<A = usize> for usize {
|
LL | impl Tr1<A = usize> for usize {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `A` in implementation
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `A` in implementation
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:27:31
|
--> $DIR/associated-types-eq-2.rs:27:31
|
||||||
|
|
|
|
||||||
LL | fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {}
|
LL | fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {}
|
||||||
| ^^^^^ associated type not allowed here
|
| ^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {}
|
LL | fn baz<I: Tr1>(_x: &<I as Tr1<A=Bar>>::A) {}
|
||||||
| ~~~~~~~
|
| ~~~~~~~
|
||||||
|
@ -92,11 +92,11 @@ help: add missing generic arguments
|
||||||
LL | impl Tr2<i32, T2, T3, T2 = Qux, T3 = usize> for Bar {
|
LL | impl Tr2<i32, T2, T3, T2 = Qux, T3 = usize> for Bar {
|
||||||
| ++++++++
|
| ++++++++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:40:15
|
--> $DIR/associated-types-eq-2.rs:40:15
|
||||||
|
|
|
|
||||||
LL | impl Tr2<i32, T2 = Qux, T3 = usize> for Bar {
|
LL | impl Tr2<i32, T2 = Qux, T3 = usize> for Bar {
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: to use `Qux` as a generic argument specify it directly
|
help: to use `Qux` as a generic argument specify it directly
|
||||||
|
|
|
|
||||||
|
@ -121,13 +121,13 @@ help: add missing generic arguments
|
||||||
LL | impl Tr2<i32, T2, T3, t2 = Qux, T3 = usize> for Qux {
|
LL | impl Tr2<i32, T2, T3, t2 = Qux, T3 = usize> for Qux {
|
||||||
| ++++++++
|
| ++++++++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:47:15
|
--> $DIR/associated-types-eq-2.rs:47:15
|
||||||
|
|
|
|
||||||
LL | impl Tr2<i32, t2 = Qux, T3 = usize> for Qux {
|
LL | impl Tr2<i32, t2 = Qux, T3 = usize> for Qux {
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | impl Tr2<i32, t2 = Qux, T3 = usize> for Qux {
|
LL | impl Tr2<i32, t2 = Qux, T3 = usize> for Qux {
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
@ -150,13 +150,13 @@ help: add missing generic arguments
|
||||||
LL | impl Tr2<i32, T2, T3, X = Qux, Y = usize> for Bar {
|
LL | impl Tr2<i32, T2, T3, X = Qux, Y = usize> for Bar {
|
||||||
| ++++++++
|
| ++++++++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:54:15
|
--> $DIR/associated-types-eq-2.rs:54:15
|
||||||
|
|
|
|
||||||
LL | impl Tr2<i32, X = Qux, Y = usize> for Bar {
|
LL | impl Tr2<i32, X = Qux, Y = usize> for Bar {
|
||||||
| ^^^^^^^ associated type not allowed here
|
| ^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | impl Tr2<i32, X = Qux, Y = usize> for Bar {
|
LL | impl Tr2<i32, X = Qux, Y = usize> for Bar {
|
||||||
| ~~~~~~~~~
|
| ~~~~~~~~~
|
||||||
|
@ -179,11 +179,11 @@ help: add missing generic argument
|
||||||
LL | impl Tr2<i32, Qux, T3, T3 = GenericTerm<i32>> for Bar {
|
LL | impl Tr2<i32, Qux, T3, T3 = GenericTerm<i32>> for Bar {
|
||||||
| ++++
|
| ++++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:61:20
|
--> $DIR/associated-types-eq-2.rs:61:20
|
||||||
|
|
|
|
||||||
LL | impl Tr2<i32, Qux, T3 = GenericTerm<i32>> for Bar {
|
LL | impl Tr2<i32, Qux, T3 = GenericTerm<i32>> for Bar {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^^^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: to use `GenericTerm<i32>` as a generic argument specify it directly
|
help: to use `GenericTerm<i32>` as a generic argument specify it directly
|
||||||
|
|
|
|
||||||
|
@ -206,7 +206,7 @@ help: add missing generic arguments
|
||||||
LL | impl Tr3<N, T2, T3, N
|
LL | impl Tr3<N, T2, T3, N
|
||||||
| ++++++++++
|
| ++++++++++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:76:10
|
--> $DIR/associated-types-eq-2.rs:76:10
|
||||||
|
|
|
|
||||||
LL | impl Tr3<N
|
LL | impl Tr3<N
|
||||||
|
@ -215,7 +215,7 @@ LL | |
|
||||||
LL | |
|
LL | |
|
||||||
LL | |
|
LL | |
|
||||||
LL | | = 42, T2 = Qux, T3 = usize> for Bar {
|
LL | | = 42, T2 = Qux, T3 = usize> for Bar {
|
||||||
| |____^ associated type not allowed here
|
| |____^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: to use `42` as a generic argument specify it directly
|
help: to use `42` as a generic argument specify it directly
|
||||||
|
|
|
|
||||||
|
@ -238,13 +238,13 @@ help: add missing generic arguments
|
||||||
LL | impl Tr3<N, T2, T3, n = 42, T2 = Qux, T3 = usize> for Qux {
|
LL | impl Tr3<N, T2, T3, n = 42, T2 = Qux, T3 = usize> for Qux {
|
||||||
| ++++++++++
|
| ++++++++++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:85:10
|
--> $DIR/associated-types-eq-2.rs:85:10
|
||||||
|
|
|
|
||||||
LL | impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
|
LL | impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
|
||||||
| ^^^^^^ associated type not allowed here
|
| ^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
|
LL | impl Tr3<n = 42, T2 = Qux, T3 = usize> for Qux {
|
||||||
| ~~~~~~~
|
| ~~~~~~~
|
||||||
|
@ -265,13 +265,13 @@ help: add missing generic arguments
|
||||||
LL | impl Tr3<N, T2, T3, N = u32, T2 = Qux, T3 = usize> for Bar {
|
LL | impl Tr3<N, T2, T3, N = u32, T2 = Qux, T3 = usize> for Bar {
|
||||||
| ++++++++++
|
| ++++++++++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:93:10
|
--> $DIR/associated-types-eq-2.rs:93:10
|
||||||
|
|
|
|
||||||
LL | impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar {
|
LL | impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar {
|
||||||
| ^^^^^^^ associated type not allowed here
|
| ^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar {
|
LL | impl Tr3<N = u32, T2 = Qux, T3 = usize> for Bar {
|
||||||
| ~~~~~~~~
|
| ~~~~~~~~
|
||||||
|
@ -294,13 +294,13 @@ help: add missing generic arguments
|
||||||
LL | impl Tr3<42, T2, T3, T2 = 42, T3 = usize> for Bar {
|
LL | impl Tr3<42, T2, T3, T2 = 42, T3 = usize> for Bar {
|
||||||
| ++++++++
|
| ++++++++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:100:14
|
--> $DIR/associated-types-eq-2.rs:100:14
|
||||||
|
|
|
|
||||||
LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar {
|
LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar {
|
||||||
| ^^^^^^^ associated type not allowed here
|
| ^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar {
|
LL | impl Tr3<42, T2 = 42, T3 = usize> for Bar {
|
||||||
| ~~~~~~~~~
|
| ~~~~~~~~~
|
||||||
|
@ -321,13 +321,13 @@ help: add missing generic arguments
|
||||||
LL | impl Tr3<N, T2, T3, X = 42, Y = Qux, Z = usize> for Bar {
|
LL | impl Tr3<N, T2, T3, X = 42, Y = Qux, Z = usize> for Bar {
|
||||||
| ++++++++++
|
| ++++++++++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:108:10
|
--> $DIR/associated-types-eq-2.rs:108:10
|
||||||
|
|
|
|
||||||
LL | impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
|
LL | impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
|
||||||
| ^^^^^^ associated type not allowed here
|
| ^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
|
LL | impl Tr3<X = 42, Y = Qux, Z = usize> for Bar {
|
||||||
| ~~~~~~~
|
| ~~~~~~~
|
||||||
|
@ -348,11 +348,11 @@ help: add missing generic argument
|
||||||
LL | impl<'a, T> St<'a, T , T = Qux> {
|
LL | impl<'a, T> St<'a, T , T = Qux> {
|
||||||
| +++
|
| +++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-2.rs:119:21
|
--> $DIR/associated-types-eq-2.rs:119:21
|
||||||
|
|
|
|
||||||
LL | impl<'a, T> St<'a , T = Qux> {
|
LL | impl<'a, T> St<'a , T = Qux> {
|
||||||
| ^^^^^^^ associated type not allowed here
|
| ^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: to use `Qux` as a generic argument specify it directly
|
help: to use `Qux` as a generic argument specify it directly
|
||||||
|
|
|
|
||||||
|
|
|
@ -11,6 +11,6 @@ impl Foo for isize {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
let x: isize = Foo::<A=usize>::bar();
|
let x: isize = Foo::<A = usize>::bar();
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/associated-types-eq-expr-path.rs:14:26
|
--> $DIR/associated-types-eq-expr-path.rs:14:26
|
||||||
|
|
|
|
||||||
LL | let x: isize = Foo::<A=usize>::bar();
|
LL | let x: isize = Foo::<A = usize>::bar();
|
||||||
| ^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ trait Super1<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Super1<'_, bar(): Send> for () {}
|
impl Super1<'_, bar(): Send> for () {}
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR not all trait items implemented
|
//~| ERROR not all trait items implemented
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -7,11 +7,11 @@ LL | #![feature(return_type_notation)]
|
||||||
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
|
||||||
= note: `#[warn(incomplete_features)]` on by default
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/rtn-in-impl-signature.rs:10:17
|
--> $DIR/rtn-in-impl-signature.rs:10:17
|
||||||
|
|
|
|
||||||
LL | impl Super1<'_, bar(): Send> for () {}
|
LL | impl Super1<'_, bar(): Send> for () {}
|
||||||
| ^^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error[E0046]: not all trait items implemented, missing: `bar`
|
error[E0046]: not all trait items implemented, missing: `bar`
|
||||||
--> $DIR/rtn-in-impl-signature.rs:10:1
|
--> $DIR/rtn-in-impl-signature.rs:10:1
|
||||||
|
|
|
@ -8,7 +8,7 @@ const T: usize = 42;
|
||||||
|
|
||||||
impl Foo<N = 3> for Bar {
|
impl Foo<N = 3> for Bar {
|
||||||
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
|
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated const equality is incomplete
|
//~| ERROR associated const equality is incomplete
|
||||||
fn do_x(&self) -> [u8; 3] {
|
fn do_x(&self) -> [u8; 3] {
|
||||||
[0u8; 3]
|
[0u8; 3]
|
||||||
|
|
|
@ -24,11 +24,11 @@ help: add missing generic argument
|
||||||
LL | impl Foo<N, N = 3> for Bar {
|
LL | impl Foo<N, N = 3> for Bar {
|
||||||
| ++
|
| ++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-89013-no-kw.rs:9:10
|
--> $DIR/issue-89013-no-kw.rs:9:10
|
||||||
|
|
|
|
||||||
LL | impl Foo<N = 3> for Bar {
|
LL | impl Foo<N = 3> for Bar {
|
||||||
| ^^^^^ associated type not allowed here
|
| ^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: to use `3` as a generic argument specify it directly
|
help: to use `3` as a generic argument specify it directly
|
||||||
|
|
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ const T: usize = 42;
|
||||||
impl Foo<N = const 3> for Bar {
|
impl Foo<N = const 3> for Bar {
|
||||||
//~^ ERROR expected lifetime, type, or constant, found keyword `const`
|
//~^ ERROR expected lifetime, type, or constant, found keyword `const`
|
||||||
//~| ERROR trait takes 1 generic
|
//~| ERROR trait takes 1 generic
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated const equality is incomplete
|
//~| ERROR associated const equality is incomplete
|
||||||
fn do_x(&self) -> [u8; 3] {
|
fn do_x(&self) -> [u8; 3] {
|
||||||
[0u8; 3]
|
[0u8; 3]
|
||||||
|
|
|
@ -36,11 +36,11 @@ help: add missing generic argument
|
||||||
LL | impl Foo<N, N = const 3> for Bar {
|
LL | impl Foo<N, N = const 3> for Bar {
|
||||||
| ++
|
| ++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-89013.rs:9:10
|
--> $DIR/issue-89013.rs:9:10
|
||||||
|
|
|
|
||||||
LL | impl Foo<N = const 3> for Bar {
|
LL | impl Foo<N = const 3> for Bar {
|
||||||
| ^^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: to use `3` as a generic argument specify it directly
|
help: to use `3` as a generic argument specify it directly
|
||||||
|
|
|
|
||||||
|
|
|
@ -10,10 +10,10 @@ impl Foo for isize {
|
||||||
fn boo(&self) -> usize { 42 }
|
fn boo(&self) -> usize { 42 }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
|
fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
//~^ ERROR associated type bindings are not allowed here [E0229]
|
//~^ ERROR associated item constraints are not allowed here [E0229]
|
||||||
//~| ERROR associated type bindings are not allowed here [E0229]
|
//~| ERROR associated item constraints are not allowed here [E0229]
|
||||||
//~| ERROR associated type bindings are not allowed here [E0229]
|
//~| ERROR associated item constraints are not allowed here [E0229]
|
||||||
//~| ERROR the trait bound `I: Foo` is not satisfied
|
//~| ERROR the trait bound `I: Foo` is not satisfied
|
||||||
//~| ERROR the trait bound `I: Foo` is not satisfied
|
//~| ERROR the trait bound `I: Foo` is not satisfied
|
||||||
|
|
||||||
|
|
|
@ -1,58 +1,58 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/E0229.rs:13:25
|
--> $DIR/E0229.rs:13:25
|
||||||
|
|
|
|
||||||
LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
|
LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
| ^^^^^ associated type not allowed here
|
| ^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
|
LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
| ~~~~~~~
|
| ~~~~~~~~~
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/E0229.rs:13:25
|
--> $DIR/E0229.rs:13:25
|
||||||
|
|
|
|
||||||
LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
|
LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
| ^^^^^ associated type not allowed here
|
| ^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
|
LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
| ~~~~~~~
|
| ~~~~~~~~~
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/E0229.rs:13:25
|
--> $DIR/E0229.rs:13:25
|
||||||
|
|
|
|
||||||
LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
|
LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
| ^^^^^ associated type not allowed here
|
| ^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
|
LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
| ~~~~~~~
|
| ~~~~~~~~~
|
||||||
|
|
||||||
error[E0277]: the trait bound `I: Foo` is not satisfied
|
error[E0277]: the trait bound `I: Foo` is not satisfied
|
||||||
--> $DIR/E0229.rs:13:15
|
--> $DIR/E0229.rs:13:15
|
||||||
|
|
|
|
||||||
LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
|
LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `I`
|
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `I`
|
||||||
|
|
|
|
||||||
help: consider restricting type parameter `I`
|
help: consider restricting type parameter `I`
|
||||||
|
|
|
|
||||||
LL | fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {}
|
LL | fn baz<I: Foo>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
error[E0277]: the trait bound `I: Foo` is not satisfied
|
error[E0277]: the trait bound `I: Foo` is not satisfied
|
||||||
--> $DIR/E0229.rs:13:37
|
--> $DIR/E0229.rs:13:39
|
||||||
|
|
|
|
||||||
LL | fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
|
LL | fn baz<I>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
| ^^ the trait `Foo` is not implemented for `I`
|
| ^^ the trait `Foo` is not implemented for `I`
|
||||||
|
|
|
|
||||||
help: consider restricting type parameter `I`
|
help: consider restricting type parameter `I`
|
||||||
|
|
|
|
||||||
LL | fn baz<I: Foo>(x: &<I as Foo<A=Bar>>::A) {}
|
LL | fn baz<I: Foo>(x: &<I as Foo<A = Bar>>::A) {}
|
||||||
| +++++
|
| +++++
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
|
@ -16,7 +16,7 @@ impl Fn<()> for Foo {
|
||||||
}
|
}
|
||||||
struct Foo1;
|
struct Foo1;
|
||||||
impl FnOnce() for Foo1 {
|
impl FnOnce() for Foo1 {
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR manual implementations of `FnOnce` are experimental
|
//~| ERROR manual implementations of `FnOnce` are experimental
|
||||||
//~| ERROR not all trait items implemented
|
//~| ERROR not all trait items implemented
|
||||||
extern "rust-call" fn call_once(self, args: ()) -> () {}
|
extern "rust-call" fn call_once(self, args: ()) -> () {}
|
||||||
|
|
|
@ -105,11 +105,11 @@ LL | impl FnOnce() for Foo1 {
|
||||||
|
|
|
|
||||||
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
|
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
|
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
|
||||||
|
|
|
|
||||||
LL | impl FnOnce() for Foo1 {
|
LL | impl FnOnce() for Foo1 {
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: parenthesized trait syntax expands to `FnOnce<(), Output=()>`
|
help: parenthesized trait syntax expands to `FnOnce<(), Output=()>`
|
||||||
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
|
--> $DIR/feature-gate-unboxed-closures-manual-impls.rs:18:6
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
struct S;
|
struct S;
|
||||||
|
|
||||||
impl Fn(u32) -> u32 for S {
|
impl Fn(u32) -> u32 for S {
|
||||||
//~^ ERROR associated type bindings are not allowed here [E0229]
|
//~^ ERROR associated item constraints are not allowed here [E0229]
|
||||||
//~| ERROR expected a `FnMut(u32)` closure, found `S`
|
//~| ERROR expected a `FnMut(u32)` closure, found `S`
|
||||||
fn call(&self) -> u32 {
|
fn call(&self) -> u32 {
|
||||||
//~^ ERROR method `call` has 1 parameter but the declaration in trait `call` has 2
|
//~^ ERROR method `call` has 1 parameter but the declaration in trait `call` has 2
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-39259.rs:6:17
|
--> $DIR/issue-39259.rs:6:17
|
||||||
|
|
|
|
||||||
LL | impl Fn(u32) -> u32 for S {
|
LL | impl Fn(u32) -> u32 for S {
|
||||||
| ^^^ associated type not allowed here
|
| ^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: parenthesized trait syntax expands to `Fn<(u32,), Output=u32>`
|
help: parenthesized trait syntax expands to `Fn<(u32,), Output=u32>`
|
||||||
--> $DIR/issue-39259.rs:6:6
|
--> $DIR/issue-39259.rs:6:6
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
trait T {
|
trait T {
|
||||||
type A: S<C<(), i32 = ()> = ()>;
|
type A: S<C<(), i32 = ()> = ()>;
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Q {}
|
trait Q {}
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-102335-gat.rs:2:21
|
--> $DIR/issue-102335-gat.rs:2:21
|
||||||
|
|
|
|
||||||
LL | type A: S<C<(), i32 = ()> = ()>;
|
LL | type A: S<C<(), i32 = ()> = ()>;
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<(), i32 = ()> = ()>;
|
LL | type A: S<C<(), i32 = ()> = ()>;
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-102335-gat.rs:2:21
|
--> $DIR/issue-102335-gat.rs:2:21
|
||||||
|
|
|
|
||||||
LL | type A: S<C<(), i32 = ()> = ()>;
|
LL | type A: S<C<(), i32 = ()> = ()>;
|
||||||
| ^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type A: S<C<(), i32 = ()> = ()>;
|
LL | type A: S<C<(), i32 = ()> = ()>;
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
|
|
|
@ -5,7 +5,7 @@ struct Foo;
|
||||||
pub trait D {
|
pub trait D {
|
||||||
fn f<T>(self)
|
fn f<T>(self)
|
||||||
where T<Bogus = Foo>: A;
|
where T<Bogus = Foo>: A;
|
||||||
//~^ ERROR associated type bindings are not allowed here [E0229]
|
//~^ ERROR associated item constraints are not allowed here [E0229]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-23543.rs:7:17
|
--> $DIR/issue-23543.rs:7:17
|
||||||
|
|
|
|
||||||
LL | where T<Bogus = Foo>: A;
|
LL | where T<Bogus = Foo>: A;
|
||||||
| ^^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ pub trait A: Copy {}
|
||||||
pub trait D {
|
pub trait D {
|
||||||
fn f<T>(self)
|
fn f<T>(self)
|
||||||
where T<Bogus = Self::AlsoBogus>: A;
|
where T<Bogus = Self::AlsoBogus>: A;
|
||||||
//~^ ERROR associated type bindings are not allowed here [E0229]
|
//~^ ERROR associated item constraints are not allowed here [E0229]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-23544.rs:5:17
|
--> $DIR/issue-23544.rs:5:17
|
||||||
|
|
|
|
||||||
LL | where T<Bogus = Self::AlsoBogus>: A;
|
LL | where T<Bogus = Self::AlsoBogus>: A;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^^^^^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,17 @@ trait A: Sized {
|
||||||
type N;
|
type N;
|
||||||
fn x() ->
|
fn x() ->
|
||||||
Self<
|
Self<
|
||||||
N= //~ ERROR associated type bindings are not allowed here
|
N= //~ ERROR associated item constraints are not allowed here
|
||||||
Self::N> {
|
Self::N> {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
fn y(&self) ->
|
fn y(&self) ->
|
||||||
std
|
std
|
||||||
<N=()> //~ ERROR associated type bindings are not allowed here
|
<N=()> //~ ERROR associated item constraints are not allowed here
|
||||||
::option::Option<()>
|
::option::Option<()>
|
||||||
{ None }
|
{ None }
|
||||||
fn z(&self) ->
|
fn z(&self) ->
|
||||||
u32<N=()> //~ ERROR associated type bindings are not allowed here
|
u32<N=()> //~ ERROR associated item constraints are not allowed here
|
||||||
{ 42 }
|
{ 42 }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-24682.rs:5:11
|
--> $DIR/issue-24682.rs:5:11
|
||||||
|
|
|
|
||||||
LL | / N=
|
LL | / N=
|
||||||
LL | | Self::N> {
|
LL | | Self::N> {
|
||||||
| |_________________^ associated type not allowed here
|
| |_________________^ associated item constraint not allowed here
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-24682.rs:11:13
|
--> $DIR/issue-24682.rs:11:13
|
||||||
|
|
|
|
||||||
LL | <N=()>
|
LL | <N=()>
|
||||||
| ^^^^ associated type not allowed here
|
| ^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-24682.rs:15:13
|
--> $DIR/issue-24682.rs:15:13
|
||||||
|
|
|
|
||||||
LL | u32<N=()>
|
LL | u32<N=()>
|
||||||
| ^^^^ associated type not allowed here
|
| ^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
<fn() as Fn()>::call;
|
<fn() as Fn()>::call;
|
||||||
//~^ ERROR associated type bindings are not allowed here [E0229]
|
//~^ ERROR associated item constraints are not allowed here [E0229]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-39687.rs:4:14
|
--> $DIR/issue-39687.rs:4:14
|
||||||
|
|
|
|
||||||
LL | <fn() as Fn()>::call;
|
LL | <fn() as Fn()>::call;
|
||||||
| ^^^^ associated type not allowed here
|
| ^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ trait CallSingle<A, B> {
|
||||||
impl<A, B, F: Fn(A) -> B> CallSingle<A, B> for F {
|
impl<A, B, F: Fn(A) -> B> CallSingle<A, B> for F {
|
||||||
fn call(&self, a: A) -> B {
|
fn call(&self, a: A) -> B {
|
||||||
<Self as Fn(A) -> B>::call(self, (a,))
|
<Self as Fn(A) -> B>::call(self, (a,))
|
||||||
//~^ ERROR associated type bindings are not allowed here
|
//~^ ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-43431.rs:9:27
|
--> $DIR/issue-43431.rs:9:27
|
||||||
|
|
|
|
||||||
LL | <Self as Fn(A) -> B>::call(self, (a,))
|
LL | <Self as Fn(A) -> B>::call(self, (a,))
|
||||||
| ^ associated type not allowed here
|
| ^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
struct Foo {}
|
struct Foo {}
|
||||||
impl Foo {
|
impl Foo {
|
||||||
fn bar(foo: Foo<Target = usize>) {}
|
fn bar(foo: Foo<Target = usize>) {}
|
||||||
//~^ associated type bindings are not allowed here
|
//~^ associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-83753-invalid-associated-type-supertrait-hrtb.rs:5:21
|
--> $DIR/issue-83753-invalid-associated-type-supertrait-hrtb.rs:5:21
|
||||||
|
|
|
|
||||||
LL | fn bar(foo: Foo<Target = usize>) {}
|
LL | fn bar(foo: Foo<Target = usize>) {}
|
||||||
| ^^^^^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | fn bar(foo: Foo<Target = usize>) {}
|
LL | fn bar(foo: Foo<Target = usize>) {}
|
||||||
| ~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -2,7 +2,7 @@ struct ErrorKind;
|
||||||
struct Error(ErrorKind);
|
struct Error(ErrorKind);
|
||||||
impl Fn(&isize) for Error {
|
impl Fn(&isize) for Error {
|
||||||
//~^ ERROR manual implementations of `Fn` are experimental [E0183]
|
//~^ ERROR manual implementations of `Fn` are experimental [E0183]
|
||||||
//~^^ ERROR associated type bindings are not allowed here [E0229]
|
//~^^ ERROR associated item constraints are not allowed here [E0229]
|
||||||
//~| ERROR not all trait items implemented
|
//~| ERROR not all trait items implemented
|
||||||
//~| ERROR expected a `FnMut(&isize)` closure, found `Error`
|
//~| ERROR expected a `FnMut(&isize)` closure, found `Error`
|
||||||
fn foo<const N: usize>(&self) -> Self::B<{ N }>;
|
fn foo<const N: usize>(&self) -> Self::B<{ N }>;
|
||||||
|
|
|
@ -20,11 +20,11 @@ LL | impl Fn(&isize) for Error {
|
||||||
|
|
|
|
||||||
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
|
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-95023.rs:3:6
|
--> $DIR/issue-95023.rs:3:6
|
||||||
|
|
|
|
||||||
LL | impl Fn(&isize) for Error {
|
LL | impl Fn(&isize) for Error {
|
||||||
| ^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: parenthesized trait syntax expands to `Fn<(&isize,), Output=()>`
|
help: parenthesized trait syntax expands to `Fn<(&isize,), Output=()>`
|
||||||
--> $DIR/issue-95023.rs:3:6
|
--> $DIR/issue-95023.rs:3:6
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
0.clone::<T = u8>(); //~ ERROR associated type bindings are not allowed here
|
0.clone::<T = u8>(); //~ ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/method-call-type-binding.rs:2:15
|
--> $DIR/method-call-type-binding.rs:2:15
|
||||||
|
|
|
|
||||||
LL | 0.clone::<T = u8>();
|
LL | 0.clone::<T = u8>();
|
||||||
| ^^^^^^ associated type not allowed here
|
| ^^^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@ trait Foo {
|
||||||
type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
|
type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
|
||||||
//~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
|
//~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
|
||||||
//~| HELP add missing
|
//~| HELP add missing
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
//~| HELP consider removing this type binding
|
//~| HELP consider removing this associated item binding
|
||||||
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
|
//~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied
|
||||||
//~| HELP add missing
|
//~| HELP add missing
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
//~| HELP consider removing this type binding
|
//~| HELP consider removing this associated item binding
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -14,13 +14,13 @@ help: add missing lifetime argument
|
||||||
LL | type Bar<'a>: Deref<Target = <Self>::Bar<'a, Target = Self>>;
|
LL | type Bar<'a>: Deref<Target = <Self>::Bar<'a, Target = Self>>;
|
||||||
| +++
|
| +++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-85347.rs:3:46
|
--> $DIR/issue-85347.rs:3:46
|
||||||
|
|
|
|
||||||
LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
|
LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
|
||||||
| ^^^^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
|
LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
|
||||||
| ~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~
|
||||||
|
@ -42,14 +42,14 @@ help: add missing lifetime argument
|
||||||
LL | type Bar<'a>: Deref<Target = <Self>::Bar<'a, Target = Self>>;
|
LL | type Bar<'a>: Deref<Target = <Self>::Bar<'a, Target = Self>>;
|
||||||
| +++
|
| +++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-85347.rs:3:46
|
--> $DIR/issue-85347.rs:3:46
|
||||||
|
|
|
|
||||||
LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
|
LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
|
||||||
| ^^^^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
help: consider removing this type binding
|
help: consider removing this associated item binding
|
||||||
|
|
|
|
||||||
LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
|
LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>;
|
||||||
| ~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -8,5 +8,5 @@ fn main() {
|
||||||
//~| HELP you might have meant to write a path instead of an associated type bound
|
//~| HELP you might have meant to write a path instead of an associated type bound
|
||||||
//~| ERROR struct takes at least 1 generic argument but 0 generic arguments were supplied
|
//~| ERROR struct takes at least 1 generic argument but 0 generic arguments were supplied
|
||||||
//~| HELP add missing generic argument
|
//~| HELP add missing generic argument
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ help: add missing generic argument
|
||||||
LL | let _: Vec<T, A:B> = A::B;
|
LL | let _: Vec<T, A:B> = A::B;
|
||||||
| ++
|
| ++
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/type-ascription-instead-of-path-in-type.rs:6:16
|
--> $DIR/type-ascription-instead-of-path-in-type.rs:6:16
|
||||||
|
|
|
|
||||||
LL | let _: Vec<A:B> = A::B;
|
LL | let _: Vec<A:B> = A::B;
|
||||||
| ^^^ associated type not allowed here
|
| ^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ struct ErrorKind;
|
||||||
struct Error(ErrorKind);
|
struct Error(ErrorKind);
|
||||||
impl Fn(&isize) for Error {
|
impl Fn(&isize) for Error {
|
||||||
//~^ ERROR manual implementations of `Fn` are experimental
|
//~^ ERROR manual implementations of `Fn` are experimental
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
//~| ERROR closure, found `Error`
|
//~| ERROR closure, found `Error`
|
||||||
//~| ERROR not all trait items implemented, missing: `call`
|
//~| ERROR not all trait items implemented, missing: `call`
|
||||||
fn from() {} //~ ERROR method `from` is not a member of trait `Fn`
|
fn from() {} //~ ERROR method `from` is not a member of trait `Fn`
|
||||||
|
|
|
@ -12,11 +12,11 @@ LL | impl Fn(&isize) for Error {
|
||||||
|
|
|
|
||||||
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
|
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/issue-87558.rs:3:6
|
--> $DIR/issue-87558.rs:3:6
|
||||||
|
|
|
|
||||||
LL | impl Fn(&isize) for Error {
|
LL | impl Fn(&isize) for Error {
|
||||||
| ^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
|
|
||||||
help: parenthesized trait syntax expands to `Fn<(&isize,), Output=()>`
|
help: parenthesized trait syntax expands to `Fn<(&isize,), Output=()>`
|
||||||
--> $DIR/issue-87558.rs:3:6
|
--> $DIR/issue-87558.rs:3:6
|
||||||
|
|
|
@ -5,6 +5,6 @@ type Pat<const START: u32, const END: u32> =
|
||||||
std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||||
//~^ ERROR type and const arguments are not allowed on const parameter `START`
|
//~^ ERROR type and const arguments are not allowed on const parameter `START`
|
||||||
//~| ERROR type arguments are not allowed on const parameter `END`
|
//~| ERROR type arguments are not allowed on const parameter `END`
|
||||||
//~| ERROR associated type bindings are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -26,11 +26,11 @@ note: const parameter `END` defined here
|
||||||
LL | type Pat<const START: u32, const END: u32> =
|
LL | type Pat<const START: u32, const END: u32> =
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error[E0229]: associated type bindings are not allowed here
|
error[E0229]: associated item constraints are not allowed here
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:67
|
--> $DIR/bad_const_generics_args_on_const_param.rs:5:67
|
||||||
|
|
|
|
||||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||||
| ^^^^^^^^^^ associated type not allowed here
|
| ^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue