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:
bors 2022-12-17 00:41:15 +00:00
commit 998e1a91db
15 changed files with 269 additions and 15 deletions

View file

@ -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(

View file

@ -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),
}
}

View file

@ -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);
}
}
}
_ => (),
}
}

View file

@ -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

View file

@ -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
}
}

View file

@ -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>") {

View file

@ -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::*;

View 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() {}
}

View file

@ -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'

View 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() {}

View 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

View 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() {}

View 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

View 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() {}

View 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`.