Skip to content

Commit 3d4c312

Browse files
authored
Rollup merge of rust-lang#104926 - spastorino:calculate_diverging_fallback-cleanups, r=lcnr
Move relationships from FulfillmentContext to Inherited r? `@lcnr`
2 parents d3322e2 + b905f80 commit 3d4c312

File tree

10 files changed

+61
-113
lines changed

10 files changed

+61
-113
lines changed

compiler/rustc_hir_typeck/src/fallback.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
196196
) -> FxHashMap<Ty<'tcx>, Ty<'tcx>> {
197197
debug!("calculate_diverging_fallback({:?})", unsolved_variables);
198198

199-
let relationships = self.fulfillment_cx.borrow_mut().relationships().clone();
200-
201199
// Construct a coercion graph where an edge `A -> B` indicates
202200
// a type variable is that is coerced
203201
let coercion_graph = self.create_coercion_graph();
@@ -281,9 +279,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
281279
roots_reachable_from_non_diverging,
282280
);
283281

284-
debug!("inherited: {:#?}", self.inh.fulfillment_cx.borrow_mut().pending_obligations());
285282
debug!("obligations: {:#?}", self.fulfillment_cx.borrow_mut().pending_obligations());
286-
debug!("relationships: {:#?}", relationships);
287283

288284
// For each diverging variable, figure out whether it can
289285
// reach a member of N. If so, it falls back to `()`. Else
@@ -297,16 +293,16 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
297293
.depth_first_search(root_vid)
298294
.any(|n| roots_reachable_from_non_diverging.visited(n));
299295

300-
let mut relationship = ty::FoundRelationships { self_in_trait: false, output: false };
296+
let mut found_infer_var_info = ty::InferVarInfo { self_in_trait: false, output: false };
301297

302-
for (vid, rel) in relationships.iter() {
303-
if self.root_var(*vid) == root_vid {
304-
relationship.self_in_trait |= rel.self_in_trait;
305-
relationship.output |= rel.output;
298+
for (vid, info) in self.inh.infer_var_info.borrow().iter() {
299+
if self.infcx.root_var(*vid) == root_vid {
300+
found_infer_var_info.self_in_trait |= info.self_in_trait;
301+
found_infer_var_info.output |= info.output;
306302
}
307303
}
308304

309-
if relationship.self_in_trait && relationship.output {
305+
if found_infer_var_info.self_in_trait && found_infer_var_info.output {
310306
// This case falls back to () to ensure that the code pattern in
311307
// tests/ui/never_type/fallback-closure-ret.rs continues to
312308
// compile when never_type_fallback is enabled.

compiler/rustc_hir_typeck/src/inherited.rs

+48-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::callee::DeferredCallResolution;
22

3-
use rustc_data_structures::fx::FxHashSet;
3+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
44
use rustc_hir as hir;
55
use rustc_hir::def_id::LocalDefId;
66
use rustc_hir::HirIdMap;
@@ -10,7 +10,8 @@ use rustc_middle::ty::visit::TypeVisitable;
1010
use rustc_middle::ty::{self, Ty, TyCtxt};
1111
use rustc_span::def_id::LocalDefIdMap;
1212
use rustc_span::{self, Span};
13-
use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
13+
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
14+
use rustc_trait_selection::traits::{self, PredicateObligation, TraitEngine, TraitEngineExt as _};
1415

1516
use std::cell::RefCell;
1617
use std::ops::Deref;
@@ -63,6 +64,8 @@ pub struct Inherited<'tcx> {
6364
/// we record that type variable here. This is later used to inform
6465
/// fallback. See the `fallback` module for details.
6566
pub(super) diverging_type_vars: RefCell<FxHashSet<Ty<'tcx>>>,
67+
68+
pub(super) infer_var_info: RefCell<FxHashMap<ty::TyVid, ty::InferVarInfo>>,
6669
}
6770

6871
impl<'tcx> Deref for Inherited<'tcx> {
@@ -128,6 +131,7 @@ impl<'tcx> Inherited<'tcx> {
128131
deferred_generator_interiors: RefCell::new(Vec::new()),
129132
diverging_type_vars: RefCell::new(Default::default()),
130133
body_id,
134+
infer_var_info: RefCell::new(Default::default()),
131135
}
132136
}
133137

@@ -136,6 +140,9 @@ impl<'tcx> Inherited<'tcx> {
136140
if obligation.has_escaping_bound_vars() {
137141
span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
138142
}
143+
144+
self.update_infer_var_info(&obligation);
145+
139146
self.fulfillment_cx.borrow_mut().register_predicate_obligation(self, obligation);
140147
}
141148

@@ -152,4 +159,43 @@ impl<'tcx> Inherited<'tcx> {
152159
self.register_predicates(infer_ok.obligations);
153160
infer_ok.value
154161
}
162+
163+
pub fn update_infer_var_info(&self, obligation: &PredicateObligation<'tcx>) {
164+
let infer_var_info = &mut self.infer_var_info.borrow_mut();
165+
166+
// (*) binder skipped
167+
if let ty::PredicateKind::Clause(ty::Clause::Trait(tpred)) = obligation.predicate.kind().skip_binder()
168+
&& let Some(ty) = self.shallow_resolve(tpred.self_ty()).ty_vid().map(|t| self.root_var(t))
169+
&& self.tcx.lang_items().sized_trait().map_or(false, |st| st != tpred.trait_ref.def_id)
170+
{
171+
let new_self_ty = self.tcx.types.unit;
172+
173+
// Then construct a new obligation with Self = () added
174+
// to the ParamEnv, and see if it holds.
175+
let o = obligation.with(self.tcx,
176+
obligation
177+
.predicate
178+
.kind()
179+
.rebind(
180+
// (*) binder moved here
181+
ty::PredicateKind::Clause(ty::Clause::Trait(tpred.with_self_ty(self.tcx, new_self_ty)))
182+
),
183+
);
184+
// Don't report overflow errors. Otherwise equivalent to may_hold.
185+
if let Ok(result) = self.probe(|_| self.evaluate_obligation(&o)) && result.may_apply() {
186+
infer_var_info.entry(ty).or_default().self_in_trait = true;
187+
}
188+
}
189+
190+
if let ty::PredicateKind::Clause(ty::Clause::Projection(predicate)) =
191+
obligation.predicate.kind().skip_binder()
192+
{
193+
// If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
194+
// we need to make it into one.
195+
if let Some(vid) = predicate.term.ty().and_then(|ty| ty.ty_vid()) {
196+
debug!("infer_var_info: {:?}.output = true", vid);
197+
infer_var_info.entry(vid).or_default().output = true;
198+
}
199+
}
200+
}
155201
}

compiler/rustc_infer/src/traits/engine.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::infer::InferCtxt;
22
use crate::traits::Obligation;
3-
use rustc_data_structures::fx::FxHashMap;
43
use rustc_hir::def_id::DefId;
54
use rustc_middle::ty::{self, ToPredicate, Ty};
65

@@ -42,8 +41,6 @@ pub trait TraitEngine<'tcx>: 'tcx {
4241
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
4342

4443
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
45-
46-
fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships>;
4744
}
4845

4946
pub trait TraitEngineExt<'tcx> {

compiler/rustc_middle/src/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2619,7 +2619,7 @@ impl<'tcx> fmt::Debug for SymbolName<'tcx> {
26192619
}
26202620

26212621
#[derive(Debug, Default, Copy, Clone)]
2622-
pub struct FoundRelationships {
2622+
pub struct InferVarInfo {
26232623
/// This is true if we identified that this Ty (`?T`) is found in a `?T: Foo`
26242624
/// obligation, where:
26252625
///

compiler/rustc_trait_selection/src/solve/fulfill.rs

-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
use std::mem;
22

3-
use rustc_data_structures::fx::FxHashMap;
43
use rustc_infer::{
54
infer::InferCtxt,
65
traits::{
76
query::NoSolution, FulfillmentError, FulfillmentErrorCode, PredicateObligation,
87
SelectionError, TraitEngine,
98
},
109
};
11-
use rustc_middle::ty;
1210

1311
use super::{search_graph, Certainty, EvalCtxt};
1412

@@ -102,8 +100,4 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
102100
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
103101
self.obligations.clone()
104102
}
105-
106-
fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships> {
107-
unimplemented!("Should be moved out of `TraitEngine`")
108-
}
109103
}

compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs

+3-15
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,18 @@ use crate::traits::{
77
ChalkEnvironmentAndGoal, FulfillmentError, FulfillmentErrorCode, PredicateObligation,
88
SelectionError, TraitEngine,
99
};
10-
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
11-
use rustc_middle::ty::{self, TypeVisitable};
10+
use rustc_data_structures::fx::FxIndexSet;
11+
use rustc_middle::ty::TypeVisitable;
1212

1313
pub struct FulfillmentContext<'tcx> {
1414
obligations: FxIndexSet<PredicateObligation<'tcx>>,
1515

16-
relationships: FxHashMap<ty::TyVid, ty::FoundRelationships>,
17-
1816
usable_in_snapshot: bool,
1917
}
2018

2119
impl FulfillmentContext<'_> {
2220
pub(super) fn new() -> Self {
23-
FulfillmentContext {
24-
obligations: FxIndexSet::default(),
25-
relationships: FxHashMap::default(),
26-
usable_in_snapshot: false,
27-
}
21+
FulfillmentContext { obligations: FxIndexSet::default(), usable_in_snapshot: false }
2822
}
2923

3024
pub(crate) fn new_in_snapshot() -> Self {
@@ -43,8 +37,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
4337
}
4438
let obligation = infcx.resolve_vars_if_possible(obligation);
4539

46-
super::relationships::update(self, infcx, &obligation);
47-
4840
self.obligations.insert(obligation);
4941
}
5042

@@ -154,8 +146,4 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
154146
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
155147
self.obligations.iter().cloned().collect()
156148
}
157-
158-
fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships> {
159-
&mut self.relationships
160-
}
161149
}

compiler/rustc_trait_selection/src/traits/fulfill.rs

+2-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::infer::{InferCtxt, TyOrConstInferVar};
2-
use rustc_data_structures::fx::FxHashMap;
32
use rustc_data_structures::obligation_forest::ProcessResult;
43
use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome};
54
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
@@ -54,8 +53,6 @@ pub struct FulfillmentContext<'tcx> {
5453
// fulfillment context.
5554
predicates: ObligationForest<PendingPredicateObligation<'tcx>>,
5655

57-
relationships: FxHashMap<ty::TyVid, ty::FoundRelationships>,
58-
5956
// Is it OK to register obligations into this infcx inside
6057
// an infcx snapshot?
6158
//
@@ -85,19 +82,11 @@ static_assert_size!(PendingPredicateObligation<'_>, 72);
8582
impl<'a, 'tcx> FulfillmentContext<'tcx> {
8683
/// Creates a new fulfillment context.
8784
pub(super) fn new() -> FulfillmentContext<'tcx> {
88-
FulfillmentContext {
89-
predicates: ObligationForest::new(),
90-
relationships: FxHashMap::default(),
91-
usable_in_snapshot: false,
92-
}
85+
FulfillmentContext { predicates: ObligationForest::new(), usable_in_snapshot: false }
9386
}
9487

9588
pub(super) fn new_in_snapshot() -> FulfillmentContext<'tcx> {
96-
FulfillmentContext {
97-
predicates: ObligationForest::new(),
98-
relationships: FxHashMap::default(),
99-
usable_in_snapshot: true,
100-
}
89+
FulfillmentContext { predicates: ObligationForest::new(), usable_in_snapshot: true }
10190
}
10291

10392
/// Attempts to select obligations using `selcx`.
@@ -139,8 +128,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
139128

140129
assert!(!infcx.is_in_snapshot() || self.usable_in_snapshot);
141130

142-
super::relationships::update(self, infcx, &obligation);
143-
144131
self.predicates
145132
.register_obligation(PendingPredicateObligation { obligation, stalled_on: vec![] });
146133
}
@@ -164,10 +151,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
164151
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> {
165152
self.predicates.map_pending_obligations(|o| o.obligation.clone())
166153
}
167-
168-
fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships> {
169-
&mut self.relationships
170-
}
171154
}
172155

173156
struct FulfillProcessor<'a, 'tcx> {

compiler/rustc_trait_selection/src/traits/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ mod object_safety;
1414
pub mod outlives_bounds;
1515
mod project;
1616
pub mod query;
17-
pub(crate) mod relationships;
1817
mod select;
1918
mod specialize;
2019
mod structural_match;

compiler/rustc_trait_selection/src/traits/relationships.rs

-48
This file was deleted.

tests/ui/traits/new-solver/fn-trait-closure.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
// compile-flags: -Ztrait-solver=next
2-
// known-bug: unknown
3-
// failure-status: 101
4-
// dont-check-compiler-stderr
5-
6-
// This test will fail until we fix `FulfillmentCtxt::relationships`. That's
7-
// because we create a type variable for closure upvar types, which is not
8-
// constrained until after we try to do fallback on diverging type variables.
9-
// Thus, we will call that function, which is unimplemented.
2+
// check-pass
103

114
fn require_fn(_: impl Fn() -> i32) {}
125

0 commit comments

Comments
 (0)