diff options
Diffstat (limited to 'compiler/rustc_trait_selection')
| -rw-r--r-- | compiler/rustc_trait_selection/src/errors.rs | 35 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 2 |
3 files changed, 33 insertions, 8 deletions
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index afac6fc6004..68fe90f0de2 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -10,7 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{Visitor, walk_ty}; -use rustc_hir::{FnRetTy, GenericParamKind}; +use rustc_hir::{FnRetTy, GenericParamKind, Node}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::print::{PrintTraitRefExt as _, TraitRefPrintOnlyTraitPath}; use rustc_middle::ty::{self, Binder, ClosureKind, FnSig, PolyTraitRef, Region, Ty, TyCtxt}; @@ -1888,10 +1888,35 @@ pub fn impl_trait_overcapture_suggestion<'tcx>( .collect::<Vec<_>>() .join(", "); - suggs.push(( - tcx.def_span(opaque_def_id).shrink_to_hi(), - format!(" + use<{concatenated_bounds}>"), - )); + let opaque_hir_id = tcx.local_def_id_to_hir_id(opaque_def_id); + // FIXME: This is a bit too conservative, since it ignores parens already written in AST. + let (lparen, rparen) = match tcx + .hir() + .parent_iter(opaque_hir_id) + .nth(1) + .expect("expected ty to have a parent always") + .1 + { + Node::PathSegment(segment) + if segment.args().paren_sugar_output().is_some_and(|ty| ty.hir_id == opaque_hir_id) => + { + ("(", ")") + } + Node::Ty(ty) => match ty.kind { + rustc_hir::TyKind::Ptr(_) | rustc_hir::TyKind::Ref(..) => ("(", ")"), + // FIXME: RPITs are not allowed to be nested in `impl Fn() -> ...`, + // but we eventually could support that, and that would necessitate + // making this more sophisticated. + _ => ("", ""), + }, + _ => ("", ""), + }; + + let rpit_span = tcx.def_span(opaque_def_id); + if !lparen.is_empty() { + suggs.push((rpit_span.shrink_to_lo(), lparen.to_string())); + } + suggs.push((rpit_span.shrink_to_hi(), format!(" + use<{concatenated_bounds}>{rparen}"))); Some(AddPreciseCapturingForOvercapture { suggs, apit_spans }) } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 49c34550f8e..541c0c915ff 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -744,7 +744,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( let Some(clause) = clause.as_projection_clause() else { return ControlFlow::Continue(()); }; - if clause.projection_def_id() != obligation.predicate.def_id { + if clause.item_def_id() != obligation.predicate.def_id { return ControlFlow::Continue(()); } @@ -847,7 +847,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>( let bound_predicate = predicate.kind(); if let ty::ClauseKind::Projection(data) = predicate.kind().skip_binder() { let data = bound_predicate.rebind(data); - if data.projection_def_id() != obligation.predicate.def_id { + if data.item_def_id() != obligation.predicate.def_id { continue; } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index d362866cbc3..25fe43e3a0e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1737,7 +1737,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { env_predicate: PolyProjectionPredicate<'tcx>, potentially_unnormalized_candidates: bool, ) -> ProjectionMatchesProjection { - debug_assert_eq!(obligation.predicate.def_id, env_predicate.projection_def_id()); + debug_assert_eq!(obligation.predicate.def_id, env_predicate.item_def_id()); let mut nested_obligations = PredicateObligations::new(); let infer_predicate = self.infcx.instantiate_binder_with_fresh_vars( |
