Skip to content

Commit be2bb4f

Browse files
committed
implement "isolated" autoderef using the Canonical mechanism
1 parent 832ac11 commit be2bb4f

File tree

5 files changed

+239
-110
lines changed

5 files changed

+239
-110
lines changed

src/librustc/infer/canonical/query_response.rs

+27
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,33 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
116116
Ok(Lrc::new(canonical_result))
117117
}
118118

119+
/// A version of `make_canonicalized_query_response` that does
120+
/// not pack in obligations, for contexts that want to drop
121+
/// pending obligations instead of treating them as an ambiguity (e.g.
122+
/// typeck "probing" contexts).
123+
///
124+
/// If you DO want to keep track of pending obligations (which
125+
/// include all region obligations, so this includes all cases
126+
/// that care about regions) with this function, you have to
127+
/// do it yourself, by e.g. having them be a part of the answer.
128+
///
129+
/// TDFX(nikomatsakis): not sure this is the best name.
130+
pub fn make_query_response_with_obligations_pending<T>(
131+
&self,
132+
inference_vars: CanonicalVarValues<'tcx>,
133+
answer: T
134+
) -> Canonical<'gcx, QueryResponse<'gcx, <T as Lift<'gcx>>::Lifted>>
135+
where
136+
T: Debug + Lift<'gcx> + TypeFoldable<'tcx>,
137+
{
138+
self.canonicalize_response(&QueryResponse {
139+
var_values: inference_vars,
140+
region_constraints: vec![],
141+
certainty: Certainty::Proven, // Ambiguities are OK!
142+
value: answer,
143+
})
144+
}
145+
119146
/// Helper for `make_canonicalized_query_response` that does
120147
/// everything up until the final canonicalization.
121148
fn make_query_response<T>(

src/librustc_typeck/check/autoderef.rs

+23-13
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc::ty::{ToPredicate, TypeFoldable};
1919
use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref};
2020

2121
use syntax_pos::Span;
22-
use syntax::ast::{NodeId, Ident};
22+
use syntax::ast::{self, Ident};
2323

2424
use std::iter;
2525

@@ -31,7 +31,7 @@ enum AutoderefKind {
3131

3232
pub struct Autoderef<'a, 'gcx: 'tcx, 'tcx: 'a> {
3333
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
34-
body_id: NodeId,
34+
body_id: ast::NodeId,
3535
param_env: ty::ParamEnv<'tcx>,
3636
steps: Vec<(Ty<'tcx>, AutoderefKind)>,
3737
cur_ty: Ty<'tcx>,
@@ -107,6 +107,26 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> {
107107
}
108108

109109
impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
110+
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
111+
param_env: ty::ParamEnv<'tcx>,
112+
body_id: ast::NodeId,
113+
span: Span,
114+
base_ty: Ty<'tcx>)
115+
-> Autoderef<'a, 'gcx, 'tcx>
116+
{
117+
Autoderef {
118+
infcx,
119+
body_id,
120+
param_env,
121+
steps: vec![],
122+
cur_ty: infcx.resolve_type_vars_if_possible(&base_ty),
123+
obligations: vec![],
124+
at_start: true,
125+
include_raw_pointers: false,
126+
span,
127+
}
128+
}
129+
110130
fn overloaded_deref_ty(&mut self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
111131
debug!("overloaded_deref_ty({:?})", ty);
112132

@@ -231,17 +251,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
231251

232252
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
233253
pub fn autoderef(&'a self, span: Span, base_ty: Ty<'tcx>) -> Autoderef<'a, 'gcx, 'tcx> {
234-
Autoderef {
235-
infcx: &self.infcx,
236-
body_id: self.body_id,
237-
param_env: self.param_env,
238-
steps: vec![],
239-
cur_ty: self.resolve_type_vars_if_possible(&base_ty),
240-
obligations: vec![],
241-
at_start: true,
242-
include_raw_pointers: false,
243-
span,
244-
}
254+
Autoderef::new(self, self.param_env, self.body_id, span, base_ty)
245255
}
246256

247257
pub fn try_overloaded_deref(&self,

0 commit comments

Comments
 (0)