Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
3e33ef4c
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
3e33ef4c
编写于
3月 24, 2016
作者:
M
mitaa
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Correct anchor for links to associated trait items
上级
dc1f6831
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
143 addition
and
81 deletion
+143
-81
src/librustdoc/clean/inline.rs
src/librustdoc/clean/inline.rs
+12
-5
src/librustdoc/clean/mod.rs
src/librustdoc/clean/mod.rs
+40
-23
src/librustdoc/html/render.rs
src/librustdoc/html/render.rs
+47
-45
src/librustdoc/passes.rs
src/librustdoc/passes.rs
+5
-8
src/test/rustdoc/issue-28478.rs
src/test/rustdoc/issue-28478.rs
+39
-0
未找到文件。
src/librustdoc/clean/inline.rs
浏览文件 @
3e33ef4c
...
...
@@ -26,7 +26,7 @@
use
core
::
DocContext
;
use
doctree
;
use
clean
::{
self
,
Attributes
};
use
clean
::{
self
,
Attributes
,
GetDefId
};
use
super
::{
Clean
,
ToSource
};
...
...
@@ -414,15 +414,22 @@ pub fn build_impl(cx: &DocContext,
clean
::
RegionBound
(
..
)
=>
unreachable!
(),
}
});
if
let
Some
(
clean
::
ResolvedPath
{
did
,
..
})
=
trait_
{
if
Some
(
did
)
==
cx
.deref_trait_did
.get
()
{
super
::
build_deref_target_impls
(
cx
,
&
trait_items
,
ret
);
}
if
trait_
.def_id
()
==
cx
.deref_trait_did
.get
()
{
super
::
build_deref_target_impls
(
cx
,
&
trait_items
,
ret
);
}
let
provided
=
trait_
.def_id
()
.map
(|
did
|
{
cx
.tcx
()
.provided_trait_methods
(
did
)
.into_iter
()
.map
(|
meth
|
meth
.name
.to_string
())
.collect
()
})
.unwrap_or
(
HashSet
::
new
());
ret
.push
(
clean
::
Item
{
inner
:
clean
::
ImplItem
(
clean
::
Impl
{
unsafety
:
hir
::
Unsafety
::
Normal
,
// FIXME: this should be decoded
derived
:
clean
::
detect_derived
(
&
attrs
),
provided_trait_methods
:
provided
,
trait_
:
trait_
,
for_
:
ty
.ty
.clean
(
cx
),
generics
:
(
&
ty
.generics
,
&
predicates
,
subst
::
TypeSpace
)
.clean
(
cx
),
...
...
src/librustdoc/clean/mod.rs
浏览文件 @
3e33ef4c
...
...
@@ -44,7 +44,7 @@
use
rustc_front
::
hir
;
use
std
::
collections
::
HashMap
;
use
std
::
collections
::
{
HashMap
,
HashSet
}
;
use
std
::
path
::
PathBuf
;
use
std
::
rc
::
Rc
;
use
std
::
u32
;
...
...
@@ -559,15 +559,9 @@ fn maybe_sized(cx: &DocContext) -> TyParamBound {
fn
is_sized_bound
(
&
self
,
cx
:
&
DocContext
)
->
bool
{
use
rustc_front
::
hir
::
TraitBoundModifier
as
TBM
;
if
let
Some
(
tcx
)
=
cx
.tcx_opt
()
{
let
sized_did
=
match
tcx
.lang_items
.sized_trait
()
{
Some
(
did
)
=>
did
,
None
=>
return
false
};
if
let
TyParamBound
::
TraitBound
(
PolyTrait
{
trait_
:
Type
::
ResolvedPath
{
did
,
..
},
..
},
TBM
::
None
)
=
*
self
{
if
did
==
sized_did
{
return
true
if
let
TyParamBound
::
TraitBound
(
PolyTrait
{
ref
trait_
,
..
},
TBM
::
None
)
=
*
self
{
if
trait_
.def_id
()
==
tcx
.lang_items
.sized_trait
()
{
return
true
;
}
}
}
...
...
@@ -724,15 +718,18 @@ fn clean(&self, cx: &DocContext) -> TyParamBound {
}
}
TraitBound
(
PolyTrait
{
trait_
:
ResolvedPath
{
path
:
path
,
typarams
:
None
,
did
:
self
.def_id
,
is_generic
:
false
,
TraitBound
(
PolyTrait
{
trait_
:
ResolvedPath
{
path
:
path
,
typarams
:
None
,
did
:
self
.def_id
,
is_generic
:
false
,
},
lifetimes
:
late_bounds
,
},
lifetimes
:
late_bounds
},
hir
::
TraitBoundModifier
::
None
)
hir
::
TraitBoundModifier
::
None
)
}
}
...
...
@@ -932,7 +929,6 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
&
'a
ty
::
GenericPredicates
<
'tcx
>
,
subst
::
ParamSpace
)
{
fn
clean
(
&
self
,
cx
:
&
DocContext
)
->
Generics
{
use
std
::
collections
::
HashSet
;
use
self
::
WherePredicate
as
WP
;
let
(
gens
,
preds
,
space
)
=
*
self
;
...
...
@@ -1486,6 +1482,16 @@ pub enum TypeKind {
TypeTypedef
,
}
pub
trait
GetDefId
{
fn
def_id
(
&
self
)
->
Option
<
DefId
>
;
}
impl
<
T
:
GetDefId
>
GetDefId
for
Option
<
T
>
{
fn
def_id
(
&
self
)
->
Option
<
DefId
>
{
self
.as_ref
()
.and_then
(|
d
|
d
.def_id
())
}
}
impl
Type
{
pub
fn
primitive_type
(
&
self
)
->
Option
<
PrimitiveType
>
{
match
*
self
{
...
...
@@ -1499,7 +1505,9 @@ pub fn primitive_type(&self) -> Option<PrimitiveType> {
_
=>
None
,
}
}
}
impl
GetDefId
for
Type
{
fn
def_id
(
&
self
)
->
Option
<
DefId
>
{
match
*
self
{
ResolvedPath
{
did
,
..
}
=>
Some
(
did
),
...
...
@@ -2208,6 +2216,7 @@ fn clean(&self, _: &DocContext) -> ImplPolarity {
pub
struct
Impl
{
pub
unsafety
:
hir
::
Unsafety
,
pub
generics
:
Generics
,
pub
provided_trait_methods
:
HashSet
<
String
>
,
pub
trait_
:
Option
<
Type
>
,
pub
for_
:
Type
,
pub
items
:
Vec
<
Item
>
,
...
...
@@ -2227,12 +2236,19 @@ fn clean(&self, cx: &DocContext) -> Vec<Item> {
// If this impl block is an implementation of the Deref trait, then we
// need to try inlining the target's inherent impl blocks as well.
if
let
Some
(
ResolvedPath
{
did
,
..
})
=
trait_
{
if
Some
(
did
)
==
cx
.deref_trait_did
.get
()
{
build_deref_target_impls
(
cx
,
&
items
,
&
mut
ret
);
}
if
trait_
.def_id
()
==
cx
.deref_trait_did
.get
()
{
build_deref_target_impls
(
cx
,
&
items
,
&
mut
ret
);
}
let
provided
=
trait_
.def_id
()
.and_then
(|
did
|
{
cx
.tcx_opt
()
.map
(|
tcx
|
{
tcx
.provided_trait_methods
(
did
)
.into_iter
()
.map
(|
meth
|
meth
.name
.to_string
())
.collect
()
})
})
.unwrap_or
(
HashSet
::
new
());
ret
.push
(
Item
{
name
:
None
,
attrs
:
self
.attrs
.clean
(
cx
),
...
...
@@ -2244,6 +2260,7 @@ fn clean(&self, cx: &DocContext) -> Vec<Item> {
inner
:
ImplItem
(
Impl
{
unsafety
:
self
.unsafety
,
generics
:
self
.generics
.clean
(
cx
),
provided_trait_methods
:
provided
,
trait_
:
trait_
,
for_
:
self
.for_
.clean
(
cx
),
items
:
items
,
...
...
src/librustdoc/html/render.rs
浏览文件 @
3e33ef4c
...
...
@@ -62,7 +62,7 @@
use
rustc
::
session
::
config
::
get_unstable_features_setting
;
use
rustc_front
::
hir
;
use
clean
::{
self
,
SelfTy
,
Attributes
};
use
clean
::{
self
,
SelfTy
,
Attributes
,
GetDefId
};
use
doctree
;
use
fold
::
DocFolder
;
use
html
::
escape
::
Escape
;
...
...
@@ -144,9 +144,7 @@ pub struct Impl {
impl
Impl
{
fn
trait_did
(
&
self
)
->
Option
<
DefId
>
{
self
.impl_.trait_
.as_ref
()
.and_then
(|
tr
|
{
if
let
clean
::
ResolvedPath
{
did
,
..
}
=
*
tr
{
Some
(
did
)}
else
{
None
}
})
self
.impl_.trait_
.def_id
()
}
}
...
...
@@ -967,7 +965,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
// Collect all the implementors of traits.
if
let
clean
::
ImplItem
(
ref
i
)
=
item
.inner
{
if
let
Some
(
clean
::
ResolvedPath
{
did
,
..
})
=
i
.trait_
{
if
let
Some
(
did
)
=
i
.trait_
.def_id
()
{
self
.implementors
.entry
(
did
)
.or_insert
(
vec!
[])
.push
(
Implementor
{
def_id
:
item
.def_id
,
stability
:
item
.stability
.clone
(),
...
...
@@ -2066,10 +2064,11 @@ fn render_stability_since(w: &mut fmt::Formatter,
render_stability_since_raw
(
w
,
item
.stable_since
(),
containing_item
.stable_since
())
}
fn
render_assoc_item
(
w
:
&
mut
fmt
::
Formatter
,
meth
:
&
clean
::
Item
,
fn
render_assoc_item
(
w
:
&
mut
fmt
::
Formatter
,
item
:
&
clean
::
Item
,
link
:
AssocItemLink
)
->
fmt
::
Result
{
fn
method
(
w
:
&
mut
fmt
::
Formatter
,
it
:
&
clean
::
Item
,
meth
:
&
clean
::
Item
,
unsafety
:
hir
::
Unsafety
,
constness
:
hir
::
Constness
,
abi
:
abi
::
Abi
,
...
...
@@ -2080,12 +2079,20 @@ fn method(w: &mut fmt::Formatter,
->
fmt
::
Result
{
use
syntax
::
abi
::
Abi
;
let
name
=
it
.name
.as_ref
()
.unwrap
();
let
anchor
=
format!
(
"#{}.{}"
,
shortty
(
it
),
name
);
let
name
=
meth
.name
.as_ref
()
.unwrap
();
let
anchor
=
format!
(
"#{}.{}"
,
shortty
(
meth
),
name
);
let
href
=
match
link
{
AssocItemLink
::
Anchor
=>
anchor
,
AssocItemLink
::
GotoSource
(
did
)
=>
{
href
(
did
)
.map
(|
p
|
format!
(
"{}{}"
,
p
.0
,
anchor
))
.unwrap_or
(
anchor
)
AssocItemLink
::
GotoSource
(
did
,
provided_methods
)
=>
{
// We're creating a link from an impl-item to the corresponding
// trait-item and need to map the anchored type accordingly.
let
ty
=
if
provided_methods
.contains
(
name
)
{
ItemType
::
Method
}
else
{
ItemType
::
TyMethod
};
href
(
did
)
.map
(|
p
|
format!
(
"{}#{}.{}"
,
p
.0
,
ty
,
name
))
.unwrap_or
(
anchor
)
}
};
let
vis_constness
=
match
get_unstable_features_setting
()
{
...
...
@@ -2106,21 +2113,21 @@ fn method(w: &mut fmt::Formatter,
decl
=
Method
(
selfty
,
d
),
where_clause
=
WhereClause
(
g
))
}
match
meth
.inner
{
match
item
.inner
{
clean
::
TyMethodItem
(
ref
m
)
=>
{
method
(
w
,
meth
,
m
.unsafety
,
hir
::
Constness
::
NotConst
,
method
(
w
,
item
,
m
.unsafety
,
hir
::
Constness
::
NotConst
,
m
.abi
,
&
m
.generics
,
&
m
.self_
,
&
m
.decl
,
link
)
}
clean
::
MethodItem
(
ref
m
)
=>
{
method
(
w
,
meth
,
m
.unsafety
,
m
.constness
,
method
(
w
,
item
,
m
.unsafety
,
m
.constness
,
m
.abi
,
&
m
.generics
,
&
m
.self_
,
&
m
.decl
,
link
)
}
clean
::
AssociatedConstItem
(
ref
ty
,
ref
default
)
=>
{
assoc_const
(
w
,
meth
,
ty
,
default
.as_ref
())
assoc_const
(
w
,
item
,
ty
,
default
.as_ref
())
}
clean
::
AssociatedTypeItem
(
ref
bounds
,
ref
default
)
=>
{
assoc_type
(
w
,
meth
,
bounds
,
default
)
assoc_type
(
w
,
item
,
bounds
,
default
)
}
_
=>
panic!
(
"render_assoc_item called on non-associated-item"
)
}
...
...
@@ -2338,9 +2345,9 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item,
}
#[derive(Copy,
Clone)]
enum
AssocItemLink
{
enum
AssocItemLink
<
'a
>
{
Anchor
,
GotoSource
(
DefId
),
GotoSource
(
DefId
,
&
'a
HashSet
<
String
>
),
}
enum
AssocItemRender
<
'a
>
{
...
...
@@ -2383,12 +2390,7 @@ fn render_assoc_items(w: &mut fmt::Formatter,
}
if
!
traits
.is_empty
()
{
let
deref_impl
=
traits
.iter
()
.find
(|
t
|
{
match
*
t
.impl_.trait_
.as_ref
()
.unwrap
()
{
clean
::
ResolvedPath
{
did
,
..
}
=>
{
Some
(
did
)
==
c
.deref_trait_did
}
_
=>
false
}
t
.impl_.trait_
.def_id
()
==
c
.deref_trait_did
});
if
let
Some
(
impl_
)
=
deref_impl
{
render_deref_methods
(
w
,
cx
,
impl_
,
containing_item
)
?
;
...
...
@@ -2400,8 +2402,8 @@ fn render_assoc_items(w: &mut fmt::Formatter,
});
for
i
in
&
manual
{
let
did
=
i
.trait_did
()
.unwrap
();
render_impl
(
w
,
cx
,
i
,
AssocItemLink
::
GotoSource
(
did
),
true
,
containing_item
.stable_since
())
?
;
let
assoc_link
=
AssocItemLink
::
GotoSource
(
did
,
&
i
.impl_.provided_trait_methods
);
render_impl
(
w
,
cx
,
i
,
assoc_link
,
true
,
containing_item
.stable_since
())
?
;
}
if
!
derived
.is_empty
()
{
write!
(
w
,
"<h3 id='derived_implementations'>
\
...
...
@@ -2409,8 +2411,8 @@ fn render_assoc_items(w: &mut fmt::Formatter,
</h3>"
)
?
;
for
i
in
&
derived
{
let
did
=
i
.trait_did
()
.unwrap
();
render_impl
(
w
,
cx
,
i
,
AssocItemLink
::
GotoSource
(
did
),
true
,
containing_item
.stable_since
())
?
;
let
assoc_link
=
AssocItemLink
::
GotoSource
(
did
,
&
i
.impl_.provided_trait_methods
);
render_impl
(
w
,
cx
,
i
,
assoc_link
,
true
,
containing_item
.stable_since
())
?
;
}
}
}
...
...
@@ -2427,17 +2429,16 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl,
}
})
.next
()
.expect
(
"Expected associated type binding"
);
let
what
=
AssocItemRender
::
DerefFor
{
trait_
:
deref_type
,
type_
:
target
};
match
*
target
{
clean
::
ResolvedPath
{
did
,
..
}
=>
render_assoc_items
(
w
,
cx
,
container_item
,
did
,
what
),
_
=>
{
if
let
Some
(
prim
)
=
target
.primitive_type
()
{
if
let
Some
(
c
)
=
cache
()
.primitive_locations
.get
(
&
prim
)
{
let
did
=
DefId
{
krate
:
*
c
,
index
:
prim
.to_def_index
()
};
render_assoc_items
(
w
,
cx
,
container_item
,
did
,
what
)
?
;
}
if
let
Some
(
did
)
=
target
.def_id
()
{
render_assoc_items
(
w
,
cx
,
container_item
,
did
,
what
)
}
else
{
if
let
Some
(
prim
)
=
target
.primitive_type
()
{
if
let
Some
(
c
)
=
cache
()
.primitive_locations
.get
(
&
prim
)
{
let
did
=
DefId
{
krate
:
*
c
,
index
:
prim
.to_def_index
()
};
render_assoc_items
(
w
,
cx
,
container_item
,
did
,
what
)
?
;
}
Ok
(())
}
Ok
(())
}
}
...
...
@@ -2521,18 +2522,19 @@ fn doctraititem(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item,
fn
render_default_items
(
w
:
&
mut
fmt
::
Formatter
,
cx
:
&
Context
,
did
:
DefId
,
t
:
&
clean
::
Trait
,
i
:
&
clean
::
Impl
,
render_static
:
bool
,
outer_version
:
Option
<&
str
>
)
->
fmt
::
Result
{
i
:
&
clean
::
Impl
,
render_static
:
bool
,
outer_version
:
Option
<&
str
>
)
->
fmt
::
Result
{
for
trait_item
in
&
t
.items
{
let
n
=
trait_item
.name
.clone
();
if
i
.items
.iter
()
.find
(|
m
|
{
m
.name
==
n
}
)
.is_some
()
{
if
i
.items
.iter
()
.find
(|
m
|
m
.name
==
n
)
.is_some
()
{
continue
;
}
let
did
=
i
.trait_
.as_ref
()
.unwrap
()
.def_id
()
.unwrap
();
let
assoc_link
=
AssocItemLink
::
GotoSource
(
did
,
&
i
.provided_trait_methods
);
doctraititem
(
w
,
cx
,
trait_item
,
AssocItemLink
::
GotoSource
(
did
)
,
render_static
,
doctraititem
(
w
,
cx
,
trait_item
,
assoc_link
,
render_static
,
outer_version
)
?
;
}
Ok
(())
...
...
@@ -2542,9 +2544,9 @@ fn render_default_items(w: &mut fmt::Formatter,
// default methods which weren't overridden in the implementation block.
// FIXME: this also needs to be done for associated types, whenever defaults
// for them work.
if
let
Some
(
clean
::
ResolvedPath
{
did
,
..
})
=
i
.impl_.trait_
{
if
let
Some
(
did
)
=
i
.trait_did
()
{
if
let
Some
(
t
)
=
cache
()
.traits
.get
(
&
did
)
{
render_default_items
(
w
,
cx
,
did
,
t
,
&
i
.impl_
,
render_header
,
outer_version
)
?
;
render_default_items
(
w
,
cx
,
t
,
&
i
.impl_
,
render_header
,
outer_version
)
?
;
}
}
write!
(
w
,
"</div>"
)
?
;
...
...
src/librustdoc/passes.rs
浏览文件 @
3e33ef4c
...
...
@@ -16,7 +16,7 @@
use
std
::
usize
;
use
rustc_front
::
hir
;
use
clean
::{
self
,
Attributes
};
use
clean
::{
self
,
Attributes
,
GetDefId
};
use
clean
::
Item
;
use
plugins
;
use
fold
;
...
...
@@ -74,7 +74,7 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
return
None
;
}
// Impls of stripped traits also don't need to exist
if
let
Some
(
clean
::
ResolvedPath
{
did
,
..
})
=
*
trait_
{
if
let
Some
(
did
)
=
trait_
.def_id
()
{
if
self
.stripped
.contains
(
&
did
)
{
return
None
;
}
...
...
@@ -223,13 +223,10 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
impl
<
'a
>
fold
::
DocFolder
for
ImplStripper
<
'a
>
{
fn
fold_item
(
&
mut
self
,
i
:
Item
)
->
Option
<
Item
>
{
if
let
clean
::
ImplItem
(
ref
imp
)
=
i
.inner
{
match
imp
.trait_
{
Some
(
clean
::
ResolvedPath
{
did
,
..
})
=>
{
if
did
.is_local
()
&&
!
self
.0
.contains
(
&
did
)
{
return
None
;
}
if
let
Some
(
did
)
=
imp
.trait_
.def_id
()
{
if
did
.is_local
()
&&
!
self
.0
.contains
(
&
did
)
{
return
None
;
}
Some
(
..
)
|
None
=>
{}
}
}
self
.fold_item_recur
(
i
)
...
...
src/test/rustdoc/issue-28478.rs
0 → 100644
浏览文件 @
3e33ef4c
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(associated_type_defaults)]
#![feature(associated_consts)]
// @has issue_28478/trait.Bar.html
pub
trait
Bar
{
// @has - '//*[@id="associatedtype.Bar"]' 'type Bar = ()'
type
Bar
=
();
// @has - '//*[@id="associatedconstant.Baz"]' 'const Baz: usize = 7'
const
Baz
:
usize
=
7
;
// @has - '//*[@id="tymethod.bar"]' 'fn bar'
fn
bar
();
// @has - '//*[@id="method.baz"]' 'fn baz'
fn
baz
()
{
}
}
// @has issue_28478/struct.Foo.html
pub
struct
Foo
;
impl
Foo
{
// @has - '//*[@href="#method.foo"]' 'foo'
pub
fn
foo
()
{}
}
impl
Bar
for
Foo
{
// @has - '//*[@href="../issue_28478/trait.Bar.html#tymethod.bar"]' 'bar'
fn
bar
()
{}
// @has - '//*[@href="../issue_28478/trait.Bar.html#method.baz"]' 'baz'
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录