diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index 6b9ce9a4599e2..b69728c24aa51 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -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( diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index b050ad20afbdb..042a50f2fd42e 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -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), } } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 7e50801f80c7b..91fcd6d690ee7 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -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); + } + } + } _ => (), } } diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 880632561b9e8..e4bb3ce3d5a99 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -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; + // N.B. Most of the keys down below have `type CacheSelector = DefaultCacheSelector;`, + // 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: + 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; + #[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; + #[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; + #[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; + #[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>) { + type CacheSelector = DefaultCacheSelector; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -92,6 +110,8 @@ impl<'tcx> Key for (Ty<'tcx>, Option>) { } impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> { + type CacheSelector = DefaultCacheSelector; + #[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; + #[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 { + type CacheSelector = DefaultCacheSelector; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -169,6 +193,8 @@ impl Key for ty::WithOptConstParam { } impl Key for SimplifiedType { + type CacheSelector = DefaultCacheSelector; + #[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; + #[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; + #[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; + #[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; + #[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; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -229,6 +265,8 @@ impl Key for (LocalDefId, LocalDefId) { } impl Key for (DefId, Option) { + type CacheSelector = DefaultCacheSelector; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.0.krate == LOCAL_CRATE @@ -243,6 +281,8 @@ impl Key for (DefId, Option) { } impl Key for (DefId, LocalDefId, Ident) { + type CacheSelector = DefaultCacheSelector; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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; + #[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> { + type CacheSelector = DefaultCacheSelector; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -459,6 +539,8 @@ impl<'tcx> Key for &'tcx ty::List> { } impl<'tcx> Key for ty::ParamEnv<'tcx> { + type CacheSelector = DefaultCacheSelector; + #[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; + #[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; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -489,6 +575,8 @@ impl Key for Symbol { } impl Key for Option { + type CacheSelector = DefaultCacheSelector; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -501,6 +589,8 @@ impl Key for Option { /// 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; + #[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; + #[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; + #[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; + #[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>) { + type CacheSelector = DefaultCacheSelector; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -556,6 +654,8 @@ impl<'tcx> Key for (ty::PolyFnSig<'tcx>, &'tcx ty::List>) { } impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List>) { + type CacheSelector = DefaultCacheSelector; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -567,6 +667,8 @@ impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List>) { } impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) { + type CacheSelector = DefaultCacheSelector; + #[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; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index b141820fe423c..aeaee524fd453 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -567,11 +567,12 @@ struct SummaryLine<'a, I: Iterator>> { inner: I, started: bool, depth: u32, + skipped_tags: u32, } impl<'a, I: Iterator>> 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>> 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>> 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>> 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 } } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 80fbe9c1f066c..146e5010e4e42 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -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#" Read more"#, assoc_href_attr(item, link, cx)); if let Some(idx) = summary_html.rfind("

") { diff --git a/src/test/codegen/enum-match.rs b/src/test/codegen/enum-match.rs index 44f1b408d21b8..827eb20154afd 100644 --- a/src/test/codegen/enum-match.rs +++ b/src/test/codegen/enum-match.rs @@ -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::*; diff --git a/src/test/rustdoc/read-more-unneeded.rs b/src/test/rustdoc/read-more-unneeded.rs new file mode 100644 index 0000000000000..0303e44426141 --- /dev/null +++ b/src/test/rustdoc/read-more-unneeded.rs @@ -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() {} +} diff --git a/src/test/rustdoc/trait-impl.rs b/src/test/rustdoc/trait-impl.rs index 195cdf009b993..9cf3226f738c8 100644 --- a/src/test/rustdoc/trait-impl.rs +++ b/src/test/rustdoc/trait-impl.rs @@ -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' diff --git a/src/test/ui/associated-inherent-types/style.rs b/src/test/ui/associated-inherent-types/style.rs new file mode 100644 index 0000000000000..8775bd19e1f98 --- /dev/null +++ b/src/test/ui/associated-inherent-types/style.rs @@ -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() {} diff --git a/src/test/ui/associated-inherent-types/style.stderr b/src/test/ui/associated-inherent-types/style.stderr new file mode 100644 index 0000000000000..f83061f8c4216 --- /dev/null +++ b/src/test/ui/associated-inherent-types/style.stderr @@ -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 + diff --git a/src/test/ui/async-await/in-trait/bad-signatures.rs b/src/test/ui/async-await/in-trait/bad-signatures.rs new file mode 100644 index 0000000000000..b86f1d1c13585 --- /dev/null +++ b/src/test/ui/async-await/in-trait/bad-signatures.rs @@ -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() {} diff --git a/src/test/ui/async-await/in-trait/bad-signatures.stderr b/src/test/ui/async-await/in-trait/bad-signatures.stderr new file mode 100644 index 0000000000000..e0ba7b53ec415 --- /dev/null +++ b/src/test/ui/async-await/in-trait/bad-signatures.stderr @@ -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: `: ` + +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 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 2 previous errors; 1 warning emitted + diff --git a/src/test/ui/dyn-star/dyn-to-rigid.rs b/src/test/ui/dyn-star/dyn-to-rigid.rs new file mode 100644 index 0000000000000..e80ee15902eef --- /dev/null +++ b/src/test/ui/dyn-star/dyn-to-rigid.rs @@ -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() {} diff --git a/src/test/ui/dyn-star/dyn-to-rigid.stderr b/src/test/ui/dyn-star/dyn-to-rigid.stderr new file mode 100644 index 0000000000000..588e6d97e5ca3 --- /dev/null +++ b/src/test/ui/dyn-star/dyn-to-rigid.stderr @@ -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`.