Skip to content

Commit 0417b04

Browse files
committed
---
yaml --- r: 223549 b: refs/heads/beta c: 0da6996 h: refs/heads/master i: 223547: 0dfedbd v: v3
1 parent d9f11cb commit 0417b04

File tree

9 files changed

+148
-168
lines changed

9 files changed

+148
-168
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ refs/tags/0.9: 36870b185fc5f5486636d4515f0e22677493f225
2323
refs/tags/0.10: ac33f2b15782272ae348dbd7b14b8257b2148b5a
2424
refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
26-
refs/heads/beta: c83f8f9bd90d0f58c0c34520d4909cde138b9f22
26+
refs/heads/beta: 0da69969d1fc8d375867ff07dfcefa2c4a2e7724
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: 938f5d7af401e2d8238522fed4a612943b6e77fd
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/src/libcore/str/pattern.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -513,17 +513,16 @@ impl<'a, 'b> Pattern<'a> for &'b str {
513513
/// Checks whether the pattern matches at the front of the haystack
514514
#[inline]
515515
fn is_prefix_of(self, haystack: &'a str) -> bool {
516-
// Use `as_bytes` so that we can slice through a character in the haystack.
517-
// Since self is always valid UTF-8, this can't result in a false positive.
518-
self.len() <= haystack.len() &&
519-
self.as_bytes() == &haystack.as_bytes()[..self.len()]
516+
haystack.is_char_boundary(self.len()) &&
517+
self == &haystack[..self.len()]
520518
}
521519

522520
/// Checks whether the pattern matches at the back of the haystack
523521
#[inline]
524522
fn is_suffix_of(self, haystack: &'a str) -> bool {
525523
self.len() <= haystack.len() &&
526-
self.as_bytes() == &haystack.as_bytes()[haystack.len() - self.len()..]
524+
haystack.is_char_boundary(haystack.len() - self.len()) &&
525+
self == &haystack[haystack.len() - self.len()..]
527526
}
528527
}
529528

branches/beta/src/librustc/diagnostics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,8 +1205,8 @@ register_diagnostics! {
12051205
E0017,
12061206
E0022,
12071207
E0038,
1208-
// E0134,
1209-
// E0135,
1208+
E0134,
1209+
E0135,
12101210
E0136,
12111211
E0138,
12121212
E0139,

branches/beta/src/librustc/middle/effect.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,26 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
5959
UnsafeFn => {}
6060
}
6161
}
62+
63+
fn check_str_index(&mut self, e: &ast::Expr) {
64+
let base_type = match e.node {
65+
ast::ExprIndex(ref base, _) => self.tcx.node_id_to_type(base.id),
66+
_ => return
67+
};
68+
debug!("effect: checking index with base type {:?}",
69+
base_type);
70+
match base_type.sty {
71+
ty::TyBox(ty) | ty::TyRef(_, ty::mt{ty, ..}) => if ty::TyStr == ty.sty {
72+
span_err!(self.tcx.sess, e.span, E0134,
73+
"modification of string types is not allowed");
74+
},
75+
ty::TyStr => {
76+
span_err!(self.tcx.sess, e.span, E0135,
77+
"modification of string types is not allowed");
78+
}
79+
_ => {}
80+
}
81+
}
6282
}
6383

6484
impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
@@ -144,6 +164,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
144164
self.require_unsafe(expr.span, "dereference of raw pointer")
145165
}
146166
}
167+
ast::ExprAssign(ref base, _) | ast::ExprAssignOp(_, ref base, _) => {
168+
self.check_str_index(&**base);
169+
}
170+
ast::ExprAddrOf(ast::MutMutable, ref base) => {
171+
self.check_str_index(&**base);
172+
}
147173
ast::ExprInlineAsm(..) => {
148174
self.require_unsafe(expr.span, "use of inline assembly");
149175
}

branches/beta/src/librustc_typeck/check/mod.rs

Lines changed: 114 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -846,82 +846,128 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
846846
// Locate trait methods
847847
let tcx = ccx.tcx;
848848
let trait_items = tcx.trait_items(impl_trait_ref.def_id);
849-
let mut overridden_associated_type = None;
850849

851850
// Check existing impl methods to see if they are both present in trait
852851
// and compatible with trait signature
853852
for impl_item in impl_items {
854-
let ty_impl_item = ccx.tcx.impl_or_trait_item(local_def(impl_item.id));
855-
let ty_trait_item = trait_items.iter()
856-
.find(|ac| ac.name() == ty_impl_item.name())
857-
.unwrap_or_else(|| {
858-
// This is checked by resolve
859-
tcx.sess.span_bug(impl_item.span,
860-
&format!("impl-item `{}` is not a member of `{:?}`",
861-
token::get_name(ty_impl_item.name()),
862-
impl_trait_ref));
863-
});
864853
match impl_item.node {
865854
ast::ConstImplItem(..) => {
866-
let impl_const = match ty_impl_item {
867-
ty::ConstTraitItem(ref cti) => cti,
868-
_ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const")
869-
};
855+
let impl_const_def_id = local_def(impl_item.id);
856+
let impl_const_ty = ccx.tcx.impl_or_trait_item(impl_const_def_id);
870857

871858
// Find associated const definition.
872-
if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item {
873-
compare_const_impl(ccx.tcx,
874-
&impl_const,
875-
impl_item.span,
876-
trait_const,
877-
&*impl_trait_ref);
878-
} else {
879-
span_err!(tcx.sess, impl_item.span, E0323,
880-
"item `{}` is an associated const, \
881-
which doesn't match its trait `{:?}`",
882-
token::get_name(impl_const.name),
883-
impl_trait_ref)
859+
let opt_associated_const =
860+
trait_items.iter()
861+
.find(|ac| ac.name() == impl_const_ty.name());
862+
match opt_associated_const {
863+
Some(associated_const) => {
864+
match (associated_const, &impl_const_ty) {
865+
(&ty::ConstTraitItem(ref const_trait),
866+
&ty::ConstTraitItem(ref const_impl)) => {
867+
compare_const_impl(ccx.tcx,
868+
&const_impl,
869+
impl_item.span,
870+
&const_trait,
871+
&*impl_trait_ref);
872+
}
873+
_ => {
874+
span_err!(tcx.sess, impl_item.span, E0323,
875+
"item `{}` is an associated const, \
876+
which doesn't match its trait `{:?}`",
877+
token::get_name(impl_const_ty.name()),
878+
impl_trait_ref)
879+
}
880+
}
881+
}
882+
None => {
883+
// This is `span_bug` as it should have already been
884+
// caught in resolve.
885+
tcx.sess.span_bug(
886+
impl_item.span,
887+
&format!(
888+
"associated const `{}` is not a member of \
889+
trait `{:?}`",
890+
token::get_name(impl_const_ty.name()),
891+
impl_trait_ref));
892+
}
884893
}
885894
}
886895
ast::MethodImplItem(ref sig, ref body) => {
887896
check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
888897

889-
let impl_method = match ty_impl_item {
890-
ty::MethodTraitItem(ref mti) => mti,
891-
_ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method")
892-
};
893-
894-
if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item {
895-
compare_impl_method(ccx.tcx,
896-
&impl_method,
897-
impl_item.span,
898-
body.id,
899-
&trait_method,
900-
&impl_trait_ref);
901-
} else {
902-
span_err!(tcx.sess, impl_item.span, E0324,
903-
"item `{}` is an associated method, \
904-
which doesn't match its trait `{:?}`",
905-
token::get_name(impl_method.name),
906-
impl_trait_ref)
898+
let impl_method_def_id = local_def(impl_item.id);
899+
let impl_item_ty = ccx.tcx.impl_or_trait_item(impl_method_def_id);
900+
901+
// If this is an impl of a trait method, find the
902+
// corresponding method definition in the trait.
903+
let opt_trait_method_ty =
904+
trait_items.iter()
905+
.find(|ti| ti.name() == impl_item_ty.name());
906+
match opt_trait_method_ty {
907+
Some(trait_method_ty) => {
908+
match (trait_method_ty, &impl_item_ty) {
909+
(&ty::MethodTraitItem(ref trait_method_ty),
910+
&ty::MethodTraitItem(ref impl_method_ty)) => {
911+
compare_impl_method(ccx.tcx,
912+
&**impl_method_ty,
913+
impl_item.span,
914+
body.id,
915+
&**trait_method_ty,
916+
&*impl_trait_ref);
917+
}
918+
_ => {
919+
span_err!(tcx.sess, impl_item.span, E0324,
920+
"item `{}` is an associated method, \
921+
which doesn't match its trait `{:?}`",
922+
token::get_name(impl_item_ty.name()),
923+
impl_trait_ref)
924+
}
925+
}
926+
}
927+
None => {
928+
// This is span_bug as it should have already been
929+
// caught in resolve.
930+
tcx.sess.span_bug(
931+
impl_item.span,
932+
&format!("method `{}` is not a member of trait `{:?}`",
933+
token::get_name(impl_item_ty.name()),
934+
impl_trait_ref));
935+
}
907936
}
908937
}
909938
ast::TypeImplItem(_) => {
910-
let impl_type = match ty_impl_item {
911-
ty::TypeTraitItem(ref tti) => tti,
912-
_ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type")
913-
};
914-
915-
if let &ty::TypeTraitItem(ref at) = ty_trait_item {
916-
if let Some(_) = at.ty {
917-
overridden_associated_type = Some(impl_item);
939+
let typedef_def_id = local_def(impl_item.id);
940+
let typedef_ty = ccx.tcx.impl_or_trait_item(typedef_def_id);
941+
942+
// If this is an impl of an associated type, find the
943+
// corresponding type definition in the trait.
944+
let opt_associated_type =
945+
trait_items.iter()
946+
.find(|ti| ti.name() == typedef_ty.name());
947+
match opt_associated_type {
948+
Some(associated_type) => {
949+
match (associated_type, &typedef_ty) {
950+
(&ty::TypeTraitItem(_), &ty::TypeTraitItem(_)) => {}
951+
_ => {
952+
span_err!(tcx.sess, impl_item.span, E0325,
953+
"item `{}` is an associated type, \
954+
which doesn't match its trait `{:?}`",
955+
token::get_name(typedef_ty.name()),
956+
impl_trait_ref)
957+
}
958+
}
959+
}
960+
None => {
961+
// This is `span_bug` as it should have already been
962+
// caught in resolve.
963+
tcx.sess.span_bug(
964+
impl_item.span,
965+
&format!(
966+
"associated type `{}` is not a member of \
967+
trait `{:?}`",
968+
token::get_name(typedef_ty.name()),
969+
impl_trait_ref));
918970
}
919-
} else {
920-
span_err!(tcx.sess, impl_item.span, E0325,
921-
"item `{}` is an associated type, \
922-
which doesn't match its trait `{:?}`",
923-
token::get_name(impl_type.name),
924-
impl_trait_ref)
925971
}
926972
}
927973
ast::MacImplItem(_) => tcx.sess.span_bug(impl_item.span,
@@ -933,8 +979,6 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
933979
let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
934980
let associated_consts = tcx.associated_consts(impl_trait_ref.def_id);
935981
let mut missing_items = Vec::new();
936-
let mut invalidated_items = Vec::new();
937-
let associated_type_overridden = overridden_associated_type.is_some();
938982
for trait_item in trait_items.iter() {
939983
match *trait_item {
940984
ty::ConstTraitItem(ref associated_const) => {
@@ -949,12 +993,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
949993
let is_provided =
950994
associated_consts.iter().any(|ac| ac.default.is_some() &&
951995
ac.name == associated_const.name);
952-
if !is_implemented {
953-
if !is_provided {
954-
missing_items.push(associated_const.name);
955-
} else if associated_type_overridden {
956-
invalidated_items.push(associated_const.name);
957-
}
996+
if !is_implemented && !is_provided {
997+
missing_items.push(format!("`{}`",
998+
token::get_name(associated_const.name)));
958999
}
9591000
}
9601001
ty::MethodTraitItem(ref trait_method) => {
@@ -969,12 +1010,8 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
9691010
});
9701011
let is_provided =
9711012
provided_methods.iter().any(|m| m.name == trait_method.name);
972-
if !is_implemented {
973-
if !is_provided {
974-
missing_items.push(trait_method.name);
975-
} else if associated_type_overridden {
976-
invalidated_items.push(trait_method.name);
977-
}
1013+
if !is_implemented && !is_provided {
1014+
missing_items.push(format!("`{}`", token::get_name(trait_method.name)));
9781015
}
9791016
}
9801017
ty::TypeTraitItem(ref associated_type) => {
@@ -987,34 +1024,17 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
9871024
}
9881025
});
9891026
let is_provided = associated_type.ty.is_some();
990-
if !is_implemented {
991-
if !is_provided {
992-
missing_items.push(associated_type.name);
993-
} else if associated_type_overridden {
994-
invalidated_items.push(associated_type.name);
995-
}
1027+
if !is_implemented && !is_provided {
1028+
missing_items.push(format!("`{}`", token::get_name(associated_type.name)));
9961029
}
9971030
}
9981031
}
9991032
}
10001033

10011034
if !missing_items.is_empty() {
10021035
span_err!(tcx.sess, impl_span, E0046,
1003-
"not all trait items implemented, missing: `{}`",
1004-
missing_items.iter()
1005-
.map(<ast::Name>::as_str)
1006-
.collect::<Vec<_>>().connect("`, `"))
1007-
}
1008-
1009-
if !invalidated_items.is_empty() {
1010-
let invalidator = overridden_associated_type.unwrap();
1011-
span_err!(tcx.sess, invalidator.span, E0399,
1012-
"the following trait items need to be reimplemented \
1013-
as `{}` was overridden: `{}`",
1014-
invalidator.ident.as_str(),
1015-
invalidated_items.iter()
1016-
.map(<ast::Name>::as_str)
1017-
.collect::<Vec<_>>().connect("`, `"))
1036+
"not all trait items implemented, missing: {}",
1037+
missing_items.connect(", "));
10181038
}
10191039
}
10201040

branches/beta/src/librustc_typeck/diagnostics.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,8 +2066,6 @@ register_diagnostics! {
20662066
// `#[lang = \"{}\"]` is allowed for the `{}` primitive
20672067
E0391, // unsupported cyclic reference between types/traits detected
20682068
E0392, // parameter `{}` is never used
2069-
E0393, // the type parameter `{}` must be explicitly specified in an object
2069+
E0393 // the type parameter `{}` must be explicitly specified in an object
20702070
// type because its default value `{}` references the type `Self`"
2071-
E0399 // trait items need to be implemented because the associated
2072-
// type `{}` was overridden
20732071
}

branches/beta/src/test/compile-fail/associated-types-overridden-default.rs

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)