Point at the def span of trait refs E0277
This commit is contained in:
parent
c55615155d
commit
0dcdbaec0b
|
@ -71,6 +71,7 @@ use rustc_hir::Node;
|
||||||
use errors::{
|
use errors::{
|
||||||
pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticStyledString,
|
pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticStyledString,
|
||||||
};
|
};
|
||||||
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_error_codes::*;
|
use rustc_error_codes::*;
|
||||||
use rustc_span::{DesugaringKind, Pos, Span};
|
use rustc_span::{DesugaringKind, Pos, Span};
|
||||||
use rustc_target::spec::abi;
|
use rustc_target::spec::abi;
|
||||||
|
@ -1362,9 +1363,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
let kind = match t.kind {
|
let kind = match t.kind {
|
||||||
ty::Closure(..) => "closure",
|
ty::Closure(..) => "closure",
|
||||||
ty::Opaque(..) => "opaque type",
|
ty::Opaque(..) => "opaque type",
|
||||||
|
ty::Generator(..) => "generator",
|
||||||
|
ty::Foreign(..) => "foreign type",
|
||||||
_ => "",
|
_ => "",
|
||||||
};
|
};
|
||||||
if let ty::Closure(def_id, _) | ty::Opaque(def_id, _) = t.kind {
|
if let ty::Closure(def_id, _)
|
||||||
|
| ty::Opaque(def_id, _)
|
||||||
|
| ty::Generator(def_id, ..)
|
||||||
|
| ty::Foreign(def_id) = t.kind
|
||||||
|
{
|
||||||
let span = self.tcx.def_span(def_id);
|
let span = self.tcx.def_span(def_id);
|
||||||
// Avoid cluttering the output when the "found" and error span overlap:
|
// Avoid cluttering the output when the "found" and error span overlap:
|
||||||
//
|
//
|
||||||
|
|
|
@ -446,7 +446,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
flags.push((sym::from_method, Some(method.to_string())));
|
flags.push((sym::from_method, Some(method.to_string())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(t) = self.get_parent_trait_ref(&obligation.cause.code) {
|
if let Some((t, _)) = self.get_parent_trait_ref(&obligation.cause.code) {
|
||||||
flags.push((sym::parent_trait, Some(t)));
|
flags.push((sym::parent_trait, Some(t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,13 +665,28 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the parent trait chain start
|
/// Gets the parent trait chain start
|
||||||
fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<String> {
|
fn get_parent_trait_ref(
|
||||||
|
&self,
|
||||||
|
code: &ObligationCauseCode<'tcx>,
|
||||||
|
) -> Option<(String, Option<Span>)> {
|
||||||
match code {
|
match code {
|
||||||
&ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
|
&ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
|
||||||
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
|
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
|
||||||
match self.get_parent_trait_ref(&data.parent_code) {
|
match self.get_parent_trait_ref(&data.parent_code) {
|
||||||
Some(t) => Some(t),
|
Some(t) => Some(t),
|
||||||
None => Some(parent_trait_ref.skip_binder().self_ty().to_string()),
|
None => {
|
||||||
|
let ty = parent_trait_ref.skip_binder().self_ty();
|
||||||
|
let span = if let ty::Closure(def_id, _)
|
||||||
|
| ty::Opaque(def_id, _)
|
||||||
|
| ty::Generator(def_id, ..)
|
||||||
|
| ty::Foreign(def_id) = ty.kind
|
||||||
|
{
|
||||||
|
Some(self.tcx.def_span(def_id))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Some((ty.to_string(), span))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -719,9 +734,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let trait_ref = trait_predicate.to_poly_trait_ref();
|
let trait_ref = trait_predicate.to_poly_trait_ref();
|
||||||
let (post_message, pre_message) = self
|
let (post_message, pre_message, type_def) = self
|
||||||
.get_parent_trait_ref(&obligation.cause.code)
|
.get_parent_trait_ref(&obligation.cause.code)
|
||||||
.map(|t| (format!(" in `{}`", t), format!("within `{}`, ", t)))
|
.map(|(t, s)| {
|
||||||
|
(
|
||||||
|
format!(" in `{}`", t),
|
||||||
|
format!("within `{}`, ", t),
|
||||||
|
s.map(|s| (format!("within this `{}`", t), s)),
|
||||||
|
)
|
||||||
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let OnUnimplementedNote { message, label, note, enclosing_scope } =
|
let OnUnimplementedNote { message, label, note, enclosing_scope } =
|
||||||
|
@ -795,6 +816,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
err.span_label(span, explanation);
|
err.span_label(span, explanation);
|
||||||
}
|
}
|
||||||
|
if let Some((msg, span)) = type_def {
|
||||||
|
err.span_label(span, &msg);
|
||||||
|
}
|
||||||
if let Some(ref s) = note {
|
if let Some(ref s) = note {
|
||||||
// If it has a custom `#[rustc_on_unimplemented]` note, let's display it
|
// If it has a custom `#[rustc_on_unimplemented]` note, let's display it
|
||||||
err.note(s.as_str());
|
err.note(s.as_str());
|
||||||
|
|
|
@ -3,6 +3,9 @@ error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl std::future::
|
||||||
|
|
|
|
||||||
LL | fn is_qux<T: Qux>(t: T) { }
|
LL | fn is_qux<T: Qux>(t: T) { }
|
||||||
| ------ --- required by this bound in `is_qux`
|
| ------ --- required by this bound in `is_qux`
|
||||||
|
LL |
|
||||||
|
LL | async fn bar() {
|
||||||
|
| - within this `impl std::future::Future`
|
||||||
...
|
...
|
||||||
LL | is_qux(bar());
|
LL | is_qux(bar());
|
||||||
| ^^^^^^ within `impl std::future::Future`, the trait `Qux` is not implemented for `Foo`
|
| ^^^^^^ within `impl std::future::Future`, the trait `Qux` is not implemented for `Foo`
|
||||||
|
|
|
@ -77,6 +77,9 @@ LL | fn send<T: Send>(_: T) {}
|
||||||
...
|
...
|
||||||
LL | send(cycle2().clone());
|
LL | send(cycle2().clone());
|
||||||
| ^^^^ `std::rc::Rc<std::string::String>` cannot be sent between threads safely
|
| ^^^^ `std::rc::Rc<std::string::String>` cannot be sent between threads safely
|
||||||
|
...
|
||||||
|
LL | fn cycle2() -> impl Clone {
|
||||||
|
| ---------- within this `impl std::clone::Clone`
|
||||||
|
|
|
|
||||||
= help: within `impl std::clone::Clone`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::string::String>`
|
= help: within `impl std::clone::Clone`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::string::String>`
|
||||||
= note: required because it appears within the type `impl std::clone::Clone`
|
= note: required because it appears within the type `impl std::clone::Clone`
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
error[E0277]: `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
|
error[E0277]: `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
|
||||||
--> $DIR/auto-trait-leak2.rs:13:5
|
--> $DIR/auto-trait-leak2.rs:13:5
|
||||||
|
|
|
|
||||||
|
LL | fn before() -> impl Fn(i32) {
|
||||||
|
| ------------ within this `impl std::ops::Fn<(i32,)>`
|
||||||
|
...
|
||||||
LL | fn send<T: Send>(_: T) {}
|
LL | fn send<T: Send>(_: T) {}
|
||||||
| ---- ---- required by this bound in `send`
|
| ---- ---- required by this bound in `send`
|
||||||
...
|
...
|
||||||
|
@ -19,6 +22,9 @@ LL | fn send<T: Send>(_: T) {}
|
||||||
...
|
...
|
||||||
LL | send(after());
|
LL | send(after());
|
||||||
| ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
|
| ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
|
||||||
|
...
|
||||||
|
LL | fn after() -> impl Fn(i32) {
|
||||||
|
| ------------ within this `impl std::ops::Fn<(i32,)>`
|
||||||
|
|
|
|
||||||
= help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
|
= help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
|
||||||
= note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
|
= note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
|
||||||
|
|
|
@ -5,7 +5,9 @@ LL | fn bar<F:FnOnce() + Send>(_: F) { }
|
||||||
| --- ---- required by this bound in `bar`
|
| --- ---- required by this bound in `bar`
|
||||||
...
|
...
|
||||||
LL | bar(move|| foo(x));
|
LL | bar(move|| foo(x));
|
||||||
| ^^^ `std::rc::Rc<usize>` cannot be sent between threads safely
|
| ^^^ ------------- within this `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22 x:std::rc::Rc<usize>]`
|
||||||
|
| |
|
||||||
|
| `std::rc::Rc<usize>` cannot be sent between threads safely
|
||||||
|
|
|
|
||||||
= help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22 x:std::rc::Rc<usize>]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<usize>`
|
= help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22 x:std::rc::Rc<usize>]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<usize>`
|
||||||
= note: required because it appears within the type `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22 x:std::rc::Rc<usize>]`
|
= note: required because it appears within the type `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22 x:std::rc::Rc<usize>]`
|
||||||
|
|
|
@ -1,13 +1,20 @@
|
||||||
error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
|
error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
|
||||||
--> $DIR/no-send-res-ports.rs:29:5
|
--> $DIR/no-send-res-ports.rs:29:5
|
||||||
|
|
|
|
||||||
LL | thread::spawn(move|| {
|
LL | thread::spawn(move|| {
|
||||||
| ^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
|
| _____^^^^^^^^^^^^^_-
|
||||||
|
| | |
|
||||||
|
| | `std::rc::Rc<()>` cannot be sent between threads safely
|
||||||
|
LL | |
|
||||||
|
LL | | let y = x;
|
||||||
|
LL | | println!("{:?}", y);
|
||||||
|
LL | | });
|
||||||
|
| |_____- within this `[closure@$DIR/no-send-res-ports.rs:29:19: 33:6 x:main::Foo]`
|
||||||
|
|
|
|
||||||
::: $SRC_DIR/libstd/thread/mod.rs:LL:COL
|
::: $SRC_DIR/libstd/thread/mod.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | F: Send + 'static,
|
LL | F: Send + 'static,
|
||||||
| ---- required by this bound in `std::thread::spawn`
|
| ---- required by this bound in `std::thread::spawn`
|
||||||
|
|
|
|
||||||
= help: within `[closure@$DIR/no-send-res-ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
|
= help: within `[closure@$DIR/no-send-res-ports.rs:29:19: 33:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
|
||||||
= note: required because it appears within the type `Port<()>`
|
= note: required because it appears within the type `Port<()>`
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
error[E0277]: the trait bound `S: std::clone::Clone` is not satisfied in `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]`
|
error[E0277]: the trait bound `S: std::clone::Clone` is not satisfied in `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]`
|
||||||
--> $DIR/not-clone-closure.rs:11:23
|
--> $DIR/not-clone-closure.rs:11:23
|
||||||
|
|
|
|
||||||
LL | let hello = hello.clone();
|
LL | let hello = move || {
|
||||||
| ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]`, the trait `std::clone::Clone` is not implemented for `S`
|
| _________________-
|
||||||
|
LL | | println!("Hello {}", a.0);
|
||||||
|
LL | | };
|
||||||
|
| |_____- within this `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]`
|
||||||
|
LL |
|
||||||
|
LL | let hello = hello.clone();
|
||||||
|
| ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]`, the trait `std::clone::Clone` is not implemented for `S`
|
||||||
|
|
|
|
||||||
= note: required because it appears within the type `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]`
|
= note: required because it appears within the type `[closure@$DIR/not-clone-closure.rs:7:17: 9:6 a:S]`
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue