Skip to content

Commit f0212e6

Browse files
committed
Fix error spans for arguments to tuple enum constructors
1 parent 2566b41 commit f0212e6

File tree

3 files changed

+371
-11
lines changed

3 files changed

+371
-11
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -714,12 +714,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
714714
self.tcx.parent(expr_ctor_def_id)
715715
}
716716
hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, hir::def::CtorKind::Fn) => {
717-
if in_ty_adt.did() == self.tcx.parent(expr_ctor_def_id) {
718-
// The constructor definition refers to the variant:
719-
// For example, for a local type `MyEnum::MyVariant` triggers this case.
720-
expr_ctor_def_id
721-
} else if in_ty_adt.did() == self.tcx.parent(self.tcx.parent(expr_ctor_def_id))
722-
{
717+
// For a typical enum like
718+
// `enum Blah<T> { Variant(T) }`
719+
// we get the following resolutions:
720+
// - expr_ctor_def_id ::: DefId(0:29 ~ source_file[b442]::Blah::Variant::{constructor#0})
721+
// - self.tcx.parent(expr_ctor_def_id) ::: DefId(0:28 ~ source_file[b442]::Blah::Variant)
722+
// - self.tcx.parent(self.tcx.parent(expr_ctor_def_id)) ::: DefId(0:26 ~ source_file[b442]::Blah)
723+
724+
// Therefore, we need to go up once to obtain the variant and up twice to obtain the type.
725+
// Note that this pattern still holds even when we `use` a variant or `use` an enum type to rename it, or chain `use` expressions
726+
// together; this resolution is handled automatically by `qpath_res`.
727+
728+
// FIXME: Deal with type aliases?
729+
if in_ty_adt.did() == self.tcx.parent(self.tcx.parent(expr_ctor_def_id)) {
723730
// The constructor definition refers to the "constructor" of the variant:
724731
// For example, `Some(5)` triggers this case.
725732
self.tcx.parent(expr_ctor_def_id)

tests/ui/errors/trait-bound-error-spans/blame-trait-error.rs

+61
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,31 @@ impl<'a, A: T1> T1 for &'a A {}
2424

2525
fn want<V: T1>(_x: V) {}
2626

27+
enum ExampleTuple<T> {
28+
ExampleTupleVariant(T),
29+
}
30+
use ExampleDifferentTupleVariantName as ExampleYetAnotherTupleVariantName;
31+
use ExampleTuple as ExampleOtherTuple;
32+
use ExampleTuple::ExampleTupleVariant as ExampleDifferentTupleVariantName;
33+
use ExampleTuple::*;
34+
35+
impl<A> T1 for ExampleTuple<A> where A: T3 {}
36+
37+
enum ExampleStruct<T> {
38+
ExampleStructVariant { field: T },
39+
}
40+
use ExampleDifferentStructVariantName as ExampleYetAnotherStructVariantName;
41+
use ExampleStruct as ExampleOtherStruct;
42+
use ExampleStruct::ExampleStructVariant as ExampleDifferentStructVariantName;
43+
use ExampleStruct::*;
44+
45+
impl<A> T1 for ExampleStruct<A> where A: T3 {}
46+
47+
struct ExampleActuallyTupleStruct<T>(T, i32);
48+
use ExampleActuallyTupleStruct as ExampleActuallyTupleStructOther;
49+
50+
impl<A> T1 for ExampleActuallyTupleStruct<A> where A: T3 {}
51+
2752
fn example<Q>(q: Q) {
2853
want(Wrapper { value: Burrito { filling: q } });
2954
//~^ ERROR the trait bound `Q: T3` is not satisfied [E0277]
@@ -36,6 +61,42 @@ fn example<Q>(q: Q) {
3661

3762
want(&Some(q));
3863
//~^ ERROR `Q` is not an iterator [E0277]
64+
65+
want(&ExampleTuple::ExampleTupleVariant(q));
66+
//~^ ERROR `Q: T3` is not satisfied [E0277]
67+
68+
want(&ExampleTupleVariant(q));
69+
//~^ ERROR `Q: T3` is not satisfied [E0277]
70+
71+
want(&ExampleOtherTuple::ExampleTupleVariant(q));
72+
//~^ ERROR `Q: T3` is not satisfied [E0277]
73+
74+
want(&ExampleDifferentTupleVariantName(q));
75+
//~^ ERROR `Q: T3` is not satisfied [E0277]
76+
77+
want(&ExampleYetAnotherTupleVariantName(q));
78+
//~^ ERROR `Q: T3` is not satisfied [E0277]
79+
80+
want(&ExampleStruct::ExampleStructVariant { field: q });
81+
//~^ ERROR `Q: T3` is not satisfied [E0277]
82+
83+
want(&ExampleStructVariant { field: q });
84+
//~^ ERROR `Q: T3` is not satisfied [E0277]
85+
86+
want(&ExampleOtherStruct::ExampleStructVariant { field: q });
87+
//~^ ERROR `Q: T3` is not satisfied [E0277]
88+
89+
want(&ExampleDifferentStructVariantName { field: q });
90+
//~^ ERROR `Q: T3` is not satisfied [E0277]
91+
92+
want(&ExampleYetAnotherStructVariantName { field: q });
93+
//~^ ERROR `Q: T3` is not satisfied [E0277]
94+
95+
want(&ExampleActuallyTupleStruct(q, 0));
96+
//~^ ERROR `Q: T3` is not satisfied [E0277]
97+
98+
want(&ExampleActuallyTupleStructOther(q, 0));
99+
//~^ ERROR `Q: T3` is not satisfied [E0277]
39100
}
40101

41102
fn main() {}

0 commit comments

Comments
 (0)