diff options
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
9 files changed, 173 insertions, 172 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 5c7733065c6..c1850f78f2f 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1468,12 +1468,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { depth: usize, generic_args: &'tcx hir::GenericArgs<'tcx>, ) { - if generic_args.parenthesized == hir::GenericArgsParentheses::ParenSugar { - self.visit_fn_like_elision( - generic_args.inputs(), - Some(generic_args.bindings[0].ty()), - false, - ); + if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() { + self.visit_fn_like_elision(inputs, Some(output), false); return; } @@ -1608,8 +1604,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } } - // Hack: when resolving the type `XX` in binding like `dyn - // Foo<'b, Item = XX>`, the current object-lifetime default + // Hack: When resolving the type `XX` in an assoc ty binding like + // `dyn Foo<'b, Item = XX>`, the current object-lifetime default // would be to examine the trait `Foo` to check whether it has // a lifetime bound declared on `Item`. e.g., if `Foo` is // 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 // in the trait ref `YY<...>` in `Item: YY<...>`. - for binding in generic_args.bindings { + for constraint in generic_args.constraints { let scope = Scope::ObjectLifetimeDefault { lifetime: if has_lifetime_parameter { None @@ -1646,7 +1642,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { }, 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. // // For example, given @@ -1659,13 +1655,14 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // `for<'a> T::Trait<'a, x(): for<'b> Other<'b>>` // 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>`. - 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 && self.tcx.def_kind(type_def_id) == DefKind::Trait && let Some((mut bound_vars, assoc_fn)) = BoundVarContext::supertrait_hrtb_vars( self.tcx, type_def_id, - binding.ident, + constraint.ident, ty::AssocKind::Fn, ) { 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 { self.tcx .dcx() - .span_delayed_bug(binding.ident.span, "bad return type notation here"); + .span_delayed_bug(constraint.ident.span, "bad return type notation here"); vec![] }; self.with(scope, |this| { let scope = Scope::Supertrait { bound_vars, s: this.scope }; this.with(scope, |this| { let (bound_vars, _) = this.poly_trait_ref_binder_info(); - this.record_late_bound_vars(binding.hir_id, bound_vars); - this.visit_assoc_type_binding(binding) + this.record_late_bound_vars(constraint.hir_id, bound_vars); + this.visit_assoc_item_constraint(constraint) }); }); } else if let Some(type_def_id) = type_def_id { let bound_vars = BoundVarContext::supertrait_hrtb_vars( self.tcx, type_def_id, - binding.ident, + constraint.ident, ty::AssocKind::Type, ) .map(|(bound_vars, _)| bound_vars); @@ -1710,10 +1707,10 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { bound_vars: bound_vars.unwrap_or_default(), s: this.scope, }; - this.with(scope, |this| this.visit_assoc_type_binding(binding)); + this.with(scope, |this| this.visit_assoc_item_constraint(constraint)); }); } else { - self.with(scope, |this| this.visit_assoc_type_binding(binding)); + self.with(scope, |this| this.visit_assoc_item_constraint(constraint)); } } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 1475e53c47c..24a1df70e05 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -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) .map(|index| (index, seg)) .or_else(|| { - args.bindings + args.constraints .iter() - .filter_map(TypeBinding::opt_const) + .copied() + .filter_map(AssocItemConstraint::ct) .position(|ct| ct.hir_id == hir_id) .map(|idx| (idx, seg)) }) diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 1c99713b3ae..8a9d4cd4ac7 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -290,8 +290,8 @@ pub struct AmbiguousLifetimeBound { } #[derive(Diagnostic)] -#[diag(hir_analysis_assoc_type_binding_not_allowed, code = E0229)] -pub struct AssocTypeBindingNotAllowed { +#[diag(hir_analysis_assoc_item_constraints_not_allowed_here, code = E0229)] +pub struct AssocItemConstraintsNotAllowedHere { #[primary_span] #[label] pub span: Span, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index b0ae73fcc4b..b6a1799c03f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -230,32 +230,34 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bounds } - /// Lower an associated item binding from HIR into `bounds`. + /// Lower an associated item constraint from the HIR into `bounds`. /// /// ### A Note on Binders /// /// Given something like `T: for<'a> Iterator<Item = &'a u32>`, /// 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. - #[instrument(level = "debug", skip(self, bounds, dup_bindings, path_span))] - pub(super) fn lower_assoc_item_binding( + #[instrument(level = "debug", skip(self, bounds, duplicates, path_span))] + pub(super) fn lower_assoc_item_constraint( &self, hir_ref_id: hir::HirId, trait_ref: ty::PolyTraitRef<'tcx>, - binding: &hir::TypeBinding<'tcx>, + constraint: &hir::AssocItemConstraint<'tcx>, bounds: &mut Bounds<'tcx>, - dup_bindings: &mut FxIndexMap<DefId, Span>, + duplicates: &mut FxIndexMap<DefId, Span>, path_span: Span, only_self_bounds: OnlySelfBounds, ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx(); - let assoc_kind = if binding.gen_args.parenthesized + let assoc_kind = if constraint.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation { 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 } else { ty::AssocKind::Type @@ -272,7 +274,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let candidate = if self.probe_trait_that_defines_assoc_item( trait_ref.def_id(), assoc_kind, - binding.ident, + constraint.ident, ) { // Simple case: The assoc item is defined in the current trait. trait_ref @@ -284,14 +286,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_ref.skip_binder().print_only_trait_name(), None, assoc_kind, - binding.ident, + constraint.ident, path_span, - Some(binding), + Some(constraint), )? }; 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()` // 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 .dcx() .struct_span_err( - binding.span, - format!("{} `{}` is private", assoc_item.kind, binding.ident), + constraint.span, + 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(); 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) .and_modify(|prev_span| { tcx.dcx().emit_err(errors::ValueOfAssociatedStructAlreadySpecified { - span: binding.span, + span: constraint.span, prev_span: *prev_span, - item_name: binding.ident, + item_name: constraint.ident, 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 mut emitted_bad_param_err = None; @@ -384,7 +386,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { alias_ty.into() } else { 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), fn_span: tcx.hir().span_if_local(assoc_item.def_id), note: (), @@ -398,19 +400,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output); 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) } else { // 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 // the associated item itself) and construct an alias type using them. 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 { ident, - hir_id: binding.hir_id, + hir_id: constraint.hir_id, res: Res::Err, - args: Some(binding.gen_args), + args: Some(constraint.gen_args), infer_args: false, }; @@ -426,26 +428,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }); // Provide the resolved type of the associated constant to `type_of(AnonConst)`. - if let hir::TypeBindingKind::Equality { term: hir::Term::Const(anon_const) } = - binding.kind + if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(anon_const) } = + constraint.kind { 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)); } alias_ty }; - match binding.kind { - hir::TypeBindingKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => { + match constraint.kind { + hir::AssocItemConstraintKind::Equality { .. } if let ty::AssocKind::Fn = assoc_kind => { 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>` // to a projection predicate: `<T as Iterator>::Item = u32`. - hir::TypeBindingKind::Equality { term } => { + hir::AssocItemConstraintKind::Equality { term } => { let term = match term { hir::Term::Ty(ty) => self.lower_ty(ty).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); // ---- ---- ^^^^^^^ // 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( late_bound_in_projection_ty, late_bound_in_term, |br_name| { struct_span_code_err!( tcx.dcx(), - binding.span, + constraint.span, E0582, "binding for associated type `{}` references {}, \ - which does not appear in the trait input types", - binding.ident, + which does not appear in the trait input types", + constraint.ident, br_name ) }, @@ -492,12 +494,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { projection_term, term, }), - binding.span, + constraint.span, ); } // 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`. - 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 // a trait predicate, since we only want to add predicates for the `Self` type. if !only_self_bounds.0 { diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 9c687d3282b..821c5653040 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -1,5 +1,5 @@ use crate::errors::{ - self, AssocTypeBindingNotAllowed, ManualImplementation, MissingTypeParams, + self, AssocItemConstraintsNotAllowedHere, ManualImplementation, MissingTypeParams, ParenthesizedFnTraitExpansion, TraitObjectDeclaredWithNoTraits, }; use crate::fluent_generated as fluent; @@ -121,7 +121,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_kind: ty::AssocKind, assoc_name: Ident, span: Span, - binding: Option<&hir::TypeBinding<'tcx>>, + constraint: Option<&hir::AssocItemConstraint<'tcx>>, ) -> ErrorGuaranteed where 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())) }) { 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, ident: Ident, span: Span, - binding: Option<&hir::TypeBinding<'tcx>>, + constraint: Option<&hir::AssocItemConstraint<'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 hir::TypeBindingKind::Constraint { .. } = binding.kind + && let Some(constraint) = constraint + && 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 } else { - binding.gen_args.span_ext + constraint.gen_args.span_ext }; Some(lo.between(span.shrink_to_hi())) } else { @@ -319,8 +319,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; // FIXME(associated_const_equality): This has quite a few false positives and negatives. - let wrap_in_braces_sugg = if let Some(binding) = binding - && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(hir_ty) } = binding.kind + let wrap_in_braces_sugg = if let Some(constraint) = constraint + && let Some(hir_ty) = constraint.ty() && let ty = self.lower_ty(hir_ty) && (ty.is_enum() || ty.references_error()) && tcx.features().associated_const_equality @@ -333,10 +333,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { 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. - let (span, expected_because_label, expected, got) = if let Some(binding) = binding - && let hir::TypeBindingKind::Equality { term } = binding.kind + let (span, expected_because_label, expected, got) = if let Some(constraint) = constraint + && let hir::AssocItemConstraintKind::Equality { term } = constraint.kind { let span = match term { 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 args = path.args?; - Some(args.bindings.iter().filter_map(|binding| { - let ident = binding.ident; + Some(args.constraints.iter().filter_map(|constraint| { + let ident = constraint.ident; let trait_def = path.res.def_id(); let assoc_item = tcx.associated_items(trait_def).find_by_name_and_kind( tcx, @@ -1192,14 +1192,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } -/// Emits an error regarding forbidden type binding associations -pub fn prohibit_assoc_item_binding( +/// Emit an error for the given associated item constraint. +pub fn prohibit_assoc_item_constraint( tcx: TyCtxt<'_>, - binding: &hir::TypeBinding<'_>, + constraint: &hir::AssocItemConstraint<'_>, segment: Option<(DefId, &hir::PathSegment<'_>, Span)>, ) -> ErrorGuaranteed { - let mut err = tcx.dcx().create_err(AssocTypeBindingNotAllowed { - span: binding.span, + let mut err = tcx.dcx().create_err(AssocItemConstraintsNotAllowedHere { + span: constraint.span, fn_trait_expansion: if let Some((_, segment, span)) = segment && segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar { @@ -1217,13 +1217,12 @@ pub fn prohibit_assoc_item_binding( // otherwise suggest the removal of the binding. if let Some((def_id, segment, _)) = segment && 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 let suggest_removal = |e: &mut Diag<'_>| { - let bindings = segment.args().bindings; + let constraints = segment.args().constraints; let args = segment.args().args; - let binding_span = binding.span; // Compute the span to remove based on the position // 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 // span encomassing everything within the generics brackets - let Some(binding_index) = bindings.iter().position(|b| b.hir_id == binding.hir_id) - else { + let Some(index) = constraints.iter().position(|b| b.hir_id == constraint.hir_id) else { bug!("a type binding exists but its HIR ID not found in generics"); }; - let preceding_span = if binding_index > 0 { - Some(bindings[binding_index - 1].span) + let preceding_span = if index > 0 { + Some(constraints[index - 1].span) } else { args.last().map(|a| a.span()) }; - let next_span = if binding_index < bindings.len() - 1 { - Some(bindings[binding_index + 1].span) - } else { - None - }; + let next_span = constraints.get(index + 1).map(|constraint| constraint.span); let removal_span = match (preceding_span, next_span) { - (Some(prec), _) => binding_span.with_lo(prec.hi()), - (None, Some(next)) => binding_span.with_hi(next.lo()), + (Some(prec), _) => constraint.span.with_lo(prec.hi()), + (None, Some(next)) => constraint.span.with_hi(next.lo()), (None, None) => { let Some(generics_span) = segment.args().span_ext() else { 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) { e.span_suggestion_verbose( removal_span, - "consider removing this type binding", + "consider removing this associated item binding", suggestion, Applicability::MaybeIncorrect, ); @@ -1281,7 +1275,7 @@ pub fn prohibit_assoc_item_binding( let suggest_direct_use = |e: &mut Diag<'_>, sp: Span| { if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(sp) { e.span_suggestion_verbose( - binding.span, + constraint.span, format!("to use `{snippet}` as a generic argument specify it directly"), snippet, Applicability::MaybeIncorrect, @@ -1289,11 +1283,11 @@ pub fn prohibit_assoc_item_binding( } }; - // Check if the type has a generic param with the - // same name as the assoc type name in type binding + // Check if the type has a generic param with the same name + // as the assoc type name in the associated item binding. let generics = tcx.generics_of(def_id); 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 if let Some(matching_param) = matching_param { @@ -1322,8 +1316,7 @@ pub(crate) fn fn_trait_to_string( ) -> String { let args = trait_segment .args - .as_ref() - .and_then(|args| args.args.get(0)) + .and_then(|args| args.args.first()) .and_then(|arg| match arg { hir::GenericArg::Type(ty) => match ty.kind { 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), } .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},)") } }) .ok(), @@ -1344,20 +1337,17 @@ pub(crate) fn fn_trait_to_string( let ret = trait_segment .args() - .bindings + .constraints .iter() - .find_map(|b| match (b.ident.name == sym::Output, &b.kind) { - (true, hir::TypeBindingKind::Equality { term }) => { - let span = match term { - hir::Term::Ty(ty) => ty.span, - hir::Term::Const(c) => tcx.hir().span(c.hir_id), - }; - - (span != tcx.hir().span(trait_segment.hir_id)) - .then_some(tcx.sess.source_map().span_to_snippet(span).ok()) - .flatten() + .find_map(|c| { + if c.ident.name == sym::Output + && let Some(ty) = c.ty() + && ty.span != tcx.hir().span(trait_segment.hir_id) + { + tcx.sess.source_map().span_to_snippet(ty.span).ok() + } else { + None } - _ => None, }) .unwrap_or_else(|| "()".to_string()); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs index 749f78e7920..455ed7d39cb 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs @@ -1,6 +1,6 @@ use super::IsMethodCall; use crate::hir_ty_lowering::{ - errors::prohibit_assoc_item_binding, ExplicitLateBound, GenericArgCountMismatch, + errors::prohibit_assoc_item_constraint, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition, GenericArgsLowerer, }; 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(); 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 = @@ -566,17 +566,19 @@ pub(crate) fn check_generic_arg_count( debug!(?gen_args_info); - let reported = WrongNumberOfGenericArgs::new( - tcx, - gen_args_info, - seg, - gen_params, - params_offset, - gen_args, - def_id, - ) - .diagnostic() - .emit_unless(gen_args.has_err()); + let reported = gen_args.has_err().unwrap_or_else(|| { + WrongNumberOfGenericArgs::new( + tcx, + gen_args_info, + seg, + gen_params, + params_offset, + gen_args, + def_id, + ) + .diagnostic() + .emit() + }); Err(reported) }; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index d9d36f5299b..7be661ba74d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -268,8 +268,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { 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); - if let Some((_, hir::Node::TypeBinding(binding))) = parents.next() - && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(obj_ty) } = binding.kind + if let Some((_, hir::Node::AssocItemConstraint(constraint))) = parents.next() + && let Some(obj_ty) = constraint.ty() { if let Some((_, hir::Node::TraitRef(..))) = parents.next() && let Some((_, hir::Node::Ty(ty))) = parents.next() @@ -279,10 +279,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { return; } - let lo = if binding.gen_args.span_ext.is_dummy() { - binding.ident.span + let lo = if constraint.gen_args.span_ext.is_dummy() { + constraint.ident.span } else { - binding.gen_args.span_ext + constraint.gen_args.span_ext }; let hi = obj_ty.span; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 4b1c0da6ce1..fd59fb4d284 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -22,7 +22,7 @@ mod object_safety; use crate::bounds::Bounds; use crate::collect::HirPlaceholderCollector; 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::middle::resolve_bound_vars as rbv; use crate::require_c_abi_if_c_variadic; @@ -324,8 +324,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { None, ty::BoundConstness::NotConst, ); - if let Some(b) = item_segment.args().bindings.first() { - prohibit_assoc_item_binding(self.tcx(), b, Some((def_id, item_segment, span))); + if let Some(c) = item_segment.args().constraints.first() { + prohibit_assoc_item_constraint(self.tcx(), c, Some((def_id, item_segment, span))); } 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`. /// 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 /// @@ -349,7 +350,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// 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` - /// 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. /// @@ -411,8 +412,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // Skip processing if type has no generic parameters. // 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 - // non-`Self` generic parameters. + // here and so associated item constraints will be handled regardless of whether there are + // any non-`Self` generic parameters. if generics.is_own_empty() { return (tcx.mk_args(parent_args), arg_count); } @@ -621,8 +622,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { None, ty::BoundConstness::NotConst, ); - if let Some(b) = item_segment.args().bindings.first() { - prohibit_assoc_item_binding(self.tcx(), b, Some((item_def_id, item_segment, span))); + if let Some(c) = item_segment.args().constraints.first() { + prohibit_assoc_item_constraint(self.tcx(), c, Some((item_def_id, item_segment, span))); } args } @@ -654,13 +655,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// *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 /// /// 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` /// /// to `bounds`. @@ -714,27 +715,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { debug!(?poly_trait_ref); bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity); - let mut dup_bindings = FxIndexMap::default(); - for binding in trait_segment.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! + let mut dup_constraints = FxIndexMap::default(); + for constraint in trait_segment.args().constraints { + // Don't register any associated item constraints for negative bounds, + // since we should have emitted an error for them earlier, and they + // would not be well-formed! if polarity != ty::PredicatePolarity::Positive { assert!( self.tcx().dcx().has_errors().is_some(), - "negative trait bounds should not have bindings", + "negative trait bounds should not have assoc item constraints", ); continue; } // 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, poly_trait_ref, - binding, + constraint, bounds, - &mut dup_bindings, - binding.span, + &mut dup_constraints, + constraint.span, only_self_bounds, ); // Okay to ignore `Err` because of `ErrorGuaranteed` (see above). @@ -766,8 +767,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Some(self_ty), constness, ); - if let Some(b) = trait_segment.args().bindings.first() { - prohibit_assoc_item_binding(self.tcx(), b, Some((trait_def_id, trait_segment, span))); + if let Some(c) = trait_segment.args().constraints.first() { + prohibit_assoc_item_constraint( + self.tcx(), + c, + Some((trait_def_id, trait_segment, span)), + ); } 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 /// 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>( &self, all_candidates: impl Fn() -> I, @@ -858,7 +863,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_kind: ty::AssocKind, assoc_name: Ident, span: Span, - binding: Option<&hir::TypeBinding<'tcx>>, + constraint: Option<&hir::AssocItemConstraint<'tcx>>, ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> where I: Iterator<Item = ty::PolyTraitRef<'tcx>>, @@ -877,7 +882,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { assoc_kind, assoc_name, span, - binding, + constraint, ); self.set_tainted_by_errors(reported); return Err(reported); @@ -897,8 +902,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }); // Provide a more specific error code index entry for equality bindings. err.code( - if let Some(binding) = binding - && let hir::TypeBindingKind::Equality { .. } = binding.kind + if let Some(constraint) = constraint + && let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind { E0222 } 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. let mut where_bounds = vec![]; for bound in [bound, bound2].into_iter().chain(matching_candidates) { @@ -921,9 +926,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bound_span, format!("ambiguous `{assoc_name}` from `{}`", bound.print_trait_sugared(),), ); - if let Some(binding) = binding { - match binding.kind { - hir::TypeBindingKind::Equality { term } => { + if let Some(constraint) = constraint { + match constraint.kind { + hir::AssocItemConstraintKind::Equality { term } => { let term: ty::Term<'_> = match term { hir::Term::Ty(ty) => self.lower_ty(ty).into(), hir::Term::Const(ct) => { @@ -937,7 +942,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { )); } // FIXME: Provide a suggestion. - hir::TypeBindingKind::Constraint { bounds: _ } => {} + hir::AssocItemConstraintKind::Bound { bounds: _ } => {} } } else { err.span_suggestion_verbose( @@ -1545,8 +1550,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { for segment in segments { // Only emit the first error to avoid overloading the user with error messages. - if let Some(b) = segment.args().bindings.first() { - return Err(prohibit_assoc_item_binding(self.tcx(), b, None)); + if let Some(c) = segment.args().constraints.first() { + return Err(prohibit_assoc_item_constraint(self.tcx(), c, None)); } } diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 9ddba7a6e7a..5d435a8edf9 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -489,7 +489,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { .in_definition_order() .filter(|item| item.kind == AssocKind::Type) .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()) .collect() @@ -679,11 +683,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { (last_lt.span().shrink_to_hi(), false) }; 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_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}"); debug!("sugg: {:?}", sugg); @@ -741,7 +745,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let sugg_prefix = if is_first { "" } else { ", " }; 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}"); debug!("sugg: {:?}", sugg); |
