Eagerly detect coroutine recursion pre-mono when possible · rust-lang/rust@d75d180 (original) (raw)
`@@ -777,7 +777,6 @@ impl<'tcx> TyCtxt<'tcx> {
`
777
777
`self,
`
778
778
`def_id: DefId,
`
779
779
`args: GenericArgsRef<'tcx>,
`
780
``
`-
inspect_coroutine_fields: InspectCoroutineFields,
`
781
780
`) -> Result<Ty<'tcx>, Ty<'tcx>> {
`
782
781
`let mut visitor = OpaqueTypeExpander {
`
783
782
`seen_opaque_tys: FxHashSet::default(),
`
`@@ -786,9 +785,7 @@ impl<'tcx> TyCtxt<'tcx> {
`
786
785
`found_recursion: false,
`
787
786
`found_any_recursion: false,
`
788
787
`check_recursion: true,
`
789
``
`-
expand_coroutines: true,
`
790
788
`tcx: self,
`
791
``
`-
inspect_coroutine_fields,
`
792
789
`};
`
793
790
``
794
791
`let expanded_type = visitor.expand_opaque_ty(def_id, args).unwrap();
`
`@@ -965,19 +962,11 @@ struct OpaqueTypeExpander<'tcx> {
`
965
962
`primary_def_id: Option,
`
966
963
`found_recursion: bool,
`
967
964
`found_any_recursion: bool,
`
968
``
`-
expand_coroutines: bool,
`
969
965
`/// Whether or not to check for recursive opaque types.
`
970
966
`` /// This is true
when we're explicitly checking for opaque type
``
971
967
`/// recursion, and 'false' otherwise to avoid unnecessary work.
`
972
968
`check_recursion: bool,
`
973
969
`tcx: TyCtxt<'tcx>,
`
974
``
`-
inspect_coroutine_fields: InspectCoroutineFields,
`
975
``
`-
}
`
976
``
-
977
``
`-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
`
978
``
`-
pub enum InspectCoroutineFields {
`
979
``
`-
No,
`
980
``
`-
Yes,
`
981
970
`}
`
982
971
``
983
972
`impl<'tcx> OpaqueTypeExpander<'tcx> {
`
`@@ -1009,41 +998,6 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
`
1009
998
`None
`
1010
999
`}
`
1011
1000
`}
`
1012
``
-
1013
``
`-
fn expand_coroutine(&mut self, def_id: DefId, args: GenericArgsRef<'tcx>) -> Option<Ty<'tcx>> {
`
1014
``
`-
if self.found_any_recursion {
`
1015
``
`-
return None;
`
1016
``
`-
}
`
1017
``
`-
let args = args.fold_with(self);
`
1018
``
`-
if !self.check_recursion || self.seen_opaque_tys.insert(def_id) {
`
1019
``
`-
let expanded_ty = match self.expanded_cache.get(&(def_id, args)) {
`
1020
``
`-
Some(expanded_ty) => *expanded_ty,
`
1021
``
`-
None => {
`
1022
``
`-
if matches!(self.inspect_coroutine_fields, InspectCoroutineFields::Yes) {
`
1023
``
`-
for bty in self.tcx.bound_coroutine_hidden_types(def_id) {
`
1024
``
`-
let hidden_ty = self.tcx.instantiate_bound_regions_with_erased(
`
1025
``
`-
bty.instantiate(self.tcx, args),
`
1026
``
`-
);
`
1027
``
`-
self.fold_ty(hidden_ty);
`
1028
``
`-
}
`
1029
``
`-
}
`
1030
``
`-
let expanded_ty = Ty::new_coroutine_witness(self.tcx, def_id, args);
`
1031
``
`-
self.expanded_cache.insert((def_id, args), expanded_ty);
`
1032
``
`-
expanded_ty
`
1033
``
`-
}
`
1034
``
`-
};
`
1035
``
`-
if self.check_recursion {
`
1036
``
`-
self.seen_opaque_tys.remove(&def_id);
`
1037
``
`-
}
`
1038
``
`-
Some(expanded_ty)
`
1039
``
`-
} else {
`
1040
``
`-
// If another opaque type that we contain is recursive, then it
`
1041
``
`-
// will report the error, so we don't have to.
`
1042
``
`-
self.found_any_recursion = true;
`
1043
``
`-
self.found_recursion = def_id == *self.primary_def_id.as_ref().unwrap();
`
1044
``
`-
None
`
1045
``
`-
}
`
1046
``
`-
}
`
1047
1001
`}
`
1048
1002
``
1049
1003
`impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
`
`@@ -1052,19 +1006,13 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
`
1052
1006
`}
`
1053
1007
``
1054
1008
`fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
`
1055
``
`-
let mut t = if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) = *t.kind() {
`
``
1009
`+
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) = *t.kind() {
`
1056
1010
`self.expand_opaque_ty(def_id, args).unwrap_or(t)
`
1057
``
`-
} else if t.has_opaque_types() || t.has_coroutines() {
`
``
1011
`+
} else if t.has_opaque_types() {
`
1058
1012
` t.super_fold_with(self)
`
1059
1013
`} else {
`
1060
1014
` t
`
1061
``
`-
};
`
1062
``
`-
if self.expand_coroutines {
`
1063
``
`-
if let ty::CoroutineWitness(def_id, args) = *t.kind() {
`
1064
``
`-
t = self.expand_coroutine(def_id, args).unwrap_or(t);
`
1065
``
`-
}
`
1066
1015
`}
`
1067
``
`-
t
`
1068
1016
`}
`
1069
1017
``
1070
1018
`fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
`
`@@ -1753,9 +1701,7 @@ pub fn reveal_opaque_types_in_bounds<'tcx>(
`
1753
1701
`found_recursion: false,
`
1754
1702
`found_any_recursion: false,
`
1755
1703
`check_recursion: false,
`
1756
``
`-
expand_coroutines: false,
`
1757
1704
` tcx,
`
1758
``
`-
inspect_coroutine_fields: InspectCoroutineFields::No,
`
1759
1705
`};
`
1760
1706
` val.fold_with(&mut visitor)
`
1761
1707
`}
`