traits::SolutionVariables,
ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate,
InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty,
- TyDefId, TyKind, TypeCtor, TyLoweringContext,
+ TyDefId, TyKind, TypeCtor,
};
use rustc_hash::FxHashSet;
use stdx::impl_from;
for ModuleDef
);
-impl From<MethodOwner> for ModuleDef {
- fn from(mowner: MethodOwner) -> Self {
- match mowner {
- MethodOwner::Trait(t) => t.into(),
- MethodOwner::Adt(t) => t.into(),
- }
- }
-}
-
impl From<VariantDef> for ModuleDef {
fn from(var: VariantDef) -> Self {
match var {
pub fn has_body(self, db: &dyn HirDatabase) -> bool {
db.function_data(self.id).has_body
}
-
- /// If this function is a method, the trait or type where it is declared.
- pub fn method_owner(self, db: &dyn HirDatabase) -> Option<MethodOwner> {
- match self.as_assoc_item(db).map(|assoc| assoc.container(db)) {
- Some(AssocItemContainer::Trait(t)) => Some(t.into()),
- Some(AssocItemContainer::ImplDef(imp)) => {
- let resolver = ModuleId::from(imp.module(db)).resolver(db.upcast());
- let ctx = TyLoweringContext::new(db, &resolver);
- let adt = Ty::from_hir(
- &ctx,
- &imp.target_trait(db).unwrap_or_else(|| imp.target_type(db)),
- )
- .as_adt()
- .map(|t| t.0)
- .unwrap();
- Some(Adt::from(adt).into())
- }
- None => None,
- }
- }
}
-#[derive(Debug)]
-pub enum MethodOwner {
- Trait(Trait),
- Adt(Adt),
-}
-
-impl_from!(Trait, Adt for MethodOwner);
-
// Note: logically, this belongs to `hir_ty`, but we are not using it there yet.
pub enum Access {
Shared,
code_model::{
Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const,
Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function,
- GenericDef, HasVisibility, ImplDef, Local, MacroDef, MethodOwner, Module, ModuleDef,
- ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility,
+ GenericDef, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, Static,
+ Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility,
},
has_source::HasSource,
semantics::{original_range, PathResolution, Semantics, SemanticsScope},
use std::iter::once;
use itertools::Itertools;
-use pulldown_cmark_to_cmark::{cmark_with_options, Options as CmarkOptions};
use pulldown_cmark::{CowStr, Event, LinkType, Options, Parser, Tag};
+use pulldown_cmark_to_cmark::{cmark_with_options, Options as CmarkOptions};
use url::Url;
use hir::{
db::{DefDatabase, HirDatabase},
- Adt, AsName, AssocItem, Crate, Field, HasAttrs, ItemInNs, ModuleDef, AssocItemContainer, AsAssocItem
+ Adt, AsAssocItem, AsName, AssocItem, AssocItemContainer, Crate, Field, HasAttrs, ItemInNs,
+ ModuleDef,
};
use ide_db::{
defs::{classify_name, classify_name_ref, Definition},
// BUG: For Option::Some
// Returns https://doc.rust-lang.org/nightly/core/prelude/v1/enum.Option.html#variant.Some
// Instead of https://doc.rust-lang.org/nightly/core/option/enum.Option.html
-// This could be worked around by turning the `EnumVariant` into `Enum` before attempting resolution,
-// but it's really just working around the problem. Ideally we need to implement a slightly different
-// version of import map which follows the same process as rustdoc. Otherwise there'll always be some
-// edge cases where we select the wrong import path.
+//
+// This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented
+// https://github.com/rust-lang/rfcs/pull/2988
fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
// Get the outermost definition for the moduledef. This is used to resolve the public path to the type,
// then we can join the method, field, etc onto it if required.
let target_def: ModuleDef = match definition {
Definition::ModuleDef(moddef) => match moddef {
- ModuleDef::Function(f) => {
- f.method_owner(db).map(|mowner| mowner.into()).unwrap_or_else(|| f.clone().into())
- }
+ ModuleDef::Function(f) => f
+ .as_assoc_item(db)
+ .and_then(|assoc| match assoc.container(db) {
+ AssocItemContainer::Trait(t) => Some(t.into()),
+ AssocItemContainer::ImplDef(impld) => {
+ impld.target_ty(db).as_adt().map(|adt| adt.into())
+ }
+ })
+ .unwrap_or_else(|| f.clone().into()),
moddef => moddef,
},
Definition::Field(f) => f.parent_def(db).into(),
}
/// Retrieve a link to documentation for the given symbol.
-pub(crate) fn external_docs(db: &RootDatabase, position: &FilePosition) -> Option<DocumentationLink> {
+pub(crate) fn external_docs(
+ db: &RootDatabase,
+ position: &FilePosition,
+) -> Option<DocumentationLink> {
let sema = Semantics::new(db);
let file = sema.parse(position.file_id).syntax().clone();
let token = pick_best(file.token_at_offset(position.offset))?;
FieldOrAssocItem::Field(field) => format!("#structfield.{}", field.name(db)),
FieldOrAssocItem::AssocItem(assoc) => match assoc {
AssocItem::Function(function) => {
- let is_trait_method =
- matches!(function.as_assoc_item(db).map(|assoc| assoc.container(db)), Some(AssocItemContainer::Trait(..)));
+ let is_trait_method = matches!(
+ function.as_assoc_item(db).map(|assoc| assoc.container(db)),
+ Some(AssocItemContainer::Trait(..))
+ );
// This distinction may get more complicated when specialisation is available.
// Rustdoc makes this decision based on whether a method 'has defaultness'.
// Currently this is only the case for provided trait methods.
use crate::{
display::{macro_label, ShortLabel, ToNav, TryToNav},
- markdown_remove::remove_markdown,
doc_links::{remove_links, rewrite_links},
+ markdown_remove::remove_markdown,
markup::Markup,
runnables::runnable,
FileId, FilePosition, NavigationTarget, RangeInfo, Runnable,