Fix panic by checking if CStore
has the crate data we want before actually querying it
This commit is contained in:
parent
987c73158e
commit
beb2f364cc
2 changed files with 18 additions and 6 deletions
|
@ -133,6 +133,10 @@ impl CStore {
|
||||||
CrateNum::new(self.metas.len() - 1)
|
CrateNum::new(self.metas.len() - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_crate_data(&self, cnum: CrateNum) -> bool {
|
||||||
|
self.metas[cnum].is_some()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_crate_data(&self, cnum: CrateNum) -> CrateMetadataRef<'_> {
|
pub(crate) fn get_crate_data(&self, cnum: CrateNum) -> CrateMetadataRef<'_> {
|
||||||
let cdata = self.metas[cnum]
|
let cdata = self.metas[cnum]
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
|
@ -565,7 +565,7 @@ fn generate_macro_def_id_path(
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
cx: &Context<'_>,
|
cx: &Context<'_>,
|
||||||
root_path: Option<&str>,
|
root_path: Option<&str>,
|
||||||
) -> (String, ItemType, Vec<Symbol>) {
|
) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
|
||||||
let tcx = cx.shared.tcx;
|
let tcx = cx.shared.tcx;
|
||||||
let crate_name = tcx.crate_name(def_id.krate).to_string();
|
let crate_name = tcx.crate_name(def_id.krate).to_string();
|
||||||
let cache = cx.cache();
|
let cache = cx.cache();
|
||||||
|
@ -583,9 +583,15 @@ fn generate_macro_def_id_path(
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let relative = fqp.iter().map(|elem| elem.to_string());
|
let relative = fqp.iter().map(|elem| elem.to_string());
|
||||||
|
let cstore = CStore::from_tcx(tcx);
|
||||||
|
// We need this to prevent a `panic` when this function is used from intra doc links...
|
||||||
|
if !cstore.has_crate_data(def_id.krate) {
|
||||||
|
debug!("No data for crate {}", crate_name);
|
||||||
|
return Err(HrefError::NotInExternalCache);
|
||||||
|
}
|
||||||
// Check to see if it is a macro 2.0 or built-in macro.
|
// Check to see if it is a macro 2.0 or built-in macro.
|
||||||
// More information in <https://rust-lang.github.io/rfcs/1584-macros.html>.
|
// More information in <https://rust-lang.github.io/rfcs/1584-macros.html>.
|
||||||
let is_macro_2 = match CStore::from_tcx(tcx).load_macro_untracked(def_id, tcx.sess) {
|
let is_macro_2 = match cstore.load_macro_untracked(def_id, tcx.sess) {
|
||||||
LoadedMacro::MacroDef(def, _) => {
|
LoadedMacro::MacroDef(def, _) => {
|
||||||
// If `ast_def.macro_rules` is `true`, then it's not a macro 2.0.
|
// If `ast_def.macro_rules` is `true`, then it's not a macro 2.0.
|
||||||
matches!(&def.kind, ast::ItemKind::MacroDef(ast_def) if !ast_def.macro_rules)
|
matches!(&def.kind, ast::ItemKind::MacroDef(ast_def) if !ast_def.macro_rules)
|
||||||
|
@ -601,7 +607,8 @@ fn generate_macro_def_id_path(
|
||||||
if path.len() < 2 {
|
if path.len() < 2 {
|
||||||
// The minimum we can have is the crate name followed by the macro name. If shorter, then
|
// The minimum we can have is the crate name followed by the macro name. If shorter, then
|
||||||
// it means that that `relative` was empty, which is an error.
|
// it means that that `relative` was empty, which is an error.
|
||||||
panic!("macro path cannot be empty!");
|
debug!("macro path cannot be empty!");
|
||||||
|
return Err(HrefError::NotInExternalCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(last) = path.last_mut() {
|
if let Some(last) = path.last_mut() {
|
||||||
|
@ -618,10 +625,11 @@ fn generate_macro_def_id_path(
|
||||||
format!("{}{}/{}", root_path.unwrap_or(""), crate_name, path.join("/"))
|
format!("{}{}/{}", root_path.unwrap_or(""), crate_name, path.join("/"))
|
||||||
}
|
}
|
||||||
ExternalLocation::Unknown => {
|
ExternalLocation::Unknown => {
|
||||||
panic!("crate {} not in cache when linkifying macros", crate_name)
|
debug!("crate {} not in cache when linkifying macros", crate_name);
|
||||||
|
return Err(HrefError::NotInExternalCache);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
(url, ItemType::Macro, fqp)
|
Ok((url, ItemType::Macro, fqp))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn href_with_root_path(
|
pub(crate) fn href_with_root_path(
|
||||||
|
@ -680,7 +688,7 @@ pub(crate) fn href_with_root_path(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else if matches!(def_kind, DefKind::Macro(_)) {
|
} else if matches!(def_kind, DefKind::Macro(_)) {
|
||||||
return Ok(generate_macro_def_id_path(did, cx, root_path));
|
return generate_macro_def_id_path(did, cx, root_path);
|
||||||
} else {
|
} else {
|
||||||
return Err(HrefError::NotInExternalCache);
|
return Err(HrefError::NotInExternalCache);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue