Auto merge of #105804 - matthiaskrgr:rollup-iaqlbl3, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #105493 (Help rust-analyzer normalize query return types) - #105710 (Don't bug if we're trying to cast `dyn*` to another type) - #105711 (bail in `collect_trait_impl_trait_tys` if signatures reference errors) - #105768 (Detect inherent associated types not having CamelCase) - #105780 (rustdoc: Don't add "Read more" link if there is no extra content) - #105802 (Make enum-match.rs test robust against variable name changes) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
998e1a91db
15 changed files with 269 additions and 15 deletions
|
@ -405,6 +405,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
|
|||
tcx.fn_sig(impl_m.def_id),
|
||||
),
|
||||
);
|
||||
impl_sig.error_reported()?;
|
||||
let impl_return_ty = impl_sig.output();
|
||||
|
||||
// Normalize the trait signature with liberated bound vars, passing it through
|
||||
|
@ -419,6 +420,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
|
|||
)
|
||||
.fold_with(&mut collector);
|
||||
let trait_sig = ocx.normalize(&norm_cause, param_env, unnormalized_trait_sig);
|
||||
trait_sig.error_reported()?;
|
||||
let trait_return_ty = trait_sig.output();
|
||||
|
||||
let wf_tys = FxIndexSet::from_iter(
|
||||
|
|
|
@ -847,13 +847,15 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
|||
|
||||
(Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast),
|
||||
|
||||
(_, DynStar) | (DynStar, _) => {
|
||||
(_, DynStar) => {
|
||||
if fcx.tcx.features().dyn_star {
|
||||
bug!("should be handled by `try_coerce`")
|
||||
} else {
|
||||
Err(CastError::IllegalCast)
|
||||
}
|
||||
}
|
||||
|
||||
(DynStar, _) => Err(CastError::IllegalCast),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -175,13 +175,23 @@ impl EarlyLintPass for NonCamelCaseTypes {
|
|||
return;
|
||||
}
|
||||
|
||||
match it.kind {
|
||||
match &it.kind {
|
||||
ast::ItemKind::TyAlias(..)
|
||||
| ast::ItemKind::Enum(..)
|
||||
| ast::ItemKind::Struct(..)
|
||||
| ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident),
|
||||
ast::ItemKind::Trait(..) => self.check_case(cx, "trait", &it.ident),
|
||||
ast::ItemKind::TraitAlias(..) => self.check_case(cx, "trait alias", &it.ident),
|
||||
|
||||
// N.B. This check is only for inherent associated types, so that we don't lint against
|
||||
// trait impls where we should have warned for the trait definition already.
|
||||
ast::ItemKind::Impl(box ast::Impl { of_trait: None, items, .. }) => {
|
||||
for it in items {
|
||||
if let ast::AssocItemKind::Type(..) = it.kind {
|
||||
self.check_case(cx, "associated type", &it.ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,15 @@ use rustc_span::{Span, DUMMY_SP};
|
|||
/// The `Key` trait controls what types can legally be used as the key
|
||||
/// for a query.
|
||||
pub trait Key: Sized {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
// N.B. Most of the keys down below have `type CacheSelector = DefaultCacheSelector<Self>;`,
|
||||
// it would be reasonable to use associated type defaults, to remove the duplication...
|
||||
//
|
||||
// ...But r-a doesn't support them yet and using a default here causes r-a to not infer
|
||||
// return types of queries which is very annoying. Thus, until r-a support associated
|
||||
// type defaults, plese restrain from using them here <3
|
||||
//
|
||||
// r-a issue: <https://github.com/rust-lang/rust-analyzer/issues/13693>
|
||||
type CacheSelector;
|
||||
|
||||
/// Given an instance of this key, what crate is it referring to?
|
||||
/// This is used to find the provider.
|
||||
|
@ -37,6 +45,8 @@ pub trait Key: Sized {
|
|||
}
|
||||
|
||||
impl Key for () {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -48,6 +58,8 @@ impl Key for () {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for ty::InstanceDef<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -59,6 +71,8 @@ impl<'tcx> Key for ty::InstanceDef<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for ty::Instance<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -70,6 +84,8 @@ impl<'tcx> Key for ty::Instance<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -81,6 +97,8 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -92,6 +110,8 @@ impl<'tcx> Key for (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -145,6 +165,8 @@ impl Key for LocalDefId {
|
|||
}
|
||||
|
||||
impl Key for DefId {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.krate == LOCAL_CRATE
|
||||
|
@ -159,6 +181,8 @@ impl Key for DefId {
|
|||
}
|
||||
|
||||
impl Key for ty::WithOptConstParam<LocalDefId> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -169,6 +193,8 @@ impl Key for ty::WithOptConstParam<LocalDefId> {
|
|||
}
|
||||
|
||||
impl Key for SimplifiedType {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -179,6 +205,8 @@ impl Key for SimplifiedType {
|
|||
}
|
||||
|
||||
impl Key for (DefId, DefId) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.0.krate == LOCAL_CRATE
|
||||
|
@ -189,6 +217,8 @@ impl Key for (DefId, DefId) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (ty::Instance<'tcx>, LocalDefId) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -199,6 +229,8 @@ impl<'tcx> Key for (ty::Instance<'tcx>, LocalDefId) {
|
|||
}
|
||||
|
||||
impl Key for (DefId, LocalDefId) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.0.krate == LOCAL_CRATE
|
||||
|
@ -209,6 +241,8 @@ impl Key for (DefId, LocalDefId) {
|
|||
}
|
||||
|
||||
impl Key for (LocalDefId, DefId) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -219,6 +253,8 @@ impl Key for (LocalDefId, DefId) {
|
|||
}
|
||||
|
||||
impl Key for (LocalDefId, LocalDefId) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -229,6 +265,8 @@ impl Key for (LocalDefId, LocalDefId) {
|
|||
}
|
||||
|
||||
impl Key for (DefId, Option<Ident>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.0.krate == LOCAL_CRATE
|
||||
|
@ -243,6 +281,8 @@ impl Key for (DefId, Option<Ident>) {
|
|||
}
|
||||
|
||||
impl Key for (DefId, LocalDefId, Ident) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.0.krate == LOCAL_CRATE
|
||||
|
@ -253,6 +293,8 @@ impl Key for (DefId, LocalDefId, Ident) {
|
|||
}
|
||||
|
||||
impl Key for (CrateNum, DefId) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.0 == LOCAL_CRATE
|
||||
|
@ -263,6 +305,8 @@ impl Key for (CrateNum, DefId) {
|
|||
}
|
||||
|
||||
impl Key for (CrateNum, SimplifiedType) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.0 == LOCAL_CRATE
|
||||
|
@ -273,6 +317,8 @@ impl Key for (CrateNum, SimplifiedType) {
|
|||
}
|
||||
|
||||
impl Key for (DefId, SimplifiedType) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.0.krate == LOCAL_CRATE
|
||||
|
@ -283,6 +329,8 @@ impl Key for (DefId, SimplifiedType) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for SubstsRef<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -293,6 +341,8 @@ impl<'tcx> Key for SubstsRef<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.0.krate == LOCAL_CRATE
|
||||
|
@ -303,6 +353,8 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
(self.0).def.did.krate == LOCAL_CRATE
|
||||
|
@ -313,6 +365,8 @@ impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -323,6 +377,8 @@ impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.1.def_id().krate == LOCAL_CRATE
|
||||
|
@ -333,6 +389,8 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (ty::Const<'tcx>, mir::Field) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -343,6 +401,8 @@ impl<'tcx> Key for (ty::Const<'tcx>, mir::Field) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for mir::interpret::ConstAlloc<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -353,6 +413,8 @@ impl<'tcx> Key for mir::interpret::ConstAlloc<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for ty::PolyTraitRef<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.def_id().krate == LOCAL_CRATE
|
||||
|
@ -363,6 +425,8 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for ty::PolyExistentialTraitRef<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.def_id().krate == LOCAL_CRATE
|
||||
|
@ -373,6 +437,8 @@ impl<'tcx> Key for ty::PolyExistentialTraitRef<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (ty::PolyTraitRef<'tcx>, ty::PolyTraitRef<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.0.def_id().krate == LOCAL_CRATE
|
||||
|
@ -383,6 +449,8 @@ impl<'tcx> Key for (ty::PolyTraitRef<'tcx>, ty::PolyTraitRef<'tcx>) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for GenericArg<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -393,6 +461,8 @@ impl<'tcx> Key for GenericArg<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for mir::ConstantKind<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -403,6 +473,8 @@ impl<'tcx> Key for mir::ConstantKind<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for ty::Const<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -413,6 +485,8 @@ impl<'tcx> Key for ty::Const<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for Ty<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -429,6 +503,8 @@ impl<'tcx> Key for Ty<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for TyAndLayout<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -439,6 +515,8 @@ impl<'tcx> Key for TyAndLayout<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (Ty<'tcx>, Ty<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -449,6 +527,8 @@ impl<'tcx> Key for (Ty<'tcx>, Ty<'tcx>) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for &'tcx ty::List<ty::Predicate<'tcx>> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -459,6 +539,8 @@ impl<'tcx> Key for &'tcx ty::List<ty::Predicate<'tcx>> {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for ty::ParamEnv<'tcx> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -469,6 +551,8 @@ impl<'tcx> Key for ty::ParamEnv<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
self.value.query_crate_is_local()
|
||||
|
@ -479,6 +563,8 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
|
|||
}
|
||||
|
||||
impl Key for Symbol {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -489,6 +575,8 @@ impl Key for Symbol {
|
|||
}
|
||||
|
||||
impl Key for Option<Symbol> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -501,6 +589,8 @@ impl Key for Option<Symbol> {
|
|||
/// Canonical query goals correspond to abstract trait operations that
|
||||
/// are not tied to any crate in particular.
|
||||
impl<'tcx, T> Key for Canonical<'tcx, T> {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -512,6 +602,8 @@ impl<'tcx, T> Key for Canonical<'tcx, T> {
|
|||
}
|
||||
|
||||
impl Key for (Symbol, u32, u32) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -523,6 +615,8 @@ impl Key for (Symbol, u32, u32) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -534,6 +628,8 @@ impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -545,6 +641,8 @@ impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -556,6 +654,8 @@ impl<'tcx> Key for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -567,6 +667,8 @@ impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
|
|||
}
|
||||
|
||||
impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
@ -578,6 +680,8 @@ impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) {
|
|||
}
|
||||
|
||||
impl Key for HirId {
|
||||
type CacheSelector = DefaultCacheSelector<Self>;
|
||||
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
true
|
||||
|
|
|
@ -567,11 +567,12 @@ struct SummaryLine<'a, I: Iterator<Item = Event<'a>>> {
|
|||
inner: I,
|
||||
started: bool,
|
||||
depth: u32,
|
||||
skipped_tags: u32,
|
||||
}
|
||||
|
||||
impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> {
|
||||
fn new(iter: I) -> Self {
|
||||
SummaryLine { inner: iter, started: false, depth: 0 }
|
||||
SummaryLine { inner: iter, started: false, depth: 0, skipped_tags: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -601,6 +602,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
|
|||
let is_allowed_tag = match event {
|
||||
Event::Start(ref c) => {
|
||||
if is_forbidden_tag(c) {
|
||||
self.skipped_tags += 1;
|
||||
return None;
|
||||
}
|
||||
self.depth += 1;
|
||||
|
@ -608,6 +610,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
|
|||
}
|
||||
Event::End(ref c) => {
|
||||
if is_forbidden_tag(c) {
|
||||
self.skipped_tags += 1;
|
||||
return None;
|
||||
}
|
||||
self.depth -= 1;
|
||||
|
@ -616,6 +619,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
|
|||
}
|
||||
_ => true,
|
||||
};
|
||||
if !is_allowed_tag {
|
||||
self.skipped_tags += 1;
|
||||
}
|
||||
return if !is_allowed_tag {
|
||||
if is_start {
|
||||
Some(Event::Start(Tag::Paragraph))
|
||||
|
@ -1096,11 +1102,11 @@ impl MarkdownItemInfo<'_> {
|
|||
}
|
||||
|
||||
impl MarkdownSummaryLine<'_> {
|
||||
pub(crate) fn into_string(self) -> String {
|
||||
pub(crate) fn into_string_with_has_more_content(self) -> (String, bool) {
|
||||
let MarkdownSummaryLine(md, links) = self;
|
||||
// This is actually common enough to special-case
|
||||
if md.is_empty() {
|
||||
return String::new();
|
||||
return (String::new(), false);
|
||||
}
|
||||
|
||||
let mut replacer = |broken_link: BrokenLink<'_>| {
|
||||
|
@ -1110,17 +1116,26 @@ impl MarkdownSummaryLine<'_> {
|
|||
.map(|link| (link.href.as_str().into(), link.new_text.as_str().into()))
|
||||
};
|
||||
|
||||
let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer));
|
||||
let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer))
|
||||
.peekable();
|
||||
let mut summary = SummaryLine::new(p);
|
||||
|
||||
let mut s = String::new();
|
||||
|
||||
let without_paragraphs = LinkReplacer::new(SummaryLine::new(p), links).filter(|event| {
|
||||
let without_paragraphs = LinkReplacer::new(&mut summary, links).filter(|event| {
|
||||
!matches!(event, Event::Start(Tag::Paragraph) | Event::End(Tag::Paragraph))
|
||||
});
|
||||
|
||||
html::push_html(&mut s, without_paragraphs);
|
||||
|
||||
s
|
||||
let has_more_content =
|
||||
matches!(summary.inner.peek(), Some(Event::Start(_))) || summary.skipped_tags > 0;
|
||||
|
||||
(s, has_more_content)
|
||||
}
|
||||
|
||||
pub(crate) fn into_string(self) -> String {
|
||||
self.into_string_with_has_more_content().0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -467,9 +467,10 @@ fn document_short(
|
|||
return;
|
||||
}
|
||||
if let Some(s) = item.doc_value() {
|
||||
let mut summary_html = MarkdownSummaryLine(&s, &item.links(cx)).into_string();
|
||||
let (mut summary_html, has_more_content) =
|
||||
MarkdownSummaryLine(&s, &item.links(cx)).into_string_with_has_more_content();
|
||||
|
||||
if s.contains('\n') {
|
||||
if has_more_content {
|
||||
let link = format!(r#" <a{}>Read more</a>"#, assoc_href_attr(item, link, cx));
|
||||
|
||||
if let Some(idx) = summary_html.rfind("</p>") {
|
||||
|
|
|
@ -34,8 +34,8 @@ pub enum Enum1 {
|
|||
|
||||
// CHECK: define i8 @match1{{.*}}
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: %1 = {{.*}}call i8 @llvm.usub.sat.i8(i8 %0, i8 1)
|
||||
// CHECK-NEXT: switch i8 %1, label {{.*}} [
|
||||
// CHECK-NEXT: [[DISCR:%.*]] = {{.*}}call i8 @llvm.usub.sat.i8(i8 %0, i8 1)
|
||||
// CHECK-NEXT: switch i8 [[DISCR]], label {{.*}} [
|
||||
#[no_mangle]
|
||||
pub fn match1(e: Enum1) -> u8 {
|
||||
use Enum1::*;
|
||||
|
|
34
src/test/rustdoc/read-more-unneeded.rs
Normal file
34
src/test/rustdoc/read-more-unneeded.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Regression test for https://github.com/rust-lang/rust/issues/105677.
|
||||
// This test ensures that the "Read more" link is only generated when
|
||||
// there is actually more documentation to read after the short summary.
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
pub trait MyFrom {
|
||||
/// # Hello
|
||||
/// ## Yolo
|
||||
/// more!
|
||||
fn try_from1();
|
||||
/// a
|
||||
/// b
|
||||
/// c
|
||||
fn try_from2();
|
||||
/// a
|
||||
///
|
||||
/// b
|
||||
///
|
||||
/// c
|
||||
fn try_from3();
|
||||
}
|
||||
|
||||
pub struct NonZero;
|
||||
|
||||
// @has 'foo/struct.NonZero.html'
|
||||
impl MyFrom for NonZero {
|
||||
// @matches - '//*[@class="docblock"]' '^Hello Read more$'
|
||||
fn try_from1() {}
|
||||
// @matches - '//*[@class="docblock"]' '^a\sb\sc$'
|
||||
fn try_from2() {}
|
||||
// @matches - '//*[@class="docblock"]' '^a Read more$'
|
||||
fn try_from3() {}
|
||||
}
|
|
@ -30,8 +30,6 @@ impl Trait for Struct {
|
|||
// @has - '//*[@id="method.b"]/../../div[@class="docblock"]' 'These docs contain'
|
||||
// @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a' 'reference link'
|
||||
// @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a/@href' 'https://example.com'
|
||||
// @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a' 'Read more'
|
||||
// @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a/@href' 'trait.Trait.html#tymethod.b'
|
||||
fn b() {}
|
||||
|
||||
// @!has - '//*[@id="method.c"]/../../div[@class="docblock"]' 'code block'
|
||||
|
|
12
src/test/ui/associated-inherent-types/style.rs
Normal file
12
src/test/ui/associated-inherent-types/style.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
#![feature(inherent_associated_types)]
|
||||
#![allow(incomplete_features, dead_code)]
|
||||
#![deny(non_camel_case_types)]
|
||||
|
||||
struct S;
|
||||
|
||||
impl S {
|
||||
type typ = ();
|
||||
//~^ ERROR associated type `typ` should have an upper camel case name
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/associated-inherent-types/style.stderr
Normal file
14
src/test/ui/associated-inherent-types/style.stderr
Normal file
|
@ -0,0 +1,14 @@
|
|||
error: associated type `typ` should have an upper camel case name
|
||||
--> $DIR/style.rs:8:10
|
||||
|
|
||||
LL | type typ = ();
|
||||
| ^^^ help: convert the identifier to upper camel case: `Typ`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/style.rs:3:9
|
||||
|
|
||||
LL | #![deny(non_camel_case_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
16
src/test/ui/async-await/in-trait/bad-signatures.rs
Normal file
16
src/test/ui/async-await/in-trait/bad-signatures.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
// edition:2021
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
//~^ WARN the feature `async_fn_in_trait` is incomplete
|
||||
|
||||
trait MyTrait {
|
||||
async fn bar(&abc self);
|
||||
//~^ ERROR expected identifier, found keyword `self`
|
||||
//~| ERROR expected one of `:`, `@`, or `|`, found keyword `self`
|
||||
}
|
||||
|
||||
impl MyTrait for () {
|
||||
async fn bar(&self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
26
src/test/ui/async-await/in-trait/bad-signatures.stderr
Normal file
26
src/test/ui/async-await/in-trait/bad-signatures.stderr
Normal file
|
@ -0,0 +1,26 @@
|
|||
error: expected identifier, found keyword `self`
|
||||
--> $DIR/bad-signatures.rs:7:23
|
||||
|
|
||||
LL | async fn bar(&abc self);
|
||||
| ^^^^ expected identifier, found keyword
|
||||
|
||||
error: expected one of `:`, `@`, or `|`, found keyword `self`
|
||||
--> $DIR/bad-signatures.rs:7:23
|
||||
|
|
||||
LL | async fn bar(&abc self);
|
||||
| -----^^^^
|
||||
| | |
|
||||
| | expected one of `:`, `@`, or `|`
|
||||
| help: declare the type after the parameter binding: `<identifier>: <type>`
|
||||
|
||||
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/bad-signatures.rs:3:12
|
||||
|
|
||||
LL | #![feature(async_fn_in_trait)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
11
src/test/ui/dyn-star/dyn-to-rigid.rs
Normal file
11
src/test/ui/dyn-star/dyn-to-rigid.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
#![feature(dyn_star)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Tr {}
|
||||
|
||||
fn f(x: dyn* Tr) -> usize {
|
||||
x as usize
|
||||
//~^ ERROR casting `(dyn* Tr + 'static)` as `usize` is invalid
|
||||
}
|
||||
|
||||
fn main() {}
|
9
src/test/ui/dyn-star/dyn-to-rigid.stderr
Normal file
9
src/test/ui/dyn-star/dyn-to-rigid.stderr
Normal file
|
@ -0,0 +1,9 @@
|
|||
error[E0606]: casting `(dyn* Tr + 'static)` as `usize` is invalid
|
||||
--> $DIR/dyn-to-rigid.rs:7:5
|
||||
|
|
||||
LL | x as usize
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0606`.
|
Loading…
Add table
Reference in a new issue