More · rust-lang/rust@f943f73 (original) (raw)

1

1

`use std::assert_matches::assert_matches;

`

2

2

`use std::fmt::Debug;

`

3

``

`-

use std:📑:PhantomData;

`

4

3

``

5

4

`use rustc_data_structures::stack::ensure_sufficient_stack;

`

6

5

`use rustc_infer::infer::InferCtxt;

`

60

59

`` /// entered before passing value to the function. This is currently needed for

``

61

60

`` /// normalize_erasing_regions, which skips binders as it walks through a type.

``

62

61

`///

`

63

``

`-

/// TODO: doc

`

``

62

`+

/// This returns a set of stalled obligations if the typing mode of the underlying infcx

`

``

63

`+

/// has any stalled coroutine def ids.

`

64

64

`pub fn deeply_normalize_with_skipped_universes_and_ambiguous_goals<'tcx, T, E>(

`

65

65

`at: At<'_, 'tcx>,

`

66

66

`value: T,

`

`@@ -72,24 +72,18 @@ where

`

72

72

`{

`

73

73

`let fulfill_cx = FulfillmentCtxt::new(at.infcx);

`

74

74

`let mut folder =

`

75

``

`-

NormalizationFolder { at, fulfill_cx, depth: 0, universes, _errors: PhantomData };

`

``

75

`+

NormalizationFolder { at, fulfill_cx, depth: 0, universes, stalled_goals: vec![] };

`

76

76

`let value = value.try_fold_with(&mut folder)?;

`

77

``

`-

let goals = folder

`

78

``

`-

.fulfill_cx

`

79

``

`-

.drain_stalled_obligations_for_coroutines(at.infcx)

`

80

``

`-

.into_iter()

`

81

``

`-

.map(|obl| obl.as_goal())

`

82

``

`-

.collect();

`

83

77

`let errors = folder.fulfill_cx.select_all_or_error(at.infcx);

`

84

``

`-

if errors.is_empty() { Ok((value, goals)) } else { Err(errors) }

`

``

78

`+

if errors.is_empty() { Ok((value, folder.stalled_goals)) } else { Err(errors) }

`

85

79

`}

`

86

80

``

87

81

`struct NormalizationFolder<'me, 'tcx, E> {

`

88

82

`at: At<'me, 'tcx>,

`

89

83

`fulfill_cx: FulfillmentCtxt<'tcx, E>,

`

90

84

`depth: usize,

`

91

85

`universes: Vec<Option>,

`

92

``

`-

_errors: PhantomData,

`

``

86

`+

stalled_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,

`

93

87

`}

`

94

88

``

95

89

`impl<'tcx, E> NormalizationFolder<'_, 'tcx, E>

`

`@@ -130,10 +124,7 @@ where

`

130

124

`);

`

131

125

``

132

126

`self.fulfill_cx.register_predicate_obligation(infcx, obligation);

`

133

``

`-

let errors = self.fulfill_cx.select_where_possible(infcx);

`

134

``

`-

if !errors.is_empty() {

`

135

``

`-

return Err(errors);

`

136

``

`-

}

`

``

127

`+

self.select_all_and_stall_coroutine_predicates()?;

`

137

128

``

138

129

`// Alias is guaranteed to be fully structurally resolved,

`

139

130

`// so we can super fold here.

`

`@@ -184,6 +175,27 @@ where

`

184

175

`self.depth -= 1;

`

185

176

`Ok(result)

`

186

177

`}

`

``

178

+

``

179

`+

fn select_all_and_stall_coroutine_predicates(&mut self) -> Result<(), Vec> {

`

``

180

`+

let errors = self.fulfill_cx.select_where_possible(self.at.infcx);

`

``

181

`+

if !errors.is_empty() {

`

``

182

`+

return Err(errors);

`

``

183

`+

}

`

``

184

+

``

185

`+

self.stalled_goals.extend(

`

``

186

`+

self.fulfill_cx

`

``

187

`+

.drain_stalled_obligations_for_coroutines(self.at.infcx)

`

``

188

`+

.into_iter()

`

``

189

`+

.map(|obl| obl.as_goal()),

`

``

190

`+

);

`

``

191

+

``

192

`+

let errors = self.fulfill_cx.collect_remaining_errors(self.at.infcx);

`

``

193

`+

if !errors.is_empty() {

`

``

194

`+

return Err(errors);

`

``

195

`+

}

`

``

196

+

``

197

`+

Ok(())

`

``

198

`+

}

`

187

199

`}

`

188

200

``

189

201

`impl<'tcx, E> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx, E>

`