Fix error spans for arguments to tuple enum constructors

This commit is contained in:
Nathan Fenner 2023-02-28 14:58:14 -08:00
parent 2566b4105d
commit f0212e6532
3 changed files with 371 additions and 11 deletions

View File

@ -714,12 +714,19 @@ 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 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))
{
// For a typical enum like
// `enum Blah<T> { Variant(T) }`
// we get the following resolutions:
// - expr_ctor_def_id ::: DefId(0:29 ~ source_file[b442]::Blah::Variant::{constructor#0})
// - self.tcx.parent(expr_ctor_def_id) ::: DefId(0:28 ~ source_file[b442]::Blah::Variant)
// - self.tcx.parent(self.tcx.parent(expr_ctor_def_id)) ::: DefId(0:26 ~ source_file[b442]::Blah)
// Therefore, we need to go up once to obtain the variant and up twice to obtain the type.
// Note that this pattern still holds even when we `use` a variant or `use` an enum type to rename it, or chain `use` expressions
// together; this resolution is handled automatically by `qpath_res`.
// FIXME: Deal with type aliases?
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)

View File

@ -24,6 +24,31 @@ impl<'a, A: T1> T1 for &'a A {}
fn want<V: T1>(_x: V) {}
enum ExampleTuple<T> {
ExampleTupleVariant(T),
}
use ExampleDifferentTupleVariantName as ExampleYetAnotherTupleVariantName;
use ExampleTuple as ExampleOtherTuple;
use ExampleTuple::ExampleTupleVariant as ExampleDifferentTupleVariantName;
use ExampleTuple::*;
impl<A> T1 for ExampleTuple<A> where A: T3 {}
enum ExampleStruct<T> {
ExampleStructVariant { field: T },
}
use ExampleDifferentStructVariantName as ExampleYetAnotherStructVariantName;
use ExampleStruct as ExampleOtherStruct;
use ExampleStruct::ExampleStructVariant as ExampleDifferentStructVariantName;
use ExampleStruct::*;
impl<A> T1 for ExampleStruct<A> where A: T3 {}
struct ExampleActuallyTupleStruct<T>(T, i32);
use ExampleActuallyTupleStruct as ExampleActuallyTupleStructOther;
impl<A> T1 for ExampleActuallyTupleStruct<A> where A: T3 {}
fn example<Q>(q: Q) {
want(Wrapper { value: Burrito { filling: q } });
//~^ ERROR the trait bound `Q: T3` is not satisfied [E0277]
@ -36,6 +61,42 @@ fn example<Q>(q: Q) {
want(&Some(q));
//~^ ERROR `Q` is not an iterator [E0277]
want(&ExampleTuple::ExampleTupleVariant(q));
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleTupleVariant(q));
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleOtherTuple::ExampleTupleVariant(q));
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleDifferentTupleVariantName(q));
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleYetAnotherTupleVariantName(q));
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleStruct::ExampleStructVariant { field: q });
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleStructVariant { field: q });
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleOtherStruct::ExampleStructVariant { field: q });
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleDifferentStructVariantName { field: q });
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleYetAnotherStructVariantName { field: q });
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleActuallyTupleStruct(q, 0));
//~^ ERROR `Q: T3` is not satisfied [E0277]
want(&ExampleActuallyTupleStructOther(q, 0));
//~^ ERROR `Q: T3` is not satisfied [E0277]
}
fn main() {}

View File

@ -1,5 +1,5 @@
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:28:46
--> $DIR/blame-trait-error.rs:53:46
|
LL | want(Wrapper { value: Burrito { filling: q } });
| ---- ^ the trait `T3` is not implemented for `Q`
@ -31,7 +31,7 @@ LL | fn example<Q: T3>(q: Q) {
| ++++
error[E0277]: `()` is not an iterator
--> $DIR/blame-trait-error.rs:31:15
--> $DIR/blame-trait-error.rs:56:15
|
LL | want(Some(()));
| ---- ^^ `()` is not an iterator
@ -54,7 +54,7 @@ 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
--> $DIR/blame-trait-error.rs:59:15
|
LL | want(Some(q));
| ---- ^ `Q` is not an iterator
@ -79,7 +79,7 @@ LL | fn example<Q: std::iter::Iterator>(q: Q) {
| +++++++++++++++++++++
error[E0277]: `Q` is not an iterator
--> $DIR/blame-trait-error.rs:37:16
--> $DIR/blame-trait-error.rs:62:16
|
LL | want(&Some(q));
| ---- ^ `Q` is not an iterator
@ -105,6 +105,298 @@ help: consider restricting type parameter `Q`
LL | fn example<Q: std::iter::Iterator>(q: Q) {
| +++++++++++++++++++++
error: aborting due to 4 previous errors
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:65:45
|
LL | want(&ExampleTuple::ExampleTupleVariant(q));
| ---- ^ the trait `T3` is not implemented for `Q`
| |
| required by a bound introduced by this call
|
note: required for `ExampleTuple<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:35:9
|
LL | impl<A> T1 for ExampleTuple<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleTuple<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:68:31
|
LL | want(&ExampleTupleVariant(q));
| ---- ^ the trait `T3` is not implemented for `Q`
| |
| required by a bound introduced by this call
|
note: required for `ExampleTuple<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:35:9
|
LL | impl<A> T1 for ExampleTuple<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleTuple<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:71:50
|
LL | want(&ExampleOtherTuple::ExampleTupleVariant(q));
| ---- ^ the trait `T3` is not implemented for `Q`
| |
| required by a bound introduced by this call
|
note: required for `ExampleTuple<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:35:9
|
LL | impl<A> T1 for ExampleTuple<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleTuple<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:74:44
|
LL | want(&ExampleDifferentTupleVariantName(q));
| ---- ^ the trait `T3` is not implemented for `Q`
| |
| required by a bound introduced by this call
|
note: required for `ExampleTuple<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:35:9
|
LL | impl<A> T1 for ExampleTuple<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleTuple<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:77:45
|
LL | want(&ExampleYetAnotherTupleVariantName(q));
| ---- ^ the trait `T3` is not implemented for `Q`
| |
| required by a bound introduced by this call
|
note: required for `ExampleTuple<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:35:9
|
LL | impl<A> T1 for ExampleTuple<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleTuple<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:80:56
|
LL | want(&ExampleStruct::ExampleStructVariant { field: q });
| ---- required by a bound introduced by this call ^ the trait `T3` is not implemented for `Q`
|
note: required for `ExampleStruct<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:45:9
|
LL | impl<A> T1 for ExampleStruct<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleStruct<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:83:41
|
LL | want(&ExampleStructVariant { field: q });
| ---- ^ the trait `T3` is not implemented for `Q`
| |
| required by a bound introduced by this call
|
note: required for `ExampleStruct<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:45:9
|
LL | impl<A> T1 for ExampleStruct<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleStruct<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:86:61
|
LL | want(&ExampleOtherStruct::ExampleStructVariant { field: q });
| ---- required by a bound introduced by this call ^ the trait `T3` is not implemented for `Q`
|
note: required for `ExampleStruct<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:45:9
|
LL | impl<A> T1 for ExampleStruct<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleStruct<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:89:54
|
LL | want(&ExampleDifferentStructVariantName { field: q });
| ---- required by a bound introduced by this call ^ the trait `T3` is not implemented for `Q`
|
note: required for `ExampleStruct<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:45:9
|
LL | impl<A> T1 for ExampleStruct<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleStruct<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:92:55
|
LL | want(&ExampleYetAnotherStructVariantName { field: q });
| ---- required by a bound introduced by this call ^ the trait `T3` is not implemented for `Q`
|
note: required for `ExampleStruct<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:45:9
|
LL | impl<A> T1 for ExampleStruct<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleStruct<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:95:38
|
LL | want(&ExampleActuallyTupleStruct(q, 0));
| ---- ^ the trait `T3` is not implemented for `Q`
| |
| required by a bound introduced by this call
|
note: required for `ExampleActuallyTupleStruct<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:50:9
|
LL | impl<A> T1 for ExampleActuallyTupleStruct<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleActuallyTupleStruct<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: T3>(q: Q) {
| ++++
error[E0277]: the trait bound `Q: T3` is not satisfied
--> $DIR/blame-trait-error.rs:98:43
|
LL | want(&ExampleActuallyTupleStructOther(q, 0));
| ---- ^ the trait `T3` is not implemented for `Q`
| |
| required by a bound introduced by this call
|
note: required for `ExampleActuallyTupleStruct<Q>` to implement `T1`
--> $DIR/blame-trait-error.rs:50:9
|
LL | impl<A> T1 for ExampleActuallyTupleStruct<A> where A: T3 {}
| ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `&ExampleActuallyTupleStruct<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: T3>(q: Q) {
| ++++
error: aborting due to 16 previous errors
For more information about this error, try `rustc --explain E0277`.