diff options
| author | Noah Lev <camelidcamel@gmail.com> | 2021-09-02 09:54:32 -0700 |
|---|---|---|
| committer | Noah Lev <camelidcamel@gmail.com> | 2021-09-02 14:28:10 -0700 |
| commit | 3a3f99a79b00b5efcb1bf061404112a281084b97 (patch) | |
| tree | f82ffa2ceb43add67ffe692a0f2bf69b06ab8d97 | |
| parent | 2a6022949077176bfff9f72282dc52e51a175cb7 (diff) | |
| download | rust-3a3f99a79b00b5efcb1bf061404112a281084b97.tar.gz rust-3a3f99a79b00b5efcb1bf061404112a281084b97.zip | |
rustdoc: Higher-ranked lifetimes can't have bounds
This cleans up the other spot I found where rustdoc was rendering bounds into the lifetime name itself. However, in this case, I don't think it could have actually happened because higher-ranked lifetime definitions aren't currently allowed to have bounds.
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 54 | ||||
| -rw-r--r-- | src/librustdoc/lib.rs | 1 | ||||
| -rw-r--r-- | src/test/rustdoc-ui/bounded-hr-lifetime.rs | 9 | ||||
| -rw-r--r-- | src/test/rustdoc-ui/bounded-hr-lifetime.stderr | 10 |
4 files changed, 45 insertions, 29 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index bb22da00576..3664687cbb7 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -30,6 +30,7 @@ use rustc_target::spec::abi::Abi; use rustc_typeck::check::intrinsic::intrinsic_operation_unsafety; use rustc_typeck::hir_ty_to_ty; +use std::assert_matches::assert_matches; use std::collections::hash_map::Entry; use std::default::Default; use std::hash::Hash; @@ -242,30 +243,6 @@ impl Clean<Lifetime> for hir::Lifetime { } } -impl Clean<Lifetime> for hir::GenericParam<'_> { - fn clean(&self, _: &mut DocContext<'_>) -> Lifetime { - match self.kind { - hir::GenericParamKind::Lifetime { .. } => { - if !self.bounds.is_empty() { - let mut bounds = self.bounds.iter().map(|bound| match bound { - hir::GenericBound::Outlives(lt) => lt, - _ => panic!(), - }); - let name = bounds.next().expect("no more bounds").name.ident(); - let mut s = format!("{}: {}", self.name.ident(), name); - for bound in bounds { - s.push_str(&format!(" + {}", bound.name.ident())); - } - Lifetime(Symbol::intern(&s)) - } else { - Lifetime(self.name.ident().name) - } - } - _ => panic!(), - } - } -} - impl Clean<Constant> for hir::ConstArg { fn clean(&self, cx: &mut DocContext<'_>) -> Constant { Constant { @@ -303,11 +280,30 @@ impl Clean<Option<Lifetime>> for ty::RegionKind { impl Clean<WherePredicate> for hir::WherePredicate<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { match *self { - hir::WherePredicate::BoundPredicate(ref wbp) => WherePredicate::BoundPredicate { - ty: wbp.bounded_ty.clean(cx), - bounds: wbp.bounds.clean(cx), - bound_params: wbp.bound_generic_params.into_iter().map(|x| x.clean(cx)).collect(), - }, + hir::WherePredicate::BoundPredicate(ref wbp) => { + let bound_params = wbp + .bound_generic_params + .into_iter() + .map(|param| { + // Higher-ranked params must be lifetimes. + // Higher-ranked lifetimes can't have bounds. + assert_matches!( + param, + hir::GenericParam { + kind: hir::GenericParamKind::Lifetime { .. }, + bounds: [], + .. + } + ); + Lifetime(param.name.ident().name) + }) + .collect(); + WherePredicate::BoundPredicate { + ty: wbp.bounded_ty.clean(cx), + bounds: wbp.bounds.clean(cx), + bound_params, + } + } hir::WherePredicate::RegionPredicate(ref wrp) => WherePredicate::RegionPredicate { lifetime: wrp.lifetime.clean(cx), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b81acd1a93f..2dbe4c42b88 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -4,6 +4,7 @@ )] #![feature(rustc_private)] #![feature(array_methods)] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(in_band_lifetimes)] diff --git a/src/test/rustdoc-ui/bounded-hr-lifetime.rs b/src/test/rustdoc-ui/bounded-hr-lifetime.rs new file mode 100644 index 00000000000..b2e000b9757 --- /dev/null +++ b/src/test/rustdoc-ui/bounded-hr-lifetime.rs @@ -0,0 +1,9 @@ +// This test ensures that rustdoc doesn't panic on higher-ranked lifetimes +// with bounds, because an error should have already been emitted by rustc. + +pub fn hrlt<'b, 'c>() +where + for<'a: 'b + 'c> &'a (): std::fmt::Debug, + //~^ ERROR lifetime bounds cannot be used in this context +{ +} diff --git a/src/test/rustdoc-ui/bounded-hr-lifetime.stderr b/src/test/rustdoc-ui/bounded-hr-lifetime.stderr new file mode 100644 index 00000000000..d8fcd6cb4b1 --- /dev/null +++ b/src/test/rustdoc-ui/bounded-hr-lifetime.stderr @@ -0,0 +1,10 @@ +error: lifetime bounds cannot be used in this context + --> $DIR/bounded-hr-lifetime.rs:6:13 + | +LL | for<'a: 'b + 'c> &'a (): std::fmt::Debug, + | ^^ ^^ + +error: Compilation failed, aborting rustdoc + +error: aborting due to 2 previous errors + |
