Auto merge of #110852 - matthiaskrgr:rollup-jz3eosr, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #108760 (Add lint to deny diagnostics composed of static strings) - #109444 (Change tidy error message for TODOs) - #110419 (Spelling library) - #110550 (Suggest deref on comparison binop RHS even if type is not Copy) - #110641 (Add new rustdoc book chapter to describe in-doc settings) - #110798 (pass `unused_extern_crates` in `librustdoc::doctest::make_test`) - #110819 (simplify TrustedLen impls) - #110825 (diagnostics: add test case for already-solved issue) - #110835 (Make some region folders a little stricter.) - #110847 (rustdoc-json: Time serialization.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
1c42cb4ef0
@ -149,6 +149,25 @@ builtin_macros_format_pos_mismatch = {$n} positional {$n ->
|
||||
[one] argument
|
||||
*[more] arguments
|
||||
} in format string, but {$desc}
|
||||
|
||||
builtin_macros_offset_of_expected_field = expected field
|
||||
|
||||
builtin_macros_offset_of_expected_two_args = expected 2 arguments
|
||||
|
||||
builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on items
|
||||
|
||||
builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
|
||||
.label = `{$kind}` because of this
|
||||
|
||||
builtin_macros_asm_explicit_register_name = explicit register arguments cannot have names
|
||||
|
||||
builtin_macros_asm_mutually_exclusive = the `{$opt1}` and `{$opt2}` options are mutually exclusive
|
||||
|
||||
builtin_macros_asm_pure_combine = the `pure` option must be combined with either `nomem` or `readonly`
|
||||
|
||||
builtin_macros_asm_pure_no_output = asm with the `pure` option must have at least one output
|
||||
|
||||
builtin_macros_asm_modifier_invalid = asm template modifier must be a single character
|
||||
|
||||
builtin_macros_test_runner_invalid = `test_runner` argument must be a path
|
||||
builtin_macros_test_runner_nargs = `#![test_runner(..)]` accepts exactly 1 argument
|
||||
|
@ -15,6 +15,8 @@ use rustc_span::{InnerSpan, Span};
|
||||
use rustc_target::asm::InlineAsmArch;
|
||||
use smallvec::smallvec;
|
||||
|
||||
use crate::errors;
|
||||
|
||||
pub struct AsmArgs {
|
||||
pub templates: Vec<P<ast::Expr>>,
|
||||
pub operands: Vec<(ast::InlineAsmOperand, Span)>,
|
||||
@ -205,7 +207,7 @@ pub fn parse_asm_args<'a>(
|
||||
// of the argument available.
|
||||
if explicit_reg {
|
||||
if name.is_some() {
|
||||
diag.struct_span_err(span, "explicit register arguments cannot have names").emit();
|
||||
diag.emit_err(errors::AsmExplicitRegisterName { span });
|
||||
}
|
||||
args.reg_args.insert(slot);
|
||||
} else if let Some(name) = name {
|
||||
@ -240,25 +242,19 @@ pub fn parse_asm_args<'a>(
|
||||
&& args.options.contains(ast::InlineAsmOptions::READONLY)
|
||||
{
|
||||
let spans = args.options_spans.clone();
|
||||
diag.struct_span_err(spans, "the `nomem` and `readonly` options are mutually exclusive")
|
||||
.emit();
|
||||
diag.emit_err(errors::AsmMutuallyExclusive { spans, opt1: "nomem", opt2: "readonly" });
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::PURE)
|
||||
&& args.options.contains(ast::InlineAsmOptions::NORETURN)
|
||||
{
|
||||
let spans = args.options_spans.clone();
|
||||
diag.struct_span_err(spans, "the `pure` and `noreturn` options are mutually exclusive")
|
||||
.emit();
|
||||
diag.emit_err(errors::AsmMutuallyExclusive { spans, opt1: "pure", opt2: "noreturn" });
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::PURE)
|
||||
&& !args.options.intersects(ast::InlineAsmOptions::NOMEM | ast::InlineAsmOptions::READONLY)
|
||||
{
|
||||
let spans = args.options_spans.clone();
|
||||
diag.struct_span_err(
|
||||
spans,
|
||||
"the `pure` option must be combined with either `nomem` or `readonly`",
|
||||
)
|
||||
.emit();
|
||||
diag.emit_err(errors::AsmPureCombine { spans });
|
||||
}
|
||||
|
||||
let mut have_real_output = false;
|
||||
@ -285,11 +281,7 @@ pub fn parse_asm_args<'a>(
|
||||
}
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::PURE) && !have_real_output {
|
||||
diag.struct_span_err(
|
||||
args.options_spans.clone(),
|
||||
"asm with the `pure` option must have at least one output",
|
||||
)
|
||||
.emit();
|
||||
diag.emit_err(errors::AsmPureNoOutput { spans: args.options_spans.clone() });
|
||||
}
|
||||
if args.options.contains(ast::InlineAsmOptions::NORETURN) && !outputs_sp.is_empty() {
|
||||
let err = diag
|
||||
@ -705,11 +697,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
|
||||
.ty_span
|
||||
.map(|sp| template_sp.from_inner(InnerSpan::new(sp.start, sp.end)))
|
||||
.unwrap_or(template_sp);
|
||||
ecx.struct_span_err(
|
||||
span,
|
||||
"asm template modifier must be a single character",
|
||||
)
|
||||
.emit();
|
||||
ecx.emit_err(errors::AsmModifierInvalid { span });
|
||||
modifier = None;
|
||||
}
|
||||
|
||||
|
@ -551,3 +551,71 @@ pub(crate) struct FormatPositionalMismatch {
|
||||
#[subdiagnostic]
|
||||
pub(crate) highlight: SingleLabelManySpans,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_test_case_non_item)]
|
||||
pub(crate) struct TestCaseNonItem {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_test_bad_fn)]
|
||||
pub(crate) struct TestBadFn {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
#[label]
|
||||
pub(crate) cause: Span,
|
||||
pub(crate) kind: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_asm_explicit_register_name)]
|
||||
pub(crate) struct AsmExplicitRegisterName {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_asm_mutually_exclusive)]
|
||||
pub(crate) struct AsmMutuallyExclusive {
|
||||
#[primary_span]
|
||||
pub(crate) spans: Vec<Span>,
|
||||
pub(crate) opt1: &'static str,
|
||||
pub(crate) opt2: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_asm_pure_combine)]
|
||||
pub(crate) struct AsmPureCombine {
|
||||
#[primary_span]
|
||||
pub(crate) spans: Vec<Span>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_asm_pure_no_output)]
|
||||
pub(crate) struct AsmPureNoOutput {
|
||||
#[primary_span]
|
||||
pub(crate) spans: Vec<Span>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_asm_modifier_invalid)]
|
||||
pub(crate) struct AsmModifierInvalid {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_test_runner_invalid)]
|
||||
pub(crate) struct TestRunnerInvalid {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(builtin_macros_test_runner_nargs)]
|
||||
pub(crate) struct TestRunnerNargs {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::errors;
|
||||
/// The expansion from a test function to the appropriate test struct for libtest
|
||||
/// Ideally, this code would be in libtest but for efficiency and error messages it lives here.
|
||||
use crate::util::{check_builtin_macro_attribute, warn_on_duplicate_attribute};
|
||||
@ -40,12 +41,7 @@ pub fn expand_test_case(
|
||||
unreachable!()
|
||||
},
|
||||
_ => {
|
||||
ecx.struct_span_err(
|
||||
anno_item.span(),
|
||||
"`#[test_case]` attribute is only allowed on items",
|
||||
)
|
||||
.emit();
|
||||
|
||||
ecx.emit_err(errors::TestCaseNonItem { span: anno_item.span() });
|
||||
return vec![];
|
||||
}
|
||||
};
|
||||
@ -533,15 +529,11 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
|
||||
match &i.kind {
|
||||
ast::ItemKind::Fn(box ast::Fn { sig, generics, .. }) => {
|
||||
if let ast::Unsafe::Yes(span) = sig.header.unsafety {
|
||||
sd.struct_span_err(i.span, "unsafe functions cannot be used for tests")
|
||||
.span_label(span, "`unsafe` because of this")
|
||||
.emit();
|
||||
sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "unsafe" });
|
||||
return false;
|
||||
}
|
||||
if let ast::Async::Yes { span, .. } = sig.header.asyncness {
|
||||
sd.struct_span_err(i.span, "async functions cannot be used for tests")
|
||||
.span_label(span, "`async` because of this")
|
||||
.emit();
|
||||
sd.emit_err(errors::TestBadFn { span: i.span, cause: span, kind: "async" });
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@ use tracing::debug;
|
||||
|
||||
use std::{iter, mem};
|
||||
|
||||
use crate::errors;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Test {
|
||||
span: Span,
|
||||
@ -385,11 +387,11 @@ fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option<ast
|
||||
[single] => match single.meta_item() {
|
||||
Some(meta_item) if meta_item.is_word() => return Some(meta_item.path.clone()),
|
||||
_ => {
|
||||
sd.struct_span_err(span, "`test_runner` argument must be a path").emit();
|
||||
sd.emit_err(errors::TestRunnerInvalid { span });
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
sd.struct_span_err(span, "`#![test_runner(..)]` accepts exactly 1 argument").emit();
|
||||
sd.emit_err(errors::TestRunnerNargs { span });
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -291,3 +291,16 @@ codegen_ssa_invalid_monomorphization_unsupported_cast = invalid monomorphization
|
||||
codegen_ssa_invalid_monomorphization_unsupported_operation = invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}`
|
||||
|
||||
codegen_ssa_invalid_monomorphization_expected_vector_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of vector type `{$vector_type}` to be a signed or unsigned integer type
|
||||
|
||||
codegen_ssa_invalid_no_sanitize = invalid argument for `no_sanitize`
|
||||
.note = expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`
|
||||
|
||||
codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]`
|
||||
.note = the attribute requires exactly one argument
|
||||
|
||||
codegen_ssa_illegal_link_ordinal_format = illegal ordinal format in `link_ordinal`
|
||||
.note = an unsuffixed integer value, e.g., `1`, is expected
|
||||
|
||||
codegen_ssa_target_feature_safe_trait = `#[target_feature(..)]` cannot be applied to safe trait method
|
||||
.label = cannot be applied to safe trait method
|
||||
.label_def = not an `unsafe` function
|
||||
|
@ -14,6 +14,7 @@ use rustc_span::symbol::Ident;
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_target::spec::{abi, SanitizerSet};
|
||||
|
||||
use crate::errors;
|
||||
use crate::target_features::from_target_feature;
|
||||
use crate::{errors::ExpectedUsedSymbol, target_features::check_target_feature_trait_unsafe};
|
||||
|
||||
@ -334,10 +335,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
||||
codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS
|
||||
}
|
||||
_ => {
|
||||
tcx.sess
|
||||
.struct_span_err(item.span(), "invalid argument for `no_sanitize`")
|
||||
.note("expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`")
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::InvalidNoSanitize { span: item.span() });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -608,10 +606,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
|
||||
let sole_meta_list = match meta_item_list {
|
||||
Some([item]) => item.lit(),
|
||||
Some(_) => {
|
||||
tcx.sess
|
||||
.struct_span_err(attr.span, "incorrect number of arguments to `#[link_ordinal]`")
|
||||
.note("the attribute requires exactly one argument")
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span });
|
||||
return None;
|
||||
}
|
||||
_ => None,
|
||||
@ -642,10 +637,7 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
tcx.sess
|
||||
.struct_span_err(attr.span, "illegal ordinal format in `link_ordinal`")
|
||||
.note("an unsuffixed integer value, e.g., `1`, is expected")
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::InvalidLinkOrdinalFormat { span: attr.span });
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -981,3 +981,37 @@ impl IntoDiagnosticArg for ExpectedPointerMutability {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_invalid_no_sanitize)]
|
||||
#[note]
|
||||
pub struct InvalidNoSanitize {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_invalid_link_ordinal_nargs)]
|
||||
#[note]
|
||||
pub struct InvalidLinkOrdinalNargs {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_illegal_link_ordinal_format)]
|
||||
#[note]
|
||||
pub struct InvalidLinkOrdinalFormat {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(codegen_ssa_target_feature_safe_trait)]
|
||||
pub struct TargetFeatureSafeTrait {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(codegen_ssa_label_def)]
|
||||
pub def: Span,
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::errors;
|
||||
use rustc_ast::ast;
|
||||
use rustc_attr::InstructionSetAttr;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
@ -443,14 +444,10 @@ pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_s
|
||||
if let DefKind::AssocFn = tcx.def_kind(id) {
|
||||
let parent_id = tcx.local_parent(id);
|
||||
if let DefKind::Trait | DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) {
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
attr_span,
|
||||
"`#[target_feature(..)]` cannot be applied to safe trait method",
|
||||
)
|
||||
.span_label(attr_span, "cannot be applied to safe trait method")
|
||||
.span_label(tcx.def_span(id), "not an `unsafe` function")
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::TargetFeatureSafeTrait {
|
||||
span: attr_span,
|
||||
def: tcx.def_span(id),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,3 +136,7 @@ expand_proc_macro_panicked =
|
||||
|
||||
expand_proc_macro_derive_tokens =
|
||||
proc-macro derive produced unparsable tokens
|
||||
|
||||
expand_duplicate_matcher_binding = duplicate matcher binding
|
||||
.label = duplicate binding
|
||||
.label2 = previous binding
|
||||
|
@ -397,3 +397,13 @@ pub struct ProcMacroDeriveTokens {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(expand_duplicate_matcher_binding)]
|
||||
pub struct DuplicateMatcherBinding {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(expand_label2)]
|
||||
pub prev: Span,
|
||||
}
|
||||
|
@ -104,6 +104,7 @@
|
||||
//! Kleene operators under which a meta-variable is repeating is the concatenation of the stacks
|
||||
//! stored when entering a macro definition starting from the state in which the meta-variable is
|
||||
//! bound.
|
||||
use crate::errors;
|
||||
use crate::mbe::{KleeneToken, TokenTree};
|
||||
|
||||
use rustc_ast::token::{Delimiter, Token, TokenKind};
|
||||
@ -281,10 +282,7 @@ fn check_binders(
|
||||
// Duplicate binders at the top-level macro definition are errors. The lint is only
|
||||
// for nested macro definitions.
|
||||
sess.span_diagnostic
|
||||
.struct_span_err(span, "duplicate matcher binding")
|
||||
.span_label(span, "duplicate binding")
|
||||
.span_label(prev_info.span, "previous binding")
|
||||
.emit();
|
||||
.emit_err(errors::DuplicateMatcherBinding { span, prev: prev_info.span });
|
||||
*valid = false;
|
||||
} else {
|
||||
binders.insert(name, BinderInfo { span, ops: ops.into() });
|
||||
|
@ -262,3 +262,17 @@ hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$de
|
||||
hir_analysis_transparent_non_zero_sized = transparent {$desc} needs at most one non-zero-sized field, but has {$field_count}
|
||||
.label = needs at most one non-zero-sized field, but has {$field_count}
|
||||
.labels = this field is non-zero-sized
|
||||
|
||||
hir_analysis_too_large_static = extern static is too large for the current architecture
|
||||
|
||||
hir_analysis_specialization_trait = implementing `rustc_specialization_trait` traits is unstable
|
||||
.help = add `#![feature(min_specialization)]` to the crate attributes to enable
|
||||
|
||||
hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are forbidden when `for<...>` is present
|
||||
.label = `for<...>` is here
|
||||
|
||||
hir_analysis_const_specialize = cannot specialize on const impl with non-const impl
|
||||
|
||||
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
|
||||
|
||||
hir_analysis_missing_tilde_const = missing `~const` qualifier for specialization
|
||||
|
@ -170,9 +170,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
if matches!(tcx.def_kind(def_id), DefKind::Static(_)
|
||||
if tcx.def_kind(tcx.local_parent(def_id)) == DefKind::ForeignMod) =>
|
||||
{
|
||||
tcx.sess
|
||||
.struct_span_err(span, "extern static is too large for the current architecture")
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::TooLargeStatic { span });
|
||||
return;
|
||||
}
|
||||
// Generic statics are rejected, but we still reach this case.
|
||||
|
@ -1576,17 +1576,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
||||
&& let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = opaque.origin
|
||||
&& source == self.fn_def_id
|
||||
{
|
||||
let opaque_ty = tcx.fold_regions(unshifted_opaque_ty, |re, depth| {
|
||||
if let ty::ReLateBound(index, bv) = re.kind() {
|
||||
if depth != ty::INNERMOST {
|
||||
return tcx.mk_re_error_with_message(
|
||||
DUMMY_SP,
|
||||
"we shouldn't walk non-predicate binders with `impl Trait`...",
|
||||
);
|
||||
}
|
||||
tcx.mk_re_late_bound(index.shifted_out_to_binder(self.depth), bv)
|
||||
} else {
|
||||
re
|
||||
let opaque_ty = tcx.fold_regions(unshifted_opaque_ty, |re, _depth| {
|
||||
match re.kind() {
|
||||
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReError(_) => re,
|
||||
r => bug!("unexpected region: {r:?}"),
|
||||
}
|
||||
});
|
||||
for (bound, bound_span) in tcx
|
||||
|
@ -5,6 +5,7 @@
|
||||
// done by the orphan and overlap modules. Then we build up various
|
||||
// mappings. That mapping code resides here.
|
||||
|
||||
use crate::errors;
|
||||
use rustc_errors::{error_code, struct_span_err};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
@ -67,13 +68,7 @@ fn enforce_trait_manually_implementable(
|
||||
tcx.trait_def(trait_def_id).specialization_kind
|
||||
{
|
||||
if !tcx.features().specialization && !tcx.features().min_specialization {
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
impl_header_span,
|
||||
"implementing `rustc_specialization_trait` traits is unstable",
|
||||
)
|
||||
.help("add `#![feature(min_specialization)]` to the crate attributes to enable")
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::SpecializationTrait { span: impl_header_span });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -386,8 +386,10 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
||||
|
||||
fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
|
||||
let ty = self.tcx.fold_regions(ty, |r, _| match *r {
|
||||
ty::ReErased => self.tcx.lifetimes.re_static,
|
||||
_ => r,
|
||||
// This is never reached in practice. If it ever is reached,
|
||||
// `ReErased` should be changed to `ReStatic`, and any other region
|
||||
// left alone.
|
||||
r => bug!("unexpected region: {r:?}"),
|
||||
});
|
||||
self.tcx().const_error_with_message(ty, span, "bad placeholder constant")
|
||||
}
|
||||
|
@ -455,13 +455,9 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if !infer_spans.is_empty() {
|
||||
self.tcx.sess
|
||||
.struct_span_err(
|
||||
infer_spans,
|
||||
"implicit types in closure signatures are forbidden when `for<...>` is present",
|
||||
)
|
||||
.span_label(for_sp, "`for<...>` is here")
|
||||
.emit();
|
||||
self.tcx
|
||||
.sess
|
||||
.emit_err(errors::ClosureImplicitHrtb { spans: infer_spans, for_sp });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,6 +633,7 @@ pub(crate) struct SIMDFFIHighlyExperimental {
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
||||
pub enum ImplNotMarkedDefault {
|
||||
#[diag(hir_analysis_impl_not_marked_default, code = "E0520")]
|
||||
#[note]
|
||||
@ -769,3 +770,48 @@ pub(crate) struct TransparentNonZeroSized<'a> {
|
||||
pub field_count: usize,
|
||||
pub desc: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_too_large_static)]
|
||||
pub(crate) struct TooLargeStatic {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_specialization_trait)]
|
||||
#[help]
|
||||
pub(crate) struct SpecializationTrait {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_closure_implicit_hrtb)]
|
||||
pub(crate) struct ClosureImplicitHrtb {
|
||||
#[primary_span]
|
||||
pub spans: Vec<Span>,
|
||||
#[label]
|
||||
pub for_sp: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_const_specialize)]
|
||||
pub(crate) struct ConstSpecialize {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_static_specialize)]
|
||||
pub(crate) struct StaticSpecialize {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_missing_tilde_const)]
|
||||
pub(crate) struct MissingTildeConst {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
@ -65,8 +65,8 @@
|
||||
//! cause use after frees with purely safe code in the same way as specializing
|
||||
//! on traits with methods can.
|
||||
|
||||
use crate::constrained_generic_params as cgp;
|
||||
use crate::errors::SubstsOnOverriddenImpl;
|
||||
use crate::{constrained_generic_params as cgp, errors};
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir as hir;
|
||||
@ -137,9 +137,7 @@ fn check_constness(tcx: TyCtxt<'_>, impl1_def_id: LocalDefId, impl2_node: Node,
|
||||
|
||||
if let hir::Constness::Const = impl2_constness {
|
||||
if let hir::Constness::NotConst = impl1_constness {
|
||||
tcx.sess
|
||||
.struct_span_err(span, "cannot specialize on const impl with non-const impl")
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::ConstSpecialize { span });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -293,7 +291,7 @@ fn check_static_lifetimes<'tcx>(
|
||||
span: Span,
|
||||
) {
|
||||
if tcx.any_free_region_meets(parent_substs, |r| r.is_static()) {
|
||||
tcx.sess.struct_span_err(span, "cannot specialize on `'static` lifetime").emit();
|
||||
tcx.sess.emit_err(errors::StaticSpecialize { span });
|
||||
}
|
||||
}
|
||||
|
||||
@ -438,7 +436,7 @@ fn trait_predicates_eq<'tcx>(
|
||||
// the one on the base.
|
||||
match (trait_pred2.constness, trait_pred1.constness) {
|
||||
(ty::BoundConstness::ConstIfConst, ty::BoundConstness::NotConst) => {
|
||||
tcx.sess.struct_span_err(span, "missing `~const` qualifier for specialization").emit();
|
||||
tcx.sess.emit_err(errors::MissingTildeConst { span });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -62,3 +62,16 @@ hir_typeck_fru_suggestion =
|
||||
[NONE]{""}
|
||||
*[other] {" "}from `{$expr}`
|
||||
}, separate the last named field with a comma
|
||||
|
||||
hir_typeck_const_select_must_be_const = this argument must be a `const fn`
|
||||
.help = consult the documentation on `const_eval_select` for more information
|
||||
|
||||
hir_typeck_const_select_must_be_fn = this argument must be a function item
|
||||
.note = expected a function item, found {$ty}
|
||||
.help = consult the documentation on `const_eval_select` for more information
|
||||
|
||||
hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field
|
||||
hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns
|
||||
|
||||
hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but rustc had trouble determining where
|
||||
.note = we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new
|
||||
|
@ -1508,6 +1508,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// FIXME(compiler-errors): We can actually do this if the checked_ty is
|
||||
// `steps` layers of boxes, not just one, but this is easier and most likely.
|
||||
|| (checked_ty.is_box() && steps == 1)
|
||||
// We can always deref a binop that takes its arguments by ref.
|
||||
|| matches!(
|
||||
self.tcx.hir().get_parent(expr.hir_id),
|
||||
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(op, ..), .. })
|
||||
if !op.node.is_by_value()
|
||||
)
|
||||
{
|
||||
let deref_kind = if checked_ty.is_box() {
|
||||
"unboxing the value"
|
||||
|
@ -228,3 +228,42 @@ impl HelpUseLatestEdition {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_const_select_must_be_const)]
|
||||
#[help]
|
||||
pub struct ConstSelectMustBeConst {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_const_select_must_be_fn)]
|
||||
#[note]
|
||||
#[help]
|
||||
pub struct ConstSelectMustBeFn<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub ty: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_union_pat_multiple_fields)]
|
||||
pub struct UnionPatMultipleFields {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_union_pat_dotdot)]
|
||||
pub struct UnionPatDotDot {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_typeck_arg_mismatch_indeterminate)]
|
||||
pub struct ArgMismatchIndeterminate {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ use crate::coercion::CoerceMany;
|
||||
use crate::fn_ctxt::arg_matrix::{ArgMatrix, Compatibility, Error, ExpectedIdx, ProvidedIdx};
|
||||
use crate::gather_locals::Declaration;
|
||||
use crate::method::MethodCallee;
|
||||
use crate::Expectation::*;
|
||||
use crate::TupleArgumentsFlag::*;
|
||||
use crate::{errors, Expectation::*};
|
||||
use crate::{
|
||||
struct_span_err, BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, Needs, RawTy,
|
||||
TupleArgumentsFlag,
|
||||
@ -283,19 +283,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if idx == 1 && !self.tcx.is_const_fn_raw(*def_id) {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(provided_arg.span, "this argument must be a `const fn`")
|
||||
.help("consult the documentation on `const_eval_select` for more information")
|
||||
.emit();
|
||||
.emit_err(errors::ConstSelectMustBeConst { span: provided_arg.span });
|
||||
}
|
||||
} else {
|
||||
self.tcx
|
||||
.sess
|
||||
.struct_span_err(provided_arg.span, "this argument must be a function item")
|
||||
.note(format!("expected a function item, found {checked_ty}"))
|
||||
.help(
|
||||
"consult the documentation on `const_eval_select` for more information",
|
||||
)
|
||||
.emit();
|
||||
self.tcx.sess.emit_err(errors::ConstSelectMustBeFn {
|
||||
span: provided_arg.span,
|
||||
ty: checked_ty,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -744,17 +738,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if cfg!(debug_assertions) {
|
||||
span_bug!(error_span, "expected errors from argument matrix");
|
||||
} else {
|
||||
tcx.sess
|
||||
.struct_span_err(
|
||||
error_span,
|
||||
"argument type mismatch was detected, \
|
||||
but rustc had trouble determining where",
|
||||
)
|
||||
.note(
|
||||
"we would appreciate a bug report: \
|
||||
https://github.com/rust-lang/rust/issues/new",
|
||||
)
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::ArgMismatchIndeterminate { span: error_span });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{FnCtxt, RawTy};
|
||||
use crate::{errors, FnCtxt, RawTy};
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{
|
||||
@ -1410,12 +1410,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Report an error if an incorrect number of fields was specified.
|
||||
if adt.is_union() {
|
||||
if fields.len() != 1 {
|
||||
tcx.sess
|
||||
.struct_span_err(pat.span, "union patterns should have exactly one field")
|
||||
.emit();
|
||||
tcx.sess.emit_err(errors::UnionPatMultipleFields { span: pat.span });
|
||||
}
|
||||
if has_rest_pat {
|
||||
tcx.sess.struct_span_err(pat.span, "`..` cannot be used in union patterns").emit();
|
||||
tcx.sess.emit_err(errors::UnionPatDotDot { span: pat.span });
|
||||
}
|
||||
} else if !unmentioned_fields.is_empty() {
|
||||
let accessible_unmentioned_fields: Vec<_> = unmentioned_fields
|
||||
|
@ -99,6 +99,8 @@ lint_diag_out_of_impl =
|
||||
|
||||
lint_untranslatable_diag = diagnostics should be created using translatable messages
|
||||
|
||||
lint_trivial_untranslatable_diag = diagnostic with static strings only
|
||||
|
||||
lint_bad_opt_access = {$msg}
|
||||
|
||||
lint_cstring_ptr = getting the inner pointer of a temporary `CString`
|
||||
|
@ -4,6 +4,7 @@
|
||||
use crate::lints::{
|
||||
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
|
||||
QueryInstability, TyQualified, TykindDiag, TykindKind, UntranslatableDiag,
|
||||
UntranslatableDiagnosticTrivial,
|
||||
};
|
||||
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
|
||||
use rustc_ast as ast;
|
||||
@ -366,7 +367,15 @@ declare_tool_lint! {
|
||||
report_in_external_macro: true
|
||||
}
|
||||
|
||||
declare_lint_pass!(Diagnostics => [ UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE_OF_IMPL ]);
|
||||
declare_tool_lint! {
|
||||
/// The `untranslatable_diagnostic_trivial` lint detects diagnostics created using only static strings.
|
||||
pub rustc::UNTRANSLATABLE_DIAGNOSTIC_TRIVIAL,
|
||||
Deny,
|
||||
"prevent creation of diagnostics which cannot be translated, which use only static strings",
|
||||
report_in_external_macro: true
|
||||
}
|
||||
|
||||
declare_lint_pass!(Diagnostics => [ UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE_OF_IMPL, UNTRANSLATABLE_DIAGNOSTIC_TRIVIAL ]);
|
||||
|
||||
impl LateLintPass<'_> for Diagnostics {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||
@ -423,6 +432,75 @@ impl LateLintPass<'_> for Diagnostics {
|
||||
}
|
||||
}
|
||||
|
||||
impl EarlyLintPass for Diagnostics {
|
||||
#[allow(unused_must_use)]
|
||||
fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &ast::Stmt) {
|
||||
// Looking for a straight chain of method calls from 'struct_span_err' to 'emit'.
|
||||
let ast::StmtKind::Semi(expr) = &stmt.kind else {
|
||||
return;
|
||||
};
|
||||
let ast::ExprKind::MethodCall(meth) = &expr.kind else {
|
||||
return;
|
||||
};
|
||||
if meth.seg.ident.name != sym::emit || !meth.args.is_empty() {
|
||||
return;
|
||||
}
|
||||
let mut segments = vec![];
|
||||
let mut cur = &meth.receiver;
|
||||
let fake = &[].into();
|
||||
loop {
|
||||
match &cur.kind {
|
||||
ast::ExprKind::Call(func, args) => {
|
||||
if let ast::ExprKind::Path(_, path) = &func.kind {
|
||||
segments.push((path.segments.last().unwrap().ident.name, args))
|
||||
}
|
||||
break;
|
||||
}
|
||||
ast::ExprKind::MethodCall(method) => {
|
||||
segments.push((method.seg.ident.name, &method.args));
|
||||
cur = &method.receiver;
|
||||
}
|
||||
ast::ExprKind::MacCall(mac) => {
|
||||
segments.push((mac.path.segments.last().unwrap().ident.name, fake));
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
segments.reverse();
|
||||
if segments.is_empty() {
|
||||
return;
|
||||
}
|
||||
if segments[0].0.as_str() != "struct_span_err" {
|
||||
return;
|
||||
}
|
||||
if !segments.iter().all(|(name, args)| {
|
||||
let arg = match name.as_str() {
|
||||
"struct_span_err" | "span_note" | "span_label" | "span_help" => &args[1],
|
||||
"note" | "help" => &args[0],
|
||||
_ => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
if let ast::ExprKind::Lit(lit) = arg.kind
|
||||
&& let ast::token::LitKind::Str = lit.kind {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}) {
|
||||
return;
|
||||
}
|
||||
cx.emit_spanned_lint(
|
||||
UNTRANSLATABLE_DIAGNOSTIC_TRIVIAL,
|
||||
stmt.span,
|
||||
UntranslatableDiagnosticTrivial,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
declare_tool_lint! {
|
||||
/// The `bad_opt_access` lint detects accessing options by field instead of
|
||||
/// the wrapper function.
|
||||
|
@ -518,6 +518,7 @@ fn register_internals(store: &mut LintStore) {
|
||||
store.register_lints(&TyTyKind::get_lints());
|
||||
store.register_late_pass(|_| Box::new(TyTyKind));
|
||||
store.register_lints(&Diagnostics::get_lints());
|
||||
store.register_early_pass(|| Box::new(Diagnostics));
|
||||
store.register_late_pass(|_| Box::new(Diagnostics));
|
||||
store.register_lints(&BadOptAccess::get_lints());
|
||||
store.register_late_pass(|_| Box::new(BadOptAccess));
|
||||
|
@ -820,6 +820,10 @@ pub struct DiagOutOfImpl;
|
||||
#[diag(lint_untranslatable_diag)]
|
||||
pub struct UntranslatableDiag;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_trivial_untranslatable_diag)]
|
||||
pub struct UntranslatableDiagnosticTrivial;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_bad_opt_access)]
|
||||
pub struct BadOptAccessDiag<'a> {
|
||||
|
@ -829,7 +829,13 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for SubstFolder<'a, 'tcx> {
|
||||
None => region_param_out_of_range(data, self.substs),
|
||||
}
|
||||
}
|
||||
_ => r,
|
||||
ty::ReLateBound(..)
|
||||
| ty::ReFree(_)
|
||||
| ty::ReStatic
|
||||
| ty::RePlaceholder(_)
|
||||
| ty::ReErased
|
||||
| ty::ReError(_) => r,
|
||||
ty::ReVar(_) => bug!("unexpected region: {r:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -742,3 +742,33 @@ parse_bad_return_type_notation_output =
|
||||
parse_bad_return_type_notation_dotdot =
|
||||
return type notation uses `()` instead of `(..)` for elided arguments
|
||||
.suggestion = remove the `..`
|
||||
|
||||
parse_bad_assoc_type_bounds = bounds on associated types do not belong here
|
||||
.label = belongs in `where` clause
|
||||
|
||||
parse_attr_after_generic = trailing attribute after generic parameter
|
||||
.label = attributes must go before parameters
|
||||
|
||||
parse_attr_without_generics = attribute without generic parameters
|
||||
.label = attributes are only permitted when preceding parameters
|
||||
|
||||
parse_where_generics = generic parameters on `where` clauses are reserved for future use
|
||||
.label = currently unsupported
|
||||
|
||||
parse_generics_in_path = unexpected generic arguments in path
|
||||
|
||||
parse_assoc_lifetime = associated lifetimes are not supported
|
||||
.label = the lifetime is given here
|
||||
.help = if you meant to specify a trait object, write `dyn Trait + 'lifetime`
|
||||
|
||||
parse_tilde_const_lifetime = `~const` may only modify trait bounds, not lifetime bounds
|
||||
|
||||
parse_maybe_lifetime = `?` may only modify trait bounds, not lifetime bounds
|
||||
|
||||
parse_parenthesized_lifetime = parenthesized lifetime bounds are not supported
|
||||
.suggestion = remove the parentheses
|
||||
|
||||
parse_const_bounds_missing_tilde = const bounds must start with `~`
|
||||
.suggestion = add `~`
|
||||
|
||||
parse_underscore_literal_suffix = underscore literal suffix is not allowed
|
||||
|
@ -2332,3 +2332,92 @@ pub(crate) struct BadReturnTypeNotationDotDot {
|
||||
#[suggestion(code = "", applicability = "maybe-incorrect")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_bad_assoc_type_bounds)]
|
||||
pub(crate) struct BadAssocTypeBounds {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_attr_after_generic)]
|
||||
pub(crate) struct AttrAfterGeneric {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_attr_without_generics)]
|
||||
pub(crate) struct AttrWithoutGenerics {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_where_generics)]
|
||||
pub(crate) struct WhereOnGenerics {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_generics_in_path)]
|
||||
pub(crate) struct GenericsInPath {
|
||||
#[primary_span]
|
||||
pub span: Vec<Span>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_assoc_lifetime)]
|
||||
#[help]
|
||||
pub(crate) struct AssocLifetime {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[label]
|
||||
pub lifetime: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_tilde_const_lifetime)]
|
||||
pub(crate) struct TildeConstLifetime {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_maybe_lifetime)]
|
||||
pub(crate) struct MaybeLifetime {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_parenthesized_lifetime)]
|
||||
pub(crate) struct ParenthesizedLifetime {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(style = "short", applicability = "machine-applicable", code = "{snippet}")]
|
||||
pub sugg: Option<Span>,
|
||||
pub snippet: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_const_bounds_missing_tilde)]
|
||||
pub(crate) struct ConstMissingTilde {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
#[suggestion(code = "~", applicability = "machine-applicable")]
|
||||
pub start: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_underscore_literal_suffix)]
|
||||
pub(crate) struct UnderscoreLiteralSuffix {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
@ -209,11 +209,7 @@ impl<'a> StringReader<'a> {
|
||||
if string == "_" {
|
||||
self.sess
|
||||
.span_diagnostic
|
||||
.struct_span_err(
|
||||
self.mk_sp(suffix_start, self.pos),
|
||||
"underscore literal suffix is not allowed",
|
||||
)
|
||||
.emit();
|
||||
.emit_err(errors::UnderscoreLiteralSuffix { span: self.mk_sp(suffix_start, self.pos) });
|
||||
None
|
||||
} else {
|
||||
Some(Symbol::intern(string))
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::errors::{
|
||||
MultipleWhereClauses, UnexpectedDefaultValueForLifetimeInGenericParameters,
|
||||
self, MultipleWhereClauses, UnexpectedDefaultValueForLifetimeInGenericParameters,
|
||||
UnexpectedSelfInGenericParameters, WhereClauseBeforeTupleStructBody,
|
||||
WhereClauseBeforeTupleStructBodySugg,
|
||||
};
|
||||
@ -181,12 +181,9 @@ impl<'a> Parser<'a> {
|
||||
let snapshot = this.create_snapshot_for_diagnostic();
|
||||
match this.parse_ty_where_predicate() {
|
||||
Ok(where_predicate) => {
|
||||
this.struct_span_err(
|
||||
where_predicate.span(),
|
||||
"bounds on associated types do not belong here",
|
||||
)
|
||||
.span_label(where_predicate.span(), "belongs in `where` clause")
|
||||
.emit();
|
||||
this.sess.emit_err(errors::BadAssocTypeBounds {
|
||||
span: where_predicate.span(),
|
||||
});
|
||||
// FIXME - try to continue parsing other generics?
|
||||
return Ok((None, TrailingToken::None));
|
||||
}
|
||||
@ -201,22 +198,11 @@ impl<'a> Parser<'a> {
|
||||
// Check for trailing attributes and stop parsing.
|
||||
if !attrs.is_empty() {
|
||||
if !params.is_empty() {
|
||||
this.struct_span_err(
|
||||
attrs[0].span,
|
||||
"trailing attribute after generic parameter",
|
||||
)
|
||||
.span_label(attrs[0].span, "attributes must go before parameters")
|
||||
.emit();
|
||||
this.sess
|
||||
.emit_err(errors::AttrAfterGeneric { span: attrs[0].span });
|
||||
} else {
|
||||
this.struct_span_err(
|
||||
attrs[0].span,
|
||||
"attribute without generic parameters",
|
||||
)
|
||||
.span_label(
|
||||
attrs[0].span,
|
||||
"attributes are only permitted when preceding parameters",
|
||||
)
|
||||
.emit();
|
||||
this.sess
|
||||
.emit_err(errors::AttrWithoutGenerics { span: attrs[0].span });
|
||||
}
|
||||
}
|
||||
return Ok((None, TrailingToken::None));
|
||||
@ -304,12 +290,7 @@ impl<'a> Parser<'a> {
|
||||
// change we parse those generics now, but report an error.
|
||||
if self.choose_generics_over_qpath(0) {
|
||||
let generics = self.parse_generics()?;
|
||||
self.struct_span_err(
|
||||
generics.span,
|
||||
"generic parameters on `where` clauses are reserved for future use",
|
||||
)
|
||||
.span_label(generics.span, "currently unsupported")
|
||||
.emit();
|
||||
self.sess.emit_err(errors::WhereOnGenerics { span: generics.span });
|
||||
}
|
||||
|
||||
loop {
|
||||
|
@ -150,16 +150,13 @@ impl<'a> Parser<'a> {
|
||||
//
|
||||
if style == PathStyle::Mod && path.segments.iter().any(|segment| segment.args.is_some())
|
||||
{
|
||||
parser
|
||||
.struct_span_err(
|
||||
path.segments
|
||||
.iter()
|
||||
.filter_map(|segment| segment.args.as_ref())
|
||||
.map(|arg| arg.span())
|
||||
.collect::<Vec<_>>(),
|
||||
"unexpected generic arguments in path",
|
||||
)
|
||||
.emit();
|
||||
let span = path
|
||||
.segments
|
||||
.iter()
|
||||
.filter_map(|segment| segment.args.as_ref())
|
||||
.map(|arg| arg.span())
|
||||
.collect::<Vec<_>>();
|
||||
parser.sess.emit_err(errors::GenericsInPath { span });
|
||||
}
|
||||
};
|
||||
|
||||
@ -620,10 +617,7 @@ impl<'a> Parser<'a> {
|
||||
c.into()
|
||||
}
|
||||
Some(GenericArg::Lifetime(lt)) => {
|
||||
self.struct_span_err(span, "associated lifetimes are not supported")
|
||||
.span_label(lt.ident.span, "the lifetime is given here")
|
||||
.help("if you meant to specify a trait object, write `dyn Trait + 'lifetime`")
|
||||
.emit();
|
||||
self.sess.emit_err(errors::AssocLifetime { span, lifetime: lt.ident.span });
|
||||
self.mk_ty(span, ast::TyKind::Err).into()
|
||||
}
|
||||
None => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::{Parser, PathStyle, TokenType};
|
||||
|
||||
use crate::errors::{
|
||||
DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
|
||||
self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType,
|
||||
FnPointerCannotBeAsync, FnPointerCannotBeConst, FnPtrWithGenerics, FnPtrWithGenericsSugg,
|
||||
InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime,
|
||||
NegativeBoundsNotSupported, NegativeBoundsNotSupportedSugg, NestedCVariadicType,
|
||||
@ -807,16 +807,11 @@ impl<'a> Parser<'a> {
|
||||
/// Emits an error if any trait bound modifiers were present.
|
||||
fn error_lt_bound_with_modifiers(&self, modifiers: BoundModifiers) {
|
||||
if let Some(span) = modifiers.maybe_const {
|
||||
self.struct_span_err(
|
||||
span,
|
||||
"`~const` may only modify trait bounds, not lifetime bounds",
|
||||
)
|
||||
.emit();
|
||||
self.sess.emit_err(errors::TildeConstLifetime { span });
|
||||
}
|
||||
|
||||
if let Some(span) = modifiers.maybe {
|
||||
self.struct_span_err(span, "`?` may only modify trait bounds, not lifetime bounds")
|
||||
.emit();
|
||||
self.sess.emit_err(errors::MaybeLifetime { span });
|
||||
}
|
||||
}
|
||||
|
||||
@ -824,19 +819,14 @@ impl<'a> Parser<'a> {
|
||||
fn recover_paren_lifetime(&mut self, lo: Span, inner_lo: Span) -> PResult<'a, ()> {
|
||||
let inner_span = inner_lo.to(self.prev_token.span);
|
||||
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
||||
let mut err = self.struct_span_err(
|
||||
lo.to(self.prev_token.span),
|
||||
"parenthesized lifetime bounds are not supported",
|
||||
);
|
||||
if let Ok(snippet) = self.span_to_snippet(inner_span) {
|
||||
err.span_suggestion_short(
|
||||
lo.to(self.prev_token.span),
|
||||
"remove the parentheses",
|
||||
snippet,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
err.emit();
|
||||
let span = lo.to(self.prev_token.span);
|
||||
let (sugg, snippet) = if let Ok(snippet) = self.span_to_snippet(inner_span) {
|
||||
(Some(span), snippet)
|
||||
} else {
|
||||
(None, String::new())
|
||||
};
|
||||
|
||||
self.sess.emit_err(errors::ParenthesizedLifetime { span, sugg, snippet });
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -857,15 +847,7 @@ impl<'a> Parser<'a> {
|
||||
} 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();
|
||||
self.sess.emit_err(errors::ConstMissingTilde { span, start: span.shrink_to_lo() });
|
||||
|
||||
Some(span)
|
||||
} else {
|
||||
|
@ -226,3 +226,10 @@ resolve_add_as_non_derive =
|
||||
|
||||
resolve_proc_macro_same_crate = can't use a procedural macro from the same crate that defines it
|
||||
.help = you can define integration tests in a directory named `tests`
|
||||
|
||||
resolve_imported_crate = `$crate` may not be imported
|
||||
|
||||
resolve_macro_use_extern_crate_self = `#[macro_use]` is not supported on `extern crate self`
|
||||
|
||||
resolve_accessible_unsure = not sure whether the path is accessible or not
|
||||
.note = the type may have associated items, but we are currently not checking them
|
||||
|
@ -9,7 +9,9 @@ use crate::def_collector::collect_definitions;
|
||||
use crate::imports::{Import, ImportKind};
|
||||
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
|
||||
use crate::Namespace::{self, MacroNS, TypeNS, ValueNS};
|
||||
use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot};
|
||||
use crate::{
|
||||
errors, Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot,
|
||||
};
|
||||
use crate::{
|
||||
MacroData, NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError,
|
||||
};
|
||||
@ -523,11 +525,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
ident.name = crate_name;
|
||||
}
|
||||
|
||||
self.r
|
||||
.tcx
|
||||
.sess
|
||||
.struct_span_err(item.span, "`$crate` may not be imported")
|
||||
.emit();
|
||||
self.r.tcx.sess.emit_err(errors::CrateImported { span: item.span });
|
||||
}
|
||||
}
|
||||
|
||||
@ -1028,11 +1026,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
self.r
|
||||
.tcx
|
||||
.sess
|
||||
.struct_span_err(
|
||||
attr.span,
|
||||
"`#[macro_use]` is not supported on `extern crate self`",
|
||||
)
|
||||
.emit();
|
||||
.emit_err(errors::MacroUseExternCrateSelf { span: attr.span });
|
||||
}
|
||||
}
|
||||
let ill_formed = |span| {
|
||||
|
@ -517,3 +517,25 @@ pub(crate) struct ProcMacroSameCrate {
|
||||
#[help]
|
||||
pub(crate) is_test: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_imported_crate)]
|
||||
pub(crate) struct CrateImported {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_macro_use_extern_crate_self)]
|
||||
pub(crate) struct MacroUseExternCrateSelf {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(resolve_accessible_unsure)]
|
||||
#[note]
|
||||
pub(crate) struct CfgAccessibleUnsure {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
}
|
||||
|
@ -436,9 +436,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> {
|
||||
// HACK(Urgau): This shouldn't be necessary
|
||||
PathResult::Failed { is_error_from_last_segment: false, .. } => {
|
||||
self.tcx.sess
|
||||
.struct_span_err(span, "not sure whether the path is accessible or not")
|
||||
.note("the type may have associated items, but we are currently not checking them")
|
||||
.emit();
|
||||
.emit_err(errors::CfgAccessibleUnsure { span });
|
||||
|
||||
// If we get a partially resolved NonModule in one namespace, we should get the
|
||||
// same result in any other namespaces, so we can return early.
|
||||
|
@ -651,6 +651,7 @@ symbols! {
|
||||
edition_panic,
|
||||
eh_catch_typeinfo,
|
||||
eh_personality,
|
||||
emit,
|
||||
emit_enum,
|
||||
emit_enum_variant,
|
||||
emit_enum_variant_arg,
|
||||
|
@ -91,14 +91,15 @@ pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>(
|
||||
) -> ty::Binder<'tcx, Ty<'tcx>> {
|
||||
debug_assert!(!ty.has_late_bound_regions());
|
||||
let mut counter = 0;
|
||||
let ty = tcx.fold_regions(ty, |mut r, current_depth| {
|
||||
if let ty::ReErased = r.kind() {
|
||||
let ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() {
|
||||
ty::ReErased => {
|
||||
let br =
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon(None) };
|
||||
counter += 1;
|
||||
r = tcx.mk_re_late_bound(current_depth, br);
|
||||
tcx.mk_re_late_bound(current_depth, br)
|
||||
}
|
||||
r
|
||||
// All free regions should be erased here.
|
||||
r => bug!("unexpected region: {r:?}"),
|
||||
});
|
||||
let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
|
||||
(0..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon(None))),
|
||||
|
@ -3006,16 +3006,16 @@ fn bind_generator_hidden_types_above<'tcx>(
|
||||
|
||||
// Only remap erased regions if we use them.
|
||||
if considering_regions {
|
||||
ty = tcx.fold_regions(ty, |mut r, current_depth| {
|
||||
if let ty::ReErased = r.kind() {
|
||||
ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() {
|
||||
ty::ReErased => {
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(counter),
|
||||
kind: ty::BrAnon(None),
|
||||
};
|
||||
counter += 1;
|
||||
r = tcx.mk_re_late_bound(current_depth, br);
|
||||
tcx.mk_re_late_bound(current_depth, br)
|
||||
}
|
||||
r
|
||||
r => bug!("unexpected region: {r:?}"),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ where
|
||||
default fn spec_from_iter(iterator: I) -> Self {
|
||||
// Since converting is O(1) now, just re-use the `Vec` logic for
|
||||
// anything where we can't do something extra-special for `VecDeque`,
|
||||
// especially as that could save us some monomorphiziation work
|
||||
// especially as that could save us some monomorphization work
|
||||
// if one uses the same iterators (like slice ones) with both.
|
||||
crate::vec::Vec::from_iter(iterator).into()
|
||||
}
|
||||
|
@ -404,12 +404,12 @@ impl str {
|
||||
// See https://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
|
||||
// for the definition of `Final_Sigma`.
|
||||
debug_assert!('Σ'.len_utf8() == 2);
|
||||
let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev())
|
||||
&& !case_ignoreable_then_cased(from[i + 2..].chars());
|
||||
let is_word_final = case_ignorable_then_cased(from[..i].chars().rev())
|
||||
&& !case_ignorable_then_cased(from[i + 2..].chars());
|
||||
to.push_str(if is_word_final { "ς" } else { "σ" });
|
||||
}
|
||||
|
||||
fn case_ignoreable_then_cased<I: Iterator<Item = char>>(iter: I) -> bool {
|
||||
fn case_ignorable_then_cased<I: Iterator<Item = char>>(iter: I) -> bool {
|
||||
use core::unicode::{Case_Ignorable, Cased};
|
||||
match iter.skip_while(|&c| Case_Ignorable(c)).next() {
|
||||
Some(c) => Cased(c),
|
||||
|
@ -201,7 +201,7 @@ where
|
||||
//
|
||||
// Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce
|
||||
// contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the
|
||||
// module documenttation why this is ok anyway.
|
||||
// module documentation why this is ok anyway.
|
||||
let dst_guard = InPlaceDstBufDrop { ptr: dst_buf, len, cap };
|
||||
src.forget_allocation_drop_remaining();
|
||||
mem::forget(dst_guard);
|
||||
|
@ -705,7 +705,7 @@ fn test_move_rev_iterator() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_splitator() {
|
||||
fn test_split_iterator() {
|
||||
let xs = &[1, 2, 3, 4, 5];
|
||||
|
||||
let splits: &[&[_]] = &[&[1], &[3], &[5]];
|
||||
@ -725,7 +725,7 @@ fn test_splitator() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_splitator_inclusive() {
|
||||
fn test_split_iterator_inclusive() {
|
||||
let xs = &[1, 2, 3, 4, 5];
|
||||
|
||||
let splits: &[&[_]] = &[&[1, 2], &[3, 4], &[5]];
|
||||
@ -745,7 +745,7 @@ fn test_splitator_inclusive() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_splitator_inclusive_reverse() {
|
||||
fn test_split_iterator_inclusive_reverse() {
|
||||
let xs = &[1, 2, 3, 4, 5];
|
||||
|
||||
let splits: &[&[_]] = &[&[5], &[3, 4], &[1, 2]];
|
||||
@ -765,7 +765,7 @@ fn test_splitator_inclusive_reverse() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_splitator_mut_inclusive() {
|
||||
fn test_split_iterator_mut_inclusive() {
|
||||
let xs = &mut [1, 2, 3, 4, 5];
|
||||
|
||||
let splits: &[&[_]] = &[&[1, 2], &[3, 4], &[5]];
|
||||
@ -785,7 +785,7 @@ fn test_splitator_mut_inclusive() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_splitator_mut_inclusive_reverse() {
|
||||
fn test_split_iterator_mut_inclusive_reverse() {
|
||||
let xs = &mut [1, 2, 3, 4, 5];
|
||||
|
||||
let splits: &[&[_]] = &[&[5], &[3, 4], &[1, 2]];
|
||||
@ -805,7 +805,7 @@ fn test_splitator_mut_inclusive_reverse() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_splitnator() {
|
||||
fn test_splitn_iterator() {
|
||||
let xs = &[1, 2, 3, 4, 5];
|
||||
|
||||
let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]];
|
||||
@ -821,7 +821,7 @@ fn test_splitnator() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_splitnator_mut() {
|
||||
fn test_splitn_iterator_mut() {
|
||||
let xs = &mut [1, 2, 3, 4, 5];
|
||||
|
||||
let splits: &[&mut [_]] = &[&mut [1, 2, 3, 4, 5]];
|
||||
@ -837,7 +837,7 @@ fn test_splitnator_mut() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rsplitator() {
|
||||
fn test_rsplit_iterator() {
|
||||
let xs = &[1, 2, 3, 4, 5];
|
||||
|
||||
let splits: &[&[_]] = &[&[5], &[3], &[1]];
|
||||
@ -855,7 +855,7 @@ fn test_rsplitator() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rsplitnator() {
|
||||
fn test_rsplitn_iterator() {
|
||||
let xs = &[1, 2, 3, 4, 5];
|
||||
|
||||
let splits: &[&[_]] = &[&[1, 2, 3, 4, 5]];
|
||||
@ -932,7 +932,7 @@ fn test_split_iterators_size_hint() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_windowsator() {
|
||||
fn test_windows_iterator() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
|
||||
let wins: &[&[_]] = &[&[1, 2], &[2, 3], &[3, 4]];
|
||||
@ -948,13 +948,13 @@ fn test_windowsator() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_windowsator_0() {
|
||||
fn test_windows_iterator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.windows(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chunksator() {
|
||||
fn test_chunks_iterator() {
|
||||
let v = &[1, 2, 3, 4, 5];
|
||||
|
||||
assert_eq!(v.chunks(2).len(), 3);
|
||||
@ -972,13 +972,13 @@ fn test_chunksator() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_chunksator_0() {
|
||||
fn test_chunks_iterator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.chunks(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chunks_exactator() {
|
||||
fn test_chunks_exact_iterator() {
|
||||
let v = &[1, 2, 3, 4, 5];
|
||||
|
||||
assert_eq!(v.chunks_exact(2).len(), 2);
|
||||
@ -996,13 +996,13 @@ fn test_chunks_exactator() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_chunks_exactator_0() {
|
||||
fn test_chunks_exact_iterator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.chunks_exact(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunksator() {
|
||||
fn test_rchunks_iterator() {
|
||||
let v = &[1, 2, 3, 4, 5];
|
||||
|
||||
assert_eq!(v.rchunks(2).len(), 3);
|
||||
@ -1020,13 +1020,13 @@ fn test_rchunksator() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_rchunksator_0() {
|
||||
fn test_rchunks_iterator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.rchunks(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rchunks_exactator() {
|
||||
fn test_rchunks_exact_iterator() {
|
||||
let v = &[1, 2, 3, 4, 5];
|
||||
|
||||
assert_eq!(v.rchunks_exact(2).len(), 2);
|
||||
@ -1044,7 +1044,7 @@ fn test_rchunks_exactator() {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_rchunks_exactator_0() {
|
||||
fn test_rchunks_exact_iterator_0() {
|
||||
let v = &[1, 2, 3, 4];
|
||||
let _it = v.rchunks_exact(0);
|
||||
}
|
||||
@ -1219,7 +1219,7 @@ fn test_ends_with() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_splitator() {
|
||||
fn test_mut_split_iterator() {
|
||||
let mut xs = [0, 1, 0, 2, 3, 0, 0, 4, 5, 0];
|
||||
assert_eq!(xs.split_mut(|x| *x == 0).count(), 6);
|
||||
for slice in xs.split_mut(|x| *x == 0) {
|
||||
@ -1235,7 +1235,7 @@ fn test_mut_splitator() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mut_splitator_rev() {
|
||||
fn test_mut_split_iterator_rev() {
|
||||
let mut xs = [1, 2, 0, 3, 4, 0, 0, 5, 6, 0];
|
||||
for slice in xs.split_mut(|x| *x == 0).rev().take(4) {
|
||||
slice.reverse();
|
||||
|
@ -2470,7 +2470,7 @@ fn test_vec_dedup_panicking() {
|
||||
|
||||
// Regression test for issue #82533
|
||||
#[test]
|
||||
fn test_extend_from_within_panicing_clone() {
|
||||
fn test_extend_from_within_panicking_clone() {
|
||||
struct Panic<'dc> {
|
||||
drop_count: &'dc AtomicU32,
|
||||
aaaaa: bool,
|
||||
|
@ -109,14 +109,14 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
|
||||
/// .field("bar", &self.bar) // We add `bar` field.
|
||||
/// .field("another", &self.another) // We add `another` field.
|
||||
/// // We even add a field which doesn't exist (because why not?).
|
||||
/// .field("not_existing_field", &1)
|
||||
/// .field("nonexistent_field", &1)
|
||||
/// .finish() // We're good to go!
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// format!("{:?}", Bar { bar: 10, another: "Hello World".to_string() }),
|
||||
/// "Bar { bar: 10, another: \"Hello World\", not_existing_field: 1 }",
|
||||
/// "Bar { bar: 10, another: \"Hello World\", nonexistent_field: 1 }",
|
||||
/// );
|
||||
/// ```
|
||||
#[stable(feature = "debug_builders", since = "1.2.0")]
|
||||
|
@ -2474,7 +2474,7 @@ extern "rust-intrinsic" {
|
||||
/// This macro should be called as `assert_unsafe_precondition!([Generics](name: Type) => Expression)`
|
||||
/// where the names specified will be moved into the macro as captured variables, and defines an item
|
||||
/// to call `const_eval_select` on. The tokens inside the square brackets are used to denote generics
|
||||
/// for the function declaractions and can be omitted if there is no generics.
|
||||
/// for the function declarations and can be omitted if there is no generics.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
@ -2733,7 +2733,7 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
||||
// SAFETY: the safety contract for `copy` must be upheld by the caller.
|
||||
unsafe {
|
||||
assert_unsafe_precondition!(
|
||||
"ptr::copy requires that both pointer arguments are aligned aligned and non-null",
|
||||
"ptr::copy requires that both pointer arguments are aligned and non-null",
|
||||
[T](src: *const T, dst: *mut T) =>
|
||||
is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)
|
||||
);
|
||||
|
@ -136,26 +136,12 @@ where
|
||||
}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<T, I, F, const N: usize> TrustedLen for FlatMap<I, [T; N], F>
|
||||
unsafe impl<I, U, F> TrustedLen for FlatMap<I, U, F>
|
||||
where
|
||||
I: TrustedLen,
|
||||
F: FnMut(I::Item) -> [T; N],
|
||||
{
|
||||
}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap<I, &'a [T; N], F>
|
||||
where
|
||||
I: TrustedLen,
|
||||
F: FnMut(I::Item) -> &'a [T; N],
|
||||
{
|
||||
}
|
||||
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap<I, &'a mut [T; N], F>
|
||||
where
|
||||
I: TrustedLen,
|
||||
F: FnMut(I::Item) -> &'a mut [T; N],
|
||||
I: Iterator,
|
||||
U: IntoIterator,
|
||||
F: FnMut(I::Item) -> U,
|
||||
FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>: TrustedLen,
|
||||
{
|
||||
}
|
||||
|
||||
@ -298,8 +284,8 @@ where
|
||||
#[unstable(feature = "trusted_len", issue = "37572")]
|
||||
unsafe impl<I> TrustedLen for Flatten<I>
|
||||
where
|
||||
I: TrustedLen,
|
||||
<I as Iterator>::Item: TrustedConstSize,
|
||||
I: Iterator<Item: IntoIterator>,
|
||||
FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>: TrustedLen,
|
||||
{
|
||||
}
|
||||
|
||||
@ -660,6 +646,27 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<const N: usize, I, T> TrustedLen
|
||||
for FlattenCompat<I, <[T; N] as IntoIterator>::IntoIter>
|
||||
where
|
||||
I: TrustedLen<Item = [T; N]>,
|
||||
{
|
||||
}
|
||||
|
||||
unsafe impl<'a, const N: usize, I, T> TrustedLen
|
||||
for FlattenCompat<I, <&'a [T; N] as IntoIterator>::IntoIter>
|
||||
where
|
||||
I: TrustedLen<Item = &'a [T; N]>,
|
||||
{
|
||||
}
|
||||
|
||||
unsafe impl<'a, const N: usize, I, T> TrustedLen
|
||||
for FlattenCompat<I, <&'a mut [T; N] as IntoIterator>::IntoIter>
|
||||
where
|
||||
I: TrustedLen<Item = &'a mut [T; N]>,
|
||||
{
|
||||
}
|
||||
|
||||
trait ConstSizeIntoIterator: IntoIterator {
|
||||
// FIXME(#31844): convert to an associated const once specialization supports that
|
||||
fn size() -> Option<usize>;
|
||||
@ -696,19 +703,6 @@ impl<T, const N: usize> ConstSizeIntoIterator for &mut [T; N] {
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "std_internals", issue = "none")]
|
||||
// FIXME(#20400): Instead of this helper trait there should be multiple impl TrustedLen for Flatten<>
|
||||
// blocks with different bounds on Iterator::Item but the compiler erroneously considers them overlapping
|
||||
pub unsafe trait TrustedConstSize: IntoIterator {}
|
||||
|
||||
#[unstable(feature = "std_internals", issue = "none")]
|
||||
unsafe impl<T, const N: usize> TrustedConstSize for [T; N] {}
|
||||
#[unstable(feature = "std_internals", issue = "none")]
|
||||
unsafe impl<T, const N: usize> TrustedConstSize for &'_ [T; N] {}
|
||||
#[unstable(feature = "std_internals", issue = "none")]
|
||||
unsafe impl<T, const N: usize> TrustedConstSize for &'_ mut [T; N] {}
|
||||
|
||||
#[inline]
|
||||
fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
|
||||
let x = f(opt.as_mut()?);
|
||||
|
@ -42,7 +42,7 @@ the successful result of some computation, `Ok(T)`, or error types that
|
||||
represent an anticipated runtime failure mode of that computation, `Err(E)`.
|
||||
`Result` is used alongside user defined types which represent the various
|
||||
anticipated runtime failure modes that the associated computation could
|
||||
encounter. `Result` must be propagated manually, often with the the help of the
|
||||
encounter. `Result` must be propagated manually, often with the help of the
|
||||
`?` operator and `Try` trait, and they must be reported manually, often with
|
||||
the help of the `Error` trait.
|
||||
|
||||
|
@ -264,7 +264,7 @@ impl<T: ?Sized> *const T {
|
||||
let dest_addr = addr as isize;
|
||||
let offset = dest_addr.wrapping_sub(self_addr);
|
||||
|
||||
// This is the canonical desugarring of this operation
|
||||
// This is the canonical desugaring of this operation
|
||||
self.wrapping_byte_offset(offset)
|
||||
}
|
||||
|
||||
|
@ -2126,7 +2126,7 @@ mod new_fn_ptr_impl {
|
||||
/// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
|
||||
/// ```
|
||||
///
|
||||
/// See [`addr_of_mut`] for how to create a pointer to unininitialized data.
|
||||
/// See [`addr_of_mut`] for how to create a pointer to uninitialized data.
|
||||
/// Doing that with `addr_of` would not make much sense since one could only
|
||||
/// read the data, and that would be Undefined Behavior.
|
||||
#[stable(feature = "raw_ref_macros", since = "1.51.0")]
|
||||
|
@ -270,7 +270,7 @@ impl<T: ?Sized> *mut T {
|
||||
let dest_addr = addr as isize;
|
||||
let offset = dest_addr.wrapping_sub(self_addr);
|
||||
|
||||
// This is the canonical desugarring of this operation
|
||||
// This is the canonical desugaring of this operation
|
||||
self.wrapping_byte_offset(offset)
|
||||
}
|
||||
|
||||
|
@ -4451,7 +4451,7 @@ impl<T, const N: usize> SlicePattern for [T; N] {
|
||||
/// This will do `binomial(N + 1, 2) = N * (N + 1) / 2 = 0, 1, 3, 6, 10, ..`
|
||||
/// comparison operations.
|
||||
fn get_many_check_valid<const N: usize>(indices: &[usize; N], len: usize) -> bool {
|
||||
// NB: The optimzer should inline the loops into a sequence
|
||||
// NB: The optimizer should inline the loops into a sequence
|
||||
// of instructions without additional branching.
|
||||
let mut valid = true;
|
||||
for (i, &idx) in indices.iter().enumerate() {
|
||||
|
@ -24,7 +24,7 @@ struct NoCopyNoDebug;
|
||||
struct NoDebug;
|
||||
|
||||
test!(
|
||||
capture_with_non_copyable_and_non_debugabble_elem_has_correct_params,
|
||||
capture_with_non_copyable_and_non_debuggable_elem_has_correct_params,
|
||||
NoCopyNoDebug,
|
||||
None,
|
||||
"N/A"
|
||||
@ -32,6 +32,6 @@ test!(
|
||||
|
||||
test!(capture_with_non_copyable_elem_has_correct_params, NoCopy, None, "N/A");
|
||||
|
||||
test!(capture_with_non_debugabble_elem_has_correct_params, NoDebug, None, "N/A");
|
||||
test!(capture_with_non_debuggable_elem_has_correct_params, NoDebug, None, "N/A");
|
||||
|
||||
test!(capture_with_copyable_and_debugabble_elem_has_correct_params, 1i32, Some(1i32), "1");
|
||||
test!(capture_with_copyable_and_debuggable_elem_has_correct_params, 1i32, Some(1i32), "1");
|
||||
|
@ -10,7 +10,7 @@ fn once_cell() {
|
||||
c.get_or_init(|| 92);
|
||||
assert_eq!(c.get(), Some(&92));
|
||||
|
||||
c.get_or_init(|| panic!("Kabom!"));
|
||||
c.get_or_init(|| panic!("Kaboom!"));
|
||||
assert_eq!(c.get(), Some(&92));
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ fn test_can_not_overflow() {
|
||||
for base in 2..=36 {
|
||||
let num = (<$t>::MAX as u128) + 1;
|
||||
|
||||
// Calcutate the string length for the smallest overflowing number:
|
||||
// Calculate the string length for the smallest overflowing number:
|
||||
let max_len_string = format_radix(num, base as u128);
|
||||
// Ensure that string length is deemed to potentially overflow:
|
||||
assert!(can_overflow::<$t>(base, &max_len_string));
|
||||
|
@ -831,9 +831,9 @@ fn partial_line_buffered_after_line_write() {
|
||||
assert_eq!(&writer.get_ref().buffer, b"Line 1\nLine 2\nLine 3");
|
||||
}
|
||||
|
||||
/// Test that, given a partial line that exceeds the length of
|
||||
/// LineBuffer's buffer (that is, without a trailing newline), that that
|
||||
/// line is written to the inner writer
|
||||
/// Test that for calls to LineBuffer::write where the passed bytes do not contain
|
||||
/// a newline and on their own are greater in length than the internal buffer, the
|
||||
/// passed bytes are immediately written to the inner writer.
|
||||
#[test]
|
||||
fn long_line_flushed() {
|
||||
let writer = ProgrammableSink::default();
|
||||
@ -844,9 +844,10 @@ fn long_line_flushed() {
|
||||
}
|
||||
|
||||
/// Test that, given a very long partial line *after* successfully
|
||||
/// flushing a complete line, that that line is buffered unconditionally,
|
||||
/// and no additional writes take place. This assures the property that
|
||||
/// `write` should make at-most-one attempt to write new data.
|
||||
/// flushing a complete line, the very long partial line is buffered
|
||||
/// unconditionally, and no additional writes take place. This assures
|
||||
/// the property that `write` should make at-most-one attempt to write
|
||||
/// new data.
|
||||
#[test]
|
||||
fn line_long_tail_not_flushed() {
|
||||
let writer = ProgrammableSink::default();
|
||||
|
@ -36,7 +36,7 @@ fn initialize_unfilled() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn addvance_filled() {
|
||||
fn advance_filled() {
|
||||
let buf: &mut [_] = &mut [0; 16];
|
||||
let mut rbuf: BorrowedBuf<'_> = buf.into();
|
||||
|
||||
|
@ -1925,7 +1925,7 @@ mod type_keyword {}
|
||||
/// `unsafe_op_in_unsafe_fn` lint can be enabled to warn against that and require explicit unsafe
|
||||
/// blocks even inside `unsafe fn`.
|
||||
///
|
||||
/// See the [Rustnomicon] and the [Reference] for more information.
|
||||
/// See the [Rustonomicon] and the [Reference] for more information.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -2129,7 +2129,7 @@ mod type_keyword {}
|
||||
/// [`impl`]: keyword.impl.html
|
||||
/// [raw pointers]: ../reference/types/pointer.html
|
||||
/// [memory safety]: ../book/ch19-01-unsafe-rust.html
|
||||
/// [Rustnomicon]: ../nomicon/index.html
|
||||
/// [Rustonomicon]: ../nomicon/index.html
|
||||
/// [nomicon-soundness]: ../nomicon/safe-unsafe-meaning.html
|
||||
/// [soundness]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library
|
||||
/// [Reference]: ../reference/unsafety.html
|
||||
|
@ -450,7 +450,7 @@ impl AsHandle for OwnedHandle {
|
||||
#[inline]
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
// Safety: `OwnedHandle` and `BorrowedHandle` have the same validity
|
||||
// invariants, and the `BorrowdHandle` is bounded by the lifetime
|
||||
// invariants, and the `BorrowedHandle` is bounded by the lifetime
|
||||
// of `&self`.
|
||||
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ impl AsSocket for OwnedSocket {
|
||||
#[inline]
|
||||
fn as_socket(&self) -> BorrowedSocket<'_> {
|
||||
// Safety: `OwnedSocket` and `BorrowedSocket` have the same validity
|
||||
// invariants, and the `BorrowdSocket` is bounded by the lifetime
|
||||
// invariants, and the `BorrowedSocket` is bounded by the lifetime
|
||||
// of `&self`.
|
||||
unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ fn sync_once_cell() {
|
||||
assert_eq!(ONCE_CELL.get(), Some(&92));
|
||||
});
|
||||
|
||||
ONCE_CELL.get_or_init(|| panic!("Kabom!"));
|
||||
ONCE_CELL.get_or_init(|| panic!("Kaboom!"));
|
||||
assert_eq!(ONCE_CELL.get(), Some(&92));
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ use crate::panic::{RefUnwindSafe, UnwindSafe};
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed};
|
||||
use crate::sys::locks as sys;
|
||||
|
||||
/// A re-entrant mutual exclusion
|
||||
/// A reentrant mutual exclusion
|
||||
///
|
||||
/// This mutex will block *other* threads waiting for the lock to become
|
||||
/// available. The thread which has already locked the mutex can lock it
|
||||
|
@ -58,7 +58,7 @@ IMAGE_BASE:
|
||||
globvar DEBUG 1
|
||||
/* The base address (relative to enclave start) of the enclave text section */
|
||||
globvar TEXT_BASE 8
|
||||
/* The size in bytes of enclacve text section */
|
||||
/* The size in bytes of enclave text section */
|
||||
globvar TEXT_SIZE 8
|
||||
/* The base address (relative to enclave start) of the enclave .eh_frame_hdr section */
|
||||
globvar EH_FRM_HDR_OFFSET 8
|
||||
@ -66,7 +66,7 @@ IMAGE_BASE:
|
||||
globvar EH_FRM_HDR_LEN 8
|
||||
/* The base address (relative to enclave start) of the enclave .eh_frame section */
|
||||
globvar EH_FRM_OFFSET 8
|
||||
/* The size in bytes of enclacve .eh_frame section */
|
||||
/* The size in bytes of enclave .eh_frame section */
|
||||
globvar EH_FRM_LEN 8
|
||||
|
||||
.org .Lxsave_clear+512
|
||||
|
@ -735,7 +735,7 @@ impl ExitStatus {
|
||||
// true on all actual versions of Unix, is widely assumed, and is specified in SuS
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
|
||||
// true for a platform pretending to be Unix, the tests (our doctests, and also
|
||||
// procsss_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
|
||||
// process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
|
||||
match NonZero_c_int::try_from(self.0) {
|
||||
/* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)),
|
||||
/* was zero, couldn't convert */ Err(_) => Ok(()),
|
||||
|
@ -199,7 +199,7 @@ impl ExitStatus {
|
||||
// true on all actual versions of Unix, is widely assumed, and is specified in SuS
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not
|
||||
// true for a platform pretending to be Unix, the tests (our doctests, and also
|
||||
// procsss_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
|
||||
// process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too.
|
||||
match NonZero_c_int::try_from(self.0) {
|
||||
Ok(failure) => Err(ExitStatusError(failure)),
|
||||
Err(_) => Ok(()),
|
||||
|
@ -494,7 +494,7 @@ impl Builder {
|
||||
MaybeDangling(mem::MaybeUninit::new(x))
|
||||
}
|
||||
fn into_inner(self) -> T {
|
||||
// SAFETY: we are always initiailized.
|
||||
// SAFETY: we are always initialized.
|
||||
let ret = unsafe { self.0.assume_init_read() };
|
||||
// Make sure we don't drop.
|
||||
mem::forget(self);
|
||||
@ -503,7 +503,7 @@ impl Builder {
|
||||
}
|
||||
impl<T> Drop for MaybeDangling<T> {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: we are always initiailized.
|
||||
// SAFETY: we are always initialized.
|
||||
unsafe { self.0.assume_init_drop() };
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
- [What is rustdoc?](what-is-rustdoc.md)
|
||||
- [Command-line arguments](command-line-arguments.md)
|
||||
- [How to read rustdoc output](how-to-read-rustdoc.md)
|
||||
- [In-doc settings](read-documentation/in-doc-settings.md)
|
||||
- [How to write documentation](how-to-write-documentation.md)
|
||||
- [What to include (and exclude)](write-documentation/what-to-include.md)
|
||||
- [The `#[doc]` attribute](write-documentation/the-doc-attribute.md)
|
||||
|
@ -68,7 +68,7 @@ Typing in the search bar instantly searches the available documentation for
|
||||
the string entered with a fuzzy matching algorithm that is tolerant of minor
|
||||
typos.
|
||||
|
||||
By default, the search results give are "In Names",
|
||||
By default, the search results given are "In Names",
|
||||
meaning that the fuzzy match is made against the names of items.
|
||||
Matching names are shown on the left, and the first few words of their
|
||||
descriptions are given on the right.
|
||||
@ -105,11 +105,6 @@ will match these queries:
|
||||
|
||||
But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`.
|
||||
|
||||
### Changing displayed theme
|
||||
|
||||
You can change the displayed theme by opening the settings menu (the gear
|
||||
icon in the upper right) and then pick a new one from there.
|
||||
|
||||
### Shortcuts
|
||||
|
||||
Pressing `S` while focused elsewhere on the page will move focus to the
|
||||
|
BIN
src/doc/rustdoc/src/images/collapsed-long-item.png
Normal file
BIN
src/doc/rustdoc/src/images/collapsed-long-item.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
src/doc/rustdoc/src/images/collapsed-trait-impls.png
Normal file
BIN
src/doc/rustdoc/src/images/collapsed-trait-impls.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
64
src/doc/rustdoc/src/read-documentation/in-doc-settings.md
Normal file
64
src/doc/rustdoc/src/read-documentation/in-doc-settings.md
Normal file
@ -0,0 +1,64 @@
|
||||
# Rustdoc in-doc settings
|
||||
|
||||
Rustdoc's HTML output includes a settings menu, and this chapter describes what
|
||||
each setting in this menu does.
|
||||
|
||||
It can be accessed by clicking on the gear button
|
||||
(<i class="fa fa-cog" aria-hidden="true"></i>) in the upper right.
|
||||
|
||||
## Changing displayed theme
|
||||
|
||||
It is possible to change the theme. If you pick the "system preference", you
|
||||
will be able to see two new sub-menus: "Preferred light theme" and "Preferred
|
||||
dark theme". It means that if your system preference is set to "light", then
|
||||
rustdoc will use the theme you selected in "Preferred light theme".
|
||||
|
||||
## Auto-hide item contents for large items
|
||||
|
||||
If the type definition contains more than 12 items, and this setting is enabled,
|
||||
it'll collapse them by default. You can see them by clicking on the `[+]` button
|
||||
to expand them.
|
||||
|
||||
A good example of this setting in use can be seen in the
|
||||
[`Iterator`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) doc
|
||||
page:
|
||||
|
||||
![Collapsed long item](../images/collapsed-long-item.png)
|
||||
|
||||
## Auto-hide item methods' documentation
|
||||
|
||||
If enabled, this setting will collapse all trait implementations blocks. It is
|
||||
convenient if you just want an overview of all the methods available. You can
|
||||
still see a method's documentation by expanding it.
|
||||
|
||||
## Auto-hide trait implementation documentation
|
||||
|
||||
If enabled, this setting will collapse all trait implementations blocks (you can
|
||||
see them in the "Trait Implementations" section). It is convenient if you just
|
||||
want an overview of all the trait implemented on a type. You can still see
|
||||
a trait implementation's associated items by expanding it.
|
||||
|
||||
Example:
|
||||
|
||||
![Collapsed trait implementations](../images/collapsed-trait-impls.png)
|
||||
|
||||
## Directly go to item in search if there is only one result
|
||||
|
||||
If this setting is enabled, you will directly be taken to the result page if
|
||||
your search only returned one element. Useful if you know exactly what you're
|
||||
looking for and want to be taken there directly and not waste time selecting the
|
||||
only search result.
|
||||
|
||||
## Show line numbers on code examples
|
||||
|
||||
If enabled, this setting will add line numbers to the code examples in the
|
||||
documentation. It provides a visual aide for the code reading.
|
||||
|
||||
## Disable keyboard shortcuts
|
||||
|
||||
If this setting is enabled, the keyboard shortcuts will be disabled. It's useful
|
||||
in case some of these shortcuts are already used by a web extension you're
|
||||
using.
|
||||
|
||||
To see the full list of the rustdoc keyboard shortcuts, you can open the help
|
||||
menu (the button with the question mark on the left of the setting menu button).
|
@ -741,8 +741,10 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionReplacer<'a, 'tcx> {
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
match *r {
|
||||
// These are the regions that can be seen in the AST.
|
||||
ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned().unwrap_or(r),
|
||||
_ => r,
|
||||
ty::ReEarlyBound(_) | ty::ReStatic | ty::ReLateBound(..) | ty::ReError(_) => r,
|
||||
r => bug!("unexpected region: {r:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -679,6 +679,10 @@ pub(crate) fn make_test(
|
||||
// parse the source, but only has false positives, not false
|
||||
// negatives.
|
||||
if s.contains(crate_name) {
|
||||
// rustdoc implicitly inserts an `extern crate` item for the own crate
|
||||
// which may be unused, so we need to allow the lint.
|
||||
prog.push_str(&format!("#[allow(unused_extern_crates)]\n"));
|
||||
|
||||
prog.push_str(&format!("extern crate r#{crate_name};\n"));
|
||||
line_offset += 1;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ fn make_test_crate_name() {
|
||||
let input = "use asdf::qwop;
|
||||
assert_eq!(2+2, 4);";
|
||||
let expected = "#![allow(unused)]
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate r#asdf;
|
||||
fn main() {
|
||||
use asdf::qwop;
|
||||
@ -128,6 +129,7 @@ fn make_test_opts_attrs() {
|
||||
let input = "use asdf::qwop;
|
||||
assert_eq!(2+2, 4);";
|
||||
let expected = "#![feature(sick_rad)]
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate r#asdf;
|
||||
fn main() {
|
||||
use asdf::qwop;
|
||||
@ -141,6 +143,7 @@ assert_eq!(2+2, 4);
|
||||
opts.attrs.push("feature(hella_dope)".to_string());
|
||||
let expected = "#![feature(sick_rad)]
|
||||
#![feature(hella_dope)]
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate r#asdf;
|
||||
fn main() {
|
||||
use asdf::qwop;
|
||||
@ -236,6 +239,7 @@ assert_eq!(asdf::foo, 4);";
|
||||
|
||||
let expected = "#![allow(unused)]
|
||||
extern crate hella_qwop;
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate r#asdf;
|
||||
fn main() {
|
||||
assert_eq!(asdf::foo, 4);
|
||||
|
@ -279,7 +279,10 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
||||
p.push(output.index.get(&output.root).unwrap().name.clone().unwrap());
|
||||
p.set_extension("json");
|
||||
let mut file = BufWriter::new(try_err!(File::create(&p), p));
|
||||
serde_json::ser::to_writer(&mut file, &output).unwrap();
|
||||
self.tcx
|
||||
.sess
|
||||
.time("rustdoc_json_serialization", || serde_json::ser::to_writer(&mut file, &output))
|
||||
.unwrap();
|
||||
try_err!(file.flush(), p);
|
||||
|
||||
Ok(())
|
||||
|
@ -385,10 +385,12 @@ pub fn check(path: &Path, bad: &mut bool) {
|
||||
}
|
||||
if filename != "style.rs" {
|
||||
if trimmed.contains("TODO") {
|
||||
err("TODO is deprecated; use FIXME")
|
||||
err(
|
||||
"TODO is used for tasks that should be done before merging a PR; If you want to leave a message in the codebase use FIXME",
|
||||
)
|
||||
}
|
||||
if trimmed.contains("//") && trimmed.contains(" XXX") {
|
||||
err("XXX is deprecated; use FIXME")
|
||||
err("Instead of XXX use FIXME")
|
||||
}
|
||||
if any_problematic_line {
|
||||
for s in problematic_consts_strings.iter() {
|
||||
|
@ -10,4 +10,4 @@
|
||||
pub fn dummy() {}
|
||||
|
||||
// ensure that `extern crate foo;` was inserted into code snips automatically:
|
||||
// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern+crate+r%23foo;%0Afn+main()+%7B%0Ause+foo::dummy;%0Adummy();%0A%7D&edition=2015"]' "Run"
|
||||
// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0A%23%5Ballow(unused_extern_crates)%5D%0Aextern+crate+r%23foo;%0Afn+main()+%7B%0Ause+foo::dummy;%0Adummy();%0A%7D&edition=2015"]' "Run"
|
||||
|
@ -72,4 +72,13 @@ fn main() {
|
||||
} else {
|
||||
&0
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct Foo;
|
||||
let foo = Foo;
|
||||
let bar = &Foo;
|
||||
|
||||
if foo == bar {
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +175,19 @@ LL | || };
|
||||
| |_____`if` and `else` have incompatible types
|
||||
| expected `i32`, found `&{integer}`
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/deref-suggestion.rs:81:15
|
||||
|
|
||||
LL | if foo == bar {
|
||||
| --- ^^^ expected `Foo`, found `&Foo`
|
||||
| |
|
||||
| expected because this is `Foo`
|
||||
|
|
||||
help: consider dereferencing the borrow
|
||||
|
|
||||
LL | if foo == *bar {
|
||||
| +
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
10
tests/ui/inference/issue-70082.rs
Normal file
10
tests/ui/inference/issue-70082.rs
Normal file
@ -0,0 +1,10 @@
|
||||
fn main() {
|
||||
// this closure is fine, and should not get any error annotations
|
||||
let em = |v: f64| -> f64 { v };
|
||||
|
||||
let x: f64 = em(1i16.into());
|
||||
|
||||
let y: f64 = 0.01f64 * 1i16.into();
|
||||
//~^ ERROR type annotations needed
|
||||
//~| HELP try using a fully qualified path
|
||||
}
|
17
tests/ui/inference/issue-70082.stderr
Normal file
17
tests/ui/inference/issue-70082.stderr
Normal file
@ -0,0 +1,17 @@
|
||||
error[E0284]: type annotations needed
|
||||
--> $DIR/issue-70082.rs:7:33
|
||||
|
|
||||
LL | let y: f64 = 0.01f64 * 1i16.into();
|
||||
| - ^^^^
|
||||
| |
|
||||
| type must be known at this point
|
||||
|
|
||||
= note: cannot satisfy `<f64 as Mul<_>>::Output == f64`
|
||||
help: try using a fully qualified path to specify the expected types
|
||||
|
|
||||
LL | let y: f64 = 0.01f64 * <i16 as Into<T>>::into(1i16);
|
||||
| +++++++++++++++++++++++ ~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0284`.
|
Loading…
x
Reference in New Issue
Block a user