Skip to content

Commit e3c2729

Browse files
author
Ariel Ben-Yehuda
committed
---
yaml --- r: 228059 b: refs/heads/try c: 90fcf26 h: refs/heads/master i: 228057: 2eda616 228055: 1cc054f v: v3
1 parent 534893a commit e3c2729

File tree

7 files changed

+144
-139
lines changed

7 files changed

+144
-139
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: aca2057ed5fb7af3f8905b2bc01f72fa001c35c8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 638ffecbd72bfa6e3f2eb4a74b3e7650cc5d2206
4+
refs/heads/try: 90fcf261f2b9c174cf800a5ac63ebf23d022fe37
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/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/try/src/librustc/middle/effect.rs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -59,26 +59,6 @@ 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-
}
8262
}
8363

8464
impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
@@ -164,12 +144,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
164144
self.require_unsafe(expr.span, "dereference of raw pointer")
165145
}
166146
}
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-
}
173147
ast::ExprInlineAsm(..) => {
174148
self.require_unsafe(expr.span, "use of inline assembly");
175149
}

branches/try/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/try/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/try/src/test/compile-fail/associated-types-overridden-default.rs renamed to branches/try/src/test/compile-fail/str-mut-idx-2.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![feature(associated_consts)]
12-
13-
pub trait Tr {
14-
type Assoc = u8;
15-
type Assoc2 = Self::Assoc;
16-
const C: u8 = 11;
17-
fn foo(&self) {}
18-
}
19-
20-
impl Tr for () {
21-
type Assoc = ();
22-
//~^ ERROR need to be reimplemented as `Assoc` was overridden: `Assoc2`, `C`, `foo`
11+
fn mutate(mut s: &mut str) {
12+
let _s: &mut str = &mut s[1..2];
13+
//~^ ERROR cannot borrow immutable indexed content as mutable
2314
}
2415

25-
fn main() {}
16+
pub fn main() {}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn bot<T>() -> T { loop {} }
12+
13+
fn mutate(s: &mut str) {
14+
s[1..2] = bot();
15+
//~^ ERROR `core::marker::Sized` is not implemented for the type `str`
16+
//~^^ ERROR `core::marker::Sized` is not implemented for the type `str`
17+
s[1usize] = bot();
18+
//~^ ERROR `core::ops::Index<usize>` is not implemented for the type `str`
19+
//~^^ ERROR `core::ops::Index<usize>` is not implemented for the type `str`
20+
}
21+
22+
pub fn main() {}

0 commit comments

Comments
 (0)