Skip to content

More associated type fixes #20412

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
// inferred by regionbk
let upvar_id = ty::UpvarId { var_id: id_var,
closure_expr_id: closure_expr.id };
let upvar_borrow = self.typer.upvar_borrow(upvar_id);
let upvar_borrow = self.typer.upvar_borrow(upvar_id).unwrap();

self.delegate.borrow(closure_expr.id,
closure_expr.span,
Expand Down
18 changes: 7 additions & 11 deletions src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ use self::VarKind::*;

use middle::def::*;
use middle::mem_categorization::Typer;
use middle::{pat_util, ty};
use middle::pat_util;
use middle::ty;
use middle::ty::UnboxedClosureTyper;
use lint;
use util::nodemap::NodeMap;

Expand Down Expand Up @@ -1515,16 +1517,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn fn_ret(&self, id: NodeId) -> ty::FnOutput<'tcx> {
let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
match fn_ty.sty {
ty::ty_unboxed_closure(closure_def_id, _, _) =>
self.ir.tcx.unboxed_closures()
.borrow()
.get(&closure_def_id)
.unwrap()
.closure_type
.sig
.0
.output,
_ => ty::ty_fn_ret(fn_ty)
ty::ty_unboxed_closure(closure_def_id, _, substs) =>
self.ir.tcx.unboxed_closure_type(closure_def_id, substs).sig.0.output,
_ =>
ty::ty_fn_ret(fn_ty),
}
}

Expand Down
13 changes: 5 additions & 8 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub use self::categorization::*;
use middle::def;
use middle::region;
use middle::ty::{mod, Ty};
use util::nodemap::{DefIdMap, NodeMap};
use util::nodemap::{NodeMap};
use util::ppaux::{ty_to_string, Repr};

use syntax::ast::{MutImmutable, MutMutable};
Expand Down Expand Up @@ -280,7 +280,7 @@ impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}
/// In the borrow checker, in contrast, type checking is complete and we
/// know that no errors have occurred, so we simply consult the tcx and we
/// can be sure that only `Ok` results will occur.
pub trait Typer<'tcx> {
pub trait Typer<'tcx> : ty::UnboxedClosureTyper<'tcx> {
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx>;
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx>;
Expand All @@ -290,11 +290,9 @@ pub trait Typer<'tcx> {
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
fn is_method_call(&self, id: ast::NodeId) -> bool;
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow;
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow>;
fn capture_mode(&self, closure_expr_id: ast::NodeId)
-> ast::CaptureClause;
fn unboxed_closures<'a>(&'a self)
-> &'a RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>>;
}

impl MutabilityCategory {
Expand Down Expand Up @@ -622,8 +620,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, false)
}
ty::ty_unboxed_closure(closure_id, _, _) => {
let unboxed_closures = self.typer.unboxed_closures().borrow();
let kind = (*unboxed_closures)[closure_id].kind;
let kind = self.typer.unboxed_closure_kind(closure_id);
let mode = self.typer.capture_mode(fn_node_id);
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, true)
}
Expand Down Expand Up @@ -800,7 +797,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
}

// Look up upvar borrow so we can get its region
let upvar_borrow = self.typer.upvar_borrow(upvar_id);
let upvar_borrow = self.typer.upvar_borrow(upvar_id).unwrap();
let ptr = BorrowedPtr(upvar_borrow.kind, upvar_borrow.region);

Rc::new(cmt_ {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
pub fn normalize_projection_type<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &Typer<'tcx>,
typer: &ty::UnboxedClosureTyper<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
cause: ObligationCause<'tcx>)
-> Ty<'tcx>
Expand Down Expand Up @@ -187,7 +187,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
pub fn select_all_or_error<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &Typer<'tcx>)
typer: &ty::UnboxedClosureTyper<'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
try!(self.select_where_possible(infcx, param_env, typer));
Expand All @@ -213,7 +213,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
pub fn select_new_obligations<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &Typer<'tcx>)
typer: &ty::UnboxedClosureTyper<'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
let mut selcx = SelectionContext::new(infcx, param_env, typer);
Expand All @@ -223,7 +223,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
pub fn select_where_possible<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &Typer<'tcx>)
typer: &ty::UnboxedClosureTyper<'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
let mut selcx = SelectionContext::new(infcx, param_env, typer);
Expand Down
38 changes: 33 additions & 5 deletions src/librustc/middle/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ pub fn poly_project_and_unify_type<'cx,'tcx>(

/// Compute result of projecting an associated type and unify it with
/// `obligation.predicate.ty` (if we can).
pub fn project_and_unify_type<'cx,'tcx>(
fn project_and_unify_type<'cx,'tcx>(
selcx: &mut SelectionContext<'cx,'tcx>,
obligation: &ProjectionObligation<'tcx>)
-> Result<Option<Vec<PredicateObligation<'tcx>>>, MismatchedProjectionTypes<'tcx>>
Expand Down Expand Up @@ -135,9 +135,19 @@ pub fn normalize<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
cause: ObligationCause<'tcx>,
value: &T)
-> Normalized<'tcx, T>
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
{
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, 0);
normalize_with_depth(selcx, cause, 0, value)
}

pub fn normalize_with_depth<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
cause: ObligationCause<'tcx>,
depth: uint,
value: &T)
-> Normalized<'tcx, T>
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
{
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth);
let result = normalizer.fold(value);
Normalized {
value: result,
Expand Down Expand Up @@ -278,9 +288,10 @@ fn opt_normalize_projection_type<'a,'b,'tcx>(
// an impl, where-clause etc) and hence we must
// re-normalize it

debug!("normalize_projection_type: projected_ty={} depth={}",
debug!("normalize_projection_type: projected_ty={} depth={} obligations={}",
projected_ty.repr(selcx.tcx()),
depth);
depth,
obligations.repr(selcx.tcx()));

if ty::type_has_projection(projected_ty) {
let tcx = selcx.tcx();
Expand Down Expand Up @@ -644,3 +655,20 @@ impl<'tcx> Repr<'tcx> for ProjectionTyCandidate<'tcx> {
}
}
}

impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Normalized<'tcx, T> {
Normalized {
value: self.value.fold_with(folder),
obligations: self.obligations.fold_with(folder),
}
}
}

impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Normalized<'tcx, T> {
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
format!("Normalized({},{})",
self.value.repr(tcx),
self.obligations.repr(tcx))
}
}
88 changes: 38 additions & 50 deletions src/librustc/middle/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use self::BuiltinBoundConditions::*;
use self::EvaluationResult::*;

use super::{DerivedObligationCause};
use super::{project};
use super::{PredicateObligation, Obligation, TraitObligation, ObligationCause};
use super::{ObligationCauseCode, BuiltinDerivedObligation};
use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
Expand All @@ -29,7 +30,7 @@ use super::{util};

use middle::fast_reject;
use middle::mem_categorization::Typer;
use middle::subst::{Subst, Substs, VecPerParamSpace};
use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace};
use middle::ty::{mod, AsPredicate, RegionEscape, ToPolyTraitRef, Ty};
use middle::infer;
use middle::infer::{InferCtxt, TypeFreshener};
Expand All @@ -44,7 +45,7 @@ use util::ppaux::Repr;
pub struct SelectionContext<'cx, 'tcx:'cx> {
infcx: &'cx InferCtxt<'cx, 'tcx>,
param_env: &'cx ty::ParameterEnvironment<'tcx>,
typer: &'cx (Typer<'tcx>+'cx),
closure_typer: &'cx (ty::UnboxedClosureTyper<'tcx>+'cx),

/// Freshener used specifically for skolemizing entries on the
/// obligation stack. This ensures that all entries on the stack
Expand Down Expand Up @@ -177,25 +178,25 @@ enum EvaluationResult<'tcx> {
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
param_env: &'cx ty::ParameterEnvironment<'tcx>,
typer: &'cx Typer<'tcx>)
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
-> SelectionContext<'cx, 'tcx> {
SelectionContext {
infcx: infcx,
param_env: param_env,
typer: typer,
closure_typer: closure_typer,
freshener: infcx.freshener(),
intercrate: false,
}
}

pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>,
param_env: &'cx ty::ParameterEnvironment<'tcx>,
typer: &'cx Typer<'tcx>)
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
-> SelectionContext<'cx, 'tcx> {
SelectionContext {
infcx: infcx,
param_env: param_env,
typer: typer,
closure_typer: closure_typer,
freshener: infcx.freshener(),
intercrate: true,
}
Expand Down Expand Up @@ -918,15 +919,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
kind,
obligation.repr(self.tcx()));

let closure_kind = match self.typer.unboxed_closures().borrow().get(&closure_def_id) {
Some(closure) => closure.kind,
None => {
self.tcx().sess.span_bug(
obligation.cause.span,
format!("No entry for unboxed closure: {}",
closure_def_id.repr(self.tcx()))[]);
}
};
let closure_kind = self.closure_typer.unboxed_closure_kind(closure_def_id);

debug!("closure_kind = {}", closure_kind);

Expand Down Expand Up @@ -1398,32 +1391,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return Ok(ParameterBuiltin);
}

match self.tcx().freevars.borrow().get(&def_id.node) {
None => {
// No upvars.
Ok(If(Vec::new()))
match self.closure_typer.unboxed_closure_upvars(def_id, substs) {
Some(upvars) => {
Ok(If(upvars.iter().map(|c| c.ty).collect()))
}

Some(freevars) => {
let tys: Vec<Ty> =
freevars
.iter()
.map(|freevar| {
let freevar_def_id = freevar.def.def_id();
self.typer.node_ty(freevar_def_id.node).subst(self.tcx(), substs)
})
.collect();
Ok(If(tys))
None => {
Ok(AmbiguousBuiltin)
}
}
}

ty::ty_struct(def_id, substs) => {
let types: Vec<Ty> =
ty::struct_fields(self.tcx(), def_id, substs)
.iter()
.map(|f| f.mt.ty)
.collect();
ty::struct_fields(self.tcx(), def_id, substs).iter()
.map(|f| f.mt.ty)
.collect();
nominal(self, bound, def_id, types)
}

Expand Down Expand Up @@ -1798,27 +1780,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
closure_def_id.repr(self.tcx()),
substs.repr(self.tcx()));

let closure_type = match self.typer.unboxed_closures().borrow().get(&closure_def_id) {
Some(closure) => closure.closure_type.clone(),
None => {
self.tcx().sess.span_bug(
obligation.cause.span,
format!("No entry for unboxed closure: {}",
closure_def_id.repr(self.tcx()))[]);
}
};
let closure_type = self.closure_typer.unboxed_closure_type(closure_def_id, substs);

debug!("confirm_unboxed_closure_candidate: closure_def_id={} closure_type={}",
closure_def_id.repr(self.tcx()),
closure_type.repr(self.tcx()));

let closure_sig = &closure_type.sig;
let arguments_tuple = closure_sig.0.inputs[0];
let substs =
let trait_substs =
Substs::new_trait(
vec![arguments_tuple.subst(self.tcx(), substs),
closure_sig.0.output.unwrap().subst(self.tcx(), substs)],
vec![arguments_tuple, closure_sig.0.output.unwrap()],
vec![],
obligation.self_ty());
let trait_ref = ty::Binder(Rc::new(ty::TraitRef {
def_id: obligation.predicate.def_id(),
substs: self.tcx().mk_substs(substs),
substs: self.tcx().mk_substs(trait_substs),
}));

debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})",
Expand Down Expand Up @@ -2100,7 +2077,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}

fn impl_predicates(&self,
fn impl_predicates(&mut self,
cause: ObligationCause<'tcx>,
recursion_depth: uint,
impl_def_id: ast::DefId,
Expand All @@ -2111,8 +2088,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
{
let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
let bounds = impl_generics.to_bounds(self.tcx(), impl_substs);
let bounds = self.infcx().plug_leaks(skol_map, snapshot, &bounds);
util::predicates_for_generics(self.tcx(), cause, recursion_depth, &bounds)
let normalized_bounds =
project::normalize_with_depth(self, cause.clone(), recursion_depth, &bounds);
let normalized_bounds =
self.infcx().plug_leaks(skol_map, snapshot, &normalized_bounds);
let mut impl_obligations =
util::predicates_for_generics(self.tcx(),
cause,
recursion_depth,
&normalized_bounds.value);
for obligation in normalized_bounds.obligations.into_iter() {
impl_obligations.push(TypeSpace, obligation);
}
impl_obligations
}

fn fn_family_trait_kind(&self,
Expand Down
Loading