Skip to content

Commit 480cd8f

Browse files
committed
Ground work for replacing the ClosureTyper trait
1 parent 79d0289 commit 480cd8f

File tree

15 files changed

+170
-21
lines changed

15 files changed

+170
-21
lines changed

src/librustc/middle/check_const.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
283283

284284
fn check_static_type(&self, e: &ast::Expr) {
285285
let ty = self.tcx.node_id_to_type(e.id);
286-
let infcx = infer::new_infer_ctxt(self.tcx, None);
286+
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None);
287287
let mut fulfill_cx = traits::FulfillmentContext::new(false);
288288
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
289289
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);

src/librustc/middle/const_eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
10311031
substs: trait_substs });
10321032

10331033
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
1034-
let infcx = infer::new_infer_ctxt(tcx, None);
1034+
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
10351035

10361036
let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment);
10371037
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),

src/librustc/middle/infer/mod.rs

+150-4
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,24 @@ pub use self::freshen::TypeFreshener;
2323
pub use self::region_inference::GenericKind;
2424

2525
use middle::free_region::FreeRegionMap;
26+
use middle::mem_categorization as mc;
27+
use middle::mem_categorization::McResult;
28+
use middle::region::{self, CodeExtent};
2629
use middle::subst;
2730
use middle::subst::Substs;
31+
use middle::subst::Subst;
32+
use middle::traits;
2833
use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
2934
use middle::ty::{self, Ty, HasTypeFlags};
3035
use middle::ty_fold::{self, TypeFolder, TypeFoldable};
3136
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
3237
use rustc_data_structures::unify::{self, UnificationTable};
33-
use std::cell::{RefCell};
38+
use std::cell::{RefCell, Ref};
3439
use std::fmt;
3540
use syntax::ast;
3641
use syntax::codemap;
3742
use syntax::codemap::Span;
38-
use util::nodemap::FnvHashMap;
43+
use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
3944

4045
use self::combine::CombineFields;
4146
use self::region_inference::{RegionVarBindings, RegionSnapshot};
@@ -64,6 +69,8 @@ pub type fres<T> = Result<T, fixup_err>; // "fixup result"
6469
pub struct InferCtxt<'a, 'tcx: 'a> {
6570
pub tcx: &'a ty::ctxt<'tcx>,
6671

72+
pub tables: &'a RefCell<ty::Tables<'tcx>>,
73+
6774
// We instantiate UnificationTable with bounds<Ty> because the
6875
// types that might instantiate a general type variable have an
6976
// order, represented by its upper and lower bounds.
@@ -80,7 +87,9 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
8087

8188
pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>,
8289

83-
// pub tables: &'a RefCell<ty::Tables<'tcx>>
90+
normalize: bool,
91+
92+
err_count_on_creation: usize,
8493
}
8594

8695
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
@@ -314,15 +323,19 @@ pub fn fixup_err_to_string(f: fixup_err) -> String {
314323
}
315324

316325
pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
326+
tables: &'a RefCell<ty::Tables<'tcx>>,
317327
param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>)
318328
-> InferCtxt<'a, 'tcx> {
319329
InferCtxt {
320330
tcx: tcx,
331+
tables: tables,
321332
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
322333
int_unification_table: RefCell::new(UnificationTable::new()),
323334
float_unification_table: RefCell::new(UnificationTable::new()),
324335
region_vars: RegionVarBindings::new(tcx),
325-
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment())
336+
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()),
337+
normalize: true,
338+
err_count_on_creation: tcx.sess.err_count()
326339
}
327340
}
328341

@@ -437,6 +450,92 @@ pub struct CombinedSnapshot {
437450
region_vars_snapshot: RegionSnapshot,
438451
}
439452

453+
impl<'a, 'tcx> mc::Typer<'tcx> for InferCtxt<'a, 'tcx> {
454+
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
455+
let ty = self.node_ty(id);
456+
self.resolve_type_vars_or_error(&ty)
457+
}
458+
459+
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
460+
let ty = self.adjust_expr_ty(expr, self.tables.borrow().adjustments.get(&expr.id));
461+
self.resolve_type_vars_or_error(&ty)
462+
}
463+
464+
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
465+
let ty = self.resolve_type_vars_if_possible(&ty);
466+
!traits::type_known_to_meet_builtin_bound(self, self, ty, ty::BoundCopy, span)
467+
}
468+
469+
fn node_method_ty(&self, method_call: ty::MethodCall)
470+
-> Option<Ty<'tcx>> {
471+
self.tables
472+
.borrow()
473+
.method_map
474+
.get(&method_call)
475+
.map(|method| method.ty)
476+
.map(|ty| self.resolve_type_vars_if_possible(&ty))
477+
}
478+
479+
fn node_method_origin(&self, method_call: ty::MethodCall)
480+
-> Option<ty::MethodOrigin<'tcx>>
481+
{
482+
self.tables
483+
.borrow()
484+
.method_map
485+
.get(&method_call)
486+
.map(|method| method.origin.clone())
487+
}
488+
489+
fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
490+
fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
491+
&tables.adjustments
492+
}
493+
494+
Ref::map(self.tables.borrow(), project_adjustments)
495+
}
496+
497+
fn is_method_call(&self, id: ast::NodeId) -> bool {
498+
self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
499+
}
500+
501+
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
502+
self.parameter_environment.temporary_scope(rvalue_id)
503+
}
504+
505+
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
506+
self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
507+
}
508+
}
509+
510+
impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> {
511+
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
512+
&self.parameter_environment
513+
}
514+
515+
fn closure_kind(&self,
516+
def_id: ast::DefId)
517+
-> Option<ty::ClosureKind>
518+
{
519+
self.tables.borrow().closure_kinds.get(&def_id).cloned()
520+
}
521+
522+
fn closure_type(&self,
523+
def_id: ast::DefId,
524+
substs: &subst::Substs<'tcx>)
525+
-> ty::ClosureTy<'tcx>
526+
{
527+
self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self.tcx, substs)
528+
}
529+
530+
fn closure_upvars(&self,
531+
def_id: ast::DefId,
532+
substs: &Substs<'tcx>)
533+
-> Option<Vec<ty::ClosureUpvar<'tcx>>>
534+
{
535+
ty::ctxt::closure_upvars(self, def_id, substs)
536+
}
537+
}
538+
440539
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
441540
pub fn freshen<T:TypeFoldable<'tcx>>(&self, t: T) -> T {
442541
t.fold_with(&mut self.freshener())
@@ -858,6 +957,48 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
858957
self.region_vars.new_bound(debruijn)
859958
}
860959

960+
/// Apply `adjustment` to the type of `expr`
961+
pub fn adjust_expr_ty(&self,
962+
expr: &ast::Expr,
963+
adjustment: Option<&ty::AutoAdjustment<'tcx>>)
964+
-> Ty<'tcx>
965+
{
966+
let raw_ty = self.expr_ty(expr);
967+
let raw_ty = self.shallow_resolve(raw_ty);
968+
let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty);
969+
raw_ty.adjust(self.tcx,
970+
expr.span,
971+
expr.id,
972+
adjustment,
973+
|method_call| self.tables
974+
.borrow()
975+
.method_map
976+
.get(&method_call)
977+
.map(|method| resolve_ty(method.ty)))
978+
}
979+
980+
pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
981+
match self.tables.borrow().node_types.get(&id) {
982+
Some(&t) => t,
983+
// FIXME
984+
None if self.tcx.sess.err_count() - self.err_count_on_creation != 0 => self.tcx.types.err,
985+
None => {
986+
self.tcx.sess.bug(
987+
&format!("no type for node {}: {} in fcx",
988+
id, self.tcx.map.node_to_string(id)));
989+
}
990+
}
991+
}
992+
993+
pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
994+
match self.tables.borrow().node_types.get(&ex.id) {
995+
Some(&t) => t,
996+
None => {
997+
self.tcx.sess.bug(&format!("no type for expr in fcx"));
998+
}
999+
}
1000+
}
1001+
8611002
pub fn resolve_regions_and_report_errors(&self,
8621003
free_regions: &FreeRegionMap,
8631004
subject_node_id: ast::NodeId) {
@@ -932,6 +1073,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
9321073
value.fold_with(&mut r)
9331074
}
9341075

1076+
fn resolve_type_vars_or_error(&self, t: &Ty<'tcx>) -> mc::McResult<Ty<'tcx>> {
1077+
let ty = self.resolve_type_vars_if_possible(t);
1078+
if ty.has_infer_types() || ty.references_error() { Err(()) } else { Ok(ty) }
1079+
}
1080+
9351081
pub fn fully_resolve<T:TypeFoldable<'tcx>>(&self, value: &T) -> fres<T> {
9361082
/*!
9371083
* Attempts to resolve all type/region variables in

src/librustc/middle/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
397397

398398
let elaborated_env = unnormalized_env.with_caller_bounds(predicates);
399399

400-
let infcx = infer::new_infer_ctxt(tcx, Some(elaborated_env));
400+
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(elaborated_env));
401401
let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause,
402402
&infcx.parameter_environment.caller_bounds) {
403403
Ok(predicates) => predicates,

src/librustc/middle/traits/select.rs

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use util::nodemap::FnvHashMap;
5454

5555
pub struct SelectionContext<'cx, 'tcx:'cx> {
5656
infcx: &'cx InferCtxt<'cx, 'tcx>,
57+
5758
closure_typer: &'cx (ty::ClosureTyper<'tcx>+'cx),
5859

5960
/// Freshener used specifically for skolemizing entries on the
@@ -77,6 +78,7 @@ pub struct SelectionContext<'cx, 'tcx:'cx> {
7778
/// other words, we consider `$0 : Bar` to be unimplemented if
7879
/// there is no type that the user could *actually name* that
7980
/// would satisfy it. This avoids crippling inference, basically.
81+
8082
intercrate: bool,
8183
}
8284

src/librustc/middle/ty.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4468,7 +4468,8 @@ impl<'tcx> TyS<'tcx> {
44684468
span: Span)
44694469
-> bool
44704470
{
4471-
let infcx = infer::new_infer_ctxt(param_env.tcx(), Some(param_env.clone()));
4471+
let tcx = param_env.tcx();
4472+
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone()));
44724473

44734474
let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env,
44744475
self, bound, span);

src/librustc_trans/trans/common.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
997997
trait_ref, trait_ref.def_id());
998998

999999
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
1000-
let infcx = infer::new_infer_ctxt(tcx, None);
1000+
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
10011001

10021002
// Do the initial selection for the obligation. This yields the
10031003
// shallow result we are looking for -- that is, what specific impl.
@@ -1059,7 +1059,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
10591059
predicates);
10601060

10611061
let tcx = ccx.tcx();
1062-
let infcx = infer::new_infer_ctxt(tcx, None);
1062+
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
10631063
let typer = NormalizingClosureTyper::new(tcx);
10641064
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
10651065
let mut fulfill_cx = traits::FulfillmentContext::new(false);

src/librustc_trans/trans/monomorphize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
324324
// FIXME(#20304) -- cache
325325
// NOTE: @jroesch
326326
// Here is of an example where we do not use a param_env but use a typer instead.
327-
let infcx = infer::new_infer_ctxt(tcx, None);
327+
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
328328
let typer = NormalizingClosureTyper::new(tcx);
329329
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
330330
let cause = traits::ObligationCause::dummy();

src/librustc_typeck/check/compare_method.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
4343
debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}",
4444
impl_trait_ref);
4545

46-
let mut infcx = infer::new_infer_ctxt(tcx, None);
46+
let mut infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
4747
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
4848

4949
let trait_to_impl_substs = &impl_trait_ref.substs;
@@ -418,7 +418,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>,
418418
debug!("compare_const_impl(impl_trait_ref={:?})",
419419
impl_trait_ref);
420420

421-
let infcx = infer::new_infer_ctxt(tcx, None);
421+
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
422422
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
423423

424424
// The below is for the most part highly similar to the procedure

src/librustc_typeck/check/dropck.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
9393
ty: named_type } =
9494
tcx.lookup_item_type(self_type_did);
9595

96-
let infcx = infer::new_infer_ctxt(tcx, None);
97-
96+
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
97+
9898
infcx.commit_if_ok(|snapshot| {
9999
let (named_type_to_skolem, skol_map) =
100100
infcx.construct_skolemized_subst(named_type_generics, snapshot);

src/librustc_typeck/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
382382
-> Inherited<'a, 'tcx> {
383383

384384
Inherited {
385-
infcx: infer::new_infer_ctxt(tcx, Some(param_env)),
385+
infcx: infer::new_infer_ctxt(tcx, tables, Some(param_env)),
386386
locals: RefCell::new(NodeMap()),
387387
tables: tables,
388388
fn_sig_map: RefCell::new(NodeMap()),

src/librustc_typeck/coherence/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
448448
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)",
449449
source, target);
450450

451-
let infcx = new_infer_ctxt(tcx, Some(param_env));
451+
let infcx = new_infer_ctxt(tcx, &tcx.tables, Some(param_env));
452452

453453
let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>,
454454
mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| {
@@ -630,7 +630,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
630630
pub fn check_coherence(crate_context: &CrateCtxt) {
631631
CoherenceChecker {
632632
crate_context: crate_context,
633-
inference_context: new_infer_ctxt(crate_context.tcx, None),
633+
inference_context: new_infer_ctxt(crate_context.tcx, &crate_context.tcx.tables, None),
634634
inherent_impls: RefCell::new(FnvHashMap()),
635635
}.check(crate_context.tcx.map.krate());
636636
unsafety::check(crate_context.tcx);

src/librustc_typeck/coherence/overlap.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
133133
impl1_def_id,
134134
impl2_def_id);
135135

136-
let infcx = infer::new_infer_ctxt(self.tcx, None);
136+
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, None);
137137
if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) {
138138
self.report_overlap_error(trait_def_id, impl1_def_id, impl2_def_id);
139139
}

src/librustc_typeck/collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2204,7 +2204,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
22042204
base_type,
22052205
base_type_free);
22062206

2207-
let infcx = infer::new_infer_ctxt(tcx, None);
2207+
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
22082208
drop(::require_same_types(tcx,
22092209
Some(&infcx),
22102210
false,

src/librustc_typeck/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
188188
{
189189
let result = match maybe_infcx {
190190
None => {
191-
let infcx = infer::new_infer_ctxt(tcx, None);
191+
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
192192
infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2)
193193
}
194194
Some(infcx) => {

0 commit comments

Comments
 (0)