Review comments

This commit is contained in:
Michael Goulet 2024-08-19 13:17:59 -04:00
parent 70641356dc
commit c1d041036e
2 changed files with 40 additions and 48 deletions

View File

@ -1,3 +1,4 @@
use std::assert_matches::debug_assert_matches;
use std::cell::LazyCell; use std::cell::LazyCell;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
@ -178,7 +179,7 @@ fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) {
ambient_variance: ty::Covariant, ambient_variance: ty::Covariant,
generics: tcx.generics_of(parent_def_id), generics: tcx.generics_of(parent_def_id),
}; };
let _ = functional_variances.relate(sig, sig); functional_variances.relate(sig, sig).unwrap();
functional_variances.variances functional_variances.variances
}), }),
outlives_env: LazyCell::new(|| { outlives_env: LazyCell::new(|| {
@ -208,10 +209,7 @@ where
VarFn: FnOnce() -> FxHashMap<DefId, ty::Variance>, VarFn: FnOnce() -> FxHashMap<DefId, ty::Variance>,
OutlivesFn: FnOnce() -> OutlivesEnvironment<'tcx>, OutlivesFn: FnOnce() -> OutlivesEnvironment<'tcx>,
{ {
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &ty::Binder<'tcx, T>) {
&mut self,
t: &ty::Binder<'tcx, T>,
) -> Self::Result {
// When we get into a binder, we need to add its own bound vars to the scope. // When we get into a binder, we need to add its own bound vars to the scope.
let mut added = vec![]; let mut added = vec![];
for arg in t.bound_vars() { for arg in t.bound_vars() {
@ -241,7 +239,7 @@ where
} }
} }
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { fn visit_ty(&mut self, t: Ty<'tcx>) {
if !t.has_aliases() { if !t.has_aliases() {
return; return;
} }
@ -293,28 +291,23 @@ where
current_def_id = generics.parent; current_def_id = generics.parent;
} }
// Compute the set of in scope params that are not captured. Get their spans, // Compute the set of in scope params that are not captured.
// since that's all we really care about them for emitting the diagnostic.
let mut uncaptured_args: FxIndexSet<_> = self let mut uncaptured_args: FxIndexSet<_> = self
.in_scope_parameters .in_scope_parameters
.iter() .iter()
.filter(|&(def_id, _)| !captured.contains(def_id)) .filter(|&(def_id, _)| !captured.contains(def_id))
.collect(); .collect();
// Remove the set of lifetimes that are in-scope that outlive some other captured
// These are args that we know are likely fine to "overcapture", since they can be // lifetime and are contravariant (i.e. covariant in argument position).
// contravariantly shortened to one of the already-captured lifetimes that they uncaptured_args.retain(|&(def_id, kind)| {
// outlive. let Some(ty::Bivariant | ty::Contravariant) = self.variances.get(def_id) else {
let covariant_long_args: FxIndexSet<_> = uncaptured_args // Keep all covariant/invariant args. Also if variance is `None`,
.iter() // then that means it's either not a lifetime, or it didn't show up
.copied() // anywhere in the signature.
.filter(|&(def_id, kind)| { return true;
let Some(ty::Bivariant | ty::Contravariant) = self.variances.get(def_id)
else {
return false;
};
let DefKind::LifetimeParam = self.tcx.def_kind(def_id) else {
return false;
}; };
// We only computed variance of lifetimes...
debug_assert_matches!(self.tcx.def_kind(def_id), DefKind::LifetimeParam);
let uncaptured = match *kind { let uncaptured = match *kind {
ParamKind::Early(name, index) => ty::Region::new_early_param( ParamKind::Early(name, index) => ty::Region::new_early_param(
self.tcx, self.tcx,
@ -325,18 +318,16 @@ where
self.parent_def_id.to_def_id(), self.parent_def_id.to_def_id(),
ty::BoundRegionKind::BrNamed(def_id, name), ty::BoundRegionKind::BrNamed(def_id, name),
), ),
ParamKind::Late => return false, // Totally ignore late bound args from binders.
ParamKind::Late => return true,
}; };
// Does this region outlive any captured region? // Does this region outlive any captured region?
captured_regions.iter().any(|r| { !captured_regions.iter().any(|r| {
self.outlives_env self.outlives_env
.free_region_map() .free_region_map()
.sub_free_regions(self.tcx, *r, uncaptured) .sub_free_regions(self.tcx, *r, uncaptured)
}) })
}) });
.collect();
// We don't care to warn on these args.
uncaptured_args.retain(|arg| !covariant_long_args.contains(arg));
// 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.
@ -546,13 +537,13 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for FunctionalVariances<'tcx> {
) -> RelateResult<'tcx, T> { ) -> RelateResult<'tcx, T> {
let old_variance = self.ambient_variance; let old_variance = self.ambient_variance;
self.ambient_variance = self.ambient_variance.xform(variance); self.ambient_variance = self.ambient_variance.xform(variance);
self.relate(a, b)?; self.relate(a, b).unwrap();
self.ambient_variance = old_variance; self.ambient_variance = old_variance;
Ok(a) Ok(a)
} }
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
structurally_relate_tys(self, a, b)?; structurally_relate_tys(self, a, b).unwrap();
Ok(a) Ok(a)
} }
@ -590,7 +581,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for FunctionalVariances<'tcx> {
a: ty::Const<'tcx>, a: ty::Const<'tcx>,
b: ty::Const<'tcx>, b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> { ) -> RelateResult<'tcx, ty::Const<'tcx>> {
structurally_relate_consts(self, a, b)?; structurally_relate_consts(self, a, b).unwrap();
Ok(a) Ok(a)
} }
@ -602,7 +593,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for FunctionalVariances<'tcx> {
where where
T: Relate<TyCtxt<'tcx>>, T: Relate<TyCtxt<'tcx>>,
{ {
self.relate(a.skip_binder(), b.skip_binder())?; self.relate(a.skip_binder(), b.skip_binder()).unwrap();
Ok(a) Ok(a)
} }
} }

View File

@ -30,6 +30,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)] #![doc(rust_logo)]
#![feature(array_windows)] #![feature(array_windows)]
#![feature(assert_matches)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(control_flow_enum)] #![feature(control_flow_enum)]
#![feature(extract_if)] #![feature(extract_if)]