diff options
| author | clubby789 <jamie@hill-daniel.co.uk> | 2023-02-11 00:00:18 +0000 |
|---|---|---|
| committer | clubby789 <jamie@hill-daniel.co.uk> | 2023-02-11 12:28:35 +0000 |
| commit | ef8de38c8498885a46119f214e17f0237dab6251 (patch) | |
| tree | 3073aa0e7a810e7d58790983fc9a8a2bd0ca32a1 /src | |
| parent | 2773383a314a4b8f481ce2bed12c32de794ffbe9 (diff) | |
rustdoc: Don't resolve link to field on different variant
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/passes/collect_intra_doc_links.rs | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 8435972bb11..1ee98a79b05 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -338,7 +338,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { match ty_res { Res::Def(DefKind::Enum, did) => match tcx.type_of(did).kind() { ty::Adt(def, _) if def.is_enum() => { - if let Some(field) = def.all_fields().find(|f| f.name == variant_field_name) { + if let Some(variant) = def.variants().iter().find(|v| v.name == variant_name) + && let Some(field) = variant.fields.iter().find(|f| f.name == variant_field_name) { Ok((ty_res, field.did)) } else { Err(UnresolvedPath { @@ -1768,15 +1769,35 @@ fn resolution_failure( // Otherwise, it must be an associated item or variant let res = partial_res.expect("None case was handled by `last_found_module`"); - let kind = match res { - Res::Def(kind, _) => Some(kind), + let kind_did = match res { + Res::Def(kind, did) => Some((kind, did)), Res::Primitive(_) => None, }; - let path_description = if let Some(kind) = kind { + let is_struct_variant = |did| { + if let ty::Adt(def, _) = tcx.type_of(did).kind() + && def.is_enum() + && let Some(variant) = def.variants().iter().find(|v| v.name == res.name(tcx)) { + // ctor is `None` if variant is a struct + variant.ctor.is_none() + } else { + false + } + }; + let path_description = if let Some((kind, did)) = kind_did { match kind { Mod | ForeignMod => "inner item", Struct => "field or associated item", Enum | Union => "variant or associated item", + Variant if is_struct_variant(did) => { + let variant = res.name(tcx); + let note = format!("variant `{variant}` has no such field"); + if let Some(span) = sp { + diag.span_label(span, ¬e); + } else { + diag.note(¬e); + } + return; + } Variant | Field | Closure |
