Skip to content

Commit 7a187c3

Browse files
authored
Auto merge of #36166 - jonathandturner:rollup, r=jonathandturner
Rollup of 16 pull requests - Successful merges: #35758, #35926, #36050, #36079, #36085, #36089, #36101, #36130, #36134, #36135, #36136, #36140, #36141, #36147, #36148, #36165 - Failed merges:
2 parents 824000a + 0cb5073 commit 7a187c3

31 files changed

+547
-85
lines changed

src/libcore/cmp.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ impl PartialOrd for Ordering {
383383
/// }
384384
/// ```
385385
///
386-
/// You may also find it useful to use `partial_cmp()` on your type`s fields. Here
386+
/// You may also find it useful to use `partial_cmp()` on your type's fields. Here
387387
/// is an example of `Person` types who have a floating-point `height` field that
388388
/// is the only field to be used for sorting:
389389
///

src/libcore/iter/range.rs

+10-22
Original file line numberDiff line numberDiff line change
@@ -263,14 +263,12 @@ impl<A: Step> ops::RangeFrom<A> {
263263
/// # Examples
264264
///
265265
/// ```
266-
/// # #![feature(step_by)]
267-
///
268-
/// for i in (0u8..).step_by(2).take(10) {
269-
/// println!("{}", i);
266+
/// #![feature(step_by)]
267+
/// fn main() {
268+
/// let result: Vec<_> = (0..).step_by(2).take(5).collect();
269+
/// assert_eq!(result, vec![0, 2, 4, 6, 8]);
270270
/// }
271271
/// ```
272-
///
273-
/// This prints the first ten even natural integers (0 to 18).
274272
#[unstable(feature = "step_by", reason = "recent addition",
275273
issue = "27741")]
276274
pub fn step_by(self, by: A) -> StepBy<A, Self> {
@@ -291,8 +289,10 @@ impl<A: Step> ops::Range<A> {
291289
///
292290
/// ```
293291
/// #![feature(step_by)]
294-
/// let result: Vec<_> = (0..10).step_by(2).collect();
295-
/// assert_eq!(result, vec![0, 2, 4, 6, 8]);
292+
/// fn main() {
293+
/// let result: Vec<_> = (0..10).step_by(2).collect();
294+
/// assert_eq!(result, vec![0, 2, 4, 6, 8]);
295+
/// }
296296
/// ```
297297
#[unstable(feature = "step_by", reason = "recent addition",
298298
issue = "27741")]
@@ -315,20 +315,8 @@ impl<A: Step> ops::RangeInclusive<A> {
315315
/// ```
316316
/// #![feature(step_by, inclusive_range_syntax)]
317317
///
318-
/// for i in (0...10).step_by(2) {
319-
/// println!("{}", i);
320-
/// }
321-
/// ```
322-
///
323-
/// This prints:
324-
///
325-
/// ```text
326-
/// 0
327-
/// 2
328-
/// 4
329-
/// 6
330-
/// 8
331-
/// 10
318+
/// let result: Vec<_> = (0...10).step_by(2).collect();
319+
/// assert_eq!(result, vec![0, 2, 4, 6, 8, 10]);
332320
/// ```
333321
#[unstable(feature = "step_by", reason = "recent addition",
334322
issue = "27741")]

src/libcore/ops.rs

+81-18
Original file line numberDiff line numberDiff line change
@@ -948,25 +948,55 @@ bitand_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
948948
///
949949
/// # Examples
950950
///
951-
/// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
952-
/// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
951+
/// In this example, the `|` operator is lifted to a trivial `Scalar` type.
953952
///
954953
/// ```
955954
/// use std::ops::BitOr;
956955
///
957-
/// struct Foo;
956+
/// #[derive(Debug, PartialEq)]
957+
/// struct Scalar(bool);
958958
///
959-
/// impl BitOr for Foo {
960-
/// type Output = Foo;
959+
/// impl BitOr for Scalar {
960+
/// type Output = Self;
961961
///
962-
/// fn bitor(self, _rhs: Foo) -> Foo {
963-
/// println!("Bitwise Or-ing!");
964-
/// self
962+
/// // rhs is the "right-hand side" of the expression `a | b`
963+
/// fn bitor(self, rhs: Self) -> Self {
964+
/// Scalar(self.0 | rhs.0)
965+
/// }
966+
/// }
967+
///
968+
/// fn main() {
969+
/// assert_eq!(Scalar(true) | Scalar(true), Scalar(true));
970+
/// assert_eq!(Scalar(true) | Scalar(false), Scalar(true));
971+
/// assert_eq!(Scalar(false) | Scalar(true), Scalar(true));
972+
/// assert_eq!(Scalar(false) | Scalar(false), Scalar(false));
973+
/// }
974+
/// ```
975+
///
976+
/// In this example, the `BitOr` trait is implemented for a `BooleanVector`
977+
/// struct.
978+
///
979+
/// ```
980+
/// use std::ops::BitOr;
981+
///
982+
/// #[derive(Debug, PartialEq)]
983+
/// struct BooleanVector(Vec<bool>);
984+
///
985+
/// impl BitOr for BooleanVector {
986+
/// type Output = Self;
987+
///
988+
/// fn bitor(self, BooleanVector(rhs): Self) -> Self {
989+
/// let BooleanVector(lhs) = self;
990+
/// assert_eq!(lhs.len(), rhs.len());
991+
/// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect())
965992
/// }
966993
/// }
967994
///
968995
/// fn main() {
969-
/// Foo | Foo;
996+
/// let bv1 = BooleanVector(vec![true, true, false, false]);
997+
/// let bv2 = BooleanVector(vec![true, false, true, false]);
998+
/// let expected = BooleanVector(vec![true, true, true, false]);
999+
/// assert_eq!(bv1 | bv2, expected);
9701000
/// }
9711001
/// ```
9721002
#[lang = "bitor"]
@@ -1001,25 +1031,58 @@ bitor_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
10011031
///
10021032
/// # Examples
10031033
///
1004-
/// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
1005-
/// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
1034+
/// In this example, the `^` operator is lifted to a trivial `Scalar` type.
10061035
///
10071036
/// ```
10081037
/// use std::ops::BitXor;
10091038
///
1010-
/// struct Foo;
1039+
/// #[derive(Debug, PartialEq)]
1040+
/// struct Scalar(bool);
10111041
///
1012-
/// impl BitXor for Foo {
1013-
/// type Output = Foo;
1042+
/// impl BitXor for Scalar {
1043+
/// type Output = Self;
10141044
///
1015-
/// fn bitxor(self, _rhs: Foo) -> Foo {
1016-
/// println!("Bitwise Xor-ing!");
1017-
/// self
1045+
/// // rhs is the "right-hand side" of the expression `a ^ b`
1046+
/// fn bitxor(self, rhs: Self) -> Self {
1047+
/// Scalar(self.0 ^ rhs.0)
1048+
/// }
1049+
/// }
1050+
///
1051+
/// fn main() {
1052+
/// assert_eq!(Scalar(true) ^ Scalar(true), Scalar(false));
1053+
/// assert_eq!(Scalar(true) ^ Scalar(false), Scalar(true));
1054+
/// assert_eq!(Scalar(false) ^ Scalar(true), Scalar(true));
1055+
/// assert_eq!(Scalar(false) ^ Scalar(false), Scalar(false));
1056+
/// }
1057+
/// ```
1058+
///
1059+
/// In this example, the `BitXor` trait is implemented for a `BooleanVector`
1060+
/// struct.
1061+
///
1062+
/// ```
1063+
/// use std::ops::BitXor;
1064+
///
1065+
/// #[derive(Debug, PartialEq)]
1066+
/// struct BooleanVector(Vec<bool>);
1067+
///
1068+
/// impl BitXor for BooleanVector {
1069+
/// type Output = Self;
1070+
///
1071+
/// fn bitxor(self, BooleanVector(rhs): Self) -> Self {
1072+
/// let BooleanVector(lhs) = self;
1073+
/// assert_eq!(lhs.len(), rhs.len());
1074+
/// BooleanVector(lhs.iter()
1075+
/// .zip(rhs.iter())
1076+
/// .map(|(x, y)| (*x || *y) && !(*x && *y))
1077+
/// .collect())
10181078
/// }
10191079
/// }
10201080
///
10211081
/// fn main() {
1022-
/// Foo ^ Foo;
1082+
/// let bv1 = BooleanVector(vec![true, true, false, false]);
1083+
/// let bv2 = BooleanVector(vec![true, false, true, false]);
1084+
/// let expected = BooleanVector(vec![false, true, true, false]);
1085+
/// assert_eq!(bv1 ^ bv2, expected);
10231086
/// }
10241087
/// ```
10251088
#[lang = "bitxor"]

src/librustc_passes/static_recursion.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
126126
idstack: Vec::new(),
127127
}
128128
}
129-
fn with_item_id_pushed<F>(&mut self, id: ast::NodeId, f: F)
129+
fn with_item_id_pushed<F>(&mut self, id: ast::NodeId, f: F, span: Span)
130130
where F: Fn(&mut Self)
131131
{
132132
if self.idstack.iter().any(|&x| x == id) {
@@ -150,7 +150,9 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
150150
"recursive static");
151151
}
152152
} else {
153-
span_err!(self.sess, *self.root_span, E0265, "recursive constant");
153+
struct_span_err!(self.sess, span, E0265, "recursive constant")
154+
.span_label(span, &format!("recursion not allowed in constant"))
155+
.emit();
154156
}
155157
return;
156158
}
@@ -203,7 +205,7 @@ impl<'a, 'ast: 'a> CheckItemRecursionVisitor<'a, 'ast> {
203205

204206
impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
205207
fn visit_item(&mut self, it: &'ast hir::Item) {
206-
self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it));
208+
self.with_item_id_pushed(it.id, |v| intravisit::walk_item(v, it), it.span);
207209
}
208210

209211
fn visit_enum_def(&mut self,
@@ -233,16 +235,16 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
233235
// If `maybe_expr` is `None`, that's because no discriminant is
234236
// specified that affects this variant. Thus, no risk of recursion.
235237
if let Some(expr) = maybe_expr {
236-
self.with_item_id_pushed(expr.id, |v| intravisit::walk_expr(v, expr));
238+
self.with_item_id_pushed(expr.id, |v| intravisit::walk_expr(v, expr), expr.span);
237239
}
238240
}
239241

240242
fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) {
241-
self.with_item_id_pushed(ti.id, |v| intravisit::walk_trait_item(v, ti));
243+
self.with_item_id_pushed(ti.id, |v| intravisit::walk_trait_item(v, ti), ti.span);
242244
}
243245

244246
fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) {
245-
self.with_item_id_pushed(ii.id, |v| intravisit::walk_impl_item(v, ii));
247+
self.with_item_id_pushed(ii.id, |v| intravisit::walk_impl_item(v, ii), ii.span);
246248
}
247249

248250
fn visit_expr(&mut self, e: &'ast hir::Expr) {

src/librustc_resolve/diagnostics.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -1270,7 +1270,42 @@ trait Foo {}
12701270
12711271
impl Foo for i32 {}
12721272
```
1273-
"##
1273+
"##,
1274+
1275+
E0530: r##"
1276+
A binding shadowed something it shouldn't.
1277+
1278+
Erroneous code example:
1279+
1280+
```compile_fail,E0530
1281+
static TEST: i32 = 0;
1282+
1283+
let r: (i32, i32) = (0, 0);
1284+
match r {
1285+
TEST => {} // error: match bindings cannot shadow statics
1286+
}
1287+
```
1288+
1289+
To fix this error, just change the binding's name in order to avoid shadowing
1290+
one of the following:
1291+
1292+
* struct name
1293+
* struct/enum variant
1294+
* static
1295+
* const
1296+
* associated const
1297+
1298+
Fixed example:
1299+
1300+
```
1301+
static TEST: i32 = 0;
1302+
1303+
let r: (i32, i32) = (0, 0);
1304+
match r {
1305+
something => {} // ok!
1306+
}
1307+
```
1308+
"##,
12741309

12751310
}
12761311

@@ -1289,7 +1324,6 @@ register_diagnostics! {
12891324
// E0419, merged into 531
12901325
// E0420, merged into 532
12911326
// E0421, merged into 531
1292-
E0530, // X bindings cannot shadow Ys
12931327
E0531, // unresolved pattern path kind `name`
12941328
E0532, // expected pattern path kind, found another pattern path kind
12951329
// E0427, merged into 530

src/librustc_typeck/check/method/suggest.rs

+1
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
242242
MethodError::Ambiguity(sources) => {
243243
let mut err = struct_span_err!(self.sess(), span, E0034,
244244
"multiple applicable items in scope");
245+
err.span_label(span, &format!("multiple `{}` found", item_name));
245246

246247
report_candidates(&mut err, sources);
247248
err.emit();

src/librustc_typeck/check/mod.rs

+11-5
Original file line numberDiff line numberDiff line change
@@ -903,14 +903,18 @@ fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
903903
{
904904
let mut err = struct_span_err!(
905905
tcx.sess, impl_item.span, E0520,
906-
"item `{}` is provided by an `impl` that specializes \
907-
another, but the item in the parent `impl` is not \
908-
marked `default` and so it cannot be specialized.",
906+
"`{}` specializes an item from a parent `impl`, but \
907+
neither that item nor the `impl` are marked `default`",
909908
impl_item.name);
909+
err.span_label(impl_item.span, &format!("cannot specialize default item `{}`",
910+
impl_item.name));
910911

911912
match tcx.span_of_impl(parent_impl) {
912913
Ok(span) => {
913-
err.span_note(span, "parent implementation is here:");
914+
err.span_label(span, &"parent `impl` is here");
915+
err.note(&format!("to specialize, either the parent `impl` or `{}` \
916+
in the parent `impl` must be marked `default`",
917+
impl_item.name));
914918
}
915919
Err(cname) => {
916920
err.note(&format!("parent implementation is in crate `{}`", cname));
@@ -1204,7 +1208,9 @@ pub fn check_simd<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, id: ast::Node
12041208
}
12051209
let e = fields[0].ty(tcx, substs);
12061210
if !fields.iter().all(|f| f.ty(tcx, substs) == e) {
1207-
span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
1211+
struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous")
1212+
.span_label(sp, &format!("SIMD elements must have the same type"))
1213+
.emit();
12081214
return;
12091215
}
12101216
match e.sty {

src/librustc_typeck/check/wfcheck.rs

+22-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use middle::region::{CodeExtent};
1616
use rustc::infer::TypeOrigin;
1717
use rustc::traits;
1818
use rustc::ty::{self, Ty, TyCtxt};
19-
use rustc::util::nodemap::FnvHashSet;
19+
use rustc::util::nodemap::{FnvHashSet, FnvHashMap};
2020

2121
use syntax::ast;
2222
use syntax_pos::Span;
@@ -519,11 +519,26 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
519519

520520
fn reject_shadowing_type_parameters(tcx: TyCtxt, span: Span, generics: &ty::Generics) {
521521
let parent = tcx.lookup_generics(generics.parent.unwrap());
522-
let impl_params: FnvHashSet<_> = parent.types.iter().map(|tp| tp.name).collect();
522+
let impl_params: FnvHashMap<_, _> = parent.types
523+
.iter()
524+
.map(|tp| (tp.name, tp.def_id))
525+
.collect();
523526

524527
for method_param in &generics.types {
525-
if impl_params.contains(&method_param.name) {
526-
error_194(tcx, span, method_param.name);
528+
if impl_params.contains_key(&method_param.name) {
529+
// Tighten up the span to focus on only the shadowing type
530+
let shadow_node_id = tcx.map.as_local_node_id(method_param.def_id).unwrap();
531+
let type_span = match tcx.map.opt_span(shadow_node_id) {
532+
Some(osp) => osp,
533+
None => span
534+
};
535+
536+
// The expectation here is that the original trait declaration is
537+
// local so it should be okay to just unwrap everything.
538+
let trait_def_id = impl_params.get(&method_param.name).unwrap();
539+
let trait_node_id = tcx.map.as_local_node_id(*trait_def_id).unwrap();
540+
let trait_decl_span = tcx.map.opt_span(trait_node_id).unwrap();
541+
error_194(tcx, type_span, trait_decl_span, method_param.name);
527542
}
528543
}
529544
}
@@ -630,10 +645,11 @@ fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::N
630645
err
631646
}
632647

633-
fn error_194(tcx: TyCtxt, span: Span, name: ast::Name) {
648+
fn error_194(tcx: TyCtxt, span: Span, trait_decl_span: Span, name: ast::Name) {
634649
struct_span_err!(tcx.sess, span, E0194,
635650
"type parameter `{}` shadows another type parameter of the same name",
636651
name)
637-
.span_label(span, &format!("`{}` shadows another type parameter", name))
652+
.span_label(span, &format!("shadows another type parameter"))
653+
.span_label(trait_decl_span, &format!("first `{}` declared here", name))
638654
.emit();
639655
}

0 commit comments

Comments
 (0)