Skip to content

Commit

Permalink
Remove astconv::ConvertedBinding
Browse files Browse the repository at this point in the history
  • Loading branch information
fmease committed Feb 17, 2024
1 parent f62a695 commit 38a2a65
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 151 deletions.
132 changes: 65 additions & 67 deletions compiler/rustc_hir_analysis/src/astconv/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ use rustc_span::{ErrorGuaranteed, Span};
use rustc_trait_selection::traits;
use smallvec::SmallVec;

use crate::astconv::{
AstConv, ConvertedBinding, ConvertedBindingKind, OnlySelfBounds, PredicateFilter,
};
use crate::astconv::{AstConv, OnlySelfBounds, PredicateFilter};
use crate::bounds::Bounds;
use crate::errors;

Expand Down Expand Up @@ -238,7 +236,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
&self,
hir_ref_id: hir::HirId,
trait_ref: ty::PolyTraitRef<'tcx>,
binding: &ConvertedBinding<'_, 'tcx>,
binding: &hir::TypeBinding<'tcx>,
bounds: &mut Bounds<'tcx>,
speculative: bool,
dup_bindings: &mut FxIndexMap<DefId, Span>,
Expand All @@ -263,21 +261,20 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {

let tcx = self.tcx();

let assoc_kind =
if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation {
ty::AssocKind::Fn
} else if let ConvertedBindingKind::Equality(term) = binding.kind
&& let ty::TermKind::Const(_) = term.node.unpack()
{
ty::AssocKind::Const
} else {
ty::AssocKind::Type
};
let assoc_kind = if binding.gen_args.parenthesized
== hir::GenericArgsParentheses::ReturnTypeNotation
{
ty::AssocKind::Fn
} else if let hir::TypeBindingKind::Equality { term: hir::Term::Const(_) } = binding.kind {
ty::AssocKind::Const
} else {
ty::AssocKind::Type
};

let candidate = if self.trait_defines_associated_item_named(
trait_ref.def_id(),
assoc_kind,
binding.item_name,
binding.ident,
) {
// Simple case: The assoc item is defined in the current trait.
trait_ref
Expand All @@ -289,14 +286,14 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
trait_ref.skip_binder().print_only_trait_name(),
None,
assoc_kind,
binding.item_name,
binding.ident,
path_span,
Some(&binding),
Some(binding),
)?
};

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()`
// instead of calling `filter_by_name_and_kind` which would needlessly normalize the
Expand All @@ -312,7 +309,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
.dcx()
.struct_span_err(
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))
.emit();
Expand All @@ -327,7 +324,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified {
span: binding.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)),
});
})
Expand Down Expand Up @@ -412,7 +409,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// 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.
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 {
ident,
hir_id: binding.hir_id,
Expand All @@ -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 {
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 {
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
// the "projection predicate" for:
//
// `<T as Iterator>::Item = u32`
bounds.push_projection_bound(
tcx,
projection_ty.map_bound(|projection_ty| ty::ProjectionPredicate {
projection_ty,
term: term.node,
}),
projection_ty
.map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }),
binding.span,
);
}
ConvertedBindingKind::Constraint(ast_bounds) => {
hir::TypeBindingKind::Constraint { bounds: ast_bounds } => {
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
//
// `<T as Iterator>::Item: Debug`
Expand Down
24 changes: 14 additions & 10 deletions compiler/rustc_hir_analysis/src/astconv/errors.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::astconv::{AstConv, ConvertedBindingKind};
use crate::astconv::AstConv;
use crate::errors::{
self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
ParenthesizedFnTraitExpansion,
Expand Down Expand Up @@ -111,7 +111,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
assoc_kind: ty::AssocKind,
assoc_name: Ident,
span: Span,
binding: Option<&super::ConvertedBinding<'_, 'tcx>>,
binding: Option<&hir::TypeBinding<'tcx>>,
) -> ErrorGuaranteed
where
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
Expand Down Expand Up @@ -290,13 +290,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
assoc_kind: ty::AssocKind,
ident: Ident,
span: Span,
binding: Option<&super::ConvertedBinding<'_, 'tcx>>,
binding: Option<&hir::TypeBinding<'tcx>>,
) -> ErrorGuaranteed {
let tcx = self.tcx();

let bound_on_assoc_const_label = if let ty::AssocKind::Const = assoc_item.kind
&& 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() {
ident.span
Expand All @@ -310,14 +310,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {

// FIXME(associated_const_equality): This has quite a few false positives and negatives.
let wrap_in_braces_sugg = if let Some(binding) = binding
&& let ConvertedBindingKind::Equality(term) = binding.kind
&& let ty::TermKind::Ty(ty) = term.node.unpack()
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind
&& let ty = self.ast_ty_to_ty(hir_ty)
&& (ty.is_enum() || ty.references_error())
&& tcx.features().associated_const_equality
{
Some(errors::AssocKindMismatchWrapInBracesSugg {
lo: term.span.shrink_to_lo(),
hi: term.span.shrink_to_hi(),
lo: hir_ty.span.shrink_to_lo(),
hi: hir_ty.span.shrink_to_hi(),
})
} else {
None
Expand All @@ -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
// one can argue that that's more “intuitive” to the user.
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 {
(ident.span, None, assoc_kind, assoc_item.kind)
};
Expand Down
Loading

0 comments on commit 38a2a65

Please sign in to comment.