Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 30 pull requests #35365

Merged
merged 73 commits into from
Aug 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
e805cb6
Add io::Error doc examples
GuillaumeGomez Jul 29, 2016
aad5f6f
Add doc example for io::Stderr
GuillaumeGomez Jul 29, 2016
451683f
Add doc example for Stdin
GuillaumeGomez Jul 29, 2016
aeb3af8
Add doc example for Stdout
GuillaumeGomez Jul 29, 2016
2bed205
Add io::Take doc example
GuillaumeGomez Jul 30, 2016
fda473f
Add urls in std::io types
GuillaumeGomez Jul 30, 2016
b77b9b7
Provide more explicit example of wildcard version in guessing game doc.
jongiddy Jul 31, 2016
65e3ff4
add extended information for E0529, slice pattern expects array or slice
zackmdavis Jun 17, 2016
7093d1d
add extended info for E0527, slice pattern element count expectations
zackmdavis Jun 17, 2016
e960021
extended info for E0528, expected at least this-and-such many elements
zackmdavis Jun 17, 2016
157f7c1
Add Derive not possible question to Copy
Havvy Jul 26, 2016
57e3b9e
Indicate where the `std::net::Incoming` struct is created.
frewsxcv Aug 2, 2016
f2d8db1
Link to relevant method/struct for `std::net::Shutdown` docs.
frewsxcv Aug 2, 2016
3081dd8
Add doc example for `std::ffi::NulError::nul_position`.
frewsxcv Aug 2, 2016
727d929
Add doc examples for `range::RangeArgument::{start,end}`.
frewsxcv Jul 26, 2016
1fa9b8d
Add doc example for Vec
GuillaumeGomez Aug 2, 2016
d90c166
Update the-stack-and-the-heap.md
mLuby Aug 2, 2016
3e46c9d
Add doc examples for FileType struct
GuillaumeGomez Jul 27, 2016
d603892
Add span method for hir::Generics struct
GuillaumeGomez Aug 3, 2016
9b690c9
Update E0132 to new format
GuillaumeGomez Aug 3, 2016
4fc6f5a
Add an example to `std::thread::park_timeout`
dns2utf8 Aug 3, 2016
20721a4
Add link to replacement function
dns2utf8 Aug 3, 2016
1607d5b
Add note test for E0132
GuillaumeGomez Aug 3, 2016
c89e278
Update error message for E0109
circuitfox Aug 3, 2016
6131815
Fixes for issues #35215 and #35216
leikahing Aug 4, 2016
0e75684
Tidying up some of the line spacing / code formatting for NOTE/ERROR …
leikahing Aug 4, 2016
ded0d51
Removing trailing whitespace leftover from last re-formatting commit
leikahing Aug 4, 2016
7fc0b2f
Update E0079 to new format
Aug 4, 2016
ee8d6b0
Update error message for E0172
Aug 4, 2016
08ff7a8
Update error message E0178
Aug 4, 2016
eeda69f
Set label for unreachable pattern
saml Aug 4, 2016
034e659
Changing label to "this is an..."
saml Aug 4, 2016
7c58b26
Updated E0071 to new format.
razielgn Aug 3, 2016
5430e55
E0110 update error format
circuitfox Aug 4, 2016
a0bdb17
Update E0124 to the new error format
sciyoshi Aug 4, 2016
df726a4
Update error format for E0137
Aug 4, 2016
76babf9
Fix precedence table in reference
ubsan Aug 4, 2016
0214ec2
Update error format for E0062
trixnz Aug 4, 2016
2f36ecf
E0119 update error format
circuitfox Aug 4, 2016
b5b3539
Update compiler error E0055 to use new error format
nickmass Aug 4, 2016
3b2f184
Update error message E0120
Aug 4, 2016
1ca95ae
Fix for issue #35336 - updating error message for for E0368 to includ…
leikahing Aug 5, 2016
a6ffa42
Update E0391 to new format.
ryan-scott-dev Aug 5, 2016
19e140b
Update E0404 to new format.
ryan-scott-dev Aug 5, 2016
1bb5552
Rollup merge of #34319 - zackmdavis:explain_slice_pattern_errors, r=G…
GuillaumeGomez Aug 5, 2016
5afe7bb
Rollup merge of #35041 - frewsxcv:range-rangeargument, r=GuillaumeGomez
GuillaumeGomez Aug 5, 2016
4944952
Rollup merge of #35042 - Havvy:copy_error_doc, r=GuillaumeGomez
GuillaumeGomez Aug 5, 2016
56a89f5
Rollup merge of #35076 - GuillaumeGomez:file_type_docs, r=steveklabnik
GuillaumeGomez Aug 5, 2016
4cf6c00
Rollup merge of #35109 - GuillaumeGomez:io_docs, r=steveklabnik
GuillaumeGomez Aug 5, 2016
7971a93
Rollup merge of #35137 - jongiddy:explicit-wildcard, r=steveklabnik
GuillaumeGomez Aug 5, 2016
e377049
Rollup merge of #35175 - frewsxcv:tcp, r=GuillaumeGomez
GuillaumeGomez Aug 5, 2016
3ca18f7
Rollup merge of #35181 - GuillaumeGomez:vec_doc, r=steveklabnik
GuillaumeGomez Aug 5, 2016
8a923d4
Rollup merge of #35182 - frewsxcv:nulerror, r=steveklabnik
GuillaumeGomez Aug 5, 2016
6e5e7e2
Rollup merge of #35189 - mLuby:patch-1, r=steveklabnik
GuillaumeGomez Aug 5, 2016
5780595
Rollup merge of #35239 - dns2utf8:doc_park_timeout, r=steveklabnik
GuillaumeGomez Aug 5, 2016
158597f
Rollup merge of #35264 - GuillaumeGomez:E0132_update, r=jonathandturner
GuillaumeGomez Aug 5, 2016
9186db8
Rollup merge of #35266 - circuitfox:35247-E0109-update-error-format, …
GuillaumeGomez Aug 5, 2016
da981cf
Rollup merge of #35285 - razielgn:updated-e0071-to-new-format, r=jona…
GuillaumeGomez Aug 5, 2016
7cb933e
Rollup merge of #35289 - birryree:E0060_E0061_format_update, r=jonath…
GuillaumeGomez Aug 5, 2016
527e326
Rollup merge of #35291 - yossi-k:master, r=jonathandturner
GuillaumeGomez Aug 5, 2016
709fd09
Rollup merge of #35294 - Roybie:35272-E0172-update-error-format, r=jo…
GuillaumeGomez Aug 5, 2016
7a31640
Rollup merge of #35296 - medzin:master, r=jonathandturner
GuillaumeGomez Aug 5, 2016
8038c17
Rollup merge of #35297 - saml:e0001-label, r=jonathandturner
GuillaumeGomez Aug 5, 2016
65a283f
Rollup merge of #35298 - Keats:err-120, r=jonathandturner
GuillaumeGomez Aug 5, 2016
84d467c
Rollup merge of #35299 - circuitfox:E0110-update-error-format, r=jona…
GuillaumeGomez Aug 5, 2016
e9b79d9
Rollup merge of #35318 - sciyoshi:update-e0124, r=jonathandturner
GuillaumeGomez Aug 5, 2016
a7b443f
Rollup merge of #35319 - Keats:err-137, r=jonathandturner
GuillaumeGomez Aug 5, 2016
6597a28
Rollup merge of #35324 - ubsan:precedence, r=steveklabnik
GuillaumeGomez Aug 5, 2016
31da06b
Rollup merge of #35326 - circuitfox:E0119-update-error-format, r=jona…
GuillaumeGomez Aug 5, 2016
8b97008
Rollup merge of #35328 - trixnz:update-error-62, r=jonathandturner
GuillaumeGomez Aug 5, 2016
0339904
Rollup merge of #35333 - nickmass:e0055-formatting, r=jonathandturner
GuillaumeGomez Aug 5, 2016
dbef510
Rollup merge of #35350 - birryree:E0368_update, r=jonathandturner
GuillaumeGomez Aug 5, 2016
cd48161
Rollup merge of #35359 - Archytaus:master, r=GuillaumeGomez
GuillaumeGomez Aug 5, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/doc/book/guessing-game.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ numbers. A bare number like above is actually shorthand for `^0.3.0`,
meaning "anything compatible with 0.3.0".
If we wanted to use only `0.3.0` exactly, we could say `rand="=0.3.0"`
(note the two equal signs).
And if we wanted to use the latest version we could use `*`.
And if we wanted to use the latest version we could use `rand="*"`.
We could also use a range of versions.
[Cargo’s documentation][cargodoc] contains more details.

Expand Down
2 changes: 2 additions & 0 deletions src/doc/book/the-stack-and-the-heap.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ The stack is very fast, and is where memory is allocated in Rust by default.
But the allocation is local to a function call, and is limited in size. The
heap, on the other hand, is slower, and is explicitly allocated by your
program. But it’s effectively unlimited in size, and is globally accessible.
Note this meaning of heap, which allocates arbitrary-sized blocks of memory in arbitrary
order, is quite different from the heap data structure.

# The Stack

Expand Down
3 changes: 2 additions & 1 deletion src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -3049,7 +3049,8 @@ as
== != < > <= >=
&&
||
= ..
.. ...
=
```

Operators at the same precedence level are evaluated left-to-right. [Unary
Expand Down
32 changes: 32 additions & 0 deletions src/libcollections/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,45 @@ pub trait RangeArgument<T> {
/// Start index (inclusive)
///
/// Return start value if present, else `None`.
///
/// # Examples
///
/// ```
/// #![feature(collections)]
/// #![feature(collections_range)]
///
/// extern crate collections;
///
/// # fn main() {
/// use collections::range::RangeArgument;
///
/// assert_eq!((..10).start(), None);
/// assert_eq!((3..10).start(), Some(&3));
/// # }
/// ```
fn start(&self) -> Option<&T> {
None
}

/// End index (exclusive)
///
/// Return end value if present, else `None`.
///
/// # Examples
///
/// ```
/// #![feature(collections)]
/// #![feature(collections_range)]
///
/// extern crate collections;
///
/// # fn main() {
/// use collections::range::RangeArgument;
///
/// assert_eq!((3..).end(), None);
/// assert_eq!((3..10).end(), Some(&10));
/// # }
/// ```
fn end(&self) -> Option<&T> {
None
}
Expand Down
19 changes: 19 additions & 0 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,25 @@ impl<T> Vec<T> {
/// Note that this will drop any excess capacity. Calling this and
/// converting back to a vector with `into_vec()` is equivalent to calling
/// `shrink_to_fit()`.
///
/// # Examples
///
/// ```
/// let v = vec![1, 2, 3];
///
/// let slice = v.into_boxed_slice();
/// ```
///
/// Any excess capacity is removed:
///
/// ```
/// let mut vec = Vec::with_capacity(10);
/// vec.extend([1, 2, 3].iter().cloned());
///
/// assert_eq!(vec.capacity(), 10);
/// let slice = vec.into_boxed_slice();
/// assert_eq!(slice.into_vec().capacity(), 3);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_boxed_slice(mut self) -> Box<[T]> {
unsafe {
Expand Down
6 changes: 6 additions & 0 deletions src/libcore/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ pub trait Unsize<T: ?Sized> {
/// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's
/// managing some resource besides its own `size_of::<T>()` bytes.
///
/// ## What if I derive `Copy` on a type that can't?
///
/// If you try to derive `Copy` on a struct or enum, you will get a compile-time error.
/// Specifically, with structs you'll get [E0204](https://doc.rust-lang.org/error-index.html#E0204)
/// and with enums you'll get [E0205](https://doc.rust-lang.org/error-index.html#E0205).
///
/// ## When should my type be `Copy`?
///
/// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing
Expand Down
34 changes: 33 additions & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use hir::def::Def;
use hir::def_id::DefId;
use util::nodemap::{NodeMap, FnvHashSet};

use syntax_pos::{mk_sp, Span, ExpnId};
use syntax_pos::{BytePos, mk_sp, Span, ExpnId};
use syntax::codemap::{self, respan, Spanned};
use syntax::abi::Abi;
use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, AsmDialect};
Expand Down Expand Up @@ -326,6 +326,38 @@ impl Generics {
pub fn is_parameterized(&self) -> bool {
self.is_lt_parameterized() || self.is_type_parameterized()
}

// Does return a span which includes lifetimes and type parameters,
// not where clause.
pub fn span(&self) -> Option<Span> {
if !self.is_parameterized() {
None
} else {
let mut span: Option<Span> = None;
for lifetime in self.lifetimes.iter() {
if let Some(ref mut span) = span {
let life_span = lifetime.lifetime.span;
span.hi = if span.hi > life_span.hi { span.hi } else { life_span.hi };
span.lo = if span.lo < life_span.lo { span.lo } else { life_span.lo };
} else {
span = Some(lifetime.lifetime.span.clone());
}
}
for ty_param in self.ty_params.iter() {
if let Some(ref mut span) = span {
span.lo = if span.lo < ty_param.span.lo { span.lo } else { ty_param.span.lo };
span.hi = if span.hi > ty_param.span.hi { span.hi } else { ty_param.span.hi };
} else {
span = Some(ty_param.span.clone());
}
}
if let Some(ref mut span) = span {
span.lo = span.lo - BytePos(1);
span.hi = span.hi + BytePos(1);
}
span
}
}
}

/// A `where` clause in a definition
Expand Down
13 changes: 9 additions & 4 deletions src/librustc/middle/astconv_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,18 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn prohibit_type_params(self, segments: &[ast::PathSegment]) {
for segment in segments {
for typ in segment.parameters.types() {
span_err!(self.sess, typ.span, E0109,
"type parameters are not allowed on this type");
struct_span_err!(self.sess, typ.span, E0109,
"type parameters are not allowed on this type")
.span_label(typ.span, &format!("type parameter not allowed"))
.emit();
break;
}
for lifetime in segment.parameters.lifetimes() {
span_err!(self.sess, lifetime.span, E0110,
"lifetime parameters are not allowed on this type");
struct_span_err!(self.sess, lifetime.span, E0110,
"lifetime parameters are not allowed on this type")
.span_label(lifetime.span,
&format!("lifetime parameter not allowed on this type"))
.emit();
break;
}
for binding in segment.parameters.bindings() {
Expand Down
7 changes: 5 additions & 2 deletions src/librustc/middle/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,11 @@ fn find_item(item: &Item, ctxt: &mut EntryContext, at_root: bool) {
if ctxt.attr_main_fn.is_none() {
ctxt.attr_main_fn = Some((item.id, item.span));
} else {
span_err!(ctxt.session, item.span, E0137,
"multiple functions with a #[main] attribute");
struct_span_err!(ctxt.session, item.span, E0137,
"multiple functions with a #[main] attribute")
.span_label(item.span, &format!("additional #[main] function"))
.span_label(ctxt.attr_main_fn.unwrap().1, &format!("first #[main] function"))
.emit();
}
},
EntryPointType::Start => {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_const_eval/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ fn check_arms(cx: &MatchCheckCtxt,
hir::MatchSource::Normal => {
let mut err = struct_span_err!(cx.tcx.sess, pat.span, E0001,
"unreachable pattern");
err.span_label(pat.span, &format!("this is an unreachable pattern"));
// if we had a catchall pattern, hint at that
for row in &seen.0 {
if pat_is_catchall(&cx.tcx.def_map.borrow(), row[0].0) {
Expand Down
8 changes: 7 additions & 1 deletion src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,13 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
name)
}
ResolutionError::IsNotATrait(name) => {
struct_span_err!(resolver.session, span, E0404, "`{}` is not a trait", name)
let mut err = struct_span_err!(resolver.session,
span,
E0404,
"`{}` is not a trait",
name);
err.span_label(span, &format!("not a trait"));
err
}
ResolutionError::UndeclaredTraitName(name, candidates) => {
let mut err = struct_span_err!(resolver.session,
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1075,8 +1075,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
Ok((trait_ref, projection_bounds))
}
_ => {
span_err!(self.tcx().sess, ty.span, E0172,
"expected a reference to a trait");
struct_span_err!(self.tcx().sess, ty.span, E0172,
"expected a reference to a trait")
.span_label(ty.span, &format!("expected a trait"))
.emit();
Err(ErrorReported)
}
}
Expand All @@ -1086,6 +1088,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
"expected a path on the left-hand side \
of `+`, not `{}`",
pprust::ty_to_string(ty));
err.span_label(ty.span, &format!("expected a path"));
let hi = bounds.iter().map(|x| match *x {
hir::TraitTyParamBound(ref tr, _) => tr.span.hi,
hir::RegionTyParamBound(ref r) => r.span.hi,
Expand Down
6 changes: 4 additions & 2 deletions src/librustc_typeck/check/autoderef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,11 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> {

if self.steps.len() == tcx.sess.recursion_limit.get() {
// We've reached the recursion limit, error gracefully.
span_err!(tcx.sess, self.span, E0055,
struct_span_err!(tcx.sess, self.span, E0055,
"reached the recursion limit while auto-dereferencing {:?}",
self.cur_ty);
self.cur_ty)
.span_label(self.span, &format!("deref recursion limit reached"))
.emit();
return None;
}

Expand Down
35 changes: 29 additions & 6 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2384,6 +2384,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
arg_count,
if arg_count == 1 {" was"} else {"s were"}),
error_code);

err.span_label(sp, &format!("expected {}{} parameter{}",
if variadic {"at least "} else {""},
expected_count,
if expected_count == 1 {""} else {"s"}));

let input_types = fn_inputs.iter().map(|i| format!("{:?}", i)).collect::<Vec<String>>();
if input_types.len() > 0 {
err.note(&format!("the following parameter type{} expected: {}",
Expand Down Expand Up @@ -3063,6 +3069,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
remaining_fields.insert(field.name, field);
}

let mut seen_fields = FnvHashMap();

let mut error_happened = false;

// Typecheck each field.
Expand All @@ -3071,13 +3079,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {

if let Some(v_field) = remaining_fields.remove(&field.name.node) {
expected_field_type = self.field_ty(field.span, v_field, substs);

seen_fields.insert(field.name.node, field.span);
} else {
error_happened = true;
expected_field_type = tcx.types.err;
if let Some(_) = variant.find_field_named(field.name.node) {
span_err!(self.tcx.sess, field.name.span, E0062,
"field `{}` specified more than once",
field.name.node);
let mut err = struct_span_err!(self.tcx.sess,
field.name.span,
E0062,
"field `{}` specified more than once",
field.name.node);

err.span_label(field.name.span, &format!("used more than once"));

if let Some(prev_span) = seen_fields.get(&field.name.node) {
err.span_label(*prev_span, &format!("first use of `{}`", field.name.node));
}

err.emit();
} else {
self.report_unknown_field(adt_ty, variant, field, ast_fields);
}
Expand Down Expand Up @@ -3147,9 +3167,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
if variant.is_none() || variant.unwrap().kind == ty::VariantKind::Tuple {
// Reject tuple structs for now, braced and unit structs are allowed.
span_err!(self.tcx.sess, span, E0071,
"`{}` does not name a struct or a struct variant",
pprust::path_to_string(path));
struct_span_err!(self.tcx.sess, path.span, E0071,
"`{}` does not name a struct or a struct variant",
pprust::path_to_string(path))
.span_label(path.span, &format!("not a struct"))
.emit();

return None;
}

Expand Down
14 changes: 9 additions & 5 deletions src/librustc_typeck/check/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// error types are considered "builtin"
if !lhs_ty.references_error() {
if let IsAssign::Yes = is_assign {
span_err!(self.tcx.sess, lhs_expr.span, E0368,
"binary assignment operation `{}=` \
cannot be applied to type `{}`",
op.node.as_str(),
lhs_ty);
struct_span_err!(self.tcx.sess, lhs_expr.span, E0368,
"binary assignment operation `{}=` \
cannot be applied to type `{}`",
op.node.as_str(),
lhs_ty)
.span_label(lhs_expr.span,
&format!("cannot use `{}=` on type `{}`",
op.node.as_str(), lhs_ty))
.emit();
} else {
let mut err = struct_span_err!(self.tcx.sess, lhs_expr.span, E0369,
"binary operation `{}` cannot be applied to type `{}`",
Expand Down
15 changes: 12 additions & 3 deletions src/librustc_typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,16 +249,25 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
if let Some(impl_node_id) = tcx.map.as_local_node_id(impl_did) {
match tcx.map.find(impl_node_id) {
Some(hir_map::NodeItem(item)) => {
span_err!(tcx.sess, item.span, E0120,
"the Drop trait may only be implemented on structures");
let span = match item.node {
ItemImpl(_, _, _, _, ref ty, _) => {
ty.span
},
_ => item.span
};
struct_span_err!(tcx.sess, span, E0120,
"the Drop trait may only be implemented on structures")
.span_label(span,
&format!("implementing Drop requires a struct"))
.emit();
}
_ => {
bug!("didn't find impl in ast map");
}
}
} else {
bug!("found external impl of Drop trait on \
:omething other than a struct");
something other than a struct");
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/librustc_typeck/coherence/overlap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,18 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
self.tcx.sess, self.tcx.span_of_impl(impl_def_id).unwrap(), E0119,
"conflicting implementations of trait `{}`{}:",
overlap.trait_desc,
overlap.self_desc.map_or(String::new(),
|ty| format!(" for type `{}`", ty)));
overlap.self_desc.clone().map_or(String::new(),
|ty| format!(" for type `{}`", ty)));

match self.tcx.span_of_impl(overlap.with_impl) {
Ok(span) => {
err.span_note(span, "conflicting implementation is here:");
err.span_label(span,
&format!("first implementation here"));
err.span_label(self.tcx.span_of_impl(impl_def_id).unwrap(),
&format!("conflicting implementation{}",
overlap.self_desc
.map_or(String::new(),
|ty| format!(" for `{}`", ty))));
}
Err(cname) => {
err.note(&format!("conflicting implementation in crate `{}`",
Expand Down
Loading