Rollup merge of #108557 - Nathan-Fenner:nathanf/adjust-error-span-fix-Some, r=WaffleLapkin
Point error span at Some constructor argument when trait resolution fails This is a follow up to #108254 and #106477 which extends error span refinement to handle a case which I mistakenly believed was handled in #106477. The goal is to refine the error span depicted below: ```rs trait Fancy {} impl <T> Fancy for Option<T> where T: Iterator {} fn want_fancy<F>(f: F) where F: Fancy {} fn example() { want_fancy(Some(5)); // (BEFORE) ^^^^^^^ `{integer}` is not an iterator // (AFTER) ^ `{integer}` is not an iterator } ``` I had used a (slightly more complex) example as an illustrative example in #108254 , but hadn't actually turned it into a test, because I had (incorrectly) believed at the time it was covered by existing behavior. It turns out that `Some` is slightly "special" in that it resolves differently from the other `enum` constructors I had tried, and therefore this test was actually broken. I've now updated the tests to include this example, and fixed the code to correctly resolve the `Some` constructor so that the span of the error is reduced.
This commit is contained in:
commit
564715a5b7
4 changed files with 463 additions and 8 deletions
|
@ -714,12 +714,26 @@ 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) {
|
||||
// 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)
|
||||
} else {
|
||||
// FIXME: Deal with type aliases?
|
||||
return Err(expr);
|
||||
}
|
||||
expr_ctor_def_id
|
||||
}
|
||||
_ => {
|
||||
return Err(expr);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue