1
Fork 0

Do less work on the good path

This commit is contained in:
Michael Goulet 2024-08-12 18:05:07 -04:00
parent f8f4d50aa3
commit 70641356dc

View file

@ -263,6 +263,12 @@ where
self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty() self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty()
&& let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin && let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin
&& parent_def_id == self.parent_def_id && parent_def_id == self.parent_def_id
{
let opaque_span = self.tcx.def_span(opaque_def_id);
let new_capture_rules =
opaque_span.at_least_rust_2024() || self.tcx.features().lifetime_capture_rules_2024;
if !new_capture_rules
&& !opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..)))
{ {
// Compute the set of args that are captured by the opaque... // Compute the set of args that are captured by the opaque...
let mut captured = FxIndexSet::default(); let mut captured = FxIndexSet::default();
@ -302,7 +308,8 @@ where
.iter() .iter()
.copied() .copied()
.filter(|&(def_id, kind)| { .filter(|&(def_id, kind)| {
let Some(ty::Bivariant | ty::Contravariant) = self.variances.get(def_id) else { let Some(ty::Bivariant | ty::Contravariant) = self.variances.get(def_id)
else {
return false; return false;
}; };
let DefKind::LifetimeParam = self.tcx.def_kind(def_id) else { let DefKind::LifetimeParam = self.tcx.def_kind(def_id) else {
@ -331,23 +338,17 @@ where
// We don't care to warn on these args. // We don't care to warn on these args.
uncaptured_args.retain(|arg| !covariant_long_args.contains(arg)); uncaptured_args.retain(|arg| !covariant_long_args.contains(arg));
let opaque_span = self.tcx.def_span(opaque_def_id);
let new_capture_rules =
opaque_span.at_least_rust_2024() || self.tcx.features().lifetime_capture_rules_2024;
// If we have uncaptured args, and if the opaque doesn't already have // If we have uncaptured args, and if the opaque doesn't already have
// `use<>` syntax on it, and we're < edition 2024, then warn the user. // `use<>` syntax on it, and we're < edition 2024, then warn the user.
if !new_capture_rules if !uncaptured_args.is_empty() {
&& !opaque.bounds.iter().any(|bound| matches!(bound, hir::GenericBound::Use(..)))
&& !uncaptured_args.is_empty()
{
let suggestion = if let Ok(snippet) = let suggestion = if let Ok(snippet) =
self.tcx.sess.source_map().span_to_snippet(opaque_span) self.tcx.sess.source_map().span_to_snippet(opaque_span)
&& snippet.starts_with("impl ") && snippet.starts_with("impl ")
{ {
let (lifetimes, others): (Vec<_>, Vec<_>) = captured let (lifetimes, others): (Vec<_>, Vec<_>) =
.into_iter() captured.into_iter().partition(|def_id| {
.partition(|def_id| self.tcx.def_kind(*def_id) == DefKind::LifetimeParam); self.tcx.def_kind(*def_id) == DefKind::LifetimeParam
});
// Take all lifetime params first, then all others (ty/ct). // Take all lifetime params first, then all others (ty/ct).
let generics: Vec<_> = lifetimes let generics: Vec<_> = lifetimes
.into_iter() .into_iter()
@ -384,10 +385,12 @@ where
}, },
); );
} }
}
// Otherwise, if we are edition 2024, have `use<>` syntax, and // Otherwise, if we are edition 2024, have `use<>` syntax, and
// have no uncaptured args, then we should warn to the user that // have no uncaptured args, then we should warn to the user that
// it's redundant to capture all args explicitly. // it's redundant to capture all args explicitly.
else if new_capture_rules if new_capture_rules
&& let Some((captured_args, capturing_span)) = && let Some((captured_args, capturing_span)) =
opaque.bounds.iter().find_map(|bound| match *bound { opaque.bounds.iter().find_map(|bound| match *bound {
hir::GenericBound::Use(a, s) => Some((a, s)), hir::GenericBound::Use(a, s) => Some((a, s)),