Skip to content

Commit 8d1fa71

Browse files
committed
Auto merge of #100205 - cjgillot:noice-doc, r=camelid
Avoid ICE in rustdoc when using `Fn` bounds Fixes #100143
2 parents f03ce30 + 28e4b9e commit 8d1fa71

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

Diff for: src/librustdoc/clean/auto_trait.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -348,15 +348,13 @@ where
348348
fn make_final_bounds(
349349
&self,
350350
ty_to_bounds: FxHashMap<Type, FxHashSet<GenericBound>>,
351-
ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)>,
351+
ty_to_fn: FxHashMap<Type, (PolyTrait, Option<Type>)>,
352352
lifetime_to_bounds: FxHashMap<Lifetime, FxHashSet<GenericBound>>,
353353
) -> Vec<WherePredicate> {
354354
ty_to_bounds
355355
.into_iter()
356356
.flat_map(|(ty, mut bounds)| {
357-
if let Some(data) = ty_to_fn.get(&ty) {
358-
let (poly_trait, output) =
359-
(data.0.as_ref().unwrap().clone(), data.1.as_ref().cloned().map(Box::new));
357+
if let Some((ref poly_trait, ref output)) = ty_to_fn.get(&ty) {
360358
let mut new_path = poly_trait.trait_.clone();
361359
let last_segment = new_path.segments.pop().expect("segments were empty");
362360

@@ -374,8 +372,9 @@ where
374372
GenericArgs::Parenthesized { inputs, output } => (inputs, output),
375373
};
376374

375+
let output = output.as_ref().cloned().map(Box::new);
377376
if old_output.is_some() && old_output != output {
378-
panic!("Output mismatch for {:?} {:?} {:?}", ty, old_output, data.1);
377+
panic!("Output mismatch for {:?} {:?} {:?}", ty, old_output, output);
379378
}
380379

381380
let new_params = GenericArgs::Parenthesized { inputs: old_input, output };
@@ -385,7 +384,10 @@ where
385384
.push(PathSegment { name: last_segment.name, args: new_params });
386385

387386
bounds.insert(GenericBound::TraitBound(
388-
PolyTrait { trait_: new_path, generic_params: poly_trait.generic_params },
387+
PolyTrait {
388+
trait_: new_path,
389+
generic_params: poly_trait.generic_params.clone(),
390+
},
389391
hir::TraitBoundModifier::None,
390392
));
391393
}
@@ -471,7 +473,7 @@ where
471473
let mut lifetime_to_bounds: FxHashMap<_, FxHashSet<_>> = Default::default();
472474
let mut ty_to_traits: FxHashMap<Type, FxHashSet<Path>> = Default::default();
473475

474-
let mut ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)> = Default::default();
476+
let mut ty_to_fn: FxHashMap<Type, (PolyTrait, Option<Type>)> = Default::default();
475477

476478
for p in clean_where_predicates {
477479
let (orig_p, p) = (p, p.clean(self.cx));
@@ -535,8 +537,8 @@ where
535537
if is_fn {
536538
ty_to_fn
537539
.entry(ty.clone())
538-
.and_modify(|e| *e = (Some(poly_trait.clone()), e.1.clone()))
539-
.or_insert(((Some(poly_trait.clone())), None));
540+
.and_modify(|e| *e = (poly_trait.clone(), e.1.clone()))
541+
.or_insert(((poly_trait.clone()), None));
540542

541543
ty_to_bounds.entry(ty.clone()).or_default();
542544
} else {
@@ -559,7 +561,13 @@ where
559561
.and_modify(|e| {
560562
*e = (e.0.clone(), Some(rhs.ty().unwrap().clone()))
561563
})
562-
.or_insert((None, Some(rhs.ty().unwrap().clone())));
564+
.or_insert((
565+
PolyTrait {
566+
trait_: trait_.clone(),
567+
generic_params: Vec::new(),
568+
},
569+
Some(rhs.ty().unwrap().clone()),
570+
));
563571
continue;
564572
}
565573

Diff for: src/test/rustdoc/fn-bound.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Regression test for #100143
2+
3+
use std::iter::Peekable;
4+
5+
pub struct Span<F: Fn(&i32)> {
6+
inner: Peekable<ConditionalIterator<F>>,
7+
}
8+
9+
pub struct ConditionalIterator<F> {
10+
f: F,
11+
}
12+
13+
14+
// @has 'fn_bound/struct.ConditionalIterator.html' '//h3[@class="code-header in-band"]' 'impl<F: Fn(&i32)> Iterator for ConditionalIterator<F>'
15+
impl<F: Fn(&i32)> Iterator for ConditionalIterator<F> {
16+
type Item = ();
17+
18+
fn next(&mut self) -> Option<Self::Item> {
19+
todo!()
20+
}
21+
}

0 commit comments

Comments
 (0)