rustc: Replace region parameters in function return values
This commit is contained in:
parent
324f57a180
commit
c8ab0c1b3b
@ -16,6 +16,7 @@ import util::ppaux::ty_to_str;
|
|||||||
import std::smallintmap;
|
import std::smallintmap;
|
||||||
import std::map::{hashmap, int_hash};
|
import std::map::{hashmap, int_hash};
|
||||||
import std::serialization::{serialize_uint, deserialize_uint};
|
import std::serialization::{serialize_uint, deserialize_uint};
|
||||||
|
import std::ufind;
|
||||||
import syntax::print::pprust::*;
|
import syntax::print::pprust::*;
|
||||||
|
|
||||||
export check_crate;
|
export check_crate;
|
||||||
@ -1554,6 +1555,33 @@ fn universally_quantify_regions(tcx: ty::ctxt, ty: ty::t) -> ty::t {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replaces region parameter types in the given type with the appropriate
|
||||||
|
// bindings.
|
||||||
|
fn replace_region_params(tcx: ty::ctxt,
|
||||||
|
sp: span,
|
||||||
|
rb: @ty::unify::region_bindings,
|
||||||
|
ty: ty::t)
|
||||||
|
-> ty::t {
|
||||||
|
|
||||||
|
if ty::type_has_rptrs(ty) {
|
||||||
|
ty::fold_ty(tcx, ty::fm_rptr({ |r|
|
||||||
|
alt r {
|
||||||
|
ty::re_param(n) {
|
||||||
|
if n < ufind::set_count(rb.sets) {
|
||||||
|
smallintmap::get(rb.regions, ufind::find(rb.sets, n))
|
||||||
|
} else {
|
||||||
|
tcx.sess.span_err(sp, "unresolved region");
|
||||||
|
r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ { r }
|
||||||
|
}
|
||||||
|
}), ty)
|
||||||
|
} else {
|
||||||
|
ty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
|
fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path,
|
||||||
subpats: [@ast::pat], expected: ty::t) {
|
subpats: [@ast::pat], expected: ty::t) {
|
||||||
// Typecheck the path.
|
// Typecheck the path.
|
||||||
@ -2277,40 +2305,38 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||||||
// A generic function for checking call expressions
|
// A generic function for checking call expressions
|
||||||
fn check_call(fcx: @fn_ctxt, sp: span, id: ast::node_id, f: @ast::expr,
|
fn check_call(fcx: @fn_ctxt, sp: span, id: ast::node_id, f: @ast::expr,
|
||||||
args: [@ast::expr])
|
args: [@ast::expr])
|
||||||
-> bool {
|
-> check_call_or_bind_result {
|
||||||
let args_opt_0: [option<@ast::expr>] = [];
|
let args_opt_0: [option<@ast::expr>] = [];
|
||||||
for arg: @ast::expr in args {
|
for arg: @ast::expr in args {
|
||||||
args_opt_0 += [some::<@ast::expr>(arg)];
|
args_opt_0 += [some::<@ast::expr>(arg)];
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut bot = check_expr(fcx, f);
|
let bot = check_expr(fcx, f);
|
||||||
// Call the generic checker.
|
// Call the generic checker.
|
||||||
let ccobr = check_call_or_bind(fcx, sp, id, expr_ty(fcx.ccx.tcx, f),
|
let ccobr = check_call_or_bind(fcx, sp, id, expr_ty(fcx.ccx.tcx, f),
|
||||||
args_opt_0);
|
args_opt_0);
|
||||||
bot |= ccobr.bot;
|
ret { bot: bot | ccobr.bot with ccobr };
|
||||||
|
|
||||||
// TODO: Munge return type.
|
|
||||||
|
|
||||||
ret bot;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A generic function for doing all of the checking for call expressions
|
// A generic function for doing all of the checking for call expressions
|
||||||
fn check_call_full(fcx: @fn_ctxt, sp: span, id: ast::node_id,
|
fn check_call_full(fcx: @fn_ctxt, sp: span, id: ast::node_id,
|
||||||
f: @ast::expr, args: [@ast::expr]) -> bool {
|
f: @ast::expr, args: [@ast::expr]) -> bool {
|
||||||
let bot = check_call(fcx, sp, id, f, args);
|
let ccobr = check_call(fcx, sp, id, f, args);
|
||||||
|
let mut bot = ccobr.bot;
|
||||||
/* need to restrict oper to being an explicit expr_path if we're
|
/* need to restrict oper to being an explicit expr_path if we're
|
||||||
inside a pure function */
|
inside a pure function */
|
||||||
require_pure_call(fcx.ccx, fcx.purity, f, sp);
|
require_pure_call(fcx.ccx, fcx.purity, f, sp);
|
||||||
|
|
||||||
// Pull the return type out of the type of the function.
|
// Pull the return type out of the type of the function.
|
||||||
let fty = ty::expr_ty(fcx.ccx.tcx, f);
|
let fty = ty::expr_ty(fcx.ccx.tcx, f);
|
||||||
let rt_1 = alt structure_of(fcx, sp, fty) {
|
let mut rt_1 = alt structure_of(fcx, sp, fty) {
|
||||||
ty::ty_fn(f) {
|
ty::ty_fn(f) {
|
||||||
bot |= f.ret_style == ast::noreturn;
|
bot |= f.ret_style == ast::noreturn;
|
||||||
f.output
|
f.output
|
||||||
}
|
}
|
||||||
_ { fcx.ccx.tcx.sess.span_fatal(sp, "calling non-function"); }
|
_ { fcx.ccx.tcx.sess.span_fatal(sp, "calling non-function"); }
|
||||||
};
|
};
|
||||||
|
rt_1 = replace_region_params(fcx.ccx.tcx, f.span, ccobr.rb, rt_1);
|
||||||
write_ty(fcx.ccx.tcx, id, rt_1);
|
write_ty(fcx.ccx.tcx, id, rt_1);
|
||||||
ret bot;
|
ret bot;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user