Skip to content

Commit 78f2271

Browse files
authored
Unrolled build for rust-lang#134857
Rollup merge of rust-lang#134857 - compiler-errors:rustdoc-unsafe-binders, r=camelid Unsafe binder support in rustdoc Adds rustdoc support for unsafe binder types: `unsafe<'a> Foo<'a>`. Doesn't add json support yet. Tracking: * rust-lang#130516
2 parents 41b5796 + aac741a commit 78f2271

File tree

7 files changed

+68
-12
lines changed

7 files changed

+68
-12
lines changed

src/librustdoc/clean/mod.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -1844,8 +1844,8 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
18441844
DynTrait(bounds, lifetime)
18451845
}
18461846
TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))),
1847-
TyKind::UnsafeBinder(..) => {
1848-
unimplemented!("unsafe binders are not supported yet")
1847+
TyKind::UnsafeBinder(unsafe_binder_ty) => {
1848+
UnsafeBinder(Box::new(clean_unsafe_binder_ty(unsafe_binder_ty, cx)))
18491849
}
18501850
// Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s.
18511851
TyKind::Infer
@@ -2075,6 +2075,11 @@ pub(crate) fn clean_middle_ty<'tcx>(
20752075
abi: sig.abi(),
20762076
}))
20772077
}
2078+
ty::UnsafeBinder(inner) => {
2079+
let generic_params = clean_bound_vars(inner.bound_vars());
2080+
let ty = clean_middle_ty(inner.into(), cx, None, None);
2081+
UnsafeBinder(Box::new(UnsafeBinderTy { generic_params, ty }))
2082+
}
20782083
ty::Adt(def, args) => {
20792084
let did = def.did();
20802085
let kind = match def.adt_kind() {
@@ -2253,7 +2258,6 @@ pub(crate) fn clean_middle_ty<'tcx>(
22532258
}
22542259
}
22552260

2256-
ty::UnsafeBinder(_) => todo!("FIXME(unsafe_binders)"),
22572261
ty::Closure(..) => panic!("Closure"),
22582262
ty::CoroutineClosure(..) => panic!("CoroutineClosure"),
22592263
ty::Coroutine(..) => panic!("Coroutine"),
@@ -2564,6 +2568,21 @@ fn clean_bare_fn_ty<'tcx>(
25642568
BareFunctionDecl { safety: bare_fn.safety, abi: bare_fn.abi, decl, generic_params }
25652569
}
25662570

2571+
fn clean_unsafe_binder_ty<'tcx>(
2572+
unsafe_binder_ty: &hir::UnsafeBinderTy<'tcx>,
2573+
cx: &mut DocContext<'tcx>,
2574+
) -> UnsafeBinderTy {
2575+
// NOTE: generics must be cleaned before args
2576+
let generic_params = unsafe_binder_ty
2577+
.generic_params
2578+
.iter()
2579+
.filter(|p| !is_elided_lifetime(p))
2580+
.map(|x| clean_generic_param(cx, None, x))
2581+
.collect();
2582+
let ty = clean_ty(unsafe_binder_ty.inner_ty, cx);
2583+
UnsafeBinderTy { generic_params, ty }
2584+
}
2585+
25672586
pub(crate) fn reexport_chain(
25682587
tcx: TyCtxt<'_>,
25692588
import_def_id: LocalDefId,

src/librustdoc/clean/types.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use {rustc_ast as ast, rustc_hir as hir};
3232
pub(crate) use self::ItemKind::*;
3333
pub(crate) use self::Type::{
3434
Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
35-
RawPointer, SelfTy, Slice, Tuple,
35+
RawPointer, SelfTy, Slice, Tuple, UnsafeBinder,
3636
};
3737
use crate::clean::cfg::Cfg;
3838
use crate::clean::clean_middle_path;
@@ -1511,6 +1511,8 @@ pub(crate) enum Type {
15111511

15121512
/// An `impl Trait`: `impl TraitA + TraitB + ...`
15131513
ImplTrait(Vec<GenericBound>),
1514+
1515+
UnsafeBinder(Box<UnsafeBinderTy>),
15141516
}
15151517

15161518
impl Type {
@@ -1703,7 +1705,7 @@ impl Type {
17031705
Type::Pat(..) => PrimitiveType::Pat,
17041706
RawPointer(..) => PrimitiveType::RawPointer,
17051707
QPath(box QPathData { ref self_type, .. }) => return self_type.def_id(cache),
1706-
Generic(_) | SelfTy | Infer | ImplTrait(_) => return None,
1708+
Generic(_) | SelfTy | Infer | ImplTrait(_) | UnsafeBinder(_) => return None,
17071709
};
17081710
Primitive(t).def_id(cache)
17091711
}
@@ -2343,6 +2345,12 @@ pub(crate) struct BareFunctionDecl {
23432345
pub(crate) abi: ExternAbi,
23442346
}
23452347

2348+
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
2349+
pub(crate) struct UnsafeBinderTy {
2350+
pub(crate) generic_params: Vec<GenericParamDef>,
2351+
pub(crate) ty: Type,
2352+
}
2353+
23462354
#[derive(Clone, Debug)]
23472355
pub(crate) struct Static {
23482356
pub(crate) type_: Box<Type>,

src/librustdoc/html/format.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,8 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
282282

283283
match pred {
284284
clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
285-
print_higher_ranked_params_with_space(bound_params, cx).fmt(f)?;
285+
print_higher_ranked_params_with_space(bound_params, cx, "for")
286+
.fmt(f)?;
286287
ty.print(cx).fmt(f)?;
287288
f.write_str(":")?;
288289
if !bounds.is_empty() {
@@ -386,7 +387,7 @@ impl clean::ConstantKind {
386387
impl clean::PolyTrait {
387388
fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
388389
display_fn(move |f| {
389-
print_higher_ranked_params_with_space(&self.generic_params, cx).fmt(f)?;
390+
print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?;
390391
self.trait_.print(cx).fmt(f)
391392
})
392393
}
@@ -968,10 +969,12 @@ fn tybounds<'a, 'tcx: 'a>(
968969
fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
969970
params: &'a [clean::GenericParamDef],
970971
cx: &'a Context<'tcx>,
972+
keyword: &'static str,
971973
) -> impl Display + 'a + Captures<'tcx> {
972974
display_fn(move |f| {
973975
if !params.is_empty() {
974-
f.write_str(if f.alternate() { "for<" } else { "for&lt;" })?;
976+
f.write_str(keyword)?;
977+
f.write_str(if f.alternate() { "<" } else { "&lt;" })?;
975978
comma_sep(params.iter().map(|lt| lt.print(cx)), true).fmt(f)?;
976979
f.write_str(if f.alternate() { "> " } else { "&gt; " })?;
977980
}
@@ -1027,7 +1030,7 @@ fn fmt_type(
10271030
primitive_link(f, prim, format_args!("{}", prim.as_sym().as_str()), cx)
10281031
}
10291032
clean::BareFunction(ref decl) => {
1030-
print_higher_ranked_params_with_space(&decl.generic_params, cx).fmt(f)?;
1033+
print_higher_ranked_params_with_space(&decl.generic_params, cx, "for").fmt(f)?;
10311034
decl.safety.print_with_space().fmt(f)?;
10321035
print_abi_with_space(decl.abi).fmt(f)?;
10331036
if f.alternate() {
@@ -1037,6 +1040,10 @@ fn fmt_type(
10371040
}
10381041
decl.decl.print(cx).fmt(f)
10391042
}
1043+
clean::UnsafeBinder(ref binder) => {
1044+
print_higher_ranked_params_with_space(&binder.generic_params, cx, "unsafe").fmt(f)?;
1045+
binder.ty.print(cx).fmt(f)
1046+
}
10401047
clean::Tuple(ref typs) => match &typs[..] {
10411048
&[] => primitive_link(f, PrimitiveType::Unit, format_args!("()"), cx),
10421049
[one] => {
@@ -1354,7 +1361,7 @@ impl clean::Impl {
13541361
// Hardcoded anchor library/core/src/primitive_docs.rs
13551362
// Link should match `# Trait implementations`
13561363

1357-
print_higher_ranked_params_with_space(&bare_fn.generic_params, cx).fmt(f)?;
1364+
print_higher_ranked_params_with_space(&bare_fn.generic_params, cx, "for").fmt(f)?;
13581365
bare_fn.safety.print_with_space().fmt(f)?;
13591366
print_abi_with_space(bare_fn.abi).fmt(f)?;
13601367
let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { "" };

src/librustdoc/html/render/search_index.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,8 @@ fn get_index_type_id(
900900
| clean::Generic(_)
901901
| clean::SelfTy
902902
| clean::ImplTrait(_)
903-
| clean::Infer => None,
903+
| clean::Infer
904+
| clean::UnsafeBinder(_) => None,
904905
}
905906
}
906907

src/librustdoc/json/conversions.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ impl FromClean<clean::Type> for Type {
573573
fn from_clean(ty: clean::Type, renderer: &JsonRenderer<'_>) -> Self {
574574
use clean::Type::{
575575
Array, BareFunction, BorrowedRef, Generic, ImplTrait, Infer, Primitive, QPath,
576-
RawPointer, SelfTy, Slice, Tuple,
576+
RawPointer, SelfTy, Slice, Tuple, UnsafeBinder,
577577
};
578578

579579
match ty {
@@ -613,6 +613,8 @@ impl FromClean<clean::Type> for Type {
613613
self_type: Box::new(self_type.into_json(renderer)),
614614
trait_: trait_.map(|trait_| trait_.into_json(renderer)),
615615
},
616+
// FIXME(unsafe_binder): Implement rustdoc-json.
617+
UnsafeBinder(_) => todo!(),
616618
}
617619
}
618620
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#![feature(unsafe_binders)]
2+
#![allow(incomplete_features)]
3+
4+
pub fn woof() -> unsafe<'a> &'a str { todo!() }

tests/rustdoc/unsafe-binder.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ aux-build:unsafe-binder-dep.rs
2+
3+
#![feature(unsafe_binders)]
4+
#![allow(incomplete_features)]
5+
6+
extern crate unsafe_binder_dep;
7+
8+
//@ has 'unsafe_binder/fn.woof.html' //pre "fn woof() -> unsafe<'a> &'a str"
9+
pub use unsafe_binder_dep::woof;
10+
11+
//@ has 'unsafe_binder/fn.meow.html' //pre "fn meow() -> unsafe<'a> &'a str"
12+
pub fn meow() -> unsafe<'a> &'a str { todo!() }
13+
14+
//@ has 'unsafe_binder/fn.meow_squared.html' //pre "fn meow_squared() -> unsafe<'b, 'a> &'a &'b str"
15+
pub fn meow_squared() -> unsafe<'b, 'a> &'a &'b str { todo!() }

0 commit comments

Comments
 (0)