-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolve Self
in a submodule when the type is not in scope
#84999
Resolve Self
in a submodule when the type is not in scope
#84999
Conversation
…solve the string by any othe way. Also if self_id refers to an Impl, it is replaced by the DefId of the object it refers to
Some changes occurred in intra-doc-links. cc @jyn514 |
(rust-highfive has picked a reviewer for you, use r? to override) |
r? @jyn514 |
So this fix the bug, no more broken link in this situation. @jyn514 and multiple comments in the code pointed out that we should maybe use self_id more, instead of strings. But when I tried to invert those two lines: .or_else(|| self.resolve_path(&path_root, TypeNS, module_id))
.or_else(|| self_id.map(|id| Res::Def(self.cx.tcx.def_kind(id), id))) it broke multiple tests. So I kept things the way there are, with just this new extra backup way to resolve the link if all the previous ones have failed. I'm pretty sure this can be improved in an other MR tho |
@@ -680,7 +682,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { | |||
let result = match ns { | |||
Namespace::MacroNS => self.resolve_macro(path_str, module_id).map_err(ErrorKind::from), | |||
Namespace::TypeNS | Namespace::ValueNS => { | |||
self.resolve(path_str, ns, module_id, extra_fragment).map(|(res, _)| res) | |||
self.resolve(path_str, ns, module_id, extra_fragment, None).map(|(res, _)| res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't passed self_id
to check_full_res
, because it had no role in solving the bug, so it call resolve
with None
instead. But maybe we should ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should; can you add self_id
as a parameter to check_full_res
? You may have to also add it to some of the error variants.
The worst that happens is the diagnostic is wrong though, so if it's complicated it's ok to save it for a follow-up. I think this is a case that would be affected:
struct Foo {
foo: i32,
}
mod bar {
impl crate::Foo {
/// Baz the [macro@Self::foo].
pub fn baz(&self) {}
}
}
@@ -515,6 +516,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { | |||
// primitives. | |||
resolve_primitive(&path_root, TypeNS) | |||
.or_else(|| self.resolve_path(&path_root, TypeNS, module_id)) | |||
.or_else(|| self_id.map(|id| Res::Def(self.cx.tcx.def_kind(id), id))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like the wrong fix; it will use other items in the same scope if they happen to have the same name. This should come first and only then resolve_primitive and resolve_path. This is #84827 (comment); please add it as a test case.
@@ -680,7 +682,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { | |||
let result = match ns { | |||
Namespace::MacroNS => self.resolve_macro(path_str, module_id).map_err(ErrorKind::from), | |||
Namespace::TypeNS | Namespace::ValueNS => { | |||
self.resolve(path_str, ns, module_id, extra_fragment).map(|(res, _)| res) | |||
self.resolve(path_str, ns, module_id, extra_fragment, None).map(|(res, _)| res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should; can you add self_id
as a parameter to check_full_res
? You may have to also add it to some of the error variants.
The worst that happens is the diagnostic is wrong though, so if it's complicated it's ok to save it for a follow-up. I think this is a case that would be affected:
struct Foo {
foo: i32,
}
mod bar {
impl crate::Foo {
/// Baz the [macro@Self::foo].
pub fn baz(&self) {}
}
}
} | ||
} | ||
_ => curr_id, | ||
}); | ||
|
||
// FIXME(jynelson): this shouldn't go through stringification, rustdoc should just use the DefId directly | ||
let self_name = self_id.and_then(|self_id| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self_name should no longer be used at all. Everything that touches it is wrong.
DefKind::Impl => { | ||
match curr_id | ||
.as_local() | ||
.map(|local_id| self.cx.tcx.hir().item(rustc_hir::ItemId { def_id: local_id })) | ||
{ | ||
Some(rustc_hir::Item { | ||
kind: | ||
rustc_hir::ItemKind::Impl(rustc_hir::Impl { | ||
self_ty: | ||
rustc_hir::Ty { | ||
kind: | ||
rustc_hir::TyKind::Path(rustc_hir::QPath::Resolved( | ||
_, | ||
rustc_hir::Path { | ||
res: rustc_hir::def::Res::Def(_, def_id), | ||
.. | ||
}, | ||
)), | ||
.. | ||
}, | ||
.. | ||
}), | ||
.. | ||
}) => *def_id, | ||
_ => curr_id, | ||
} | ||
} | ||
_ => curr_id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is all wrong, it will break for impls from foreign crates. Use the logic below from self_name
instead.
(This is what I removed initially in #76467.)
I won't have time to review any follow-ups. r? @Manishearth |
☔ The latest upstream changes (presumably #85328) made this pull request unmergeable. Please resolve the merge conflicts. |
@tdelabro Ping from triage, any updates on this? |
@tdelabro Ping from triage - closing this as inactive. please feel free to reopen when you're ready to address the merge conflicts and comments from reviewers. |
fix #84827