Skip to content

Commit 60ac06e

Browse files
committed
Bubble old_defining_use_anchor upwards from select_all_or_error
1 parent 581c1e0 commit 60ac06e

File tree

15 files changed

+83
-40
lines changed

15 files changed

+83
-40
lines changed

compiler/rustc_hir_analysis/src/autoderef.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::errors::AutoDerefReachedRecursionLimit;
22
use crate::traits::query::evaluate_obligation::InferCtxtExt;
33
use crate::traits::NormalizeExt;
44
use crate::traits::{self, TraitEngine, TraitEngineExt};
5-
use rustc_infer::infer::InferCtxt;
5+
use rustc_infer::infer::{DefiningAnchor, InferCtxt};
66
use rustc_middle::ty::TypeVisitableExt;
77
use rustc_middle::ty::{self, Ty, TyCtxt};
88
use rustc_session::Limit;
@@ -30,6 +30,7 @@ pub struct Autoderef<'a, 'tcx> {
3030
span: Span,
3131
body_id: LocalDefId,
3232
param_env: ty::ParamEnv<'tcx>,
33+
defining_use_anchor: DefiningAnchor,
3334

3435
// Current state:
3536
state: AutoderefSnapshot<'tcx>,
@@ -99,6 +100,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
99100
body_def_id: LocalDefId,
100101
span: Span,
101102
base_ty: Ty<'tcx>,
103+
defining_use_anchor: DefiningAnchor,
102104
) -> Autoderef<'a, 'tcx> {
103105
Autoderef {
104106
infcx,
@@ -114,6 +116,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
114116
},
115117
include_raw_pointers: false,
116118
silence_errors: false,
119+
defining_use_anchor,
117120
}
118121
}
119122

@@ -145,7 +148,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
145148
let mut fulfillcx = <dyn TraitEngine<'tcx>>::new_in_snapshot(tcx);
146149
let normalized_ty =
147150
normalized_ty.into_value_registering_obligations(self.infcx, &mut *fulfillcx);
148-
let errors = fulfillcx.select_where_possible(&self.infcx);
151+
let errors = fulfillcx.select_where_possible(&self.infcx, self.defining_use_anchor);
149152
if !errors.is_empty() {
150153
// This shouldn't happen, except for evaluate/fulfill mismatches,
151154
// but that's not a reason for an ICE (`predicate_may_hold` is conservative

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1545,7 +1545,7 @@ pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
15451545
let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate);
15461546
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
15471547
}
1548-
let errors = fulfillment_cx.select_all_or_error(&infcx);
1548+
let errors = fulfillment_cx.select_all_or_error(&infcx, DefiningAnchor::Bind(def_id));
15491549
debug!(?errors);
15501550
if !errors.is_empty() {
15511551
infcx.err_ctxt().report_fulfillment_errors(&errors, None);

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1674,7 +1674,14 @@ fn receiver_is_valid<'tcx>(
16741674
return true;
16751675
}
16761676

1677-
let mut autoderef = Autoderef::new(infcx, wfcx.param_env, wfcx.body_def_id, span, receiver_ty);
1677+
let mut autoderef = Autoderef::new(
1678+
infcx,
1679+
wfcx.param_env,
1680+
wfcx.body_def_id,
1681+
span,
1682+
receiver_ty,
1683+
wfcx.ocx.defining_use_anchor(),
1684+
);
16781685

16791686
// The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`.
16801687
if arbitrary_self_types_enabled {

compiler/rustc_hir_typeck/src/autoderef.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::iter;
1212

1313
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1414
pub fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'tcx> {
15-
Autoderef::new(self, self.param_env, self.body_id, span, base_ty)
15+
Autoderef::new(self, self.param_env, self.body_id, span, base_ty, self.defining_use_anchor)
1616
}
1717

1818
pub fn try_overloaded_deref(

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
594594
&self,
595595
mutate_fulfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
596596
) {
597-
let mut result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
597+
let mut result =
598+
self.fulfillment_cx.borrow_mut().select_where_possible(self, self.defining_use_anchor);
598599
if !result.is_empty() {
599600
mutate_fulfillment_errors(&mut result);
600601
self.adjust_fulfillment_errors_for_expr_obligation(&mut result);
@@ -746,7 +747,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
746747

747748
let expect_args = self
748749
.fudge_inference_if_ok(|| {
749-
let ocx = ObligationCtxt::new_in_snapshot(self);
750+
let ocx = ObligationCtxt::new_in_snapshot(self)
751+
.with_defining_use_anchor(self.defining_use_anchor);
750752

751753
// Attempt to apply a subtyping relationship between the formal
752754
// return type (likely containing type variables if the function

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -507,10 +507,16 @@ fn method_autoderef_steps<'tcx>(
507507
let (ref infcx, goal, inference_vars) = tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &goal);
508508
let ParamEnvAnd { param_env, value: self_ty } = goal;
509509

510-
let mut autoderef =
511-
Autoderef::new(infcx, param_env, hir::def_id::CRATE_DEF_ID, DUMMY_SP, self_ty)
512-
.include_raw_pointers()
513-
.silence_errors();
510+
let mut autoderef = Autoderef::new(
511+
infcx,
512+
param_env,
513+
hir::def_id::CRATE_DEF_ID,
514+
DUMMY_SP,
515+
self_ty,
516+
infer::DefiningAnchor::Error,
517+
)
518+
.include_raw_pointers()
519+
.silence_errors();
514520
let mut reached_raw_pointer = false;
515521
let mut steps: Vec<_> = autoderef
516522
.by_ref()

compiler/rustc_infer/src/infer/canonical/query_response.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl<'tcx> InferCtxt<'tcx> {
111111
let tcx = self.tcx;
112112

113113
// Select everything, returning errors.
114-
let true_errors = fulfill_cx.select_where_possible(self);
114+
let true_errors = fulfill_cx.select_where_possible(self, self.old_defining_use_anchor);
115115
debug!("true_errors = {:#?}", true_errors);
116116

117117
if !true_errors.is_empty() {
@@ -121,7 +121,7 @@ impl<'tcx> InferCtxt<'tcx> {
121121
}
122122

123123
// Anything left unselected *now* must be an ambiguity.
124-
let ambig_errors = fulfill_cx.select_all_or_error(self);
124+
let ambig_errors = fulfill_cx.select_all_or_error(self, self.old_defining_use_anchor);
125125
debug!("ambig_errors = {:#?}", ambig_errors);
126126

127127
let region_obligations = self.take_registered_region_obligations();

compiler/rustc_infer/src/traits/engine.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::infer::InferCtxt;
1+
use crate::infer::{DefiningAnchor, InferCtxt};
22
use crate::traits::Obligation;
33
use rustc_hir::def_id::DefId;
44
use rustc_middle::ty::{self, ToPredicate, Ty};
@@ -36,7 +36,11 @@ pub trait TraitEngine<'tcx>: 'tcx {
3636
obligation: PredicateObligation<'tcx>,
3737
);
3838

39-
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
39+
fn select_where_possible(
40+
&mut self,
41+
infcx: &InferCtxt<'tcx>,
42+
defining_use_anchor: DefiningAnchor,
43+
) -> Vec<FulfillmentError<'tcx>>;
4044

4145
fn collect_remaining_errors(&mut self) -> Vec<FulfillmentError<'tcx>>;
4246

@@ -58,7 +62,11 @@ pub trait TraitEngineExt<'tcx> {
5862
obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
5963
);
6064

61-
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
65+
fn select_all_or_error(
66+
&mut self,
67+
infcx: &InferCtxt<'tcx>,
68+
defining_use_anchor: DefiningAnchor,
69+
) -> Vec<FulfillmentError<'tcx>>;
6270
}
6371

6472
impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
@@ -72,8 +80,12 @@ impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
7280
}
7381
}
7482

75-
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
76-
let errors = self.select_where_possible(infcx);
83+
fn select_all_or_error(
84+
&mut self,
85+
infcx: &InferCtxt<'tcx>,
86+
defining_use_anchor: DefiningAnchor,
87+
) -> Vec<FulfillmentError<'tcx>> {
88+
let errors = self.select_where_possible(infcx, defining_use_anchor);
7789
if !errors.is_empty() {
7890
return errors;
7991
}

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::mem;
22

3-
use rustc_infer::infer::InferCtxt;
3+
use rustc_infer::infer::{DefiningAnchor, InferCtxt};
44
use rustc_infer::traits::{
55
query::NoSolution, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
66
PredicateObligation, SelectionError, TraitEngine,
@@ -51,7 +51,11 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
5151
.collect()
5252
}
5353

54-
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
54+
fn select_where_possible(
55+
&mut self,
56+
infcx: &InferCtxt<'tcx>,
57+
_defining_use_anchor: DefiningAnchor,
58+
) -> Vec<FulfillmentError<'tcx>> {
5559
let mut errors = Vec::new();
5660
for i in 0.. {
5761
if !infcx.tcx.recursion_limit().value_within_limit(i) {

compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::traits::{
88
SelectionError, TraitEngine,
99
};
1010
use rustc_data_structures::fx::FxIndexSet;
11+
use rustc_infer::infer::DefiningAnchor;
1112
use rustc_middle::ty::TypeVisitableExt;
1213

1314
pub struct FulfillmentContext<'tcx> {
@@ -54,7 +55,11 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
5455
.collect()
5556
}
5657

57-
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
58+
fn select_where_possible(
59+
&mut self,
60+
infcx: &InferCtxt<'tcx>,
61+
_defining_use_anchor: DefiningAnchor,
62+
) -> Vec<FulfillmentError<'tcx>> {
5863
if !self.usable_in_snapshot {
5964
assert!(!infcx.is_in_snapshot());
6065
}

0 commit comments

Comments
 (0)