Skip to content

Simplify the AST representation of ty param bounds #3792

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
wants to merge 1 commit into from
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
12 changes: 5 additions & 7 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,11 @@ const crate_node_id: node_id = 0;

#[auto_serialize]
#[auto_deserialize]
enum ty_param_bound {
bound_copy,
bound_send,
bound_const,
bound_owned,
bound_trait(@Ty),
}
// The AST represents all type param bounds as types.
// typeck::collect::compute_bounds matches these against
// the "special" built-in traits (see middle::lang_items) and
// detects Copy, Send, Owned, and Const.
enum ty_param_bound = @Ty;

#[auto_serialize]
#[auto_deserialize]
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/ext/auto_serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ priv impl ext_ctxt {
path: @ast::path,
bounds: @~[ast::ty_param_bound]
) -> ast::ty_param {
let bound = ast::bound_trait(@{
let bound = ast::ty_param_bound(@{
id: self.next_id(),
node: ast::ty_path(path, self.next_id()),
span: span,
Expand Down Expand Up @@ -366,7 +366,7 @@ fn mk_impl(
let mut trait_tps = vec::append(
~[ty_param],
do tps.map |tp| {
let t_bound = ast::bound_trait(@{
let t_bound = ast::ty_param_bound(@{
id: cx.next_id(),
node: ast::ty_path(path, cx.next_id()),
span: span,
Expand Down
5 changes: 1 addition & 4 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,7 @@ fn fold_fn_decl(decl: ast::fn_decl, fld: ast_fold) -> ast::fn_decl {
}

fn fold_ty_param_bound(tpb: ty_param_bound, fld: ast_fold) -> ty_param_bound {
match tpb {
bound_copy | bound_send | bound_const | bound_owned => tpb,
bound_trait(ty) => bound_trait(fld.fold_ty(ty))
}
ty_param_bound(fld.fold_ty(*tpb))
}

fn fold_ty_param(tp: ty_param, fld: ast_fold) -> ty_param {
Expand Down
20 changes: 10 additions & 10 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ use obsolete::{
};
use ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
bind_by_ref, bind_by_implicit_ref, bind_by_value, bind_by_move,
bitand, bitor, bitxor, blk, blk_check_mode, bound_const,
bound_copy, bound_send, bound_trait, bound_owned, box, by_copy,
bitand, bitor, bitxor, blk, blk_check_mode, box, by_copy,
by_move, by_ref, by_val, capture_clause,
capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item,
class_immutable, class_mutable,
Expand Down Expand Up @@ -2326,19 +2325,20 @@ impl Parser {
return spanned(lo, hi, bloc);
}

fn mk_ty_path(i: ident) -> @Ty {
@{id: self.get_id(), node: ty_path(
ident_to_path(copy self.last_span, i),
self.get_id()), span: self.last_span}
}

fn parse_optional_ty_param_bounds() -> @~[ty_param_bound] {
let mut bounds = ~[];
if self.eat(token::COLON) {
while is_ident(self.token) {
if is_ident(self.token) {
// XXX: temporary until kinds become traits
let maybe_bound = match self.token {
token::IDENT(copy sid, _) => {
match *self.id_to_str(sid) {
~"Send" => Some(bound_send),
~"Copy" => Some(bound_copy),
~"Const" => Some(bound_const),
~"Owned" => Some(bound_owned),

~"send"
| ~"copy"
Expand All @@ -2348,7 +2348,7 @@ impl Parser {
ObsoleteLowerCaseKindBounds);
// Bogus value, but doesn't matter, since
// is an error
Some(bound_send)
Some(ty_param_bound(self.mk_ty_path(sid)))
}

_ => None
Expand All @@ -2363,11 +2363,11 @@ impl Parser {
bounds.push(bound);
}
None => {
bounds.push(bound_trait(self.parse_ty(false)));
bounds.push(ty_param_bound(self.parse_ty(false)));
}
}
} else {
bounds.push(bound_trait(self.parse_ty(false)));
bounds.push(ty_param_bound(self.parse_ty(false)));
}
}
}
Expand Down
10 changes: 2 additions & 8 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1690,17 +1690,11 @@ fn print_arg_mode(s: ps, m: ast::mode) {
}

fn print_bounds(s: ps, bounds: @~[ast::ty_param_bound]) {
if vec::len(*bounds) > 0u {
if bounds.is_not_empty() {
word(s.s, ~":");
for vec::each(*bounds) |bound| {
nbsp(s);
match *bound {
ast::bound_copy => word(s.s, ~"Copy"),
ast::bound_send => word(s.s, ~"Send"),
ast::bound_const => word(s.s, ~"Const"),
ast::bound_owned => word(s.s, ~"Owned"),
ast::bound_trait(t) => print_type(s, t)
}
print_type(s, **bound);
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/libsyntax/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,7 @@ fn visit_foreign_item<E>(ni: @foreign_item, e: E, v: vt<E>) {

fn visit_ty_param_bounds<E>(bounds: @~[ty_param_bound], e: E, v: vt<E>) {
for vec::each(*bounds) |bound| {
match *bound {
bound_trait(t) => v.visit_ty(t, e, v),
bound_copy | bound_send | bound_const | bound_owned => ()
}
v.visit_ty(**bound, e, v)
}
}

Expand Down
18 changes: 6 additions & 12 deletions src/rustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use middle::pat_util::{pat_bindings};
use syntax::ast::{_mod, add, arm};
use syntax::ast::{bind_by_ref, bind_by_implicit_ref, bind_by_value};
use syntax::ast::{bitand, bitor, bitxor};
use syntax::ast::{blk, bound_const, bound_copy, bound_owned, bound_send};
use syntax::ast::{bound_trait, binding_mode, capture_clause, class_ctor};
use syntax::ast::{class_dtor, crate, crate_num, decl_item};
use syntax::ast::{binding_mode, blk,
capture_clause, class_ctor, class_dtor};
use syntax::ast::{crate, crate_num, decl_item};
use syntax::ast::{def, def_arg, def_binding, def_class, def_const, def_fn};
use syntax::ast::{def_foreign_mod, def_id, def_label, def_local, def_mod};
use syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
Expand Down Expand Up @@ -38,6 +38,7 @@ use syntax::ast::{trait_ref, tuple_variant_kind, Ty, ty_bool, ty_char};
use syntax::ast::{ty_f, ty_f32, ty_f64, ty_float, ty_i, ty_i16, ty_i32};
use syntax::ast::{ty_i64, ty_i8, ty_int, ty_param, ty_path, ty_str, ty_u};
use syntax::ast::{ty_u16, ty_u32, ty_u64, ty_u8, ty_uint, type_value_ns};
use syntax::ast::{ty_param_bound};
use syntax::ast::{variant, view_item, view_item_export, view_item_import};
use syntax::ast::{view_item_use, view_path_glob, view_path_list};
use syntax::ast::{view_path_simple, visibility, anonymous, named};
Expand Down Expand Up @@ -3689,14 +3690,7 @@ impl Resolver {
visitor: ResolveVisitor) {
for type_parameters.each |type_parameter| {
for type_parameter.bounds.each |bound| {
match *bound {
bound_copy | bound_send | bound_const | bound_owned => {
// Nothing to do.
}
bound_trait(trait_type) => {
self.resolve_type(trait_type, visitor);
}
}
self.resolve_type(**bound, visitor);
}
}
}
Expand Down Expand Up @@ -4013,7 +4007,7 @@ impl Resolver {
let mut result_def = None;

// First, check to see whether the name is a primitive type.
if path.idents.len() == 1u {
if path.idents.len() == 1 {
let name = path.idents.last();

match self.primitive_type_table
Expand Down
45 changes: 29 additions & 16 deletions src/rustc/middle/typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,28 +707,41 @@ fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
}
}

// Translate the AST's notion of ty param bounds (which are just newtyped Tys)
// to ty's notion of ty param bounds, which can either be user-defined traits,
// or one of the four built-in traits (formerly known as kinds): Const, Copy,
// Owned, and Send.
fn compute_bounds(ccx: @crate_ctxt,
ast_bounds: @~[ast::ty_param_bound]) -> ty::param_bounds {
@do vec::flat_map(*ast_bounds) |b| {
match *b {
ast::bound_send => ~[ty::bound_send],
ast::bound_copy => ~[ty::bound_copy],
ast::bound_const => ~[ty::bound_const],
ast::bound_owned => ~[ty::bound_owned],
ast::bound_trait(t) => {
let ity = ast_ty_to_ty(ccx, empty_rscope, t);
match ty::get(ity).sty {
ty::ty_trait(*) => {
~[ty::bound_trait(ity)]
}
_ => {
let li = &ccx.tcx.lang_items;
let ity = ast_ty_to_ty(ccx, empty_rscope, **b);
match ty::get(ity).sty {
ty::ty_trait(did, _, _) => {
let d = Some(did);
if d == li.send_trait {
~[ty::bound_send]
}
else if d == li.copy_trait {
~[ty::bound_copy]
}
else if d == li.const_trait {
~[ty::bound_const]
}
else if d == li.owned_trait {
~[ty::bound_owned]
}
else {
// Must be a user-defined trait
~[ty::bound_trait(ity)]
}
}
_ => {
ccx.tcx.sess.span_err(
t.span, ~"type parameter bounds must be \
trait types");
(*b).span, ~"type parameter bounds must be \
trait types");
~[]
}
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/tag-that-dare-not-speak-its-name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

extern mod core;

fn last<T: Copy>(v: ~[const T]) -> core::Option<T> {
fn last<T>(v: ~[const &T]) -> core::Option<T> {
fail;
}

Expand Down
1 change: 0 additions & 1 deletion src/test/run-pass/issue-2284.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// xfail-test
trait Send {
fn f();
}
Expand Down