Skip to content

Rollup of 5 pull requests #100868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Aug 22, 2022
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
85a9c74
Add tests that check `Vec::retain` predicate execution order.
AngelicosPhosphoros Jul 17, 2022
c6558c0
Recover keywords in bounds
WaffleLapkin Jul 29, 2022
798016c
add a silly test for keywords in trait bounds recovery
WaffleLapkin Jul 29, 2022
c198a20
Catch overflow early
ouz-a Aug 19, 2022
4b47686
Update issue-83150.stderr
ouz-a Aug 19, 2022
17ddcb4
Improve primitive/std docs separation and headers
camsteffen Apr 30, 2022
5d5e451
recover `const Tr` bounds (no `~`)
WaffleLapkin Aug 21, 2022
d6fdf14
Migrate forbidden_let
finalchild Aug 17, 2022
80451de
Use DiagnosticMessage for BufferedEarlyLint.msg
finalchild Aug 17, 2022
e144a23
Migrate deprecated_where_clause_location, forbidden_assoc_constraint,…
finalchild Aug 17, 2022
88afae5
Tidy
finalchild Aug 18, 2022
e3d4c40
Migrate trait_fn_async
finalchild Aug 18, 2022
8d042f4
Migrate trait_fn_const
finalchild Aug 18, 2022
269c853
Migrate forbidden_lifetime_bound, forbidden_non_lifetime_param, too_m…
finalchild Aug 18, 2022
c6903c0
Migrate doc_comment_on_fn_param, forbidden_attr_on_fn_param
finalchild Aug 18, 2022
07e0bc9
Rename c_var_args_without_named_arg to c_var_args_is_sole_param
finalchild Aug 18, 2022
bfefefb
Migrate fn_param_forbidden_self and rename others to have prefix fn_p…
finalchild Aug 18, 2022
b28cc09
Support #[fatal(..)]
finalchild Aug 18, 2022
8ed8aac
Fix `build_format` not unescaping braces properly
finalchild Aug 18, 2022
e331ae5
Migrate forbidden_default and *_without_body
finalchild Aug 18, 2022
6a34074
Remove redundant clone
finalchild Aug 18, 2022
70e0af6
Fix incorrect return type of emit_fatal
finalchild Aug 20, 2022
09d495c
Replace #[error(..)] etc. to #[diag(..)]
finalchild Aug 21, 2022
a4950ef
Rollup merge of #93162 - camsteffen:std-prim-docs, r=Mark-Simulacrum
Dylan-DPC Aug 22, 2022
33b5ce6
Rollup merge of #99386 - AngelicosPhosphoros:add_retain_test_maybeuni…
Dylan-DPC Aug 22, 2022
3842117
Rollup merge of #99915 - WaffleLapkin:recover_keyword_bounds, r=compi…
Dylan-DPC Aug 22, 2022
57e521e
Rollup merge of #100694 - finalchild:ast-passes-diag, r=TaKO8Ki
Dylan-DPC Aug 22, 2022
88e39b2
Rollup merge of #100757 - ouz-a:issue-95134, r=jackh726
Dylan-DPC Aug 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -3595,6 +3595,7 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_macros",
"rustc_parse",
"rustc_session",
"rustc_span",
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/Cargo.toml
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_macros = { path = "../rustc_macros" }
rustc_parse = { path = "../rustc_parse" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
248 changes: 80 additions & 168 deletions compiler/rustc_ast_passes/src/ast_validation.rs

Large diffs are not rendered by default.

248 changes: 248 additions & 0 deletions compiler/rustc_ast_passes/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
//! Errors emitted by ast_passes.
use rustc_errors::{fluent, AddSubdiagnostic, Applicability, Diagnostic};
use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
use rustc_span::{Span, Symbol};

use crate::ast_validation::ForbiddenLetReason;

#[derive(SessionDiagnostic)]
#[diag(ast_passes::forbidden_let)]
#[note]
pub struct ForbiddenLet {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub(crate) reason: ForbiddenLetReason,
}

impl AddSubdiagnostic for ForbiddenLetReason {
fn add_to_diagnostic(self, diag: &mut Diagnostic) {
match self {
Self::GenericForbidden => {}
Self::NotSupportedOr(span) => {
diag.span_note(span, fluent::ast_passes::not_supported_or);
}
Self::NotSupportedParentheses(span) => {
diag.span_note(span, fluent::ast_passes::not_supported_parentheses);
}
}
}
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::forbidden_assoc_constraint)]
pub struct ForbiddenAssocConstraint {
#[primary_span]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::keyword_lifetime)]
pub struct KeywordLifetime {
#[primary_span]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::invalid_label)]
pub struct InvalidLabel {
#[primary_span]
pub span: Span,
pub name: Symbol,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::invalid_visibility, code = "E0449")]
pub struct InvalidVisibility {
#[primary_span]
pub span: Span,
#[label(ast_passes::implied)]
pub implied: Option<Span>,
#[subdiagnostic]
pub note: Option<InvalidVisibilityNote>,
}

#[derive(SessionSubdiagnostic)]
pub enum InvalidVisibilityNote {
#[note(ast_passes::individual_impl_items)]
IndividualImplItems,
#[note(ast_passes::individual_foreign_items)]
IndividualForeignItems,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::trait_fn_async, code = "E0706")]
#[note]
#[note(ast_passes::note2)]
pub struct TraitFnAsync {
#[primary_span]
pub fn_span: Span,
#[label]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::trait_fn_const, code = "E0379")]
pub struct TraitFnConst {
#[primary_span]
#[label]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::forbidden_lifetime_bound)]
pub struct ForbiddenLifetimeBound {
#[primary_span]
pub spans: Vec<Span>,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::forbidden_non_lifetime_param)]
pub struct ForbiddenNonLifetimeParam {
#[primary_span]
pub spans: Vec<Span>,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::fn_param_too_many)]
pub struct FnParamTooMany {
#[primary_span]
pub span: Span,
pub max_num_args: usize,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::fn_param_c_var_args_only)]
pub struct FnParamCVarArgsOnly {
#[primary_span]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::fn_param_c_var_args_not_last)]
pub struct FnParamCVarArgsNotLast {
#[primary_span]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::fn_param_doc_comment)]
pub struct FnParamDocComment {
#[primary_span]
#[label]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::fn_param_forbidden_attr)]
pub struct FnParamForbiddenAttr {
#[primary_span]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::fn_param_forbidden_self)]
#[note]
pub struct FnParamForbiddenSelf {
#[primary_span]
#[label]
pub span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::forbidden_default)]
pub struct ForbiddenDefault {
#[primary_span]
pub span: Span,
#[label]
pub def_span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::assoc_const_without_body)]
pub struct AssocConstWithoutBody {
#[primary_span]
pub span: Span,
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
pub replace_span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::assoc_fn_without_body)]
pub struct AssocFnWithoutBody {
#[primary_span]
pub span: Span,
#[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
pub replace_span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::assoc_type_without_body)]
pub struct AssocTypeWithoutBody {
#[primary_span]
pub span: Span,
#[suggestion(code = " = <type>;", applicability = "has-placeholders")]
pub replace_span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::const_without_body)]
pub struct ConstWithoutBody {
#[primary_span]
pub span: Span,
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
pub replace_span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::static_without_body)]
pub struct StaticWithoutBody {
#[primary_span]
pub span: Span,
#[suggestion(code = " = <expr>;", applicability = "has-placeholders")]
pub replace_span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::ty_alias_without_body)]
pub struct TyAliasWithoutBody {
#[primary_span]
pub span: Span,
#[suggestion(code = " = <type>;", applicability = "has-placeholders")]
pub replace_span: Span,
}

#[derive(SessionDiagnostic)]
#[diag(ast_passes::fn_without_body)]
pub struct FnWithoutBody {
#[primary_span]
pub span: Span,
#[suggestion(code = " {{ <body> }}", applicability = "has-placeholders")]
pub replace_span: Span,
#[subdiagnostic]
pub extern_block_suggestion: Option<ExternBlockSuggestion>,
}

pub struct ExternBlockSuggestion {
pub start_span: Span,
pub end_span: Span,
pub abi: Option<Symbol>,
}

impl AddSubdiagnostic for ExternBlockSuggestion {
fn add_to_diagnostic(self, diag: &mut Diagnostic) {
let start_suggestion = if let Some(abi) = self.abi {
format!("extern \"{}\" {{", abi)
} else {
"extern {".to_owned()
};
let end_suggestion = " }".to_owned();

diag.multipart_suggestion(
fluent::ast_passes::extern_block_suggestion,
vec![(self.start_span, start_suggestion), (self.end_span, end_suggestion)],
Applicability::MaybeIncorrect,
);
}
}
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/lib.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
#![recursion_limit = "256"]

pub mod ast_validation;
mod errors;
pub mod feature_gate;
pub mod node_count;
pub mod show_span;
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/format.rs
Original file line number Diff line number Diff line change
@@ -1176,7 +1176,7 @@ fn create_lints_for_named_arguments_used_positionally(cx: &mut Context<'_, '_>)

cx.ecx.buffered_early_lint.push(BufferedEarlyLint {
span: MultiSpan::from_span(named_arg.positional_named_arg_span),
msg: msg.clone(),
msg: msg.into(),
node_id: ast::CRATE_NODE_ID,
lint_id: LintId::of(&NAMED_ARGUMENTS_USED_POSITIONALLY),
diagnostic: BuiltinLintDiagnostics::NamedArgumentUsedPositionally {
93 changes: 93 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/ast_passes.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
ast_passes_forbidden_let =
`let` expressions are not supported here
.note = only supported directly in conditions of `if` and `while` expressions
.not_supported_or = `||` operators are not supported in let chain expressions
.not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains
ast_passes_deprecated_where_clause_location =
where clause not allowed here
ast_passes_forbidden_assoc_constraint =
associated type bounds are not allowed within structs, enums, or unions
ast_passes_keyword_lifetime =
lifetimes cannot use keyword names
ast_passes_invalid_label =
invalid label name `{$name}`
ast_passes_invalid_visibility =
unnecessary visibility qualifier
.implied = `pub` not permitted here because it's implied
.individual_impl_items = place qualifiers on individual impl items instead
.individual_foreign_items = place qualifiers on individual foreign items instead
ast_passes_trait_fn_async =
functions in traits cannot be declared `async`
.label = `async` because of this
.note = `async` trait functions are not currently supported
.note2 = consider using the `async-trait` crate: https://crates.io/crates/async-trait
ast_passes_trait_fn_const =
functions in traits cannot be declared const
.label = functions in traits cannot be const
ast_passes_forbidden_lifetime_bound =
lifetime bounds cannot be used in this context
ast_passes_forbidden_non_lifetime_param =
only lifetime parameters can be used in this context
ast_passes_fn_param_too_many =
function can not have more than {$max_num_args} arguments
ast_passes_fn_param_c_var_args_only =
C-variadic function must be declared with at least one named argument
ast_passes_fn_param_c_var_args_not_last =
`...` must be the last argument of a C-variadic function
ast_passes_fn_param_doc_comment =
documentation comments cannot be applied to function parameters
.label = doc comments are not allowed here
ast_passes_fn_param_forbidden_attr =
allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters
ast_passes_fn_param_forbidden_self =
`self` parameter is only allowed in associated functions
.label = not semantically valid as function parameter
.note = associated functions are those in `impl` or `trait` definitions
ast_passes_forbidden_default =
`default` is only allowed on items in trait impls
.label = `default` because of this
ast_passes_assoc_const_without_body =
associated constant in `impl` without body
.suggestion = provide a definition for the constant
ast_passes_assoc_fn_without_body =
associated function in `impl` without body
.suggestion = provide a definition for the function
ast_passes_assoc_type_without_body =
associated type in `impl` without body
.suggestion = provide a definition for the type
ast_passes_const_without_body =
free constant item without body
.suggestion = provide a definition for the constant
ast_passes_static_without_body =
free static item without body
.suggestion = provide a definition for the static
ast_passes_ty_alias_without_body =
free type alias without body
.suggestion = provide a definition for the type
ast_passes_fn_without_body =
free function without a body
.suggestion = provide a definition for the function
.extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
1 change: 1 addition & 0 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ pub use unic_langid::{langid, LanguageIdentifier};

// Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module.
fluent_messages! {
ast_passes => "../locales/en-US/ast_passes.ftl",
borrowck => "../locales/en-US/borrowck.ftl",
builtin_macros => "../locales/en-US/builtin_macros.ftl",
const_eval => "../locales/en-US/const_eval.ftl",
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
lint_id.lint,
Some(span),
|lint| {
lint.build(&msg).emit();
lint.build(msg).emit();
},
diagnostic,
);
12 changes: 6 additions & 6 deletions compiler/rustc_lint_defs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ pub use self::Level::*;
use rustc_ast::node_id::{NodeId, NodeMap};
use rustc_ast::{AttrId, Attribute};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_error_messages::MultiSpan;
use rustc_error_messages::{DiagnosticMessage, MultiSpan};
use rustc_hir::HashStableContext;
use rustc_hir::HirId;
use rustc_span::edition::Edition;
@@ -491,7 +491,7 @@ pub struct BufferedEarlyLint {
pub span: MultiSpan,

/// The lint message.
pub msg: String,
pub msg: DiagnosticMessage,

/// The `NodeId` of the AST node that generated the lint.
pub node_id: NodeId,
@@ -520,11 +520,11 @@ impl LintBuffer {
lint: &'static Lint,
node_id: NodeId,
span: MultiSpan,
msg: &str,
msg: impl Into<DiagnosticMessage>,
diagnostic: BuiltinLintDiagnostics,
) {
let lint_id = LintId::of(lint);
let msg = msg.to_string();
let msg = msg.into();
self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, msg, diagnostic });
}

@@ -537,7 +537,7 @@ impl LintBuffer {
lint: &'static Lint,
id: NodeId,
sp: impl Into<MultiSpan>,
msg: &str,
msg: impl Into<DiagnosticMessage>,
) {
self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiagnostics::Normal)
}
@@ -547,7 +547,7 @@ impl LintBuffer {
lint: &'static Lint,
id: NodeId,
sp: impl Into<MultiSpan>,
msg: &str,
msg: impl Into<DiagnosticMessage>,
diagnostic: BuiltinLintDiagnostics,
) {
self.add_lint(lint, id, sp.into(), msg, diagnostic)
59 changes: 32 additions & 27 deletions compiler/rustc_macros/src/diagnostics/utils.rs
Original file line number Diff line number Diff line change
@@ -235,35 +235,40 @@ pub(crate) trait HasFieldMap {
// the referenced fields. Leaves `it` sitting on the closing brace of the format string, so
// the next call to `it.next()` retrieves the next character.
while let Some(c) = it.next() {
if c == '{' && *it.peek().unwrap_or(&'\0') != '{' {
let mut eat_argument = || -> Option<String> {
let mut result = String::new();
// Format specifiers look like:
//
// format := '{' [ argument ] [ ':' format_spec ] '}' .
//
// Therefore, we only need to eat until ':' or '}' to find the argument.
while let Some(c) = it.next() {
result.push(c);
let next = *it.peek().unwrap_or(&'\0');
if next == '}' {
break;
} else if next == ':' {
// Eat the ':' character.
assert_eq!(it.next().unwrap(), ':');
break;
}
}
// Eat until (and including) the matching '}'
while it.next()? != '}' {
continue;
if c != '{' {
continue;
}
if *it.peek().unwrap_or(&'\0') == '{' {
assert_eq!(it.next().unwrap(), '{');
continue;
}
let mut eat_argument = || -> Option<String> {
let mut result = String::new();
// Format specifiers look like:
//
// format := '{' [ argument ] [ ':' format_spec ] '}' .
//
// Therefore, we only need to eat until ':' or '}' to find the argument.
while let Some(c) = it.next() {
result.push(c);
let next = *it.peek().unwrap_or(&'\0');
if next == '}' {
break;
} else if next == ':' {
// Eat the ':' character.
assert_eq!(it.next().unwrap(), ':');
break;
}
Some(result)
};

if let Some(referenced_field) = eat_argument() {
referenced_fields.insert(referenced_field);
}
// Eat until (and including) the matching '}'
while it.next()? != '}' {
continue;
}
Some(result)
};

if let Some(referenced_field) = eat_argument() {
referenced_fields.insert(referenced_field);
}
}

22 changes: 21 additions & 1 deletion compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
@@ -640,7 +640,13 @@ impl<'a> Parser<'a> {
let mut bounds = Vec::new();
let mut negative_bounds = Vec::new();

while self.can_begin_bound() || self.token.is_keyword(kw::Dyn) {
while self.can_begin_bound()
// Continue even if we find a keyword.
// This is necessary for error recover on, for example, `impl fn()`.
//
// The only keyword that can go after generic bounds is `where`, so stop if it's it.
|| (self.token.is_reserved_ident() && !self.token.is_keyword(kw::Where))
{
if self.token.is_keyword(kw::Dyn) {
// Account for `&dyn Trait + dyn Other`.
self.struct_span_err(self.token.span, "invalid `dyn` keyword")
@@ -803,6 +809,20 @@ impl<'a> Parser<'a> {
self.expect_keyword(kw::Const)?;
let span = tilde.to(self.prev_token.span);
self.sess.gated_spans.gate(sym::const_trait_impl, span);
Some(span)
} else if self.eat_keyword(kw::Const) {
let span = self.prev_token.span;
self.sess.gated_spans.gate(sym::const_trait_impl, span);

self.struct_span_err(span, "const bounds must start with `~`")
.span_suggestion(
span.shrink_to_lo(),
"add `~`",
"~",
Applicability::MachineApplicable,
)
.emit();

Some(span)
} else {
None
16 changes: 16 additions & 0 deletions compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
@@ -360,6 +360,17 @@ impl ParseSess {
self.create_warning(warning).emit()
}

pub fn create_fatal<'a>(
&'a self,
fatal: impl SessionDiagnostic<'a, !>,
) -> DiagnosticBuilder<'a, !> {
fatal.into_diagnostic(self)
}

pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) -> ! {
self.create_fatal(fatal).emit()
}

#[rustc_lint_diagnostics]
pub fn struct_err(
&self,
@@ -373,6 +384,11 @@ impl ParseSess {
self.span_diagnostic.struct_warn(msg)
}

#[rustc_lint_diagnostics]
pub fn struct_fatal(&self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'_, !> {
self.span_diagnostic.struct_fatal(msg)
}

#[rustc_lint_diagnostics]
pub fn struct_diagnostic<G: EmissionGuarantee>(
&self,
9 changes: 9 additions & 0 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
@@ -482,6 +482,15 @@ impl Session {
pub fn emit_warning<'a>(&'a self, warning: impl SessionDiagnostic<'a, ()>) {
self.parse_sess.emit_warning(warning)
}
pub fn create_fatal<'a>(
&'a self,
fatal: impl SessionDiagnostic<'a, !>,
) -> DiagnosticBuilder<'a, !> {
self.parse_sess.create_fatal(fatal)
}
pub fn emit_fatal<'a>(&'a self, fatal: impl SessionDiagnostic<'a, !>) -> ! {
self.parse_sess.emit_fatal(fatal)
}
#[inline]
pub fn err_count(&self) -> usize {
self.diagnostic().err_count()
12 changes: 12 additions & 0 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
@@ -554,6 +554,18 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
.flatten()
.unwrap_or_else(|| ty::Term::Ty(ty.super_fold_with(self)))
};
// For cases like #95134 we would like to catch overflows early
// otherwise they slip away away and cause ICE.
let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
let obligation = Obligation::with_depth(
self.cause.clone(),
recursion_limit.0,
self.param_env,
ty,
);
self.selcx.infcx().report_overflow_error(&obligation, true);
}
debug!(
?self.depth,
?ty,
2 changes: 1 addition & 1 deletion library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! A pointer type for heap allocation.
//! The `Box<T>` type for heap allocation.
//!
//! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
//! heap allocation in Rust. Boxes provide ownership for this allocation, and
80 changes: 5 additions & 75 deletions library/alloc/src/slice.rs
Original file line number Diff line number Diff line change
@@ -1,82 +1,12 @@
//! A dynamically-sized view into a contiguous sequence, `[T]`.
//! Utilities for the slice primitive type.
//!
//! *[See also the slice primitive type](slice).*
//!
//! Slices are a view into a block of memory represented as a pointer and a
//! length.
//! Most of the structs in this module are iterator types which can only be created
//! using a certain function. For example, `slice.iter()` yields an [`Iter`].
//!
//! ```
//! // slicing a Vec
//! let vec = vec![1, 2, 3];
//! let int_slice = &vec[..];
//! // coercing an array to a slice
//! let str_slice: &[&str] = &["one", "two", "three"];
//! ```
//!
//! Slices are either mutable or shared. The shared slice type is `&[T]`,
//! while the mutable slice type is `&mut [T]`, where `T` represents the element
//! type. For example, you can mutate the block of memory that a mutable slice
//! points to:
//!
//! ```
//! let x = &mut [1, 2, 3];
//! x[1] = 7;
//! assert_eq!(x, &[1, 7, 3]);
//! ```
//!
//! Here are some of the things this module contains:
//!
//! ## Structs
//!
//! There are several structs that are useful for slices, such as [`Iter`], which
//! represents iteration over a slice.
//!
//! ## Trait Implementations
//!
//! There are several implementations of common traits for slices. Some examples
//! include:
//!
//! * [`Clone`]
//! * [`Eq`], [`Ord`] - for slices whose element type are [`Eq`] or [`Ord`].
//! * [`Hash`] - for slices whose element type is [`Hash`].
//!
//! ## Iteration
//!
//! The slices implement `IntoIterator`. The iterator yields references to the
//! slice elements.
//!
//! ```
//! let numbers = &[0, 1, 2];
//! for n in numbers {
//! println!("{n} is a number!");
//! }
//! ```
//!
//! The mutable slice yields mutable references to the elements:
//!
//! ```
//! let mut scores = [7, 8, 9];
//! for score in &mut scores[..] {
//! *score += 1;
//! }
//! ```
//!
//! This iterator yields mutable references to the slice's elements, so while
//! the element type of the slice is `i32`, the element type of the iterator is
//! `&mut i32`.
//!
//! * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default
//! iterators.
//! * Further methods that return iterators are [`.split`], [`.splitn`],
//! [`.chunks`], [`.windows`] and more.
//!
//! [`Hash`]: core::hash::Hash
//! [`.iter`]: slice::iter
//! [`.iter_mut`]: slice::iter_mut
//! [`.split`]: slice::split
//! [`.splitn`]: slice::splitn
//! [`.chunks`]: slice::chunks
//! [`.windows`]: slice::windows
//! A few functions are provided to create a slice from a value reference
//! or from a raw pointer.
#![stable(feature = "rust1", since = "1.0.0")]
// Many of the usings in this module are only used in the test configuration.
// It's cleaner to just turn off the unused_imports warning than to fix them.
22 changes: 1 addition & 21 deletions library/alloc/src/str.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,6 @@
//! Unicode string slices.
//! Utilities for the `str` primitive type.
//!
//! *[See also the `str` primitive type](str).*
//!
//! The `&str` type is one of the two main string types, the other being `String`.
//! Unlike its `String` counterpart, its contents are borrowed.
//!
//! # Basic Usage
//!
//! A basic string declaration of `&str` type:
//!
//! ```
//! let hello_world = "Hello, World!";
//! ```
//!
//! Here we have declared a string literal, also known as a string slice.
//! String literals have a static lifetime, which means the string `hello_world`
//! is guaranteed to be valid for the duration of the entire program.
//! We can explicitly specify `hello_world`'s lifetime as well:
//!
//! ```
//! let hello_world: &'static str = "Hello, world!";
//! ```
#![stable(feature = "rust1", since = "1.0.0")]
// Many of the usings in this module are only used in the test configuration.
45 changes: 45 additions & 0 deletions library/alloc/tests/vec.rs
Original file line number Diff line number Diff line change
@@ -293,6 +293,22 @@ fn test_retain() {
assert_eq!(vec, [2, 4]);
}

#[test]
fn test_retain_predicate_order() {
for to_keep in [true, false] {
let mut number_of_executions = 0;
let mut vec = vec![1, 2, 3, 4];
let mut next_expected = 1;
vec.retain(|&x| {
assert_eq!(next_expected, x);
next_expected += 1;
number_of_executions += 1;
to_keep
});
assert_eq!(number_of_executions, 4);
}
}

#[test]
fn test_retain_pred_panic_with_hole() {
let v = (0..5).map(Rc::new).collect::<Vec<_>>();
@@ -354,6 +370,35 @@ fn test_retain_drop_panic() {
assert!(v.iter().all(|r| Rc::strong_count(r) == 1));
}

#[test]
fn test_retain_maybeuninits() {
// This test aimed to be run under miri.
use core::mem::MaybeUninit;
let mut vec: Vec<_> = [1i32, 2, 3, 4].map(|v| MaybeUninit::new(vec![v])).into();
vec.retain(|x| {
// SAFETY: Retain must visit every element of Vec in original order and exactly once.
// Our values is initialized at creation of Vec.
let v = unsafe { x.assume_init_ref()[0] };
if v & 1 == 0 {
return true;
}
// SAFETY: Value is initialized.
// Value wouldn't be dropped by `Vec::retain`
// because `MaybeUninit` doesn't drop content.
drop(unsafe { x.assume_init_read() });
false
});
let vec: Vec<i32> = vec
.into_iter()
.map(|x| unsafe {
// SAFETY: All values dropped in retain predicate must be removed by `Vec::retain`.
// Remaining values are initialized.
x.assume_init()[0]
})
.collect();
assert_eq!(vec, [2, 4]);
}

#[test]
fn test_dedup() {
fn case(a: Vec<i32>, b: Vec<i32>) {
5 changes: 1 addition & 4 deletions library/core/src/any.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
//! This module contains the `Any` trait, which enables dynamic typing
//! of any `'static` type through runtime reflection. It also contains the
//! `Provider` trait and accompanying API, which enable trait objects to provide
//! data based on typed requests, an alternate form of runtime reflection.
//! Utilities for dynamic typing or type reflection.
//!
//! # `Any` and `TypeId`
//!
2 changes: 1 addition & 1 deletion library/core/src/array/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Helper functions and types for fixed-length arrays.
//! Utilities for the array primitive type.
//!
//! *[See also the array primitive type](array).*
2 changes: 1 addition & 1 deletion library/core/src/borrow.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! A module for working with borrowed data.
//! Utilities for working with borrowed data.
#![stable(feature = "rust1", since = "1.0.0")]

4 changes: 3 additions & 1 deletion library/core/src/char/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! A character type.
//! Utilities for the `char` primitive type.
//!
//! *[See also the `char` primitive type](primitive@char).*
//!
//! The `char` type represents a single character. More specifically, since
//! 'character' isn't a well-defined concept in Unicode, `char` is a '[Unicode
4 changes: 2 additions & 2 deletions library/core/src/cmp.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Functionality for ordering and comparison.
//! Utilities for comparing and ordering values.
//!
//! This module contains various tools for ordering and comparing values. In
//! This module contains various tools for comparing and ordering values. In
//! summary:
//!
//! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and
2 changes: 1 addition & 1 deletion library/core/src/default.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! The `Default` trait for types which may have meaningful default values.
//! The `Default` trait for types with a default value.
#![stable(feature = "rust1", since = "1.0.0")]

2 changes: 1 addition & 1 deletion library/core/src/num/f32.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Constants specific to the `f32` single-precision floating point type.
//! Constants for the `f32` single-precision floating point type.
//!
//! *[See also the `f32` primitive type][f32].*
//!
2 changes: 1 addition & 1 deletion library/core/src/num/f64.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Constants specific to the `f64` double-precision floating point type.
//! Constants for the `f64` double-precision floating point type.
//!
//! *[See also the `f64` primitive type][f64].*
//!
61 changes: 53 additions & 8 deletions library/core/src/primitive_docs.rs
Original file line number Diff line number Diff line change
@@ -801,11 +801,53 @@ mod prim_array {}
/// assert_eq!(2 * pointer_size, std::mem::size_of::<Box<[u8]>>());
/// assert_eq!(2 * pointer_size, std::mem::size_of::<Rc<[u8]>>());
/// ```
///
/// ## Trait Implementations
///
/// Some traits are implemented for slices if the element type implements
/// that trait. This includes [`Eq`], [`Hash`] and [`Ord`].
///
/// ## Iteration
///
/// The slices implement `IntoIterator`. The iterator yields references to the
/// slice elements.
///
/// ```
/// let numbers: &[i32] = &[0, 1, 2];
/// for n in numbers {
/// println!("{n} is a number!");
/// }
/// ```
///
/// The mutable slice yields mutable references to the elements:
///
/// ```
/// let mut scores: &mut [i32] = &mut [7, 8, 9];
/// for score in scores {
/// *score += 1;
/// }
/// ```
///
/// This iterator yields mutable references to the slice's elements, so while
/// the element type of the slice is `i32`, the element type of the iterator is
/// `&mut i32`.
///
/// * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default
/// iterators.
/// * Further methods that return iterators are [`.split`], [`.splitn`],
/// [`.chunks`], [`.windows`] and more.
///
/// [`Hash`]: core::hash::Hash
/// [`.iter`]: slice::iter
/// [`.iter_mut`]: slice::iter_mut
/// [`.split`]: slice::split
/// [`.splitn`]: slice::splitn
/// [`.chunks`]: slice::chunks
/// [`.windows`]: slice::windows
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_slice {}

#[doc(primitive = "str")]
//
/// String slices.
///
/// *[See also the `std::str` module](crate::str).*
@@ -816,19 +858,22 @@ mod prim_slice {}
///
/// String slices are always valid UTF-8.
///
/// # Examples
/// # Basic Usage
///
/// String literals are string slices:
///
/// ```
/// let hello = "Hello, world!";
///
/// // with an explicit type annotation
/// let hello: &'static str = "Hello, world!";
/// let hello_world = "Hello, World!";
/// ```
///
/// They are `'static` because they're stored directly in the final binary, and
/// so will be valid for the `'static` duration.
/// Here we have declared a string slice initialized with a string literal.
/// String literals have a static lifetime, which means the string `hello_world`
/// is guaranteed to be valid for the duration of the entire program.
/// We can explicitly specify `hello_world`'s lifetime as well:
///
/// ```
/// let hello_world: &'static str = "Hello, world!";
/// ```
///
/// # Representation
///
2 changes: 1 addition & 1 deletion library/std/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Interfaces for working with Errors.
//! The `Error` trait provides common functionality for errors.
//!
//! # Error Handling In Rust
//!
2 changes: 1 addition & 1 deletion library/std/src/f32.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Constants specific to the `f32` single-precision floating point type.
//! Constants for the `f32` single-precision floating point type.
//!
//! *[See also the `f32` primitive type](primitive@f32).*
//!
2 changes: 1 addition & 1 deletion library/std/src/f64.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Constants specific to the `f64` double-precision floating point type.
//! Constants for the `f64` double-precision floating point type.
//!
//! *[See also the `f64` primitive type](primitive@f64).*
//!
61 changes: 53 additions & 8 deletions library/std/src/primitive_docs.rs
Original file line number Diff line number Diff line change
@@ -801,11 +801,53 @@ mod prim_array {}
/// assert_eq!(2 * pointer_size, std::mem::size_of::<Box<[u8]>>());
/// assert_eq!(2 * pointer_size, std::mem::size_of::<Rc<[u8]>>());
/// ```
///
/// ## Trait Implementations
///
/// Some traits are implemented for slices if the element type implements
/// that trait. This includes [`Eq`], [`Hash`] and [`Ord`].
///
/// ## Iteration
///
/// The slices implement `IntoIterator`. The iterator yields references to the
/// slice elements.
///
/// ```
/// let numbers: &[i32] = &[0, 1, 2];
/// for n in numbers {
/// println!("{n} is a number!");
/// }
/// ```
///
/// The mutable slice yields mutable references to the elements:
///
/// ```
/// let mut scores: &mut [i32] = &mut [7, 8, 9];
/// for score in scores {
/// *score += 1;
/// }
/// ```
///
/// This iterator yields mutable references to the slice's elements, so while
/// the element type of the slice is `i32`, the element type of the iterator is
/// `&mut i32`.
///
/// * [`.iter`] and [`.iter_mut`] are the explicit methods to return the default
/// iterators.
/// * Further methods that return iterators are [`.split`], [`.splitn`],
/// [`.chunks`], [`.windows`] and more.
///
/// [`Hash`]: core::hash::Hash
/// [`.iter`]: slice::iter
/// [`.iter_mut`]: slice::iter_mut
/// [`.split`]: slice::split
/// [`.splitn`]: slice::splitn
/// [`.chunks`]: slice::chunks
/// [`.windows`]: slice::windows
#[stable(feature = "rust1", since = "1.0.0")]
mod prim_slice {}

#[doc(primitive = "str")]
//
/// String slices.
///
/// *[See also the `std::str` module](crate::str).*
@@ -816,19 +858,22 @@ mod prim_slice {}
///
/// String slices are always valid UTF-8.
///
/// # Examples
/// # Basic Usage
///
/// String literals are string slices:
///
/// ```
/// let hello = "Hello, world!";
///
/// // with an explicit type annotation
/// let hello: &'static str = "Hello, world!";
/// let hello_world = "Hello, World!";
/// ```
///
/// They are `'static` because they're stored directly in the final binary, and
/// so will be valid for the `'static` duration.
/// Here we have declared a string slice initialized with a string literal.
/// String literals have a static lifetime, which means the string `hello_world`
/// is guaranteed to be valid for the duration of the entire program.
/// We can explicitly specify `hello_world`'s lifetime as well:
///
/// ```
/// let hello_world: &'static str = "Hello, world!";
/// ```
///
/// # Representation
///
7 changes: 1 addition & 6 deletions src/test/ui/issues/issue-23122-2.stderr
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
error[E0275]: overflow evaluating the requirement `<T as Next>::Next`
--> $DIR/issue-23122-2.rs:10:17
|
LL | type Next = <GetNext<T::Next> as Next>::Next;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`)
note: required for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next`
--> $DIR/issue-23122-2.rs:9:15
|
LL | impl<T: Next> Next for GetNext<T> {
| ^^^^ ^^^^^^^^^^

error: aborting due to previous error

47 changes: 47 additions & 0 deletions src/test/ui/parser/kw-in-trait-bounds.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// edition:2018

fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
//~^ ERROR expected identifier, found keyword `fn`
//~| ERROR expected identifier, found keyword `fn`
//~| ERROR expected identifier, found keyword `fn`
//~| ERROR cannot find trait `r#fn` in this scope
//~| ERROR cannot find trait `r#fn` in this scope
//~| ERROR cannot find trait `r#fn` in this scope
//~| HELP a trait with a similar name exists
//~| HELP a trait with a similar name exists
//~| HELP a trait with a similar name exists
//~| HELP escape `fn` to use it as an identifier
//~| HELP escape `fn` to use it as an identifier
//~| HELP escape `fn` to use it as an identifier
where
G: fn(),
//~^ ERROR expected identifier, found keyword `fn`
//~| ERROR cannot find trait `r#fn` in this scope
//~| HELP a trait with a similar name exists
//~| HELP escape `fn` to use it as an identifier
{}

fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
//~^ ERROR expected identifier, found keyword `struct`
//~| ERROR expected identifier, found keyword `struct`
//~| ERROR expected identifier, found keyword `struct`
//~| ERROR cannot find trait `r#struct` in this scope
//~| ERROR cannot find trait `r#struct` in this scope
//~| ERROR cannot find trait `r#struct` in this scope
//~| HELP a trait with a similar name exists
//~| HELP a trait with a similar name exists
//~| HELP a trait with a similar name exists
//~| HELP escape `struct` to use it as an identifier
//~| HELP escape `struct` to use it as an identifier
//~| HELP escape `struct` to use it as an identifier
where
B: struct,
//~^ ERROR expected identifier, found keyword `struct`
//~| ERROR cannot find trait `r#struct` in this scope
//~| HELP a trait with a similar name exists
//~| HELP escape `struct` to use it as an identifier
{}

trait Struct {}

fn main() {}
171 changes: 171 additions & 0 deletions src/test/ui/parser/kw-in-trait-bounds.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
error: expected identifier, found keyword `fn`
--> $DIR/kw-in-trait-bounds.rs:3:10
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
| ^^ expected identifier, found keyword
|
help: escape `fn` to use it as an identifier
|
LL | fn _f<F: r#fn(), G>(_: impl fn(), _: &dyn fn())
| ++

error: expected identifier, found keyword `fn`
--> $DIR/kw-in-trait-bounds.rs:3:27
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
| ^^ expected identifier, found keyword
|
help: escape `fn` to use it as an identifier
|
LL | fn _f<F: fn(), G>(_: impl r#fn(), _: &dyn fn())
| ++

error: expected identifier, found keyword `fn`
--> $DIR/kw-in-trait-bounds.rs:3:41
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
| ^^ expected identifier, found keyword
|
help: escape `fn` to use it as an identifier
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn r#fn())
| ++

error: expected identifier, found keyword `fn`
--> $DIR/kw-in-trait-bounds.rs:17:4
|
LL | G: fn(),
| ^^ expected identifier, found keyword
|
help: escape `fn` to use it as an identifier
|
LL | G: r#fn(),
| ++

error: expected identifier, found keyword `struct`
--> $DIR/kw-in-trait-bounds.rs:24:10
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
| ^^^^^^ expected identifier, found keyword
|
help: escape `struct` to use it as an identifier
|
LL | fn _g<A: r#struct, B>(_: impl struct, _: &dyn struct)
| ++

error: expected identifier, found keyword `struct`
--> $DIR/kw-in-trait-bounds.rs:24:29
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
| ^^^^^^ expected identifier, found keyword
|
help: escape `struct` to use it as an identifier
|
LL | fn _g<A: struct, B>(_: impl r#struct, _: &dyn struct)
| ++

error: expected identifier, found keyword `struct`
--> $DIR/kw-in-trait-bounds.rs:24:45
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
| ^^^^^^ expected identifier, found keyword
|
help: escape `struct` to use it as an identifier
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn r#struct)
| ++

error: expected identifier, found keyword `struct`
--> $DIR/kw-in-trait-bounds.rs:38:8
|
LL | B: struct,
| ^^^^^^ expected identifier, found keyword
|
help: escape `struct` to use it as an identifier
|
LL | B: r#struct,
| ++

error[E0405]: cannot find trait `r#fn` in this scope
--> $DIR/kw-in-trait-bounds.rs:3:10
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
LL | pub trait Fn<Args>: FnMut<Args> {
| ------------------------------- similarly named trait `Fn` defined here

error[E0405]: cannot find trait `r#fn` in this scope
--> $DIR/kw-in-trait-bounds.rs:17:4
|
LL | G: fn(),
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
LL | pub trait Fn<Args>: FnMut<Args> {
| ------------------------------- similarly named trait `Fn` defined here

error[E0405]: cannot find trait `r#fn` in this scope
--> $DIR/kw-in-trait-bounds.rs:3:27
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
LL | pub trait Fn<Args>: FnMut<Args> {
| ------------------------------- similarly named trait `Fn` defined here

error[E0405]: cannot find trait `r#fn` in this scope
--> $DIR/kw-in-trait-bounds.rs:3:41
|
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
::: $SRC_DIR/core/src/ops/function.rs:LL:COL
|
LL | pub trait Fn<Args>: FnMut<Args> {
| ------------------------------- similarly named trait `Fn` defined here

error[E0405]: cannot find trait `r#struct` in this scope
--> $DIR/kw-in-trait-bounds.rs:24:10
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
...
LL | trait Struct {}
| ------------ similarly named trait `Struct` defined here

error[E0405]: cannot find trait `r#struct` in this scope
--> $DIR/kw-in-trait-bounds.rs:38:8
|
LL | B: struct,
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
...
LL | trait Struct {}
| ------------ similarly named trait `Struct` defined here

error[E0405]: cannot find trait `r#struct` in this scope
--> $DIR/kw-in-trait-bounds.rs:24:29
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
...
LL | trait Struct {}
| ------------ similarly named trait `Struct` defined here

error[E0405]: cannot find trait `r#struct` in this scope
--> $DIR/kw-in-trait-bounds.rs:24:45
|
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
...
LL | trait Struct {}
| ------------ similarly named trait `Struct` defined here

error: aborting due to 16 previous errors

For more information about this error, try `rustc --explain E0405`.
4 changes: 3 additions & 1 deletion src/test/ui/recursion/issue-83150.stderr
Original file line number Diff line number Diff line change
@@ -9,9 +9,11 @@ LL | func(&mut iter.map(|x| x + 1))
= note: `#[warn(unconditional_recursion)]` on by default
= help: a `loop` may express intention better if this is on purpose

error[E0275]: overflow evaluating the requirement `Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>: Iterator`
error[E0275]: overflow evaluating the requirement `<std::ops::Range<u8> as Iterator>::Item`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
= note: required for `Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`
= note: 64 redundant requirements hidden
= note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>, [closure@$DIR/issue-83150.rs:11:24: 11:27]>` to implement `Iterator`

error: aborting due to previous error; 1 warning emitted
28 changes: 28 additions & 0 deletions src/test/ui/recursion/issue-95134.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// build-fail
// compile-flags: -Copt-level=0
//~^^ ERROR overflow evaluating the requirement

pub fn encode_num<Writer: ExampleWriter>(n: u32, mut writer: Writer) -> Result<(), Writer::Error> {
if n > 15 {
encode_num(n / 16, &mut writer)?;
}
Ok(())
}

pub trait ExampleWriter {
type Error;
}

impl<'a, T: ExampleWriter> ExampleWriter for &'a mut T {
type Error = T::Error;
}

struct EmptyWriter;

impl ExampleWriter for EmptyWriter {
type Error = ();
}

fn main() {
encode_num(69, &mut EmptyWriter).unwrap();
}
7 changes: 7 additions & 0 deletions src/test/ui/recursion/issue-95134.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error[E0275]: overflow evaluating the requirement `<EmptyWriter as ExampleWriter>::Error`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_95134`)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0275`.
2 changes: 1 addition & 1 deletion src/test/ui/rfc-2632-const-trait-impl/without-tilde.rs
Original file line number Diff line number Diff line change
@@ -3,4 +3,4 @@
#![feature(const_trait_impl)]

struct S<T: const Tr>;
//~^ ERROR expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, `~`, lifetime, or path
//~^ ERROR const bounds must start with `~`
6 changes: 4 additions & 2 deletions src/test/ui/rfc-2632-const-trait-impl/without-tilde.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error: expected one of `!`, `(`, `,`, `=`, `>`, `?`, `for`, `~`, lifetime, or path, found keyword `const`
error: const bounds must start with `~`
--> $DIR/without-tilde.rs:5:13
|
LL | struct S<T: const Tr>;
| ^^^^^ expected one of 10 possible tokens
| -^^^^
| |
| help: add `~`: `~`

error: aborting due to previous error