Remove astconv::ConvertedBinding
This commit is contained in:
parent
f62a695572
commit
38a2a65f0b
3 changed files with 96 additions and 151 deletions
|
@ -9,9 +9,7 @@ use rustc_span::{ErrorGuaranteed, Span};
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use crate::astconv::{
|
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
|
||||||
AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter,
|
|
||||||
};
|
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
|
|
||||||
|
@ -238,7 +236,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
&self,
|
&self,
|
||||||
hir_ref_id: hir::HirId,
|
hir_ref_id: hir::HirId,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
binding: &ConvertedBinding<'_, 'tcx>,
|
binding: &hir::TypeBinding<'tcx>,
|
||||||
bounds: &mut Bounds<'tcx>,
|
bounds: &mut Bounds<'tcx>,
|
||||||
speculative: bool,
|
speculative: bool,
|
||||||
dup_bindings: &mut FxIndexMap<DefId, Span>,
|
dup_bindings: &mut FxIndexMap<DefId, Span>,
|
||||||
|
@ -263,21 +261,20 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
|
|
||||||
let assoc_kind =
|
let assoc_kind = if binding.gen_args.parenthesized
|
||||||
if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation {
|
== hir::GenericArgsParentheses::ReturnTypeNotation
|
||||||
ty::AssocKind::Fn
|
{
|
||||||
} else if let ConvertedBindingKind::Equality(term) = binding.kind
|
ty::AssocKind::Fn
|
||||||
&& let ty::TermKind::Const(_) = term.node.unpack()
|
} else if let hir::TypeBindingKind::Equality { term: hir::Term::Const(_) } = binding.kind {
|
||||||
{
|
ty::AssocKind::Const
|
||||||
ty::AssocKind::Const
|
} else {
|
||||||
} else {
|
ty::AssocKind::Type
|
||||||
ty::AssocKind::Type
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let candidate = if self.trait_defines_associated_item_named(
|
let candidate = if self.trait_defines_associated_item_named(
|
||||||
trait_ref.def_id(),
|
trait_ref.def_id(),
|
||||||
assoc_kind,
|
assoc_kind,
|
||||||
binding.item_name,
|
binding.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
|
||||||
|
@ -289,14 +286,14 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
trait_ref.skip_binder().print_only_trait_name(),
|
trait_ref.skip_binder().print_only_trait_name(),
|
||||||
None,
|
None,
|
||||||
assoc_kind,
|
assoc_kind,
|
||||||
binding.item_name,
|
binding.ident,
|
||||||
path_span,
|
path_span,
|
||||||
Some(&binding),
|
Some(binding),
|
||||||
)?
|
)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let (assoc_ident, def_scope) =
|
let (assoc_ident, def_scope) =
|
||||||
tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id);
|
tcx.adjust_ident_and_get_scope(binding.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
|
||||||
|
@ -312,7 +309,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
.dcx()
|
.dcx()
|
||||||
.struct_span_err(
|
.struct_span_err(
|
||||||
binding.span,
|
binding.span,
|
||||||
format!("{} `{}` is private", assoc_item.kind, binding.item_name),
|
format!("{} `{}` is private", assoc_item.kind, binding.ident),
|
||||||
)
|
)
|
||||||
.with_span_label(binding.span, format!("private {}", assoc_item.kind))
|
.with_span_label(binding.span, format!("private {}", assoc_item.kind))
|
||||||
.emit();
|
.emit();
|
||||||
|
@ -327,7 +324,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
|
tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
|
||||||
span: binding.span,
|
span: binding.span,
|
||||||
prev_span: *prev_span,
|
prev_span: *prev_span,
|
||||||
item_name: binding.item_name,
|
item_name: binding.ident,
|
||||||
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
|
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
@ -412,7 +409,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
// 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.
|
||||||
candidate.map_bound(|trait_ref| {
|
candidate.map_bound(|trait_ref| {
|
||||||
let ident = Ident::new(assoc_item.name, binding.item_name.span);
|
let ident = Ident::new(assoc_item.name, binding.ident.span);
|
||||||
let item_segment = hir::PathSegment {
|
let item_segment = hir::PathSegment {
|
||||||
ident,
|
ident,
|
||||||
hir_id: binding.hir_id,
|
hir_id: binding.hir_id,
|
||||||
|
@ -436,66 +433,67 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
if !speculative {
|
|
||||||
// Find any late-bound regions declared in `ty` that are not
|
|
||||||
// declared in the trait-ref or assoc_item. These are not well-formed.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
|
|
||||||
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
|
|
||||||
if let ConvertedBindingKind::Equality(term) = binding.kind {
|
|
||||||
let late_bound_in_projection_ty =
|
|
||||||
tcx.collect_constrained_late_bound_regions(&projection_ty);
|
|
||||||
let late_bound_in_term =
|
|
||||||
tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(term.node));
|
|
||||||
debug!(?late_bound_in_projection_ty);
|
|
||||||
debug!(?late_bound_in_term);
|
|
||||||
|
|
||||||
// NOTE(associated_const_equality): This error should be impossible to trigger
|
|
||||||
// with associated const equality bounds.
|
|
||||||
// FIXME: point at the type params that don't have appropriate lifetimes:
|
|
||||||
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
|
||||||
// ---- ---- ^^^^^^^
|
|
||||||
self.validate_late_bound_regions(
|
|
||||||
late_bound_in_projection_ty,
|
|
||||||
late_bound_in_term,
|
|
||||||
|br_name| {
|
|
||||||
struct_span_code_err!(
|
|
||||||
tcx.dcx(),
|
|
||||||
binding.span,
|
|
||||||
E0582,
|
|
||||||
"binding for associated type `{}` references {}, \
|
|
||||||
which does not appear in the trait input types",
|
|
||||||
binding.item_name,
|
|
||||||
br_name
|
|
||||||
)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match binding.kind {
|
match binding.kind {
|
||||||
ConvertedBindingKind::Equality(..) if let ty::AssocKind::Fn = assoc_kind => {
|
hir::TypeBindingKind::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: binding.span,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
ConvertedBindingKind::Equality(term) => {
|
hir::TypeBindingKind::Equality { term } => {
|
||||||
|
let term = match term {
|
||||||
|
hir::Term::Ty(ty) => self.ast_ty_to_ty(ty).into(),
|
||||||
|
hir::Term::Const(ct) => ty::Const::from_anon_const(tcx, ct.def_id).into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if !speculative {
|
||||||
|
// Find any late-bound regions declared in `ty` that are not
|
||||||
|
// declared in the trait-ref or assoc_item. These are not well-formed.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
|
||||||
|
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
|
||||||
|
let late_bound_in_projection_ty =
|
||||||
|
tcx.collect_constrained_late_bound_regions(&projection_ty);
|
||||||
|
let late_bound_in_term =
|
||||||
|
tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(term));
|
||||||
|
debug!(?late_bound_in_projection_ty);
|
||||||
|
debug!(?late_bound_in_term);
|
||||||
|
|
||||||
|
// FIXME: point at the type params that don't have appropriate lifetimes:
|
||||||
|
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
||||||
|
// ---- ---- ^^^^^^^
|
||||||
|
// NOTE(associated_const_equality): This error should be impossible to trigger
|
||||||
|
// with associated const equality bounds.
|
||||||
|
self.validate_late_bound_regions(
|
||||||
|
late_bound_in_projection_ty,
|
||||||
|
late_bound_in_term,
|
||||||
|
|br_name| {
|
||||||
|
struct_span_code_err!(
|
||||||
|
tcx.dcx(),
|
||||||
|
binding.span,
|
||||||
|
E0582,
|
||||||
|
"binding for associated type `{}` references {}, \
|
||||||
|
which does not appear in the trait input types",
|
||||||
|
binding.ident,
|
||||||
|
br_name
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
|
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
|
||||||
// the "projection predicate" for:
|
// the "projection predicate" for:
|
||||||
//
|
//
|
||||||
// `<T as Iterator>::Item = u32`
|
// `<T as Iterator>::Item = u32`
|
||||||
bounds.push_projection_bound(
|
bounds.push_projection_bound(
|
||||||
tcx,
|
tcx,
|
||||||
projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
|
projection_ty
|
||||||
projection_ty,
|
.map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }),
|
||||||
term: term.node,
|
|
||||||
}),
|
|
||||||
binding.span,
|
binding.span,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ConvertedBindingKind::Constraint(ast_bounds) => {
|
hir::TypeBindingKind::Constraint { bounds: ast_bounds } => {
|
||||||
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
|
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
|
||||||
//
|
//
|
||||||
// `<T as Iterator>::Item: Debug`
|
// `<T as Iterator>::Item: Debug`
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::astconv::{AstConv, ConvertedBindingKind};
|
use crate::astconv::AstConv;
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
|
self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
|
||||||
ParenthesizedFnTraitExpansion,
|
ParenthesizedFnTraitExpansion,
|
||||||
|
@ -111,7 +111,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
assoc_kind: ty::AssocKind,
|
assoc_kind: ty::AssocKind,
|
||||||
assoc_name: Ident,
|
assoc_name: Ident,
|
||||||
span: Span,
|
span: Span,
|
||||||
binding: Option<&super::ConvertedBinding<'_, 'tcx>>,
|
binding: Option<&hir::TypeBinding<'tcx>>,
|
||||||
) -> ErrorGuaranteed
|
) -> ErrorGuaranteed
|
||||||
where
|
where
|
||||||
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
||||||
|
@ -290,13 +290,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
assoc_kind: ty::AssocKind,
|
assoc_kind: ty::AssocKind,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
span: Span,
|
span: Span,
|
||||||
binding: Option<&super::ConvertedBinding<'_, 'tcx>>,
|
binding: Option<&hir::TypeBinding<'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(binding) = binding
|
||||||
&& let ConvertedBindingKind::Constraint(_) = binding.kind
|
&& let hir::TypeBindingKind::Constraint { .. } = binding.kind
|
||||||
{
|
{
|
||||||
let lo = if binding.gen_args.span_ext.is_dummy() {
|
let lo = if binding.gen_args.span_ext.is_dummy() {
|
||||||
ident.span
|
ident.span
|
||||||
|
@ -310,14 +310,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
|
|
||||||
// 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(binding) = binding
|
||||||
&& let ConvertedBindingKind::Equality(term) = binding.kind
|
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind
|
||||||
&& let ty::TermKind::Ty(ty) = term.node.unpack()
|
&& let ty = self.ast_ty_to_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
|
||||||
{
|
{
|
||||||
Some(errors::AssocKindMismatchWrapInBracesSugg {
|
Some(errors::AssocKindMismatchWrapInBracesSugg {
|
||||||
lo: term.span.shrink_to_lo(),
|
lo: hir_ty.span.shrink_to_lo(),
|
||||||
hi: term.span.shrink_to_hi(),
|
hi: hir_ty.span.shrink_to_hi(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -326,9 +326,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// For equality bounds, we want to blame the term (RHS) instead of the item (LHS) since
|
// For equality bounds, 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(binding) = binding
|
||||||
&& let ConvertedBindingKind::Equality(term) = binding.kind
|
&& let hir::TypeBindingKind::Equality { term } = binding.kind
|
||||||
{
|
{
|
||||||
(term.span, Some(ident.span), assoc_item.kind, assoc_kind)
|
let span = match term {
|
||||||
|
hir::Term::Ty(ty) => ty.span,
|
||||||
|
hir::Term::Const(ct) => tcx.def_span(ct.def_id),
|
||||||
|
};
|
||||||
|
(span, Some(ident.span), assoc_item.kind, assoc_kind)
|
||||||
} else {
|
} else {
|
||||||
(ident.span, None, assoc_kind, assoc_item.kind)
|
(ident.span, None, assoc_kind, assoc_item.kind)
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,6 @@ use rustc_middle::ty::{
|
||||||
};
|
};
|
||||||
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
|
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
|
||||||
use rustc_span::edit_distance::find_best_match_for_name;
|
use rustc_span::edit_distance::find_best_match_for_name;
|
||||||
use rustc_span::source_map::{respan, Spanned};
|
|
||||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||||
use rustc_span::{sym, BytePos, Span, DUMMY_SP};
|
use rustc_span::{sym, BytePos, Span, DUMMY_SP};
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
|
@ -151,21 +150,6 @@ pub trait AstConv<'tcx> {
|
||||||
fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
|
fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct ConvertedBinding<'a, 'tcx> {
|
|
||||||
hir_id: hir::HirId,
|
|
||||||
item_name: Ident,
|
|
||||||
kind: ConvertedBindingKind<'a, 'tcx>,
|
|
||||||
gen_args: &'tcx GenericArgs<'tcx>,
|
|
||||||
span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum ConvertedBindingKind<'a, 'tcx> {
|
|
||||||
Equality(Spanned<ty::Term<'tcx>>),
|
|
||||||
Constraint(&'a [hir::GenericBound<'tcx>]),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// New-typed boolean indicating whether explicit late-bound lifetimes
|
/// New-typed boolean indicating whether explicit late-bound lifetimes
|
||||||
/// are present in a set of generic arguments.
|
/// are present in a set of generic arguments.
|
||||||
///
|
///
|
||||||
|
@ -316,7 +300,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
/// Given the type/lifetime/const arguments provided to some path (along with
|
/// Given the type/lifetime/const arguments provided to some path (along with
|
||||||
/// an implicit `Self`, if this is a trait reference), returns the complete
|
/// an implicit `Self`, if this is a trait reference), returns the complete
|
||||||
/// set of generic arguments. This may involve applying defaulted type parameters.
|
/// set of generic arguments. This may involve applying defaulted type parameters.
|
||||||
/// Constraints on associated types are created from `create_assoc_bindings_for_generic_args`.
|
///
|
||||||
|
/// Constraints on associated types are not converted here but
|
||||||
|
/// separately in `add_predicates_for_ast_type_binding`.
|
||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
|
@ -329,8 +315,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
/// 2. The path in question is the path to the trait `std::ops::Index`,
|
/// 2. The path in question is the path to the trait `std::ops::Index`,
|
||||||
/// 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`, the associated type bindings like
|
/// parameters are returned in the `GenericArgsRef`
|
||||||
/// `Output = u32` are returned from `create_assoc_bindings_for_generic_args`.
|
/// 4. Associated type bindings like `Output = u32` are contained in `generic_args.bindings`.
|
||||||
///
|
///
|
||||||
/// 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.
|
||||||
///
|
///
|
||||||
|
@ -591,52 +577,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
(args, arg_count)
|
(args, arg_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_assoc_bindings_for_generic_args<'a>(
|
|
||||||
&self,
|
|
||||||
generic_args: &'a hir::GenericArgs<'tcx>,
|
|
||||||
) -> Vec<ConvertedBinding<'a, 'tcx>> {
|
|
||||||
// Convert associated-type bindings or constraints into a separate vector.
|
|
||||||
// Example: Given this:
|
|
||||||
//
|
|
||||||
// T: Iterator<Item = u32>
|
|
||||||
//
|
|
||||||
// The `T` is passed in as a self-type; the `Item = u32` is
|
|
||||||
// not a "type parameter" of the `Iterator` trait, but rather
|
|
||||||
// a restriction on `<T as Iterator>::Item`, so it is passed
|
|
||||||
// back separately.
|
|
||||||
let assoc_bindings = generic_args
|
|
||||||
.bindings
|
|
||||||
.iter()
|
|
||||||
.map(|binding| {
|
|
||||||
let kind = match &binding.kind {
|
|
||||||
hir::TypeBindingKind::Equality { term } => match term {
|
|
||||||
hir::Term::Ty(ty) => ConvertedBindingKind::Equality(respan(
|
|
||||||
ty.span,
|
|
||||||
self.ast_ty_to_ty(ty).into(),
|
|
||||||
)),
|
|
||||||
hir::Term::Const(c) => {
|
|
||||||
let span = self.tcx().def_span(c.def_id);
|
|
||||||
let c = Const::from_anon_const(self.tcx(), c.def_id);
|
|
||||||
ConvertedBindingKind::Equality(respan(span, c.into()))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hir::TypeBindingKind::Constraint { bounds } => {
|
|
||||||
ConvertedBindingKind::Constraint(bounds)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ConvertedBinding {
|
|
||||||
hir_id: binding.hir_id,
|
|
||||||
item_name: binding.ident,
|
|
||||||
kind,
|
|
||||||
gen_args: binding.gen_args,
|
|
||||||
span: binding.span,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
assoc_bindings
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_args_for_associated_item(
|
pub fn create_args_for_associated_item(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -742,18 +682,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
|
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
|
||||||
debug!(?bound_vars);
|
debug!(?bound_vars);
|
||||||
|
|
||||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
|
|
||||||
|
|
||||||
let poly_trait_ref = ty::Binder::bind_with_vars(
|
let poly_trait_ref = ty::Binder::bind_with_vars(
|
||||||
ty::TraitRef::new(tcx, trait_def_id, generic_args),
|
ty::TraitRef::new(tcx, trait_def_id, generic_args),
|
||||||
bound_vars,
|
bound_vars,
|
||||||
);
|
);
|
||||||
|
|
||||||
debug!(?poly_trait_ref, ?assoc_bindings);
|
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_bindings = FxIndexMap::default();
|
||||||
for binding in &assoc_bindings {
|
for binding in args.bindings {
|
||||||
// Don't register additional associated type bounds for negative bounds,
|
// Don't register additional associated type bounds for negative bounds,
|
||||||
// since we should have emitten an error for them earlier, and they will
|
// since we should have emitten an error for them earlier, and they will
|
||||||
// not be well-formed!
|
// not be well-formed!
|
||||||
|
@ -1029,7 +967,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
assoc_kind: ty::AssocKind,
|
assoc_kind: ty::AssocKind,
|
||||||
assoc_name: Ident,
|
assoc_name: Ident,
|
||||||
span: Span,
|
span: Span,
|
||||||
binding: Option<&ConvertedBinding<'_, 'tcx>>,
|
binding: Option<&hir::TypeBinding<'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>>,
|
||||||
|
@ -1069,7 +1007,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
// 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(binding) = binding
|
||||||
&& let ConvertedBindingKind::Equality(_) = binding.kind
|
&& let hir::TypeBindingKind::Equality { .. } = binding.kind
|
||||||
{
|
{
|
||||||
E0222
|
E0222
|
||||||
} else {
|
} else {
|
||||||
|
@ -1094,16 +1032,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
);
|
);
|
||||||
if let Some(binding) = binding {
|
if let Some(binding) = binding {
|
||||||
match binding.kind {
|
match binding.kind {
|
||||||
ConvertedBindingKind::Equality(term) => {
|
hir::TypeBindingKind::Equality { term } => {
|
||||||
|
let term: ty::Term<'_> = match term {
|
||||||
|
hir::Term::Ty(ty) => self.ast_ty_to_ty(ty).into(),
|
||||||
|
hir::Term::Const(ct) => {
|
||||||
|
ty::Const::from_anon_const(tcx, ct.def_id).into()
|
||||||
|
}
|
||||||
|
};
|
||||||
// FIXME(#97583): This isn't syntactically well-formed!
|
// FIXME(#97583): This isn't syntactically well-formed!
|
||||||
where_bounds.push(format!(
|
where_bounds.push(format!(
|
||||||
" T: {trait}::{assoc_name} = {term}",
|
" T: {trait}::{assoc_name} = {term}",
|
||||||
trait = bound.print_only_trait_path(),
|
trait = bound.print_only_trait_path(),
|
||||||
term = term.node,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
// FIXME: Provide a suggestion.
|
// FIXME: Provide a suggestion.
|
||||||
ConvertedBindingKind::Constraint(_bounds) => {}
|
hir::TypeBindingKind::Constraint { bounds: _ } => {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue