Skip to content

Commit d26ccbf

Browse files
author
Jakub Wieczorek
committed
---
yaml --- r: 156251 b: refs/heads/snap-stage3 c: 0c48c57 h: refs/heads/master i: 156249: adaeb41 156247: a67d91a v: v3
1 parent 256aeb7 commit d26ccbf

30 files changed

+692
-91
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: c29a7520e7fb4a5b4d4eccfc594e05793ef6688d
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 38517d0eba2ee69443449fbe6b1ce7dea7deca7b
4+
refs/heads/snap-stage3: 0c48c5712dc52bb1f9e70181f1b68feff75269c2
55
refs/heads/try: 6601b0501e31d08d3892a2d5a7d8a57ab120bf75
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/doc/reference.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,23 @@ let c = [Cookie, Cookie, Cookie, Cookie];
13281328
The precise memory layout of a structure is not specified. One can specify a
13291329
particular layout using the [`repr` attribute](#ffi-attributes).
13301330

1331+
By using the `struct_inherit` feature gate, structures may use single
1332+
inheritance. A Structure may only inherit from a single other structure, called
1333+
the _super-struct_. The inheriting structure (sub-struct) acts as if all fields
1334+
in the super-struct were present in the sub-struct. Fields declared in a
1335+
sub-struct must not have the same name as any field in any (transitive)
1336+
super-struct. All fields (both declared and inherited) must be specified in any
1337+
initializers. Inheritance between structures does not give subtyping or
1338+
coercion. The super-struct and sub-struct must be defined in the same crate.
1339+
The super-struct must be declared using the `virtual` keyword. For example:
1340+
1341+
```{.ignore}
1342+
virtual struct Sup { x: int }
1343+
struct Sub : Sup { y: int }
1344+
let s = Sub {x: 10, y: 11};
1345+
let sx = s.x;
1346+
```
1347+
13311348
### Enumerations
13321349

13331350
An _enumeration_ is a simultaneous definition of a nominal [enumerated

branches/snap-stage3/src/librustc/diagnostics.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ register_diagnostics!(
5656
E0038,
5757
E0039,
5858
E0040,
59+
E0041,
5960
E0044,
6061
E0045,
6162
E0046,
@@ -122,6 +123,7 @@ register_diagnostics!(
122123
E0121,
123124
E0122,
124125
E0124,
126+
E0126,
125127
E0127,
126128
E0128,
127129
E0129,
@@ -139,6 +141,9 @@ register_diagnostics!(
139141
E0141,
140142
E0152,
141143
E0153,
144+
E0154,
145+
E0155,
146+
E0156,
142147
E0157,
143148
E0158,
144149
E0159,

branches/snap-stage3/src/librustc/middle/check_match.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,15 +638,15 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
638638
PatEnum(..) =>
639639
match cx.tcx.def_map.borrow().find(&pat.id) {
640640
Some(&DefConst(..)) =>
641-
cx.tcx.sess.span_bug(pat.span, "static pattern should've \
641+
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
642642
been rewritten"),
643643
Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
644644
_ => vec!(Single)
645645
},
646646
PatStruct(..) =>
647647
match cx.tcx.def_map.borrow().find(&pat.id) {
648648
Some(&DefConst(..)) =>
649-
cx.tcx.sess.span_bug(pat.span, "static pattern should've \
649+
cx.tcx.sess.span_bug(pat.span, "const pattern should've \
650650
been rewritten"),
651651
Some(&DefVariant(_, id, _)) => vec!(Variant(id)),
652652
_ => vec!(Single)

branches/snap-stage3/src/librustc/middle/pat_util.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,25 @@ pub type PatIdMap = HashMap<Ident, NodeId>;
2525
pub fn pat_id_map(dm: &resolve::DefMap, pat: &Pat) -> PatIdMap {
2626
let mut map = HashMap::new();
2727
pat_bindings(dm, pat, |_bm, p_id, _s, path1| {
28-
map.insert(path1.node, p_id);
28+
map.insert(path1.node, p_id);
2929
});
3030
map
3131
}
3232

33+
pub fn pat_is_refutable(dm: &resolve::DefMap, pat: &Pat) -> bool {
34+
match pat.node {
35+
PatLit(_) | PatRange(_, _) => true,
36+
PatEnum(_, _) | PatIdent(_, _, None) | PatStruct(..) => {
37+
match dm.borrow().find(&pat.id) {
38+
Some(&DefVariant(..)) => true,
39+
_ => false
40+
}
41+
}
42+
PatVec(_, _, _) => true,
43+
_ => false
44+
}
45+
}
46+
3347
pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &Pat) -> bool {
3448
match pat.node {
3549
PatEnum(_, _) | PatIdent(_, _, None) | PatStruct(..) => {

branches/snap-stage3/src/librustc/middle/resolve.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use syntax::parse::token::special_idents;
5454
use syntax::parse::token;
5555
use syntax::codemap::{Span, DUMMY_SP, Pos};
5656
use syntax::owned_slice::OwnedSlice;
57+
use syntax::ptr::P;
5758
use syntax::visit;
5859
use syntax::visit::Visitor;
5960

@@ -4178,6 +4179,7 @@ impl<'a> Resolver<'a> {
41784179
ItemStruct(ref struct_def, ref generics) => {
41794180
self.resolve_struct(item.id,
41804181
generics,
4182+
&struct_def.super_struct,
41814183
struct_def.fields.as_slice());
41824184
}
41834185

@@ -4503,6 +4505,7 @@ impl<'a> Resolver<'a> {
45034505
fn resolve_struct(&mut self,
45044506
id: NodeId,
45054507
generics: &Generics,
4508+
super_struct: &Option<P<Ty>>,
45064509
fields: &[StructField]) {
45074510
// If applicable, create a rib for the type parameters.
45084511
self.with_type_parameter_rib(HasTypeParameters(generics,
@@ -4514,6 +4517,42 @@ impl<'a> Resolver<'a> {
45144517
this.resolve_type_parameters(&generics.ty_params);
45154518
this.resolve_where_clause(&generics.where_clause);
45164519

4520+
// Resolve the super struct.
4521+
match *super_struct {
4522+
Some(ref t) => match t.node {
4523+
TyPath(ref path, None, path_id) => {
4524+
match this.resolve_path(id, path, TypeNS, true) {
4525+
Some((DefTy(def_id, _), lp)) if this.structs.contains_key(&def_id) => {
4526+
let def = DefStruct(def_id);
4527+
debug!("(resolving struct) resolved `{}` to type {:?}",
4528+
token::get_ident(path.segments
4529+
.last().unwrap()
4530+
.identifier),
4531+
def);
4532+
debug!("(resolving struct) writing resolution for `{}` (id {})",
4533+
this.path_idents_to_string(path),
4534+
path_id);
4535+
this.record_def(path_id, (def, lp));
4536+
}
4537+
Some((DefStruct(_), _)) => {
4538+
span_err!(this.session, t.span, E0154,
4539+
"super-struct is defined in a different crate");
4540+
},
4541+
Some(_) => {
4542+
span_err!(this.session, t.span, E0155,
4543+
"super-struct is not a struct type");
4544+
}
4545+
None => {
4546+
span_err!(this.session, t.span, E0156,
4547+
"super-struct could not be resolved");
4548+
}
4549+
}
4550+
},
4551+
_ => this.session.span_bug(t.span, "path not mapped to a TyPath")
4552+
},
4553+
None => {}
4554+
}
4555+
45174556
// Resolve fields.
45184557
for field in fields.iter() {
45194558
this.resolve_type(&*field.node.ty);

branches/snap-stage3/src/librustc/middle/trans/_match.rs

Lines changed: 69 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ use util::ppaux::{Repr, vec_map_to_string};
218218

219219
use std;
220220
use std::collections::HashMap;
221+
use std::iter::AdditiveIterator;
221222
use std::rc::Rc;
222223
use syntax::ast;
223224
use syntax::ast::{DUMMY_NODE_ID, Ident};
@@ -754,33 +755,41 @@ impl FailureHandler {
754755
}
755756
}
756757

757-
fn pick_col(m: &[Match]) -> uint {
758-
fn score(p: &ast::Pat) -> uint {
759-
match p.node {
760-
ast::PatLit(_) | ast::PatEnum(_, _) | ast::PatRange(_, _) => 1u,
761-
ast::PatIdent(_, _, Some(ref p)) => score(&**p),
762-
_ => 0u
758+
fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> {
759+
fn pat_score(def_map: &DefMap, pat: &ast::Pat) -> uint {
760+
match pat.node {
761+
ast::PatIdent(_, _, Some(ref inner)) => pat_score(def_map, &**inner),
762+
_ if pat_is_refutable(def_map, pat) => 1u,
763+
_ => 0u
763764
}
764765
}
765-
let mut scores = Vec::from_elem(m[0].pats.len(), 0u);
766-
for br in m.iter() {
767-
for (i, ref p) in br.pats.iter().enumerate() {
768-
*scores.get_mut(i) += score(&***p);
766+
767+
let column_score: |&[Match], uint| -> uint = |m, col| {
768+
let total_score = m.iter()
769+
.map(|row| row.pats[col])
770+
.map(|pat| pat_score(def_map, pat))
771+
.sum();
772+
773+
// Irrefutable columns always go first, they'd only be duplicated in the branches.
774+
if total_score == 0 {
775+
std::uint::MAX
776+
} else {
777+
total_score
769778
}
770-
}
771-
let mut max_score = 0u;
772-
let mut best_col = 0u;
773-
for (i, score) in scores.iter().enumerate() {
774-
let score = *score;
775-
776-
// Irrefutable columns always go first, they'd only be duplicated in
777-
// the branches.
778-
if score == 0u { return i; }
779-
// If no irrefutable ones are found, we pick the one with the biggest
780-
// branching factor.
781-
if score > max_score { max_score = score; best_col = i; }
782-
}
783-
return best_col;
779+
};
780+
781+
let column_contains_any_nonwild_patterns: |&uint| -> bool = |&col| {
782+
m.iter().any(|row| match row.pats[col].node {
783+
ast::PatWild(_) => false,
784+
_ => true
785+
})
786+
};
787+
788+
range(0, m[0].pats.len())
789+
.filter(column_contains_any_nonwild_patterns)
790+
.map(|col| (col, column_score(m, col)))
791+
.max_by(|&(_, score)| score)
792+
.map(|(col, _)| col)
784793
}
785794

786795
// Compiles a comparison between two things.
@@ -951,44 +960,45 @@ fn compile_submatch<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
951960
return;
952961
}
953962

954-
let col_count = m[0].pats.len();
955-
if col_count == 0u {
956-
let data = &m[0].data;
957-
for &(ref ident, ref value_ptr) in m[0].bound_ptrs.iter() {
958-
let llmatch = data.bindings_map.get(ident).llmatch;
959-
call_lifetime_start(bcx, llmatch);
960-
Store(bcx, *value_ptr, llmatch);
963+
let tcx = bcx.tcx();
964+
let def_map = &tcx.def_map;
965+
match pick_column_to_specialize(def_map, m) {
966+
Some(col) => {
967+
let val = vals[col];
968+
if has_nested_bindings(m, col) {
969+
let expanded = expand_nested_bindings(bcx, m, col, val);
970+
compile_submatch_continue(bcx,
971+
expanded.as_slice(),
972+
vals,
973+
chk,
974+
col,
975+
val,
976+
has_genuine_default)
977+
} else {
978+
compile_submatch_continue(bcx, m, vals, chk, col, val, has_genuine_default)
979+
}
961980
}
962-
match data.arm.guard {
963-
Some(ref guard_expr) => {
964-
bcx = compile_guard(bcx,
965-
&**guard_expr,
966-
m[0].data,
967-
m[1..m.len()],
968-
vals,
969-
chk,
970-
has_genuine_default);
981+
None => {
982+
let data = &m[0].data;
983+
for &(ref ident, ref value_ptr) in m[0].bound_ptrs.iter() {
984+
let llmatch = data.bindings_map.get(ident).llmatch;
985+
call_lifetime_start(bcx, llmatch);
986+
Store(bcx, *value_ptr, llmatch);
971987
}
972-
_ => ()
988+
match data.arm.guard {
989+
Some(ref guard_expr) => {
990+
bcx = compile_guard(bcx,
991+
&**guard_expr,
992+
m[0].data,
993+
m[1..m.len()],
994+
vals,
995+
chk,
996+
has_genuine_default);
997+
}
998+
_ => ()
999+
}
1000+
Br(bcx, data.bodycx.llbb);
9731001
}
974-
Br(bcx, data.bodycx.llbb);
975-
return;
976-
}
977-
978-
let col = pick_col(m);
979-
let val = vals[col];
980-
981-
if has_nested_bindings(m, col) {
982-
let expanded = expand_nested_bindings(bcx, m, col, val);
983-
compile_submatch_continue(bcx,
984-
expanded.as_slice(),
985-
vals,
986-
chk,
987-
col,
988-
val,
989-
has_genuine_default)
990-
} else {
991-
compile_submatch_continue(bcx, m, vals, chk, col, val, has_genuine_default)
9921002
}
9931003
}
9941004

0 commit comments

Comments
 (0)