about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNathan Fenner <nfenneremail@gmail.com>2023-02-27 23:58:35 -0800
committerNathan Fenner <nfenneremail@gmail.com>2023-02-27 23:58:35 -0800
commit2566b4105d60a422229c645a784186b52e15fde6 (patch)
tree7d34efc7860f78dced8c5867aba5b0dae20a1670
parent7281249a19a9755e9d889ee251ec323629caadab (diff)
downloadrust-2566b4105d60a422229c645a784186b52e15fde6.tar.gz
rust-2566b4105d60a422229c645a784186b52e15fde6.zip
Point error span at Some constructor argument when trait resolution fails
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs14
-rw-r--r--tests/ui/errors/trait-bound-error-spans/blame-trait-error.rs13
-rw-r--r--tests/ui/errors/trait-bound-error-spans/blame-trait-error.stderr81
-rw-r--r--tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr4
4 files changed, 103 insertions, 9 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index d64492e503d..3b72326be7c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -714,12 +714,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.tcx.parent(expr_ctor_def_id)
                 }
                 hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
-                    // If this is a variant, its parent is the type definition.
-                    if in_ty_adt.did() != self.tcx.parent(expr_ctor_def_id) {
-                        // FIXME: Deal with type aliases?
+                    if in_ty_adt.did() == self.tcx.parent(expr_ctor_def_id) {
+                        // The constructor definition refers to the variant:
+                        // For example, for a local type `MyEnum::MyVariant` triggers this case.
+                        expr_ctor_def_id
+                    } else if in_ty_adt.did() == self.tcx.parent(self.tcx.parent(expr_ctor_def_id))
+                    {
+                        // The constructor definition refers to the "constructor" of the variant:
+                        // For example, `Some(5)` triggers this case.
+                        self.tcx.parent(expr_ctor_def_id)
+                    } else {
                         return Err(expr);
                     }
-                    expr_ctor_def_id
                 }
                 _ => {
                     return Err(expr);
diff --git a/tests/ui/errors/trait-bound-error-spans/blame-trait-error.rs b/tests/ui/errors/trait-bound-error-spans/blame-trait-error.rs
index 5134c672f5f..5e939b71b13 100644
--- a/tests/ui/errors/trait-bound-error-spans/blame-trait-error.rs
+++ b/tests/ui/errors/trait-bound-error-spans/blame-trait-error.rs
@@ -18,11 +18,24 @@ struct Burrito<F> {
     filling: F,
 }
 
+impl<It: Iterator> T1 for Option<It> {}
+
+impl<'a, A: T1> T1 for &'a A {}
+
 fn want<V: T1>(_x: V) {}
 
 fn example<Q>(q: Q) {
     want(Wrapper { value: Burrito { filling: q } });
     //~^ ERROR the trait bound `Q: T3` is not satisfied [E0277]
+
+    want(Some(()));
+    //~^ ERROR `()` is not an iterator [E0277]
+
+    want(Some(q));
+    //~^ ERROR `Q` is not an iterator [E0277]
+
+    want(&Some(q));
+    //~^ ERROR `Q` is not an iterator [E0277]
 }
 
 fn main() {}
diff --git a/tests/ui/errors/trait-bound-error-spans/blame-trait-error.stderr b/tests/ui/errors/trait-bound-error-spans/blame-trait-error.stderr
index 27b002db130..e95c73f36dc 100644
--- a/tests/ui/errors/trait-bound-error-spans/blame-trait-error.stderr
+++ b/tests/ui/errors/trait-bound-error-spans/blame-trait-error.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Q: T3` is not satisfied
-  --> $DIR/blame-trait-error.rs:24:46
+  --> $DIR/blame-trait-error.rs:28:46
    |
 LL |     want(Wrapper { value: Burrito { filling: q } });
    |     ----                                     ^ the trait `T3` is not implemented for `Q`
@@ -21,7 +21,7 @@ LL | impl<B: T2> T1 for Wrapper<B> {}
    |         |
    |         unsatisfied trait bound introduced here
 note: required by a bound in `want`
-  --> $DIR/blame-trait-error.rs:21:12
+  --> $DIR/blame-trait-error.rs:25:12
    |
 LL | fn want<V: T1>(_x: V) {}
    |            ^^ required by this bound in `want`
@@ -30,6 +30,81 @@ help: consider restricting type parameter `Q`
 LL | fn example<Q: T3>(q: Q) {
    |             ++++
 
-error: aborting due to previous error
+error[E0277]: `()` is not an iterator
+  --> $DIR/blame-trait-error.rs:31:15
+   |
+LL |     want(Some(()));
+   |     ----      ^^ `()` is not an iterator
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Iterator` is not implemented for `()`
+   = help: the trait `T1` is implemented for `Option<It>`
+note: required for `Option<()>` to implement `T1`
+  --> $DIR/blame-trait-error.rs:21:20
+   |
+LL | impl<It: Iterator> T1 for Option<It> {}
+   |          --------  ^^     ^^^^^^^^^^
+   |          |
+   |          unsatisfied trait bound introduced here
+note: required by a bound in `want`
+  --> $DIR/blame-trait-error.rs:25:12
+   |
+LL | fn want<V: T1>(_x: V) {}
+   |            ^^ required by this bound in `want`
+
+error[E0277]: `Q` is not an iterator
+  --> $DIR/blame-trait-error.rs:34:15
+   |
+LL |     want(Some(q));
+   |     ----      ^ `Q` is not an iterator
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required for `Option<Q>` to implement `T1`
+  --> $DIR/blame-trait-error.rs:21:20
+   |
+LL | impl<It: Iterator> T1 for Option<It> {}
+   |          --------  ^^     ^^^^^^^^^^
+   |          |
+   |          unsatisfied trait bound introduced here
+note: required by a bound in `want`
+  --> $DIR/blame-trait-error.rs:25:12
+   |
+LL | fn want<V: T1>(_x: V) {}
+   |            ^^ required by this bound in `want`
+help: consider restricting type parameter `Q`
+   |
+LL | fn example<Q: std::iter::Iterator>(q: Q) {
+   |             +++++++++++++++++++++
+
+error[E0277]: `Q` is not an iterator
+  --> $DIR/blame-trait-error.rs:37:16
+   |
+LL |     want(&Some(q));
+   |     ----       ^ `Q` is not an iterator
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required for `Option<Q>` to implement `T1`
+  --> $DIR/blame-trait-error.rs:21:20
+   |
+LL | impl<It: Iterator> T1 for Option<It> {}
+   |          --------  ^^     ^^^^^^^^^^
+   |          |
+   |          unsatisfied trait bound introduced here
+   = note: 1 redundant requirement hidden
+   = note: required for `&Option<Q>` to implement `T1`
+note: required by a bound in `want`
+  --> $DIR/blame-trait-error.rs:25:12
+   |
+LL | fn want<V: T1>(_x: V) {}
+   |            ^^ required by this bound in `want`
+help: consider restricting type parameter `Q`
+   |
+LL | fn example<Q: std::iter::Iterator>(q: Q) {
+   |             +++++++++++++++++++++
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr b/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr
index 6913771f288..b6a24e12bcc 100644
--- a/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr
+++ b/tests/ui/errors/traits/blame-trait-error-spans-on-exprs.stderr
@@ -91,10 +91,10 @@ LL | fn example<Q: T3>(q: Q) {
    |             ++++
 
 error[E0277]: the trait bound `Q: T3` is not satisfied
-  --> $DIR/blame-trait-error-spans-on-exprs.rs:93:27
+  --> $DIR/blame-trait-error-spans-on-exprs.rs:93:53
    |
 LL |     want(Wrapper { value: TacoKinds::OneTaco(false, q) });
-   |     ----                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `T3` is not implemented for `Q`
+   |     ----                                            ^ the trait `T3` is not implemented for `Q`
    |     |
    |     required by a bound introduced by this call
    |