Skip to content

Refactor representation of bounds to separate out BuiltinBounds into its own type. #6336

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

Closed
Closed
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
40 changes: 28 additions & 12 deletions src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,18 +555,34 @@ fn parse_type_param_def(st: @mut PState, conv: conv_did) -> ty::TypeParameterDef
bounds: parse_bounds(st, conv)}
}

fn parse_bounds(st: @mut PState, conv: conv_did) -> @~[ty::param_bound] {
let mut bounds = ~[];
fn parse_bounds(st: @mut PState, conv: conv_did) -> @ty::ParamBounds {
let mut param_bounds = ty::ParamBounds {
builtin_bounds: ty::EmptyBuiltinBounds(),
trait_bounds: ~[]
};
loop {
bounds.push(match next(st) {
'S' => ty::bound_owned,
'C' => ty::bound_copy,
'K' => ty::bound_const,
'O' => ty::bound_durable,
'I' => ty::bound_trait(@parse_trait_ref(st, conv)),
'.' => break,
_ => fail!(~"parse_bounds: bad bounds")
});
match next(st) {
'S' => {
param_bounds.builtin_bounds.add(ty::BoundOwned);
}
'C' => {
param_bounds.builtin_bounds.add(ty::BoundCopy);
}
'K' => {
param_bounds.builtin_bounds.add(ty::BoundConst);
}
'O' => {
param_bounds.builtin_bounds.add(ty::BoundStatic);
}
'I' => {
param_bounds.trait_bounds.push(@parse_trait_ref(st, conv));
}
'.' => {
return @param_bounds;
}
_ => {
fail!(~"parse_bounds: bad bounds")
}
}
}
@bounds
}
24 changes: 13 additions & 11 deletions src/librustc/metadata/tyencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,19 +396,21 @@ fn enc_fn_sig(w: @io::Writer, cx: @ctxt, fsig: &ty::FnSig) {
enc_ty(w, cx, fsig.output);
}

fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: @~[ty::param_bound]) {
for (*bs).each |bound| {
match *bound {
ty::bound_owned => w.write_char('S'),
ty::bound_copy => w.write_char('C'),
ty::bound_const => w.write_char('K'),
ty::bound_durable => w.write_char('O'),
ty::bound_trait(tp) => {
w.write_char('I');
enc_trait_ref(w, cx, tp);
}
fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: @ty::ParamBounds) {
for bs.builtin_bounds.each |bound| {
match bound {
ty::BoundOwned => w.write_char('S'),
ty::BoundCopy => w.write_char('C'),
ty::BoundConst => w.write_char('K'),
ty::BoundStatic => w.write_char('O'),
}
}

for bs.trait_bounds.each |&tp| {
w.write_char('I');
enc_trait_ref(w, cx, tp);
}

w.write_char('.');
}

Expand Down
40 changes: 7 additions & 33 deletions src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use middle::pat_util;
use middle::ty;
use middle::typeck;
use util::ppaux::{Repr, ty_to_str};
use util::ppaux::UserString;

use syntax::ast::*;
use syntax::attr::attrs_contains_name;
Expand Down Expand Up @@ -338,46 +339,19 @@ pub fn check_bounds(cx: Context,
type_param_def: &ty::TypeParameterDef)
{
let kind = ty::type_contents(cx.tcx, ty);
let mut missing = ~[];
for type_param_def.bounds.each |bound| {
match *bound {
ty::bound_trait(_) => {
/* Not our job, checking in typeck */
}

ty::bound_copy => {
if !kind.is_copy(cx.tcx) {
missing.push("Copy");
}
}

ty::bound_durable => {
if !kind.is_durable(cx.tcx) {
missing.push("'static");
}
}

ty::bound_owned => {
if !kind.is_owned(cx.tcx) {
missing.push("Owned");
}
}

ty::bound_const => {
if !kind.is_const(cx.tcx) {
missing.push("Const");
}
}
let mut missing = ty::EmptyBuiltinBounds();
for type_param_def.bounds.builtin_bounds.each |bound| {
if !kind.meets_bound(cx.tcx, bound) {
missing.add(bound);
}
}

if !missing.is_empty() {
cx.tcx.sess.span_err(
sp,
fmt!("instantiating a type parameter with an incompatible type \
`%s`, which does not fulfill `%s`",
ty_to_str(cx.tcx, ty),
str::connect_slices(missing, " ")));
missing.user_string(cx.tcx)));
}
}

Expand Down Expand Up @@ -440,7 +414,7 @@ pub fn check_owned(cx: Context, ty: ty::t, sp: span) -> bool {

// note: also used from middle::typeck::regionck!
pub fn check_durable(tcx: ty::ctxt, ty: ty::t, sp: span) -> bool {
if !ty::type_is_durable(tcx, ty) {
if !ty::type_is_static(tcx, ty) {
match ty::get(ty).sty {
ty::ty_param(*) => {
tcx.sess.span_err(sp, "value may contain borrowed \
Expand Down
26 changes: 10 additions & 16 deletions src/librustc/middle/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,11 @@ impl<T:Subst> Subst for ~[T] {
}
}

impl<T:Subst> Subst for @~[T] {
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> @~[T] {
@(**self).subst(tcx, substs)
impl<T:Subst> Subst for @T {
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> @T {
match self {
&@ref t => @t.subst(tcx, substs)
}
}
}

Expand Down Expand Up @@ -115,19 +117,11 @@ impl Subst for ty::BareFnTy {
}
}

impl Subst for ty::param_bound {
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::param_bound {
match self {
&ty::bound_copy |
&ty::bound_durable |
&ty::bound_owned |
&ty::bound_const => {
*self
}

&ty::bound_trait(tref) => {
ty::bound_trait(@tref.subst(tcx, substs))
}
impl Subst for ty::ParamBounds {
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::ParamBounds {
ty::ParamBounds {
builtin_bounds: self.builtin_bounds,
trait_bounds: self.trait_bounds.subst(tcx, substs)
}
}
}
Expand Down
11 changes: 3 additions & 8 deletions src/librustc/middle/trans/monomorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,14 +348,9 @@ pub fn make_mono_id(ccx: @CrateContext,
let mut i = 0;
vec::map_zip(*item_ty.generics.type_param_defs, substs, |type_param_def, subst| {
let mut v = ~[];
for type_param_def.bounds.each |bound| {
match *bound {
ty::bound_trait(_) => {
v.push(meth::vtable_id(ccx, /*bad*/copy vts[i]));
i += 1;
}
_ => ()
}
for type_param_def.bounds.trait_bounds.each |_bound| {
v.push(meth::vtable_id(ccx, /*bad*/copy vts[i]));
i += 1;
}
(*subst, if !v.is_empty() { Some(v) } else { None })
})
Expand Down
107 changes: 61 additions & 46 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use util::ppaux::{note_and_explain_region, bound_region_to_str};
use util::ppaux::{trait_store_to_str, ty_to_str, vstore_to_str};
use util::ppaux::Repr;
use util::common::{indenter};
use util::enum_set::{EnumSet, CLike};

use core;
use core::ptr::to_unsafe_ptr;
Expand Down Expand Up @@ -58,8 +59,6 @@ pub struct field {
mt: mt
}

pub type param_bounds = @~[param_bound];

pub struct method {
ident: ast::ident,
generics: ty::Generics,
Expand Down Expand Up @@ -655,12 +654,32 @@ pub enum type_err {
}

#[deriving(Eq, IterBytes)]
pub enum param_bound {
bound_copy,
bound_durable,
bound_owned,
bound_const,
bound_trait(@TraitRef),
pub struct ParamBounds {
builtin_bounds: BuiltinBounds,
trait_bounds: ~[@TraitRef]
}

pub type BuiltinBounds = EnumSet<BuiltinBound>;

#[deriving(Eq, IterBytes)]
pub enum BuiltinBound {
BoundCopy,
BoundStatic,
BoundOwned,
BoundConst,
}

pub fn EmptyBuiltinBounds() -> BuiltinBounds {
EnumSet::empty()
}

impl CLike for BuiltinBound {
pub fn to_uint(&self) -> uint {
*self as uint
}
pub fn from_uint(v: uint) -> BuiltinBound {
unsafe { cast::transmute(v) }
}
}

#[deriving(Eq)]
Expand Down Expand Up @@ -817,7 +836,7 @@ impl to_bytes::IterBytes for RegionVid {

pub struct TypeParameterDef {
def_id: ast::def_id,
bounds: param_bounds
bounds: @ParamBounds
}

/// Information about the type/lifetime parametesr associated with an item.
Expand Down Expand Up @@ -1497,14 +1516,6 @@ pub fn substs_to_str(cx: ctxt, substs: &substs) -> ~str {
substs.repr(cx)
}

pub fn param_bound_to_str(cx: ctxt, pb: &param_bound) -> ~str {
pb.repr(cx)
}

pub fn param_bounds_to_str(cx: ctxt, pbs: param_bounds) -> ~str {
pbs.repr(cx)
}

pub fn subst(cx: ctxt,
substs: &substs,
typ: t)
Expand Down Expand Up @@ -1795,6 +1806,19 @@ pub struct TypeContents {
}

pub impl TypeContents {
fn meets_bounds(&self, cx: ctxt, bbs: BuiltinBounds) -> bool {
iter::all(|bb| self.meets_bound(cx, bb), |f| bbs.each(f))
}

fn meets_bound(&self, cx: ctxt, bb: BuiltinBound) -> bool {
match bb {
BoundCopy => self.is_copy(cx),
BoundStatic => self.is_static(cx),
BoundConst => self.is_const(cx),
BoundOwned => self.is_owned(cx)
}
}

fn intersects(&self, tc: TypeContents) -> bool {
(self.bits & tc.bits) != 0
}
Expand All @@ -1808,11 +1832,11 @@ pub impl TypeContents {
TC_EMPTY_ENUM
}

fn is_durable(&self, cx: ctxt) -> bool {
!self.intersects(TypeContents::nondurable(cx))
fn is_static(&self, cx: ctxt) -> bool {
!self.intersects(TypeContents::nonstatic(cx))
}

fn nondurable(_cx: ctxt) -> TypeContents {
fn nonstatic(_cx: ctxt) -> TypeContents {
TC_BORROWED_POINTER
}

Expand Down Expand Up @@ -1917,8 +1941,8 @@ pub fn type_is_copyable(cx: ctxt, t: ty::t) -> bool {
type_contents(cx, t).is_copy(cx)
}

pub fn type_is_durable(cx: ctxt, t: ty::t) -> bool {
type_contents(cx, t).is_durable(cx)
pub fn type_is_static(cx: ctxt, t: ty::t) -> bool {
type_contents(cx, t).is_static(cx)
}

pub fn type_is_owned(cx: ctxt, t: ty::t) -> bool {
Expand Down Expand Up @@ -2198,19 +2222,19 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
debug!("type_param_def_to_contents(%s)", type_param_def.repr(cx));
let _i = indenter();

let r = type_param_def.bounds.foldl(TC_ALL, |tc, bound| {
let mut tc = TC_ALL;
for type_param_def.bounds.builtin_bounds.each |bound| {
debug!("tc = %s, bound = %?", tc.to_str(), bound);
match *bound {
bound_copy => tc - TypeContents::nonimplicitly_copyable(cx),
bound_durable => tc - TypeContents::nondurable(cx),
bound_owned => tc - TypeContents::nonowned(cx),
bound_const => tc - TypeContents::nonconst(cx),
bound_trait(_) => *tc
}
});
tc = tc - match bound {
BoundCopy => TypeContents::nonimplicitly_copyable(cx),
BoundStatic => TypeContents::nonstatic(cx),
BoundOwned => TypeContents::nonowned(cx),
BoundConst => TypeContents::nonconst(cx),
};
}

debug!("result = %s", r.to_str());
return r;
debug!("result = %s", tc.to_str());
return tc;
}
}

Expand Down Expand Up @@ -3577,7 +3601,7 @@ pub fn trait_supertraits(cx: ctxt,
pub fn trait_ref_supertraits(cx: ctxt, trait_ref: &ty::TraitRef) -> ~[@TraitRef] {
let supertrait_refs = trait_supertraits(cx, trait_ref.def_id);
supertrait_refs.map(
|supertrait_ref| @supertrait_ref.subst(cx, &trait_ref.substs))
|supertrait_ref| supertrait_ref.subst(cx, &trait_ref.substs))
}

fn lookup_locally_or_in_crate_store<V:Copy>(
Expand Down Expand Up @@ -4261,18 +4285,9 @@ pub fn determine_inherited_purity(parent: (ast::purity, ast::node_id),
// relation on the supertraits from each bounded trait's constraint
// list.
pub fn each_bound_trait_and_supertraits(tcx: ctxt,
bounds: param_bounds,
f: &fn(&TraitRef) -> bool) {
for bounds.each |bound| {
let bound_trait_ref = match *bound {
ty::bound_trait(bound_t) => bound_t,

ty::bound_copy | ty::bound_owned |
ty::bound_const | ty::bound_durable => {
loop; // skip non-trait bounds
}
};

bounds: &ParamBounds,
f: &fn(@TraitRef) -> bool) {
for bounds.trait_bounds.each |&bound_trait_ref| {
let mut supertrait_set = HashMap::new();
let mut trait_refs = ~[];
let mut i = 0;
Expand Down
Loading