about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2023-12-28 16:38:24 +0100
committerLeón Orell Valerian Liehr <me@fmease.dev>2024-02-17 08:20:05 +0100
commit38a2a65f0b7bcf137bc4756c4fa1db1c3ba3b0c9 (patch)
treeee1c75b4f312f9fb28f03da587bfb2b305857a92 /compiler
parentf62a695572770330f0853cf9744beb5b3068e6c4 (diff)
downloadrust-38a2a65f0b7bcf137bc4756c4fa1db1c3ba3b0c9.tar.gz
rust-38a2a65f0b7bcf137bc4756c4fa1db1c3ba3b0c9.zip
Remove astconv::ConvertedBinding
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs132
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs24
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs91
3 files changed, 96 insertions, 151 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index 0c35ec99dae..6940b4a5045 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -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;
 
@@ -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>,
@@ -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
@@ -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
@@ -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();
@@ -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)),
                     });
                 })
@@ -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,
@@ -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`
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index f04114229bf..ad34c31ef8f 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -1,4 +1,4 @@
-use crate::astconv::{AstConv, ConvertedBindingKind};
+use crate::astconv::AstConv;
 use crate::errors::{
     self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams,
     ParenthesizedFnTraitExpansion,
@@ -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>>,
@@ -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
@@ -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
@@ -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)
         };
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 94c49453cdc..3ccf78567ed 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -35,7 +35,6 @@ use rustc_middle::ty::{
 };
 use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
 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::{sym, BytePos, Span, DUMMY_SP};
 use rustc_target::spec::abi;
@@ -151,21 +150,6 @@ pub trait AstConv<'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
 /// 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
     /// an implicit `Self`, if this is a trait reference), returns the complete
     /// 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:
     ///
@@ -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`,
     ///    which will have been resolved to a `def_id`
     /// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type
-    ///    parameters are returned in the `GenericArgsRef`, the associated type bindings like
-    ///    `Output = u32` are returned from `create_assoc_bindings_for_generic_args`.
+    ///    parameters are returned in the `GenericArgsRef`
+    /// 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.
     ///
@@ -591,52 +577,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         (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(
         &self,
         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);
         debug!(?bound_vars);
 
-        let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
-
         let poly_trait_ref = ty::Binder::bind_with_vars(
             ty::TraitRef::new(tcx, trait_def_id, generic_args),
             bound_vars,
         );
 
-        debug!(?poly_trait_ref, ?assoc_bindings);
+        debug!(?poly_trait_ref);
         bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
 
         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,
             // since we should have emitten an error for them earlier, and they will
             // not be well-formed!
@@ -1029,7 +967,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         assoc_kind: ty::AssocKind,
         assoc_name: Ident,
         span: Span,
-        binding: Option<&ConvertedBinding<'_, 'tcx>>,
+        binding: Option<&hir::TypeBinding<'tcx>>,
     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
     where
         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.
             err.code(
                 if let Some(binding) = binding
-                    && let ConvertedBindingKind::Equality(_) = binding.kind
+                    && let hir::TypeBindingKind::Equality { .. } = binding.kind
                 {
                     E0222
                 } else {
@@ -1094,16 +1032,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     );
                     if let Some(binding) = binding {
                         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!
                                 where_bounds.push(format!(
                                     "        T: {trait}::{assoc_name} = {term}",
                                     trait = bound.print_only_trait_path(),
-                                    term = term.node,
                                 ));
                             }
                             // FIXME: Provide a suggestion.
-                            ConvertedBindingKind::Constraint(_bounds) => {}
+                            hir::TypeBindingKind::Constraint { bounds: _ } => {}
                         }
                     } else {
                         err.span_suggestion_verbose(