Skip to content

Commit fc23492

Browse files
committed
---
yaml --- r: 121676 b: refs/heads/try c: 10b12bc h: refs/heads/master v: v3
1 parent 905a309 commit fc23492

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+377
-109
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 8fe47bc3bb34d7a1ce7bbd2c6fc5ea7a6dbf57a4
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: bab614f5fa725d248afc5f0530c835f37998ce8f
5-
refs/heads/try: 70d4b50071fb6766eab93da5e752e37a62d7a19e
5+
refs/heads/try: 10b12bc123984dfd0858a68c5ad2fe33cdc01ede
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/doc/rust.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3004,7 +3004,7 @@ ten_times(|j| println!("hello, {}", j));
30043004
### While loops
30053005

30063006
~~~~ {.ebnf .gram}
3007-
while_expr : "while" expr '{' block '}' ;
3007+
while_expr : "while" no_struct_literal_expr '{' block '}' ;
30083008
~~~~
30093009

30103010
A `while` loop begins by evaluating the boolean loop conditional expression.
@@ -3071,7 +3071,7 @@ A `continue` expression is only permitted in the body of a loop.
30713071
### For expressions
30723072

30733073
~~~~ {.ebnf .gram}
3074-
for_expr : "for" pat "in" expr '{' block '}' ;
3074+
for_expr : "for" pat "in" no_struct_literal_expr '{' block '}' ;
30753075
~~~~
30763076

30773077
A `for` expression is a syntactic construct for looping over elements
@@ -3105,7 +3105,7 @@ for i in range(0u, 256) {
31053105
### If expressions
31063106

31073107
~~~~ {.ebnf .gram}
3108-
if_expr : "if" expr '{' block '}'
3108+
if_expr : "if" no_struct_literal_expr '{' block '}'
31093109
else_tail ? ;
31103110
31113111
else_tail : "else" [ if_expr
@@ -3126,7 +3126,7 @@ then any `else` block is executed.
31263126
### Match expressions
31273127

31283128
~~~~ {.ebnf .gram}
3129-
match_expr : "match" expr '{' match_arm * '}' ;
3129+
match_expr : "match" no_struct_literal_expr '{' match_arm * '}' ;
31303130
31313131
match_arm : attribute * match_pat "=>" [ expr "," | '{' block '}' ] ;
31323132

branches/try/src/etc/2014-06-rewrite-bytes-macros.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/env python
1+
#!/usr/bin/env python
22
#
33
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
44
# file at the top-level directory of this distribution and at

branches/try/src/librustc/front/feature_gate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
//! enabled.
1717
//!
1818
//! Features are enabled in programs via the crate-level attributes of
19-
//! #![feature(...)] with a comma-separated list of features.
19+
//! `#![feature(...)]` with a comma-separated list of features.
2020
2121
use middle::lint;
2222

branches/try/src/librustc/middle/check_match.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ fn check_exhaustive(cx: &MatchCheckCtxt, sp: Span, m: &Matrix) {
194194
#[deriving(Clone, PartialEq)]
195195
enum ctor {
196196
single,
197-
variant(DefId /* variant */, bool /* is_structure */),
197+
variant(DefId),
198198
val(const_val),
199199
range(const_val, const_val),
200200
vec(uint)
@@ -218,7 +218,8 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &ctor, pats: Vec<Gc<Pat>>, lty:
218218

219219
ty::ty_enum(cid, _) | ty::ty_struct(cid, _) => {
220220
let (vid, is_structure) = match ctor {
221-
&variant(vid, is_structure) => (vid, is_structure),
221+
&variant(vid) => (vid,
222+
ty::enum_variant_with_id(cx.tcx, cid, vid).arg_names.is_some()),
222223
_ => (cid, true)
223224
};
224225
if is_structure {
@@ -316,7 +317,7 @@ fn all_constructors(cx: &MatchCheckCtxt, m: &Matrix, left_ty: ty::t) -> Vec<ctor
316317
ty::ty_enum(eid, _) =>
317318
ty::enum_variants(cx.tcx, eid)
318319
.iter()
319-
.map(|va| variant(va.id, va.arg_names.is_some()))
320+
.map(|va| variant(va.id))
320321
.collect(),
321322

322323
ty::ty_vec(_, None) =>
@@ -440,7 +441,7 @@ fn pat_ctor_id(cx: &MatchCheckCtxt, left_ty: ty::t, p: Gc<Pat>) -> Option<ctor>
440441
let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
441442
Some(val(eval_const_expr(cx.tcx, &*const_expr)))
442443
},
443-
Some(&DefVariant(_, id, is_structure)) => Some(variant(id, is_structure)),
444+
Some(&DefVariant(_, id, _)) => Some(variant(id)),
444445
_ => None
445446
},
446447
PatEnum(..) =>
@@ -449,12 +450,12 @@ fn pat_ctor_id(cx: &MatchCheckCtxt, left_ty: ty::t, p: Gc<Pat>) -> Option<ctor>
449450
let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
450451
Some(val(eval_const_expr(cx.tcx, &*const_expr)))
451452
},
452-
Some(&DefVariant(_, id, is_structure)) => Some(variant(id, is_structure)),
453+
Some(&DefVariant(_, id, _)) => Some(variant(id)),
453454
_ => Some(single)
454455
},
455456
PatStruct(..) =>
456457
match cx.tcx.def_map.borrow().find(&pat.id) {
457-
Some(&DefVariant(_, id, is_structure)) => Some(variant(id, is_structure)),
458+
Some(&DefVariant(_, id, _)) => Some(variant(id)),
458459
_ => Some(single)
459460
},
460461
PatLit(expr) =>
@@ -504,7 +505,7 @@ fn constructor_arity(cx: &MatchCheckCtxt, ctor: &ctor, ty: ty::t) -> uint {
504505
},
505506
ty::ty_enum(eid, _) => {
506507
match *ctor {
507-
variant(id, _) => enum_variant_with_id(cx.tcx, eid, id).args.len(),
508+
variant(id) => enum_variant_with_id(cx.tcx, eid, id).args.len(),
508509
_ => unreachable!()
509510
}
510511
}
@@ -551,9 +552,10 @@ fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
551552
&PatIdent(_, _, _) => {
552553
let opt_def = cx.tcx.def_map.borrow().find_copy(pat_id);
553554
match opt_def {
554-
Some(DefVariant(_, id, _)) => match *ctor_id {
555-
variant(vid, _) if vid == id => Some(vec!()),
556-
_ => None
555+
Some(DefVariant(_, id, _)) => if *ctor_id == variant(id) {
556+
Some(vec!())
557+
} else {
558+
None
557559
},
558560
Some(DefStatic(did, _)) => {
559561
let const_expr = lookup_const_by_id(cx.tcx, did).unwrap();
@@ -587,7 +589,7 @@ fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
587589
}
588590
}
589591
}
590-
DefVariant(_, id, _) if variant(id, false) != *ctor_id => None,
592+
DefVariant(_, id, _) if *ctor_id != variant(id) => None,
591593
DefVariant(..) | DefFn(..) | DefStruct(..) => {
592594
Some(match args {
593595
&Some(ref args) => args.clone(),
@@ -602,7 +604,7 @@ fn specialize(cx: &MatchCheckCtxt, r: &[Gc<Pat>],
602604
// Is this a struct or an enum variant?
603605
let def = cx.tcx.def_map.borrow().get_copy(pat_id);
604606
let class_id = match def {
605-
DefVariant(_, variant_id, _) => if *ctor_id == variant(variant_id, true) {
607+
DefVariant(_, variant_id, _) => if *ctor_id == variant(variant_id) {
606608
Some(variant_id)
607609
} else {
608610
None

branches/try/src/librustc/middle/resolve.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3894,8 +3894,31 @@ impl<'a> Resolver<'a> {
38943894
self.resolve_error(trait_reference.path.span, msg.as_slice());
38953895
}
38963896
Some(def) => {
3897-
debug!("(resolving trait) found trait def: {:?}", def);
3898-
self.record_def(trait_reference.ref_id, def);
3897+
match def {
3898+
(DefTrait(_), _) => {
3899+
debug!("(resolving trait) found trait def: {:?}", def);
3900+
self.record_def(trait_reference.ref_id, def);
3901+
}
3902+
(def, _) => {
3903+
self.resolve_error(trait_reference.path.span,
3904+
format!("`{}` is not a trait",
3905+
self.path_idents_to_str(
3906+
&trait_reference.path)));
3907+
3908+
// If it's a typedef, give a note
3909+
match def {
3910+
DefTy(_) => {
3911+
self.session.span_note(
3912+
trait_reference.path.span,
3913+
format!("`type` aliases cannot \
3914+
be used for traits")
3915+
.as_slice());
3916+
}
3917+
_ => {}
3918+
}
3919+
}
3920+
}
3921+
38993922
}
39003923
}
39013924
}
@@ -4021,6 +4044,9 @@ impl<'a> Resolver<'a> {
40214044

40224045
this.with_current_self_type(self_type, |this| {
40234046
for method in methods.iter() {
4047+
// If this is a trait impl, ensure the method exists in trait
4048+
this.check_trait_method(&**method);
4049+
40244050
// We also need a new scope for the method-specific type parameters.
40254051
this.resolve_method(MethodRibKind(id, Provided(method.id)),
40264052
&**method);
@@ -4030,6 +4056,21 @@ impl<'a> Resolver<'a> {
40304056
});
40314057
}
40324058

4059+
fn check_trait_method(&self, method: &Method) {
4060+
// If there is a TraitRef in scope for an impl, then the method must be in the trait.
4061+
for &(did, ref trait_ref) in self.current_trait_ref.iter() {
4062+
let method_name = method.ident.name;
4063+
4064+
if self.method_map.borrow().find(&(method_name, did)).is_none() {
4065+
let path_str = self.path_idents_to_str(&trait_ref.path);
4066+
self.resolve_error(method.span,
4067+
format!("method `{}` is not a member of trait `{}`",
4068+
token::get_name(method_name),
4069+
path_str).as_slice());
4070+
}
4071+
}
4072+
}
4073+
40334074
fn resolve_module(&mut self, module: &Mod, _span: Span,
40344075
_name: Ident, id: NodeId) {
40354076
// Write the implementations in scope into the module metadata.

branches/try/src/librustc/middle/ty_fold.rs

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use middle::subst::VecPerParamSpace;
1515
use middle::ty;
1616
use middle::typeck;
1717
use std::rc::Rc;
18+
use syntax::ast;
1819
use syntax::owned_slice::OwnedSlice;
1920
use util::ppaux::Repr;
2021

@@ -449,10 +450,23 @@ impl<'a> TypeFolder for BottomUpFolder<'a> {
449450
///////////////////////////////////////////////////////////////////////////
450451
// Region folder
451452

453+
/// Folds over the substructure of a type, visiting its component
454+
/// types and all regions that occur *free* within it.
455+
///
456+
/// That is, `ty::t` can contain function or method types that bind
457+
/// regions at the call site (`ReLateBound`), and occurrences of
458+
/// regions (aka "lifetimes") that are bound within a type are not
459+
/// visited by this folder; only regions that occur free will be
460+
/// visited by `fld_r`.
461+
///
462+
/// (The distinction between "free" and "bound" is represented by
463+
/// keeping track of each `FnSig` in the lexical context of the
464+
/// current position of the fold.)
452465
pub struct RegionFolder<'a> {
453466
tcx: &'a ty::ctxt,
454467
fld_t: |ty::t|: 'a -> ty::t,
455468
fld_r: |ty::Region|: 'a -> ty::Region,
469+
within_binder_ids: Vec<ast::NodeId>,
456470
}
457471

458472
impl<'a> RegionFolder<'a> {
@@ -463,7 +477,8 @@ impl<'a> RegionFolder<'a> {
463477
RegionFolder {
464478
tcx: tcx,
465479
fld_t: fld_t,
466-
fld_r: fld_r
480+
fld_r: fld_r,
481+
within_binder_ids: vec![],
467482
}
468483
}
469484

@@ -474,22 +489,53 @@ impl<'a> RegionFolder<'a> {
474489
RegionFolder {
475490
tcx: tcx,
476491
fld_t: noop,
477-
fld_r: fld_r
492+
fld_r: fld_r,
493+
within_binder_ids: vec![],
478494
}
479495
}
480496
}
481497

498+
/// If `ty` has `FnSig` (i.e. closure or fn), return its binder_id;
499+
/// else None.
500+
fn opt_binder_id_of_function(t: ty::t) -> Option<ast::NodeId> {
501+
match ty::get(t).sty {
502+
ty::ty_closure(ref f) => Some(f.sig.binder_id),
503+
ty::ty_bare_fn(ref f) => Some(f.sig.binder_id),
504+
_ => None,
505+
}
506+
}
507+
482508
impl<'a> TypeFolder for RegionFolder<'a> {
483509
fn tcx<'a>(&'a self) -> &'a ty::ctxt { self.tcx }
484510

485511
fn fold_ty(&mut self, ty: ty::t) -> ty::t {
486512
debug!("RegionFolder.fold_ty({})", ty.repr(self.tcx()));
513+
let opt_binder_id = opt_binder_id_of_function(ty);
514+
match opt_binder_id {
515+
Some(binder_id) => self.within_binder_ids.push(binder_id),
516+
None => {}
517+
}
518+
487519
let t1 = super_fold_ty(self, ty);
488-
(self.fld_t)(t1)
520+
let ret = (self.fld_t)(t1);
521+
522+
if opt_binder_id.is_some() {
523+
self.within_binder_ids.pop();
524+
}
525+
526+
ret
489527
}
490528

491529
fn fold_region(&mut self, r: ty::Region) -> ty::Region {
492-
debug!("RegionFolder.fold_region({})", r.repr(self.tcx()));
493-
(self.fld_r)(r)
530+
match r {
531+
ty::ReLateBound(binder_id, _) if self.within_binder_ids.contains(&binder_id) => {
532+
debug!("RegionFolder.fold_region({}) skipped bound region", r.repr(self.tcx()));
533+
r
534+
}
535+
_ => {
536+
debug!("RegionFolder.fold_region({}) folding free region", r.repr(self.tcx()));
537+
(self.fld_r)(r)
538+
}
539+
}
494540
}
495541
}

branches/try/src/librustc/middle/typeck/check/_match.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -726,22 +726,38 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) {
726726
}
727727

728728
// Helper function to check gc, box and & patterns
729-
pub fn check_pointer_pat(pcx: &pat_ctxt,
730-
pointer_kind: PointerKind,
731-
inner: &ast::Pat,
732-
pat_id: ast::NodeId,
733-
span: Span,
734-
expected: ty::t) {
729+
fn check_pointer_pat(pcx: &pat_ctxt,
730+
pointer_kind: PointerKind,
731+
inner: &ast::Pat,
732+
pat_id: ast::NodeId,
733+
span: Span,
734+
expected: ty::t) {
735735
let fcx = pcx.fcx;
736+
let tcx = fcx.ccx.tcx;
736737
let check_inner: |ty::t| = |e_inner| {
737-
check_pat(pcx, inner, e_inner);
738-
fcx.write_ty(pat_id, expected);
738+
match ty::get(e_inner).sty {
739+
ty::ty_trait(_) if pat_is_binding(&tcx.def_map, inner) => {
740+
// This is "x = SomeTrait" being reduced from
741+
// "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
742+
check_pat(pcx, inner, ty::mk_err());
743+
tcx.sess.span_err(
744+
span,
745+
format!("type `{}` cannot be dereferenced",
746+
fcx.infcx().ty_to_str(expected)).as_slice());
747+
fcx.write_error(pat_id);
748+
}
749+
_ => {
750+
check_pat(pcx, inner, e_inner);
751+
fcx.write_ty(pat_id, expected);
752+
}
753+
}
739754
};
755+
740756
match *structure_of(fcx, span, expected) {
741-
ty::ty_uniq(e_inner) if pointer_kind == Send && !ty::type_is_trait(e_inner) => {
757+
ty::ty_uniq(e_inner) if pointer_kind == Send => {
742758
check_inner(e_inner);
743759
}
744-
ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed && !ty::type_is_trait(e_inner.ty) => {
760+
ty::ty_rptr(_, e_inner) if pointer_kind == Borrowed => {
745761
check_inner(e_inner.ty);
746762
}
747763
_ => {

branches/try/src/librustc/middle/typeck/check/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,8 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
784784
&impl_trait_ref.substs);
785785
}
786786
None => {
787-
tcx.sess.span_err(
787+
// This is span_bug as it should have already been caught in resolve.
788+
tcx.sess.span_bug(
788789
impl_method.span,
789790
format!(
790791
"method `{}` is not a member of trait `{}`",

0 commit comments

Comments
 (0)