diff --git a/Cargo.lock b/Cargo.lock index 6857451116ddd..1677422122e2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3669,6 +3669,7 @@ dependencies = [ "rustc_feature", "rustc_lexer", "rustc_lint_defs", + "rustc_macros", "rustc_parse", "rustc_parse_format", "rustc_session", diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index 9d81330745fe2..d359d7efb6268 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -62,7 +62,8 @@ impl OutlivesSuggestionBuilder { | RegionNameSource::AnonRegionFromUpvar(..) | RegionNameSource::AnonRegionFromOutput(..) | RegionNameSource::AnonRegionFromYieldTy(..) - | RegionNameSource::AnonRegionFromAsyncFn(..) => { + | RegionNameSource::AnonRegionFromAsyncFn(..) + | RegionNameSource::AnonRegionFromImplSignature(..) => { debug!("Region {:?} is NOT suggestable", name); false } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 1db4b902f7150..8f3699553d92c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -6,7 +6,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, RegionVid, Ty}; +use rustc_middle::ty::{self, DefIdTree, RegionVid, Ty}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -45,6 +45,8 @@ pub(crate) enum RegionNameSource { AnonRegionFromYieldTy(Span, String), /// An anonymous region from an async fn. AnonRegionFromAsyncFn(Span), + /// An anonymous region from an impl self type or trait + AnonRegionFromImplSignature(Span, &'static str), } /// Describes what to highlight to explain to the user that we're giving an anonymous region a @@ -75,7 +77,8 @@ impl RegionName { | RegionNameSource::AnonRegionFromUpvar(..) | RegionNameSource::AnonRegionFromOutput(..) | RegionNameSource::AnonRegionFromYieldTy(..) - | RegionNameSource::AnonRegionFromAsyncFn(..) => false, + | RegionNameSource::AnonRegionFromAsyncFn(..) + | RegionNameSource::AnonRegionFromImplSignature(..) => false, } } @@ -87,7 +90,8 @@ impl RegionName { | RegionNameSource::SynthesizedFreeEnvRegion(span, _) | RegionNameSource::AnonRegionFromUpvar(span, _) | RegionNameSource::AnonRegionFromYieldTy(span, _) - | RegionNameSource::AnonRegionFromAsyncFn(span) => Some(span), + | RegionNameSource::AnonRegionFromAsyncFn(span) + | RegionNameSource::AnonRegionFromImplSignature(span, _) => Some(span), RegionNameSource::AnonRegionFromArgument(ref highlight) | RegionNameSource::AnonRegionFromOutput(ref highlight, _) => match *highlight { RegionNameHighlight::MatchedHirTy(span) @@ -166,6 +170,12 @@ impl RegionName { RegionNameSource::AnonRegionFromYieldTy(span, type_name) => { diag.span_label(*span, format!("yield type is {type_name}")); } + RegionNameSource::AnonRegionFromImplSignature(span, location) => { + diag.span_label( + *span, + format!("lifetime `{self}` appears in the `impl`'s {location}"), + ); + } RegionNameSource::Static => {} } } @@ -240,7 +250,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr)) .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr)) .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr)); + .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr)); if let Some(ref value) = value { self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone()); @@ -847,4 +858,43 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name), }) } + + fn give_name_if_anonymous_region_appears_in_impl_signature( + &self, + fr: RegionVid, + ) -> Option { + let ty::ReEarlyBound(region) = *self.to_error_region(fr)? else { + return None; + }; + if region.has_name() { + return None; + }; + + let tcx = self.infcx.tcx; + let body_parent_did = tcx.opt_parent(self.mir_def_id().to_def_id())?; + if tcx.parent(region.def_id) != body_parent_did + || tcx.def_kind(body_parent_did) != DefKind::Impl + { + return None; + } + + let mut found = false; + tcx.fold_regions(tcx.type_of(body_parent_did), &mut true, |r: ty::Region<'tcx>, _| { + if *r == ty::ReEarlyBound(region) { + found = true; + } + r + }); + + Some(RegionName { + name: self.synthesize_region_name(), + source: RegionNameSource::AnonRegionFromImplSignature( + tcx.def_span(region.def_id), + // FIXME(compiler-errors): Does this ever actually show up + // anywhere other than the self type? I couldn't create an + // example of a `'_` in the impl's trait being referenceable. + if found { "self type" } else { "header" }, + ), + }) + } } diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 9031c3b2ecfbb..7dc947f7d9a14 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -16,6 +16,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } +rustc_macros = { path = "../rustc_macros" } rustc_parse = { path = "../rustc_parse" } rustc_target = { path = "../rustc_target" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index f5ef4765df64f..c75d83bd0a0e3 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -8,6 +8,7 @@ use rustc_ast::tokenstream::TokenStream; use rustc_attr as attr; use rustc_errors::PResult; use rustc_expand::base::{self, *}; +use rustc_macros::SessionDiagnostic; use rustc_span::Span; pub fn expand_cfg( @@ -34,13 +35,26 @@ pub fn expand_cfg( } } -fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> { +#[derive(SessionDiagnostic)] +#[error(slug = "builtin-macros-requires-cfg-pattern")] +struct RequiresCfgPattern { + #[primary_span] + #[label] + span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(slug = "builtin-macros-expected-one-cfg-pattern")] +struct OneCfgPattern { + #[primary_span] + span: Span, +} + +fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> { let mut p = cx.new_parser_from_tts(tts); if p.token == token::Eof { - let mut err = cx.struct_span_err(sp, "macro requires a cfg-pattern as an argument"); - err.span_label(sp, "cfg-pattern required"); - return Err(err); + return Err(cx.create_err(RequiresCfgPattern { span })); } let cfg = p.parse_meta_item()?; @@ -48,7 +62,7 @@ fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a let _ = p.eat(&token::Comma); if !p.eat(&token::Eof) { - return Err(cx.struct_span_err(sp, "expected 1 cfg-pattern")); + return Err(cx.create_err(OneCfgPattern { span })); } Ok(cfg) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 8ac5f094cf6ee..b5b63942e2c6e 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1140,7 +1140,7 @@ impl<'a> Linker for EmLinker<'a> { fn no_crt_objects(&mut self) {} fn no_default_libraries(&mut self) { - self.cmd.args(&["-s", "DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=[]"]); + self.cmd.arg("-nodefaultlibs"); } fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) { diff --git a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl new file mode 100644 index 0000000000000..1d3e33c81851f --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl @@ -0,0 +1,5 @@ +builtin-macros-requires-cfg-pattern = + macro requires a cfg-pattern as an argument + .label = cfg-pattern required + +builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index ba7cc4908b80f..7211c05432698 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -33,6 +33,7 @@ pub use unic_langid::{langid, LanguageIdentifier}; fluent_messages! { parser => "../locales/en-US/parser.ftl", typeck => "../locales/en-US/typeck.ftl", + builtin_macros => "../locales/en-US/builtin_macros.ftl", } pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES}; diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 75b6b1cc9195b..245719bff1202 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -14,7 +14,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, use rustc_lint_defs::builtin::PROC_MACRO_BACK_COMPAT; use rustc_lint_defs::BuiltinLintDiagnostics; use rustc_parse::{self, parser, MACRO_ARGUMENTS}; -use rustc_session::{parse::ParseSess, Limit, Session}; +use rustc_session::{parse::ParseSess, Limit, Session, SessionDiagnostic}; use rustc_span::def_id::{CrateNum, DefId, LocalDefId}; use rustc_span::edition::Edition; use rustc_span::hygiene::{AstPass, ExpnData, ExpnKind, LocalExpnId}; @@ -1085,6 +1085,17 @@ impl<'a> ExtCtxt<'a> { self.sess.parse_sess.span_diagnostic.struct_span_err(sp, msg) } + pub fn create_err( + &self, + err: impl SessionDiagnostic<'a>, + ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + self.sess.create_err(err) + } + + pub fn emit_err(&self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed { + self.sess.emit_err(err) + } + /// Emit `msg` attached to `sp`, without immediately stopping /// compilation. /// diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index cb1c6f4098767..1cd19c7eaab35 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -26,6 +26,9 @@ macro_rules! pluralize { ("is", $x:expr) => { if $x == 1 { "is" } else { "are" } }; + ("was", $x:expr) => { + if $x == 1 { "was" } else { "were" } + }; ("this", $x:expr) => { if $x == 1 { "this" } else { "these" } }; diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 4265559cd3197..3f5b16d5ea5f7 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2145,10 +2145,7 @@ impl<'tcx> Place<'tcx> { pub fn iter_projections( self, ) -> impl Iterator, PlaceElem<'tcx>)> + DoubleEndedIterator { - self.projection.iter().enumerate().map(move |(i, proj)| { - let base = PlaceRef { local: self.local, projection: &self.projection[..i] }; - (base, proj) - }) + self.as_ref().iter_projections() } /// Generates a new place by appending `more_projections` to the existing ones @@ -2208,6 +2205,23 @@ impl<'tcx> PlaceRef<'tcx> { None } } + + /// Iterate over the projections in evaluation order, i.e., the first element is the base with + /// its projection and then subsequently more projections are added. + /// As a concrete example, given the place a.b.c, this would yield: + /// - (a, .b) + /// - (a.b, .c) + /// + /// Given a place without projections, the iterator is empty. + #[inline] + pub fn iter_projections( + self, + ) -> impl Iterator, PlaceElem<'tcx>)> + DoubleEndedIterator { + self.projection.iter().enumerate().map(move |(i, proj)| { + let base = PlaceRef { local: self.local, projection: &self.projection[..i] }; + (base, *proj) + }) + } } impl Debug for Place<'_> { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c9589a7048870..c3df9a66fe718 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -74,7 +74,7 @@ use std::mem; use std::ops::{Bound, Deref}; use std::sync::Arc; -use super::RvalueScopes; +use super::{ImplPolarity, RvalueScopes}; pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { /// Creates a new `OnDiskCache` instance from the serialized data in `data`. @@ -2230,6 +2230,20 @@ impl<'tcx> TyCtxt<'tcx> { }) } + /// Given a `ty`, return whether it's an `impl Future<...>`. + pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool { + let ty::Opaque(def_id, _) = ty.kind() else { return false }; + let future_trait = self.lang_items().future_trait().unwrap(); + + self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| { + let ty::PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder() else { + return false; + }; + trait_predicate.trait_ref.def_id == future_trait + && trait_predicate.polarity == ImplPolarity::Positive + }) + } + /// Computes the def-ids of the transitive supertraits of `trait_def_id`. This (intentionally) /// does not compute the full elaborated super-predicates but just the set of def-ids. It is used /// to identify which traits may define a given associated type to help avoid cycle errors. diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index e934e189f05f3..0cc6d05d1d086 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1502,6 +1502,7 @@ impl<'a> Resolver<'a> { return PathResult::NonModule(PartialRes::new(Res::Err)); } else if opt_ns.is_some() && (is_last || maybe_assoc) { self.lint_if_path_starts_with_module(finalize, path, second_binding); + record_segment_res(self, res); return PathResult::NonModule(PartialRes::with_unresolved_segments( res, path.len() - i - 1, diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs index 975051100b039..6a1a5e7a1d712 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs @@ -28,6 +28,7 @@ pub fn target() -> Target { linker: None, is_like_emscripten: true, panic_strategy: PanicStrategy::Unwind, + no_default_libraries: false, post_link_args, families: cvs!["unix", "wasm"], ..options diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 0485cac9e9f74..fbe66d7dcdd2b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2386,24 +2386,87 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { { let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); - let ty = parent_trait_ref.skip_binder().self_ty(); - matches!(ty.kind(), ty::Generator(..)) - || matches!(ty.kind(), ty::Closure(..)) + let nested_ty = parent_trait_ref.skip_binder().self_ty(); + matches!(nested_ty.kind(), ty::Generator(..)) + || matches!(nested_ty.kind(), ty::Closure(..)) } else { false } }; + let from_generator = tcx.lang_items().from_generator_fn().unwrap(); + // Don't print the tuple of capture types - if !is_upvar_tys_infer_tuple { - let msg = format!("required because it appears within the type `{}`", ty); - match ty.kind() { - ty::Adt(def, _) => match self.tcx.opt_item_ident(def.did()) { - Some(ident) => err.span_note(ident.span, &msg), - None => err.note(&msg), - }, - _ => err.note(&msg), - }; + 'print: { + if !is_upvar_tys_infer_tuple { + let msg = format!("required because it appears within the type `{}`", ty); + match ty.kind() { + ty::Adt(def, _) => { + // `gen_future` is used in all async functions; it doesn't add any additional info. + if self.tcx.is_diagnostic_item(sym::gen_future, def.did()) { + break 'print; + } + match self.tcx.opt_item_ident(def.did()) { + Some(ident) => err.span_note(ident.span, &msg), + None => err.note(&msg), + } + } + ty::Opaque(def_id, _) => { + // Avoid printing the future from `core::future::from_generator`, it's not helpful + if tcx.parent(*def_id) == from_generator { + break 'print; + } + + // If the previous type is `from_generator`, this is the future generated by the body of an async function. + // Avoid printing it twice (it was already printed in the `ty::Generator` arm below). + let is_future = tcx.ty_is_opaque_future(ty); + debug!( + ?obligated_types, + ?is_future, + "note_obligation_cause_code: check for async fn" + ); + if is_future + && obligated_types.last().map_or(false, |ty| match ty.kind() { + ty::Opaque(last_def_id, _) => { + tcx.parent(*last_def_id) == from_generator + } + _ => false, + }) + { + break 'print; + } + err.span_note(self.tcx.def_span(def_id), &msg) + } + ty::GeneratorWitness(bound_tys) => { + use std::fmt::Write; + + // FIXME: this is kind of an unusual format for rustc, can we make it more clear? + // Maybe we should just remove this note altogether? + // FIXME: only print types which don't meet the trait requirement + let mut msg = + "required because it captures the following types: ".to_owned(); + for ty in bound_tys.skip_binder() { + write!(msg, "`{}`, ", ty).unwrap(); + } + err.note(msg.trim_end_matches(", ")) + } + ty::Generator(def_id, _, _) => { + let sp = self.tcx.def_span(def_id); + + // Special-case this to say "async block" instead of `[static generator]`. + let kind = tcx.generator_kind(def_id).unwrap(); + err.span_note( + sp, + &format!("required because it's used within this {}", kind), + ) + } + ty::Closure(def_id, _) => err.span_note( + self.tcx.def_span(def_id), + &format!("required because it's used within this closure"), + ), + _ => err.note(&msg), + }; + } } obligated_types.push(ty); diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 84e3180b491a1..eec3b24aec260 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -2111,14 +2111,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { extend: impl Fn(&mut DiagnosticBuilder<'tcx, ErrorGuaranteed>), ) -> bool { let args = segments.clone().flat_map(|segment| segment.args().args); - let types_and_spans: Vec<_> = segments - .clone() - .flat_map(|segment| { - segment.res.and_then(|res| { - if segment.args().args.is_empty() { - None - } else { - Some(( + + let (lt, ty, ct, inf) = + args.clone().fold((false, false, false, false), |(lt, ty, ct, inf), arg| match arg { + hir::GenericArg::Lifetime(_) => (true, ty, ct, inf), + hir::GenericArg::Type(_) => (lt, true, ct, inf), + hir::GenericArg::Const(_) => (lt, ty, true, inf), + hir::GenericArg::Infer(_) => (lt, ty, ct, true), + }); + let mut emitted = false; + if lt || ty || ct || inf { + let types_and_spans: Vec<_> = segments + .clone() + .flat_map(|segment| { + segment.res.and_then(|res| { + if segment.args().args.is_empty() { + None + } else { + Some(( match res { Res::PrimTy(ty) => format!("{} `{}`", res.descr(), ty.name()), Res::Def(_, def_id) @@ -2130,32 +2140,23 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }, segment.ident.span, )) - } + } + }) }) - }) - .collect(); - let this_type = match &types_and_spans[..] { - [.., _, (last, _)] => format!( - "{} and {last}", - types_and_spans[..types_and_spans.len() - 1] - .iter() - .map(|(x, _)| x.as_str()) - .intersperse(&", ") - .collect::() - ), - [(only, _)] => only.to_string(), - [] => "this type".to_string(), - }; + .collect(); + let this_type = match &types_and_spans[..] { + [.., _, (last, _)] => format!( + "{} and {last}", + types_and_spans[..types_and_spans.len() - 1] + .iter() + .map(|(x, _)| x.as_str()) + .intersperse(&", ") + .collect::() + ), + [(only, _)] => only.to_string(), + [] => "this type".to_string(), + }; - let (lt, ty, ct, inf) = - args.clone().fold((false, false, false, false), |(lt, ty, ct, inf), arg| match arg { - hir::GenericArg::Lifetime(_) => (true, ty, ct, inf), - hir::GenericArg::Type(_) => (lt, true, ct, inf), - hir::GenericArg::Const(_) => (lt, ty, true, inf), - hir::GenericArg::Infer(_) => (lt, ty, ct, true), - }); - let mut emitted = false; - if lt || ty || ct || inf { let arg_spans: Vec = args.map(|arg| arg.span()).collect(); let mut kinds = Vec::with_capacity(4); diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 77d6495f38c2f..b4476d5c59b2b 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -26,10 +26,10 @@ use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructEx use rustc_ast as ast; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::Diagnostic; -use rustc_errors::EmissionGuarantee; -use rustc_errors::ErrorGuaranteed; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{ + pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId, + EmissionGuarantee, ErrorGuaranteed, +}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -1701,12 +1701,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; self.typeck_results.borrow_mut().fru_field_types_mut().insert(expr_id, fru_tys); } else if adt_kind != AdtKind::Union && !remaining_fields.is_empty() { - let inaccessible_remaining_fields = remaining_fields.iter().any(|(_, (_, field))| { - !field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx) - }); + debug!(?remaining_fields); + let private_fields: Vec<&ty::FieldDef> = variant + .fields + .iter() + .filter(|field| { + !field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx) + }) + .collect(); - if inaccessible_remaining_fields { - self.report_inaccessible_fields(adt_ty, span); + if !private_fields.is_empty() { + self.report_private_fields(adt_ty, span, private_fields, ast_fields); } else { self.report_missing_fields( adt_ty, @@ -1830,7 +1835,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Report an error for a struct field expression when there are invisible fields. /// /// ```text - /// error: cannot construct `Foo` with struct literal syntax due to inaccessible fields + /// error: cannot construct `Foo` with struct literal syntax due to private fields /// --> src/main.rs:8:5 /// | /// 8 | foo::Foo {}; @@ -1838,13 +1843,54 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// /// error: aborting due to previous error /// ``` - fn report_inaccessible_fields(&self, adt_ty: Ty<'tcx>, span: Span) { - self.tcx.sess.span_err( + fn report_private_fields( + &self, + adt_ty: Ty<'tcx>, + span: Span, + private_fields: Vec<&ty::FieldDef>, + used_fields: &'tcx [hir::ExprField<'tcx>], + ) { + let mut err = self.tcx.sess.struct_span_err( span, &format!( - "cannot construct `{adt_ty}` with struct literal syntax due to inaccessible fields", + "cannot construct `{adt_ty}` with struct literal syntax due to private fields", ), ); + let (used_private_fields, remaining_private_fields): ( + Vec<(Symbol, Span, bool)>, + Vec<(Symbol, Span, bool)>, + ) = private_fields + .iter() + .map(|field| { + match used_fields.iter().find(|used_field| field.name == used_field.ident.name) { + Some(used_field) => (field.name, used_field.span, true), + None => (field.name, self.tcx.def_span(field.did), false), + } + }) + .partition(|field| field.2); + err.span_labels(used_private_fields.iter().map(|(_, span, _)| *span), "private field"); + if !remaining_private_fields.is_empty() { + let remaining_private_fields_len = remaining_private_fields.len(); + let names = match &remaining_private_fields + .iter() + .map(|(name, _, _)| name.to_string()) + .collect::>()[..] + { + _ if remaining_private_fields_len > 6 => String::new(), + [name] => format!("`{name}` "), + [names @ .., last] => { + let names = names.iter().map(|name| format!("`{name}`")).collect::>(); + format!("{} and `{last}` ", names.join(", ")) + } + [] => unreachable!(), + }; + err.note(format!( + "... and other private field{s} {names}that {were} not provided", + s = pluralize!(remaining_private_fields_len), + were = pluralize!("was", remaining_private_fields_len), + )); + } + err.emit(); } fn report_unknown_field( diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 3706300dcfeb7..197e7aaaccf3d 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -374,10 +374,11 @@ impl BinaryHeap { BinaryHeap { data: vec![] } } - /// Creates an empty `BinaryHeap` with a specific capacity. - /// This preallocates enough memory for `capacity` elements, - /// so that the `BinaryHeap` does not have to be reallocated - /// until it contains at least that many values. + /// Creates an empty `BinaryHeap` with at least the specified capacity. + /// + /// The binary heap will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is 0, the binary heap will not allocate. /// /// # Examples /// @@ -906,16 +907,18 @@ impl BinaryHeap { self.data.capacity() } - /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the - /// given `BinaryHeap`. Does nothing if the capacity is already sufficient. + /// Reserves the minimum capacity for at least `additional` elements more than + /// the current length. Unlike [`reserve`], this will not + /// deliberately over-allocate to speculatively avoid frequent allocations. + /// After calling `reserve_exact`, capacity will be greater than or equal to + /// `self.len() + additional`. Does nothing if the capacity is already + /// sufficient. /// - /// Note that the allocator may give the collection more space than it requests. Therefore - /// capacity can not be relied upon to be precisely minimal. Prefer [`reserve`] if future - /// insertions are expected. + /// [`reserve`]: BinaryHeap::reserve /// /// # Panics /// - /// Panics if the new capacity overflows `usize`. + /// Panics if the new capacity overflows [`usize`]. /// /// # Examples /// @@ -935,12 +938,15 @@ impl BinaryHeap { self.data.reserve_exact(additional); } - /// Reserves capacity for at least `additional` more elements to be inserted in the - /// `BinaryHeap`. The collection may reserve more space to avoid frequent reallocations. + /// Reserves capacity for at least `additional` elements more than the + /// current length. The allocator may reserve more space to speculatively + /// avoid frequent allocations. After calling `reserve`, + /// capacity will be greater than or equal to `self.len() + additional`. + /// Does nothing if capacity is already sufficient. /// /// # Panics /// - /// Panics if the new capacity overflows `usize`. + /// Panics if the new capacity overflows [`usize`]. /// /// # Examples /// @@ -958,10 +964,11 @@ impl BinaryHeap { self.data.reserve(additional); } - /// Tries to reserve the minimum capacity for exactly `additional` - /// elements to be inserted in the given `BinaryHeap`. After calling - /// `try_reserve_exact`, capacity will be greater than or equal to - /// `self.len() + additional` if it returns `Ok(())`. + /// Tries to reserve the minimum capacity for at least `additional` elements + /// more than the current length. Unlike [`try_reserve`], this will not + /// deliberately over-allocate to speculatively avoid frequent allocations. + /// After calling `try_reserve_exact`, capacity will be greater than or + /// equal to `self.len() + additional` if it returns `Ok(())`. /// Does nothing if the capacity is already sufficient. /// /// Note that the allocator may give the collection more space than it @@ -999,11 +1006,11 @@ impl BinaryHeap { self.data.try_reserve_exact(additional) } - /// Tries to reserve capacity for at least `additional` more elements to be inserted - /// in the given `BinaryHeap`. The collection may reserve more space to avoid - /// frequent reallocations. After calling `try_reserve`, capacity will be - /// greater than or equal to `self.len() + additional`. Does nothing if - /// capacity is already sufficient. + /// Tries to reserve capacity for at least `additional` elements more than the + /// current length. The allocator may reserve more space to speculatively + /// avoid frequent allocations. After calling `try_reserve`, capacity will be + /// greater than or equal to `self.len() + additional` if it returns + /// `Ok(())`. Does nothing if capacity is already sufficient. /// /// # Errors /// diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index f92e5759b6f9e..4d895d83745b2 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -688,7 +688,7 @@ impl VecDeque { self.cap() - 1 } - /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the + /// Reserves the minimum capacity for at least `additional` more elements to be inserted in the /// given deque. Does nothing if the capacity is already sufficient. /// /// Note that the allocator may give the collection more space than it requests. Therefore @@ -716,7 +716,7 @@ impl VecDeque { } /// Reserves capacity for at least `additional` more elements to be inserted in the given - /// deque. The collection may reserve more space to avoid frequent reallocations. + /// deque. The collection may reserve more space to speculatively avoid frequent reallocations. /// /// # Panics /// @@ -748,10 +748,10 @@ impl VecDeque { } } - /// Tries to reserve the minimum capacity for exactly `additional` more elements to + /// Tries to reserve the minimum capacity for at least `additional` more elements to /// be inserted in the given deque. After calling `try_reserve_exact`, - /// capacity will be greater than or equal to `self.len() + additional`. - /// Does nothing if the capacity is already sufficient. + /// capacity will be greater than or equal to `self.len() + additional` if + /// it returns `Ok(())`. Does nothing if the capacity is already sufficient. /// /// Note that the allocator may give the collection more space than it /// requests. Therefore, capacity can not be relied upon to be precisely @@ -791,10 +791,10 @@ impl VecDeque { } /// Tries to reserve capacity for at least `additional` more elements to be inserted - /// in the given deque. The collection may reserve more space to avoid + /// in the given deque. The collection may reserve more space to speculatively avoid /// frequent reallocations. After calling `try_reserve`, capacity will be - /// greater than or equal to `self.len() + additional`. Does nothing if - /// capacity is already sufficient. + /// greater than or equal to `self.len() + additional` if it returns + /// `Ok(())`. Does nothing if capacity is already sufficient. /// /// # Errors /// diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 668af60611b86..8883880726594 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -455,13 +455,13 @@ impl String { String { vec: Vec::new() } } - /// Creates a new empty `String` with a particular capacity. + /// Creates a new empty `String` with at least the specified capacity. /// /// `String`s have an internal buffer to hold their data. The capacity is /// the length of that buffer, and can be queried with the [`capacity`] /// method. This method creates an empty `String`, but one with an initial - /// buffer that can hold `capacity` bytes. This is useful when you may be - /// appending a bunch of data to the `String`, reducing the number of + /// buffer that can hold at least `capacity` bytes. This is useful when you + /// may be appending a bunch of data to the `String`, reducing the number of /// reallocations it needs to do. /// /// [`capacity`]: String::capacity @@ -979,21 +979,16 @@ impl String { self.vec.capacity() } - /// Ensures that this `String`'s capacity is at least `additional` bytes - /// larger than its length. - /// - /// The capacity may be increased by more than `additional` bytes if it - /// chooses, to prevent frequent reallocations. - /// - /// If you do not want this "at least" behavior, see the [`reserve_exact`] - /// method. + /// Reserves capacity for at least `additional` bytes more than the + /// current length. The allocator may reserve more space to speculatively + /// avoid frequent allocations. After calling `reserve`, + /// capacity will be greater than or equal to `self.len() + additional`. + /// Does nothing if capacity is already sufficient. /// /// # Panics /// /// Panics if the new capacity overflows [`usize`]. /// - /// [`reserve_exact`]: String::reserve_exact - /// /// # Examples /// /// Basic usage: @@ -1013,15 +1008,16 @@ impl String { /// s.push('a'); /// s.push('b'); /// - /// // s now has a length of 2 and a capacity of 10 + /// // s now has a length of 2 and a capacity of at least 10 + /// let capacity = s.capacity(); /// assert_eq!(2, s.len()); - /// assert_eq!(10, s.capacity()); + /// assert!(capacity >= 10); /// - /// // Since we already have an extra 8 capacity, calling this... + /// // Since we already have at least an extra 8 capacity, calling this... /// s.reserve(8); /// /// // ... doesn't actually increase. - /// assert_eq!(10, s.capacity()); + /// assert_eq!(capacity, s.capacity()); /// ``` #[cfg(not(no_global_oom_handling))] #[inline] @@ -1030,17 +1026,18 @@ impl String { self.vec.reserve(additional) } - /// Ensures that this `String`'s capacity is `additional` bytes - /// larger than its length. - /// - /// Consider using the [`reserve`] method unless you absolutely know - /// better than the allocator. + /// Reserves the minimum capacity for at least `additional` bytes more than + /// the current length. Unlike [`reserve`], this will not + /// deliberately over-allocate to speculatively avoid frequent allocations. + /// After calling `reserve_exact`, capacity will be greater than or equal to + /// `self.len() + additional`. Does nothing if the capacity is already + /// sufficient. /// /// [`reserve`]: String::reserve /// /// # Panics /// - /// Panics if the new capacity overflows `usize`. + /// Panics if the new capacity overflows [`usize`]. /// /// # Examples /// @@ -1061,15 +1058,16 @@ impl String { /// s.push('a'); /// s.push('b'); /// - /// // s now has a length of 2 and a capacity of 10 + /// // s now has a length of 2 and a capacity of at least 10 + /// let capacity = s.capacity(); /// assert_eq!(2, s.len()); - /// assert_eq!(10, s.capacity()); + /// assert!(capacity >= 10); /// - /// // Since we already have an extra 8 capacity, calling this... + /// // Since we already have at least an extra 8 capacity, calling this... /// s.reserve_exact(8); /// /// // ... doesn't actually increase. - /// assert_eq!(10, s.capacity()); + /// assert_eq!(capacity, s.capacity()); /// ``` #[cfg(not(no_global_oom_handling))] #[inline] @@ -1078,11 +1076,11 @@ impl String { self.vec.reserve_exact(additional) } - /// Tries to reserve capacity for at least `additional` more elements to be inserted - /// in the given `String`. The collection may reserve more space to avoid - /// frequent reallocations. After calling `reserve`, capacity will be - /// greater than or equal to `self.len() + additional`. Does nothing if - /// capacity is already sufficient. + /// Tries to reserve capacity for at least `additional` bytes more than the + /// current length. The allocator may reserve more space to speculatively + /// avoid frequent allocations. After calling `try_reserve`, capacity will be + /// greater than or equal to `self.len() + additional` if it returns + /// `Ok(())`. Does nothing if capacity is already sufficient. /// /// # Errors /// @@ -1112,9 +1110,11 @@ impl String { self.vec.try_reserve(additional) } - /// Tries to reserve the minimum capacity for exactly `additional` more elements to - /// be inserted in the given `String`. After calling `try_reserve_exact`, - /// capacity will be greater than or equal to `self.len() + additional`. + /// Tries to reserve the minimum capacity for at least `additional` bytes + /// more than the current length. Unlike [`try_reserve`], this will not + /// deliberately over-allocate to speculatively avoid frequent allocations. + /// After calling `try_reserve_exact`, capacity will be greater than or + /// equal to `self.len() + additional` if it returns `Ok(())`. /// Does nothing if the capacity is already sufficient. /// /// Note that the allocator may give the collection more space than it diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 2670b15982ad9..24e849aab4cce 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1355,15 +1355,16 @@ impl Clone for Arc { // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) let old_size = self.inner().strong.fetch_add(1, Relaxed); - // However we need to guard against massive refcounts in case someone - // is `mem::forget`ing Arcs. If we don't do this the count can overflow - // and users will use-after free. We racily saturate to `isize::MAX` on - // the assumption that there aren't ~2 billion threads incrementing - // the reference count at once. This branch will never be taken in - // any realistic program. + // However we need to guard against massive refcounts in case someone is `mem::forget`ing + // Arcs. If we don't do this the count can overflow and users will use-after free. This + // branch will never be taken in any realistic program. We abort because such a program is + // incredibly degenerate, and we don't care to support it. // - // We abort because such a program is incredibly degenerate, and we - // don't care to support it. + // This check is not 100% water-proof: we error when the refcount grows beyond `isize::MAX`. + // But we do that check *after* having done the increment, so there is a chance here that + // the worst already happened and we actually do overflow the `usize` counter. However, that + // requires the counter to grow from `isize::MAX` to `usize::MAX` between the increment + // above and the `abort` below, which seems exceedingly unlikely. if old_size > MAX_REFCOUNT { abort(); } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 1c0cb6636a134..e25f98d8aa695 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -425,17 +425,25 @@ impl Vec { Vec { buf: RawVec::NEW, len: 0 } } - /// Constructs a new, empty `Vec` with the specified capacity. + /// Constructs a new, empty `Vec` with at least the specified capacity. /// - /// The vector will be able to hold exactly `capacity` elements without - /// reallocating. If `capacity` is 0, the vector will not allocate. + /// The vector will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is 0, the vector will not allocate. /// /// It is important to note that although the returned vector has the - /// *capacity* specified, the vector will have a zero *length*. For an - /// explanation of the difference between length and capacity, see + /// minimum *capacity* specified, the vector will have a zero *length*. For + /// an explanation of the difference between length and capacity, see /// *[Capacity and reallocation]*. /// + /// If it is imporant to know the exact allocated capacity of a `Vec`, + /// always use the [`capacity`] method after construction. + /// + /// For `Vec` where `T` is a zero-sized type, there will be no allocation + /// and the capacity will always be `usize::MAX`. + /// /// [Capacity and reallocation]: #capacity-and-reallocation + /// [`capacity`]: Vec::capacity /// /// # Panics /// @@ -448,19 +456,24 @@ impl Vec { /// /// // The vector contains no items, even though it has capacity for more /// assert_eq!(vec.len(), 0); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// /// // These are all done without reallocating... /// for i in 0..10 { /// vec.push(i); /// } /// assert_eq!(vec.len(), 10); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// /// // ...but this may make the vector reallocate /// vec.push(11); /// assert_eq!(vec.len(), 11); /// assert!(vec.capacity() >= 11); + /// + /// // A vector of a zero-sized type will always over-allocate, since no + /// // allocation is necessary + /// let vec_units = Vec::<()>::with_capacity(10); + /// assert_eq!(vec_units.capacity(), usize::MAX); /// ``` #[cfg(not(no_global_oom_handling))] #[inline] @@ -566,18 +579,26 @@ impl Vec { Vec { buf: RawVec::new_in(alloc), len: 0 } } - /// Constructs a new, empty `Vec` with the specified capacity with the provided - /// allocator. + /// Constructs a new, empty `Vec` with at least the specified capacity + /// with the provided allocator. /// - /// The vector will be able to hold exactly `capacity` elements without - /// reallocating. If `capacity` is 0, the vector will not allocate. + /// The vector will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is 0, the vector will not allocate. /// /// It is important to note that although the returned vector has the - /// *capacity* specified, the vector will have a zero *length*. For an - /// explanation of the difference between length and capacity, see + /// minimum *capacity* specified, the vector will have a zero *length*. For + /// an explanation of the difference between length and capacity, see /// *[Capacity and reallocation]*. /// + /// If it is imporant to know the exact allocated capacity of a `Vec`, + /// always use the [`capacity`] method after construction. + /// + /// For `Vec` where `T` is a zero-sized type, there will be no allocation + /// and the capacity will always be `usize::MAX`. + /// /// [Capacity and reallocation]: #capacity-and-reallocation + /// [`capacity`]: Vec::capacity /// /// # Panics /// @@ -607,6 +628,11 @@ impl Vec { /// vec.push(11); /// assert_eq!(vec.len(), 11); /// assert!(vec.capacity() >= 11); + /// + /// // A vector of a zero-sized type will always over-allocate, since no + /// // allocation is necessary + /// let vec_units = Vec::<(), System>::with_capacity_in(10, System); + /// assert_eq!(vec_units.capacity(), usize::MAX); /// ``` #[cfg(not(no_global_oom_handling))] #[inline] @@ -793,10 +819,10 @@ impl Vec { } /// Reserves capacity for at least `additional` more elements to be inserted - /// in the given `Vec`. The collection may reserve more space to avoid - /// frequent reallocations. After calling `reserve`, capacity will be - /// greater than or equal to `self.len() + additional`. Does nothing if - /// capacity is already sufficient. + /// in the given `Vec`. The collection may reserve more space to + /// speculatively avoid frequent reallocations. After calling `reserve`, + /// capacity will be greater than or equal to `self.len() + additional`. + /// Does nothing if capacity is already sufficient. /// /// # Panics /// @@ -815,10 +841,12 @@ impl Vec { self.buf.reserve(self.len, additional); } - /// Reserves the minimum capacity for exactly `additional` more elements to - /// be inserted in the given `Vec`. After calling `reserve_exact`, - /// capacity will be greater than or equal to `self.len() + additional`. - /// Does nothing if the capacity is already sufficient. + /// Reserves the minimum capacity for at least `additional` more elements to + /// be inserted in the given `Vec`. Unlike [`reserve`], this will not + /// deliberately over-allocate to speculatively avoid frequent allocations. + /// After calling `reserve_exact`, capacity will be greater than or equal to + /// `self.len() + additional`. Does nothing if the capacity is already + /// sufficient. /// /// Note that the allocator may give the collection more space than it /// requests. Therefore, capacity can not be relied upon to be precisely @@ -844,10 +872,10 @@ impl Vec { } /// Tries to reserve capacity for at least `additional` more elements to be inserted - /// in the given `Vec`. The collection may reserve more space to avoid + /// in the given `Vec`. The collection may reserve more space to speculatively avoid /// frequent reallocations. After calling `try_reserve`, capacity will be - /// greater than or equal to `self.len() + additional`. Does nothing if - /// capacity is already sufficient. + /// greater than or equal to `self.len() + additional` if it returns + /// `Ok(())`. Does nothing if capacity is already sufficient. /// /// # Errors /// @@ -879,10 +907,11 @@ impl Vec { self.buf.try_reserve(self.len, additional) } - /// Tries to reserve the minimum capacity for exactly `additional` - /// elements to be inserted in the given `Vec`. After calling - /// `try_reserve_exact`, capacity will be greater than or equal to - /// `self.len() + additional` if it returns `Ok(())`. + /// Tries to reserve the minimum capacity for at least `additional` + /// elements to be inserted in the given `Vec`. Unlike [`try_reserve`], + /// this will not deliberately over-allocate to speculatively avoid frequent + /// allocations. After calling `try_reserve_exact`, capacity will be greater + /// than or equal to `self.len() + additional` if it returns `Ok(())`. /// Does nothing if the capacity is already sufficient. /// /// Note that the allocator may give the collection more space than it diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index cc768c73c0e03..5520f6ebf1904 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -2128,6 +2128,15 @@ fn test_vec_cycle_wrapped() { c3.refs.v[1].set(Some(&c2)); } +#[test] +fn test_zero_sized_capacity() { + for len in [0, 1, 2, 4, 8, 16, 32, 64, 128, 256] { + let v = Vec::<()>::with_capacity(len); + assert_eq!(v.len(), 0); + assert_eq!(v.capacity(), usize::MAX); + } +} + #[test] fn test_zero_sized_vec_push() { const N: usize = 8; diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 237c5ee73409e..db811343fa322 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -233,10 +233,11 @@ impl HashMap { Default::default() } - /// Creates an empty `HashMap` with the specified capacity. + /// Creates an empty `HashMap` with at least the specified capacity. /// /// The hash map will be able to hold at least `capacity` elements without - /// reallocating. If `capacity` is 0, the hash map will not allocate. + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is 0, the hash set will not allocate. /// /// # Examples /// @@ -282,18 +283,19 @@ impl HashMap { HashMap { base: base::HashMap::with_hasher(hash_builder) } } - /// Creates an empty `HashMap` with the specified capacity, using `hash_builder` - /// to hash the keys. + /// Creates an empty `HashMap` with at least the specified capacity, using + /// `hasher` to hash the keys. /// /// The hash map will be able to hold at least `capacity` elements without - /// reallocating. If `capacity` is 0, the hash map will not allocate. + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is 0, the hash map will not allocate. /// - /// Warning: `hash_builder` is normally randomly generated, and + /// Warning: `hasher` is normally randomly generated, and /// is designed to allow HashMaps to be resistant to attacks that /// cause many collisions and very poor performance. Setting it /// manually using this function can expose a DoS attack vector. /// - /// The `hash_builder` passed should implement the [`BuildHasher`] trait for + /// The `hasher` passed should implement the [`BuildHasher`] trait for /// the HashMap to be useful, see its documentation for details. /// /// # Examples @@ -308,8 +310,8 @@ impl HashMap { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap { - HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hash_builder) } + pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashMap { + HashMap { base: base::HashMap::with_capacity_and_hasher(capacity, hasher) } } /// Returns the number of elements the map can hold without reallocating. @@ -731,8 +733,10 @@ where S: BuildHasher, { /// Reserves capacity for at least `additional` more elements to be inserted - /// in the `HashMap`. The collection may reserve more space to avoid - /// frequent reallocations. + /// in the `HashMap`. The collection may reserve more space to speculatively + /// avoid frequent reallocations. After calling `reserve`, + /// capacity will be greater than or equal to `self.len() + additional`. + /// Does nothing if capacity is already sufficient. /// /// # Panics /// @@ -752,8 +756,11 @@ where } /// Tries to reserve capacity for at least `additional` more elements to be inserted - /// in the given `HashMap`. The collection may reserve more space to avoid - /// frequent reallocations. + /// in the `HashMap`. The collection may reserve more space to speculatively + /// avoid frequent reallocations. After calling `reserve`, + /// capacity will be greater than or equal to `self.len() + additional` if + /// it returns `Ok(())`. + /// Does nothing if capacity is already sufficient. /// /// # Errors /// @@ -766,7 +773,7 @@ where /// use std::collections::HashMap; /// /// let mut map: HashMap<&str, isize> = HashMap::new(); - /// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?"); + /// map.try_reserve(10).expect("why is the test harness OOMing on a handful of bytes?"); /// ``` #[inline] #[stable(feature = "try_reserve", since = "1.57.0")] diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index fa498a987d6af..abff82788a38d 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -133,10 +133,11 @@ impl HashSet { Default::default() } - /// Creates an empty `HashSet` with the specified capacity. + /// Creates an empty `HashSet` with at least the specified capacity. /// /// The hash set will be able to hold at least `capacity` elements without - /// reallocating. If `capacity` is 0, the hash set will not allocate. + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is 0, the hash set will not allocate. /// /// # Examples /// @@ -379,11 +380,12 @@ impl HashSet { HashSet { base: base::HashSet::with_hasher(hasher) } } - /// Creates an empty `HashSet` with the specified capacity, using + /// Creates an empty `HashSet` with at least the specified capacity, using /// `hasher` to hash the keys. /// /// The hash set will be able to hold at least `capacity` elements without - /// reallocating. If `capacity` is 0, the hash set will not allocate. + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is 0, the hash set will not allocate. /// /// Warning: `hasher` is normally randomly generated, and /// is designed to allow `HashSet`s to be resistant to attacks that @@ -434,8 +436,10 @@ where S: BuildHasher, { /// Reserves capacity for at least `additional` more elements to be inserted - /// in the `HashSet`. The collection may reserve more space to avoid - /// frequent reallocations. + /// in the `HashSet`. The collection may reserve more space to speculatively + /// avoid frequent reallocations. After calling `reserve`, + /// capacity will be greater than or equal to `self.len() + additional`. + /// Does nothing if capacity is already sufficient. /// /// # Panics /// @@ -456,8 +460,11 @@ where } /// Tries to reserve capacity for at least `additional` more elements to be inserted - /// in the given `HashSet`. The collection may reserve more space to avoid - /// frequent reallocations. + /// in the `HashSet`. The collection may reserve more space to speculatively + /// avoid frequent reallocations. After calling `reserve`, + /// capacity will be greater than or equal to `self.len() + additional` if + /// it returns `Ok(())`. + /// Does nothing if capacity is already sufficient. /// /// # Errors /// @@ -469,7 +476,7 @@ where /// ``` /// use std::collections::HashSet; /// let mut set: HashSet = HashSet::new(); - /// set.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?"); + /// set.try_reserve(10).expect("why is the test harness OOMing on a handful of bytes?"); /// ``` #[inline] #[stable(feature = "try_reserve", since = "1.57.0")] diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 95d274c3c91e7..f2bbcc85cecda 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -196,10 +196,11 @@ impl OsString { self.inner.push_slice(&s.as_ref().inner) } - /// Creates a new `OsString` with the given capacity. + /// Creates a new `OsString` with at least the given capacity. /// - /// The string will be able to hold exactly `capacity` length units of other - /// OS strings without reallocating. If `capacity` is 0, the string will not + /// The string will be able to hold at least `capacity` length units of other + /// OS strings without reallocating. This method is allowed to allocate for + /// more units than `capacity`. If `capacity` is 0, the string will not /// allocate. /// /// See the main `OsString` documentation information about encoding and capacity units. @@ -263,9 +264,10 @@ impl OsString { } /// Reserves capacity for at least `additional` more capacity to be inserted - /// in the given `OsString`. + /// in the given `OsString`. Does nothing if the capacity is + /// already sufficient. /// - /// The collection may reserve more space to avoid frequent reallocations. + /// The collection may reserve more space to speculatively avoid frequent reallocations. /// /// See the main `OsString` documentation information about encoding and capacity units. /// @@ -285,10 +287,10 @@ impl OsString { } /// Tries to reserve capacity for at least `additional` more length units - /// in the given `OsString`. The string may reserve more space to avoid + /// in the given `OsString`. The string may reserve more space to speculatively avoid /// frequent reallocations. After calling `try_reserve`, capacity will be - /// greater than or equal to `self.len() + additional`. Does nothing if - /// capacity is already sufficient. + /// greater than or equal to `self.len() + additional` if it returns `Ok(())`. + /// Does nothing if capacity is already sufficient. /// /// See the main `OsString` documentation information about encoding and capacity units. /// @@ -322,7 +324,7 @@ impl OsString { self.inner.try_reserve(additional) } - /// Reserves the minimum capacity for exactly `additional` more capacity to + /// Reserves the minimum capacity for at least `additional` more capacity to /// be inserted in the given `OsString`. Does nothing if the capacity is /// already sufficient. /// @@ -349,7 +351,7 @@ impl OsString { self.inner.reserve_exact(additional) } - /// Tries to reserve the minimum capacity for exactly `additional` + /// Tries to reserve the minimum capacity for at least `additional` /// more length units in the given `OsString`. After calling /// `try_reserve_exact`, capacity will be greater than or equal to /// `self.len() + additional` if it returns `Ok(())`. diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs index 2d3a0f37b4c2a..6acb937e78479 100644 --- a/library/std/src/io/buffered/bufwriter.rs +++ b/library/std/src/io/buffered/bufwriter.rs @@ -97,11 +97,11 @@ impl BufWriter { BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner) } - /// Creates a new `BufWriter` with the specified buffer capacity. + /// Creates a new `BufWriter` with at least the specified buffer capacity. /// /// # Examples /// - /// Creating a buffer with a buffer of a hundred bytes. + /// Creating a buffer with a buffer of at least a hundred bytes. /// /// ```no_run /// use std::io::BufWriter; diff --git a/library/std/src/io/buffered/linewriter.rs b/library/std/src/io/buffered/linewriter.rs index d7b620d6f9177..a26a4ab330e7a 100644 --- a/library/std/src/io/buffered/linewriter.rs +++ b/library/std/src/io/buffered/linewriter.rs @@ -89,8 +89,8 @@ impl LineWriter { LineWriter::with_capacity(1024, inner) } - /// Creates a new `LineWriter` with a specified capacity for the internal - /// buffer. + /// Creates a new `LineWriter` with at least the specified capacity for the + /// internal buffer. /// /// # Examples /// diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index 03834411d1529..9cf038687f117 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.9.5 \ No newline at end of file +0.9.6 \ No newline at end of file diff --git a/src/doc/book b/src/doc/book index 396fdb69de7fb..efbafdba36184 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 396fdb69de7fb18f24b15c7ad13491b1c1fa7231 +Subproject commit efbafdba3618487fbc9305318fcab9775132ac15 diff --git a/src/doc/embedded-book b/src/doc/embedded-book index cbb494f96da32..e17dcef5e9634 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit cbb494f96da3268c2925bdadc65ca83d42f2d4ef +Subproject commit e17dcef5e96346ee3d7fa56820ddc7e5c39636bc diff --git a/src/doc/reference b/src/doc/reference index 683bfe5cd64d5..9fce337a55ee4 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 683bfe5cd64d589c6a1645312ab5f93b6385ccbb +Subproject commit 9fce337a55ee4a4629205f6094656195cecad231 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index dbb7e5e2345ee..1095df2a5850f 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit dbb7e5e2345ee26199ffba218156b6009016a20c +Subproject commit 1095df2a5850f2d345fad43a30633133365875ba diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 6e4d6435db89b..048d925f0a955 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 6e4d6435db89bcc027b1bba9742e4f59666f5412 +Subproject commit 048d925f0a955aac601c4160c0e7f05771bcf63b diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index d0229bdb5f23c..b4b7790eebba1 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -387,16 +387,20 @@ nav.sub { overflow-y: hidden; } +.rustdoc.source .sidebar .sidebar-logo { + display: none; +} + .source .sidebar > *:not(#sidebar-toggle) { opacity: 0; visibility: hidden; } -.source .sidebar.expanded { +.source-sidebar-expanded .source .sidebar { overflow-y: auto; } -.source .sidebar.expanded > *:not(#sidebar-toggle) { +.source-sidebar-expanded .source .sidebar > *:not(#sidebar-toggle) { opacity: 1; visibility: visible; } @@ -1682,11 +1686,11 @@ details.rustdoc-toggle[open] > summary.hideme::after { /* When we expand the sidebar on the source code page, we hide the logo on the left of the search bar to have more space. */ - .sidebar.expanded + main .width-limiter .sub-logo-container.rust-logo { + .source-sidebar-expanded .source .sidebar + main .width-limiter .sub-logo-container.rust-logo { display: none; } - .source .sidebar.expanded { + .source-sidebar-expanded .source .sidebar { width: 300px; } } @@ -1766,7 +1770,7 @@ details.rustdoc-toggle[open] > summary.hideme::after { } .sidebar.shown, - .sidebar.expanded, + .source-sidebar-expanded .source .sidebar, .sidebar:focus-within { left: 0; } @@ -1889,11 +1893,7 @@ details.rustdoc-toggle[open] > summary.hideme::after { left: -11px; } - .sidebar.expanded #sidebar-toggle { - font-size: 1.5rem; - } - - .sidebar:not(.expanded) #sidebar-toggle { + #sidebar-toggle { position: fixed; left: 1px; top: 100px; @@ -1910,6 +1910,14 @@ details.rustdoc-toggle[open] > summary.hideme::after { border-left: 0; } + .source-sidebar-expanded #sidebar-toggle { + left: unset; + top: unset; + width: unset; + border-top-right-radius: unset; + border-bottom-right-radius: unset; + } + #source-sidebar { z-index: 11; } @@ -1952,7 +1960,7 @@ details.rustdoc-toggle[open] > summary.hideme::after { padding-left: 2em; } - .source .sidebar.expanded { + .source-sidebar-expanded .source .sidebar { max-width: 100vw; width: 100vw; } @@ -2010,9 +2018,12 @@ details.rustdoc-toggle[open] > summary.hideme::after { width: 35px; } - .sidebar:not(.expanded) #sidebar-toggle { + #sidebar-toggle { top: 10px; } + .source-sidebar-expanded #sidebar-toggle { + top: unset; + } } .method-toggle summary, diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index 10f93a1c058da..290c29d3141a2 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -63,14 +63,13 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { } function toggleSidebar() { - const sidebar = document.querySelector("nav.sidebar"); const child = this.children[0]; if (child.innerText === ">") { - sidebar.classList.add("expanded"); + addClass(document.documentElement, "source-sidebar-expanded"); child.innerText = "<"; updateLocalStorage("source-sidebar-show", "true"); } else { - sidebar.classList.remove("expanded"); + removeClass(document.documentElement, "source-sidebar-expanded"); child.innerText = ">"; updateLocalStorage("source-sidebar-show", "false"); } @@ -103,11 +102,6 @@ function createSourceSidebar() { const sidebar = document.createElement("div"); sidebar.id = "source-sidebar"; - if (getCurrentValue("source-sidebar-show") !== "true") { - container.classList.remove("expanded"); - } else { - container.classList.add("expanded"); - } let hasFoundFile = false; diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 4fcf049923491..1c4c88344888c 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -1,3 +1,8 @@ +// storage.js is loaded in the `` of all rustdoc pages and doesn't +// use `async` or `defer`. That means it blocks further parsing and rendering +// of the page: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script. +// This makes it the correct place to act on settings that affect the display of +// the page, so we don't see major layout changes during the load of the page. "use strict"; const darkThemes = ["dark", "ayu"]; @@ -236,6 +241,12 @@ if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) { switchToSavedTheme(); } +if (getSettingValue("source-sidebar-show") === "true") { + // At this point in page load, `document.body` is not available yet. + // Set a class on the `` element instead. + addClass(document.documentElement, "source-sidebar-expanded"); +} + // If we navigate away (for example to a settings page), and then use the back or // forward button to get back to a page, the theme may have changed in the meantime. // But scripts may not be re-loaded in such a case due to the bfcache diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 4fde63c99d4b9..c627dcc30d667 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -43,7 +43,7 @@ impl JsonRenderer<'_> { let span = item.span(self.tcx); let clean::Item { name, attrs: _, kind: _, visibility, item_id, cfg: _ } = item; let inner = match *item.kind { - clean::StrippedItem(_) => return None, + clean::StrippedItem(_) | clean::KeywordItem(_) => return None, _ => from_clean_item(item, self.tcx), }; Some(Item { @@ -254,11 +254,8 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum { }, // FIXME: do not map to Typedef but to a custom variant AssocTypeItem(t, _) => ItemEnum::Typedef(t.into_tcx(tcx)), - // `convert_item` early returns `None` for striped items - StrippedItem(_) => unreachable!(), - KeywordItem(_) => { - panic!("{:?} is not supported for JSON output", item) - } + // `convert_item` early returns `None` for striped items and keywords. + StrippedItem(_) | KeywordItem(_) => unreachable!(), ExternCrateItem { ref src } => ItemEnum::ExternCrate { name: name.as_ref().unwrap().to_string(), rename: src.map(|x| x.to_string()), @@ -764,7 +761,7 @@ impl FromWithTcx for ItemKind { fn ids(items: impl IntoIterator, tcx: TyCtxt<'_>) -> Vec { items .into_iter() - .filter(|x| !x.is_stripped()) + .filter(|x| !x.is_stripped() && !x.is_keyword()) .map(|i| from_item_id_with_name(i.item_id, tcx, i.name)) .collect() } diff --git a/src/test/rustdoc-gui/sidebar-source-code.goml b/src/test/rustdoc-gui/sidebar-source-code.goml index 8b4a8bd40dd7e..724520bc399d0 100644 --- a/src/test/rustdoc-gui/sidebar-source-code.goml +++ b/src/test/rustdoc-gui/sidebar-source-code.goml @@ -8,12 +8,12 @@ assert-css: ("nav.sidebar", {"width": "50px"}) // We now click on the button to expand the sidebar. click: (10, 10) // We wait for the sidebar to be expanded. -wait-for-css: ("nav.sidebar.expanded", {"width": "300px"}) -assert-css: ("nav.sidebar.expanded a", {"font-size": "14px"}) +wait-for-css: (".source-sidebar-expanded nav.sidebar", {"width": "300px"}) +assert-css: (".source-sidebar-expanded nav.sidebar a", {"font-size": "14px"}) // We collapse the sidebar. click: (10, 10) // We ensure that the class has been removed. -wait-for: "nav.sidebar:not(.expanded)" +wait-for: "html:not(.expanded)" assert: "nav.sidebar" // We now switch to mobile mode. @@ -22,11 +22,11 @@ size: (600, 600) assert-css: ("nav.sidebar", {"width": "1px"}) // We expand the sidebar. click: "#sidebar-toggle" -assert-css: ("nav.sidebar.expanded", {"width": "600px"}) +assert-css: (".source-sidebar-expanded nav.sidebar", {"width": "600px"}) // We collapse the sidebar. click: (10, 10) // We ensure that the class has been removed. -assert-false: "nav.sidebar.expanded" +assert-false: ".source-sidebar-expanded" assert: "nav.sidebar" // Check that the topbar is not visible diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index 188b2605f0f13..b45512601f208 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -32,7 +32,7 @@ assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH) // First we "open" it. click: "#sidebar-toggle" -assert: ".sidebar.expanded" +assert: ".source-sidebar-expanded" // We check that the first entry of the sidebar is collapsed (which, for whatever reason, // is number 2 and not 1...). diff --git a/src/test/rustdoc-json/keyword.rs b/src/test/rustdoc-json/keyword.rs new file mode 100644 index 0000000000000..78a843aca7b95 --- /dev/null +++ b/src/test/rustdoc-json/keyword.rs @@ -0,0 +1,21 @@ +// Regression test for . + +// Keywords should not be generated in rustdoc JSON output and this test +// ensures it. + +#![feature(rustdoc_internals)] +#![no_std] + +// @has keyword.json +// @!has - "$.index[*][?(@.name=='match')]" +// @has - "$.index[*][?(@.name=='foo')]" + +#[doc(keyword = "match")] +/// this is a test! +pub mod foo {} + +// @!has - "$.index[*][?(@.name=='hello')]" +// @!has - "$.index[*][?(@.name=='bar')]" +#[doc(keyword = "hello")] +/// hello +mod bar {} diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr index 28d94b14ac914..4285fbbeceb60 100644 --- a/src/test/ui/async-await/issue-68112.stderr +++ b/src/test/ui/async-await/issue-68112.stderr @@ -42,15 +42,27 @@ LL | require_send(send_fut); | = help: the trait `Sync` is not implemented for `RefCell` = note: required because of the requirements on the impl of `Send` for `Arc>` - = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36]` - = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36]>` - = note: required because it appears within the type `impl Future>>` - = note: required because it appears within the type `impl Future>>` - = note: required because it appears within the type `impl Future>>` - = note: required because it appears within the type `{ResumeTy, impl Future>>, (), i32, Ready}` - = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6]` - = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6]>` - = note: required because it appears within the type `impl Future` +note: required because it's used within this `async fn` body + --> $DIR/issue-68112.rs:47:31 + | +LL | async fn ready2(t: T) -> T { t } + | ^^^^^ +note: required because it appears within the type `impl Future>>` + --> $DIR/issue-68112.rs:48:31 + | +LL | fn make_non_send_future2() -> impl Future>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required because it captures the following types: `ResumeTy`, `impl Future>>`, `()`, `i32`, `Ready` +note: required because it's used within this `async` block + --> $DIR/issue-68112.rs:55:26 + | +LL | let send_fut = async { + | __________________________^ +LL | | let non_send_fut = make_non_send_future2(); +LL | | let _ = non_send_fut.await; +LL | | ready(0).await; +LL | | }; + | |_____^ note: required by a bound in `require_send` --> $DIR/issue-68112.rs:11:25 | diff --git a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr new file mode 100644 index 0000000000000..43b7cb8cece36 --- /dev/null +++ b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr @@ -0,0 +1,40 @@ +error[E0277]: `Sender` cannot be shared between threads safely + --> $DIR/issue-70935-complex-spans.rs:13:45 + | +LL | fn foo(tx: std::sync::mpsc::Sender) -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^ `Sender` cannot be shared between threads safely + | + = help: the trait `Sync` is not implemented for `Sender` + = note: required because of the requirements on the impl of `Send` for `&Sender` +note: required because it's used within this closure + --> $DIR/issue-70935-complex-spans.rs:25:13 + | +LL | baz(|| async{ + | _____________^ +LL | | foo(tx.clone()); +LL | | }).await; + | |_________^ +note: required because it's used within this `async fn` body + --> $DIR/issue-70935-complex-spans.rs:9:67 + | +LL | async fn baz(_c: impl FnMut() -> T) where T: Future { + | ___________________________________________________________________^ +LL | | +LL | | } + | |_^ + = note: required because it captures the following types: `ResumeTy`, `impl Future`, `()` +note: required because it's used within this `async` block + --> $DIR/issue-70935-complex-spans.rs:23:16 + | +LL | async move { + | ________________^ +LL | | +LL | | baz(|| async{ +LL | | foo(tx.clone()); +LL | | }).await; +LL | | } + | |_____^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/async-await/issue-70935-complex-spans.stderr b/src/test/ui/async-await/issue-70935-complex-spans.normal.stderr similarity index 81% rename from src/test/ui/async-await/issue-70935-complex-spans.stderr rename to src/test/ui/async-await/issue-70935-complex-spans.normal.stderr index db3099381196b..2174f260a7135 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.stderr +++ b/src/test/ui/async-await/issue-70935-complex-spans.normal.stderr @@ -1,12 +1,12 @@ error: future cannot be sent between threads safely - --> $DIR/issue-70935-complex-spans.rs:10:45 + --> $DIR/issue-70935-complex-spans.rs:13:45 | LL | fn foo(tx: std::sync::mpsc::Sender) -> impl Future + Send { | ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send` | = help: the trait `Sync` is not implemented for `Sender` note: future is not `Send` as this value is used across an await - --> $DIR/issue-70935-complex-spans.rs:15:11 + --> $DIR/issue-70935-complex-spans.rs:27:11 | LL | baz(|| async{ | _____________- @@ -14,9 +14,9 @@ LL | | foo(tx.clone()); LL | | }).await; | | - ^^^^^^ await occurs here, with the value maybe used later | |_________| - | has type `[closure@$DIR/issue-70935-complex-spans.rs:13:13: 15:10]` which is not `Send` + | has type `[closure@$DIR/issue-70935-complex-spans.rs:25:13: 27:10]` which is not `Send` note: the value is later dropped here - --> $DIR/issue-70935-complex-spans.rs:15:17 + --> $DIR/issue-70935-complex-spans.rs:27:17 | LL | }).await; | ^ diff --git a/src/test/ui/async-await/issue-70935-complex-spans.rs b/src/test/ui/async-await/issue-70935-complex-spans.rs index 2965a7e0654a4..f45ce1f25efa0 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.rs +++ b/src/test/ui/async-await/issue-70935-complex-spans.rs @@ -1,16 +1,28 @@ // edition:2018 +// revisions: normal drop_tracking +// [drop_tracking]compile-flags:-Zdrop-tracking // #70935: Check if we do not emit snippet // with newlines which lead complex diagnostics. use std::future::Future; async fn baz(_c: impl FnMut() -> T) where T: Future { +//[drop_tracking]~^ within this `async fn` body } fn foo(tx: std::sync::mpsc::Sender) -> impl Future + Send { - //~^ ERROR: future cannot be sent between threads safely + //[normal]~^ ERROR: future cannot be sent between threads safely + //[drop_tracking]~^^ ERROR: `Sender` cannot be shared + //[drop_tracking]~| NOTE: cannot be shared + //[drop_tracking]~| NOTE: requirements on the impl of `Send` + //[drop_tracking]~| NOTE: captures the following types + //[drop_tracking]~| NOTE: in this expansion + //[drop_tracking]~| NOTE: in this expansion + //[drop_tracking]~| NOTE: in this expansion + //[drop_tracking]~| NOTE: in this expansion async move { - baz(|| async{ + //[drop_tracking]~^ within this `async` block + baz(|| async{ //[drop_tracking]~ NOTE: used within this closure foo(tx.clone()); }).await; } diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.rs b/src/test/ui/async-await/partial-drop-partial-reinit.rs index 73f0ca8153cb9..fe0fce7afd9f9 100644 --- a/src/test/ui/async-await/partial-drop-partial-reinit.rs +++ b/src/test/ui/async-await/partial-drop-partial-reinit.rs @@ -5,9 +5,15 @@ fn main() { gimme_send(foo()); //~^ ERROR cannot be sent between threads safely + //~| NOTE cannot be sent + //~| NOTE bound introduced by + //~| NOTE appears within the type + //~| NOTE captures the following types } fn gimme_send(t: T) { +//~^ NOTE required by this bound +//~| NOTE required by a bound drop(t); } @@ -20,6 +26,8 @@ impl Drop for NotSend { impl !Send for NotSend {} async fn foo() { +//~^ NOTE used within this `async fn` body +//~| NOTE within this `impl Future let mut x = (NotSend {},); drop(x.0); x.0 = NotSend {}; diff --git a/src/test/ui/async-await/partial-drop-partial-reinit.stderr b/src/test/ui/async-await/partial-drop-partial-reinit.stderr index a1c4957e9843a..05f5358340a98 100644 --- a/src/test/ui/async-await/partial-drop-partial-reinit.stderr +++ b/src/test/ui/async-await/partial-drop-partial-reinit.stderr @@ -11,13 +11,21 @@ LL | async fn foo() { | = help: within `impl Future`, the trait `Send` is not implemented for `NotSend` = note: required because it appears within the type `(NotSend,)` - = note: required because it appears within the type `{ResumeTy, (NotSend,), impl Future, ()}` - = note: required because it appears within the type `[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]` - = note: required because it appears within the type `std::future::from_generator::GenFuture<[static generator@$DIR/partial-drop-partial-reinit.rs:22:16: 27:2]>` - = note: required because it appears within the type `impl Future` - = note: required because it appears within the type `impl Future` + = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `impl Future`, `()` +note: required because it's used within this `async fn` body + --> $DIR/partial-drop-partial-reinit.rs:28:16 + | +LL | async fn foo() { + | ________________^ +LL | | +LL | | +LL | | let mut x = (NotSend {},); +... | +LL | | bar().await; +LL | | } + | |_^ note: required by a bound in `gimme_send` - --> $DIR/partial-drop-partial-reinit.rs:10:18 + --> $DIR/partial-drop-partial-reinit.rs:14:18 | LL | fn gimme_send(t: T) { | ^^^^ required by this bound in `gimme_send` diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr index 618c9a172473c..cbc4e2e52315f 100644 --- a/src/test/ui/closures/closure-move-sync.stderr +++ b/src/test/ui/closures/closure-move-sync.stderr @@ -6,7 +6,15 @@ LL | let t = thread::spawn(|| { | = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>` = note: required because of the requirements on the impl of `Send` for `&std::sync::mpsc::Receiver<()>` - = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:6:27: 9:6]` +note: required because it's used within this closure + --> $DIR/closure-move-sync.rs:6:27 + | +LL | let t = thread::spawn(|| { + | ___________________________^ +LL | | recv.recv().unwrap(); +LL | | +LL | | }); + | |_____^ note: required by a bound in `spawn` --> $SRC_DIR/std/src/thread/mod.rs:LL:COL | @@ -21,7 +29,11 @@ LL | thread::spawn(|| tx.send(()).unwrap()); | = help: the trait `Sync` is not implemented for `Sender<()>` = note: required because of the requirements on the impl of `Send` for `&Sender<()>` - = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:18:19: 18:42]` +note: required because it's used within this closure + --> $DIR/closure-move-sync.rs:18:19 + | +LL | thread::spawn(|| tx.send(()).unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `spawn` --> $SRC_DIR/std/src/thread/mod.rs:LL:COL | diff --git a/src/test/ui/error-codes/E0109.stderr b/src/test/ui/error-codes/E0109.stderr index da00fdde6bd0a..8f4cb86de99a0 100644 --- a/src/test/ui/error-codes/E0109.stderr +++ b/src/test/ui/error-codes/E0109.stderr @@ -1,10 +1,10 @@ -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `u32` --> $DIR/E0109.rs:1:14 | LL | type X = u32; | --- ^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u32` | help: primitive type `u32` doesn't have generic parameters | diff --git a/src/test/ui/error-codes/E0110.stderr b/src/test/ui/error-codes/E0110.stderr index 5babb5c2961b7..4ce2a0a410ce4 100644 --- a/src/test/ui/error-codes/E0110.stderr +++ b/src/test/ui/error-codes/E0110.stderr @@ -1,10 +1,10 @@ -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `u32` --> $DIR/E0110.rs:1:14 | LL | type X = u32<'static>; | --- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u32` | help: primitive type `u32` doesn't have generic parameters | diff --git a/src/test/ui/generator/issue-68112.rs b/src/test/ui/generator/issue-68112.rs index feb07c9bf8802..3fcef773b68ab 100644 --- a/src/test/ui/generator/issue-68112.rs +++ b/src/test/ui/generator/issue-68112.rs @@ -20,6 +20,10 @@ pub fn make_gen1(t: T) -> Ready { } fn require_send(_: impl Send) {} +//~^ NOTE required by a bound +//~| NOTE required by a bound +//~| NOTE required by this bound +//~| NOTE required by this bound fn make_non_send_generator() -> impl Generator>> { make_gen1(Arc::new(RefCell::new(0))) @@ -28,29 +32,39 @@ fn make_non_send_generator() -> impl Generator>> { fn test1() { let send_gen = || { let _non_send_gen = make_non_send_generator(); + //~^ NOTE not `Send` yield; - }; + //~^ NOTE yield occurs here + //~| NOTE value is used across a yield + }; //~ NOTE later dropped here require_send(send_gen); //~^ ERROR generator cannot be sent between threads + //~| NOTE not `Send` } pub fn make_gen2(t: T) -> impl Generator { - || { +//~^ NOTE appears within the type +//~| NOTE expansion of desugaring + || { //~ NOTE used within this generator yield; t } } -fn make_non_send_generator2() -> impl Generator>> { +fn make_non_send_generator2() -> impl Generator>> { //~ NOTE appears within the type +//~^ NOTE expansion of desugaring make_gen2(Arc::new(RefCell::new(0))) } fn test2() { - let send_gen = || { + let send_gen = || { //~ NOTE used within this generator let _non_send_gen = make_non_send_generator2(); yield; }; require_send(send_gen); //~^ ERROR `RefCell` cannot be shared between threads safely + //~| NOTE `RefCell` cannot be shared between threads safely + //~| NOTE requirements on the impl + //~| NOTE captures the following types } fn main() {} diff --git a/src/test/ui/generator/issue-68112.stderr b/src/test/ui/generator/issue-68112.stderr index a7d7a73254886..83f068c207643 100644 --- a/src/test/ui/generator/issue-68112.stderr +++ b/src/test/ui/generator/issue-68112.stderr @@ -1,17 +1,19 @@ error: generator cannot be sent between threads safely - --> $DIR/issue-68112.rs:33:5 + --> $DIR/issue-68112.rs:40:5 | LL | require_send(send_gen); | ^^^^^^^^^^^^ generator is not `Send` | = help: the trait `Sync` is not implemented for `RefCell` note: generator is not `Send` as this value is used across a yield - --> $DIR/issue-68112.rs:31:9 + --> $DIR/issue-68112.rs:36:9 | LL | let _non_send_gen = make_non_send_generator(); | ------------- has type `impl Generator>>` which is not `Send` +LL | LL | yield; | ^^^^^ yield occurs here, with `_non_send_gen` maybe used later +... LL | }; | - `_non_send_gen` is later dropped here note: required by a bound in `require_send` @@ -21,18 +23,41 @@ LL | fn require_send(_: impl Send) {} | ^^^^ required by this bound in `require_send` error[E0277]: `RefCell` cannot be shared between threads safely - --> $DIR/issue-68112.rs:52:5 + --> $DIR/issue-68112.rs:63:5 | LL | require_send(send_gen); | ^^^^^^^^^^^^ `RefCell` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `RefCell` = note: required because of the requirements on the impl of `Send` for `Arc>` - = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:38:5: 41:6]` - = note: required because it appears within the type `impl Generator>>` - = note: required because it appears within the type `impl Generator>>` - = note: required because it appears within the type `{impl Generator>>, ()}` - = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:48:20: 51:6]` +note: required because it's used within this generator + --> $DIR/issue-68112.rs:48:5 + | +LL | / || { +LL | | yield; +LL | | t +LL | | } + | |_____^ +note: required because it appears within the type `impl Generator>>` + --> $DIR/issue-68112.rs:45:30 + | +LL | pub fn make_gen2(t: T) -> impl Generator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required because it appears within the type `impl Generator>>` + --> $DIR/issue-68112.rs:53:34 + | +LL | fn make_non_send_generator2() -> impl Generator>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required because it captures the following types: `impl Generator>>`, `()` +note: required because it's used within this generator + --> $DIR/issue-68112.rs:59:20 + | +LL | let send_gen = || { + | ____________________^ +LL | | let _non_send_gen = make_non_send_generator2(); +LL | | yield; +LL | | }; + | |_____^ note: required by a bound in `require_send` --> $DIR/issue-68112.rs:22:25 | diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index 4d2faa198f1af..edf9ee628a2bc 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -6,7 +6,16 @@ LL | assert_send(|| { | = help: the trait `Sync` is not implemented for `Cell` = note: required because of the requirements on the impl of `Send` for `&Cell` - = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:16:17: 20:6]` +note: required because it's used within this generator + --> $DIR/not-send-sync.rs:16:17 + | +LL | assert_send(|| { + | _________________^ +LL | | +LL | | drop(&a); +LL | | yield; +LL | | }); + | |_____^ note: required by a bound in `assert_send` --> $DIR/not-send-sync.rs:7:23 | diff --git a/src/test/ui/generator/print/generator-print-verbose-1.stderr b/src/test/ui/generator/print/generator-print-verbose-1.stderr index 2f7faf520d969..3ee4c1458bad3 100644 --- a/src/test/ui/generator/print/generator-print-verbose-1.stderr +++ b/src/test/ui/generator/print/generator-print-verbose-1.stderr @@ -28,11 +28,34 @@ LL | require_send(send_gen); | = help: the trait `Sync` is not implemented for `RefCell` = note: required because of the requirements on the impl of `Send` for `Arc>` - = note: required because it appears within the type `[make_gen2>>::{closure#0} upvar_tys=(Arc>) {()}]` - = note: required because it appears within the type `Opaque(DefId(0:39 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc>])` - = note: required because it appears within the type `Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])` - = note: required because it appears within the type `{Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), []), ()}` - = note: required because it appears within the type `[test2::{closure#0} upvar_tys=() {Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), []), ()}]` +note: required because it's used within this generator + --> $DIR/generator-print-verbose-1.rs:42:5 + | +LL | / || { +LL | | yield; +LL | | t +LL | | } + | |_____^ +note: required because it appears within the type `Opaque(DefId(0:39 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc>])` + --> $DIR/generator-print-verbose-1.rs:41:30 + | +LL | pub fn make_gen2(t: T) -> impl Generator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required because it appears within the type `Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])` + --> $DIR/generator-print-verbose-1.rs:47:34 + | +LL | fn make_non_send_generator2() -> impl Generator>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: required because it captures the following types: `Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()` +note: required because it's used within this generator + --> $DIR/generator-print-verbose-1.rs:52:20 + | +LL | let send_gen = || { + | ____________________^ +LL | | let _non_send_gen = make_non_send_generator2(); +LL | | yield; +LL | | }; + | |_____^ note: required by a bound in `require_send` --> $DIR/generator-print-verbose-1.rs:26:25 | diff --git a/src/test/ui/generator/print/generator-print-verbose-2.stderr b/src/test/ui/generator/print/generator-print-verbose-2.stderr index fb2a5754dd306..1356fa5f15295 100644 --- a/src/test/ui/generator/print/generator-print-verbose-2.stderr +++ b/src/test/ui/generator/print/generator-print-verbose-2.stderr @@ -6,7 +6,16 @@ LL | assert_send(|| { | = help: the trait `Sync` is not implemented for `Cell` = note: required because of the requirements on the impl of `Send` for `&'_#4r Cell` - = note: required because it appears within the type `[main::{closure#1} upvar_tys=(&'_#4r Cell) _#17t]` +note: required because it's used within this generator + --> $DIR/generator-print-verbose-2.rs:19:17 + | +LL | assert_send(|| { + | _________________^ +LL | | +LL | | drop(&a); +LL | | yield; +LL | | }); + | |_____^ note: required by a bound in `assert_send` --> $DIR/generator-print-verbose-2.rs:10:23 | diff --git a/src/test/ui/impl-trait/auto-trait-leak2.rs b/src/test/ui/impl-trait/auto-trait-leak2.rs index a464f576dc783..09450089adaa8 100644 --- a/src/test/ui/impl-trait/auto-trait-leak2.rs +++ b/src/test/ui/impl-trait/auto-trait-leak2.rs @@ -3,23 +3,37 @@ use std::rc::Rc; // Fast path, main can see the concrete type returned. fn before() -> impl Fn(i32) { +//~^ NOTE within this `impl Fn +//~| NOTE within the type `impl Fn +//~| NOTE expansion of desugaring let p = Rc::new(Cell::new(0)); - move |x| p.set(x) + move |x| p.set(x) //~ NOTE used within this closure } fn send(_: T) {} +//~^ NOTE required by a bound +//~| NOTE required by a bound +//~| NOTE required by this bound +//~| NOTE required by this bound fn main() { send(before()); //~^ ERROR `Rc>` cannot be sent between threads safely + //~| NOTE `Rc>` cannot be sent between threads safely + //~| NOTE required by a bound send(after()); //~^ ERROR `Rc>` cannot be sent between threads safely + //~| NOTE `Rc>` cannot be sent between threads safely + //~| NOTE required by a bound } // Deferred path, main has to wait until typeck finishes, // to check if the return type of after is Send. fn after() -> impl Fn(i32) { +//~^ NOTE within this `impl Fn(i32)` +//~| NOTE in this expansion +//~| NOTE appears within the type let p = Rc::new(Cell::new(0)); - move |x| p.set(x) + move |x| p.set(x) //~ NOTE used within this closure } diff --git a/src/test/ui/impl-trait/auto-trait-leak2.stderr b/src/test/ui/impl-trait/auto-trait-leak2.stderr index 37ae3c6802964..d825843492d49 100644 --- a/src/test/ui/impl-trait/auto-trait-leak2.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak2.stderr @@ -1,5 +1,5 @@ error[E0277]: `Rc>` cannot be sent between threads safely - --> $DIR/auto-trait-leak2.rs:13:10 + --> $DIR/auto-trait-leak2.rs:20:10 | LL | fn before() -> impl Fn(i32) { | ------------ within this `impl Fn(i32)` @@ -10,16 +10,24 @@ LL | send(before()); | required by a bound introduced by this call | = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc>` - = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:7:5: 7:22]` - = note: required because it appears within the type `impl Fn(i32)` +note: required because it's used within this closure + --> $DIR/auto-trait-leak2.rs:10:5 + | +LL | move |x| p.set(x) + | ^^^^^^^^^^^^^^^^^ +note: required because it appears within the type `impl Fn(i32)` + --> $DIR/auto-trait-leak2.rs:5:16 + | +LL | fn before() -> impl Fn(i32) { + | ^^^^^^^^^^^^ note: required by a bound in `send` - --> $DIR/auto-trait-leak2.rs:10:12 + --> $DIR/auto-trait-leak2.rs:13:12 | LL | fn send(_: T) {} | ^^^^ required by this bound in `send` error[E0277]: `Rc>` cannot be sent between threads safely - --> $DIR/auto-trait-leak2.rs:16:10 + --> $DIR/auto-trait-leak2.rs:25:10 | LL | send(after()); | ---- ^^^^^^^ `Rc>` cannot be sent between threads safely @@ -30,10 +38,18 @@ LL | fn after() -> impl Fn(i32) { | ------------ within this `impl Fn(i32)` | = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc>` - = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22]` - = note: required because it appears within the type `impl Fn(i32)` +note: required because it's used within this closure + --> $DIR/auto-trait-leak2.rs:38:5 + | +LL | move |x| p.set(x) + | ^^^^^^^^^^^^^^^^^ +note: required because it appears within the type `impl Fn(i32)` + --> $DIR/auto-trait-leak2.rs:33:15 + | +LL | fn after() -> impl Fn(i32) { + | ^^^^^^^^^^^^ note: required by a bound in `send` - --> $DIR/auto-trait-leak2.rs:10:12 + --> $DIR/auto-trait-leak2.rs:13:12 | LL | fn send(_: T) {} | ^^^^ required by this bound in `send` diff --git a/src/test/ui/inference/cannot-infer-closure-circular.rs b/src/test/ui/inference/cannot-infer-closure-circular.rs index ae879db68ec13..affb481496d02 100644 --- a/src/test/ui/inference/cannot-infer-closure-circular.rs +++ b/src/test/ui/inference/cannot-infer-closure-circular.rs @@ -4,10 +4,10 @@ fn main() { // error handles this gracefully, and in particular doesn't generate an extra // note about the `?` operator in the closure body, which isn't relevant to // the inference. - let x = |r| { + let x = |r| { //~ ERROR type annotations needed for `Result<(), E>` let v = r?; Ok(v) }; - let _ = x(x(Ok(()))); //~ ERROR type annotations needed for `Result<(), E>` + let _ = x(x(Ok(()))); } diff --git a/src/test/ui/inference/cannot-infer-closure-circular.stderr b/src/test/ui/inference/cannot-infer-closure-circular.stderr index 3ad8e3cda16e5..b706cd2bc36e8 100644 --- a/src/test/ui/inference/cannot-infer-closure-circular.stderr +++ b/src/test/ui/inference/cannot-infer-closure-circular.stderr @@ -1,13 +1,13 @@ error[E0282]: type annotations needed for `Result<(), E>` - --> $DIR/cannot-infer-closure-circular.rs:12:9 + --> $DIR/cannot-infer-closure-circular.rs:7:14 | -LL | let _ = x(x(Ok(()))); - | ^ +LL | let x = |r| { + | ^ | -help: consider giving this pattern a type, where the type for type parameter `E` is specified +help: consider giving this closure parameter an explicit type, where the type for type parameter `E` is specified | -LL | let _: Result<(), E> = x(x(Ok(()))); - | +++++++++++++++ +LL | let x = |r: Result<(), E>| { + | +++++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr index cb22d5adb717d..66fe3c74e2c87 100644 --- a/src/test/ui/interior-mutability/interior-mutability.stderr +++ b/src/test/ui/interior-mutability/interior-mutability.stderr @@ -7,7 +7,11 @@ LL | catch_unwind(|| { x.set(23); }); = help: within `Cell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required because it appears within the type `Cell` = note: required because of the requirements on the impl of `UnwindSafe` for `&Cell` - = note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:5:18: 5:35]` +note: required because it's used within this closure + --> $DIR/interior-mutability.rs:5:18 + | +LL | catch_unwind(|| { x.set(23); }); + | ^^^^^^^^^^^^^^^^^ note: required by a bound in `catch_unwind` --> $SRC_DIR/std/src/panic.rs:LL:COL | diff --git a/src/test/ui/issues/issue-76077.rs b/src/test/ui/issues/issue-76077.rs index 1ecd37de2e14a..2d29093b01b02 100644 --- a/src/test/ui/issues/issue-76077.rs +++ b/src/test/ui/issues/issue-76077.rs @@ -6,5 +6,5 @@ pub mod foo { fn main() { foo::Foo {}; - //~^ ERROR cannot construct `Foo` with struct literal syntax due to inaccessible fields + //~^ ERROR cannot construct `Foo` with struct literal syntax due to private fields } diff --git a/src/test/ui/issues/issue-76077.stderr b/src/test/ui/issues/issue-76077.stderr index d834ec5e0edd2..197ca8d5a7b25 100644 --- a/src/test/ui/issues/issue-76077.stderr +++ b/src/test/ui/issues/issue-76077.stderr @@ -1,8 +1,10 @@ -error: cannot construct `Foo` with struct literal syntax due to inaccessible fields +error: cannot construct `Foo` with struct literal syntax due to private fields --> $DIR/issue-76077.rs:8:5 | LL | foo::Foo {}; | ^^^^^^^^ + | + = note: ... and other private field `you_cant_use_this_field` that was not provided error: aborting due to previous error diff --git a/src/test/ui/kindck/kindck-nonsendable-1.stderr b/src/test/ui/kindck/kindck-nonsendable-1.stderr index b3ebe7f5c7dc3..727573a0be4ed 100644 --- a/src/test/ui/kindck/kindck-nonsendable-1.stderr +++ b/src/test/ui/kindck/kindck-nonsendable-1.stderr @@ -7,7 +7,11 @@ LL | bar(move|| foo(x)); | `Rc` cannot be sent between threads safely | = help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22]`, the trait `Send` is not implemented for `Rc` - = note: required because it appears within the type `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22]` +note: required because it's used within this closure + --> $DIR/kindck-nonsendable-1.rs:9:9 + | +LL | bar(move|| foo(x)); + | ^^^^^^^^^^^^^ note: required by a bound in `bar` --> $DIR/kindck-nonsendable-1.rs:5:21 | diff --git a/src/test/ui/macros/cfg.rs b/src/test/ui/macros/cfg.rs index 222161a8183a2..2aac50a9d011a 100644 --- a/src/test/ui/macros/cfg.rs +++ b/src/test/ui/macros/cfg.rs @@ -2,4 +2,5 @@ fn main() { cfg!(); //~ ERROR macro requires a cfg-pattern cfg!(123); //~ ERROR expected identifier cfg!(foo = 123); //~ ERROR literal in `cfg` predicate value must be a string + cfg!(foo, bar); //~ ERROR expected 1 cfg-pattern } diff --git a/src/test/ui/macros/cfg.stderr b/src/test/ui/macros/cfg.stderr index 4785ef9aae482..2633d5f720d70 100644 --- a/src/test/ui/macros/cfg.stderr +++ b/src/test/ui/macros/cfg.stderr @@ -18,6 +18,14 @@ error[E0565]: literal in `cfg` predicate value must be a string LL | cfg!(foo = 123); | ^^^ -error: aborting due to 3 previous errors +error: expected 1 cfg-pattern + --> $DIR/cfg.rs:5:5 + | +LL | cfg!(foo, bar); + | ^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `cfg` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0565`. diff --git a/src/test/ui/nll/issue-98170.rs b/src/test/ui/nll/issue-98170.rs new file mode 100644 index 0000000000000..6bb12f52d3f3e --- /dev/null +++ b/src/test/ui/nll/issue-98170.rs @@ -0,0 +1,25 @@ +pub struct MyStruct<'a> { + field: &'a [u32], +} + +impl MyStruct<'_> { + pub fn new<'a>(field: &'a [u32]) -> MyStruct<'a> { + Self { field } + //~^ ERROR lifetime may not live long enough + //~| ERROR lifetime may not live long enough + } +} + +trait Trait<'a> { + fn new(field: &'a [u32]) -> MyStruct<'a>; +} + +impl<'a> Trait<'a> for MyStruct<'_> { + fn new(field: &'a [u32]) -> MyStruct<'a> { + Self { field } + //~^ ERROR lifetime may not live long enough + //~| ERROR lifetime may not live long enough + } +} + +fn main() {} diff --git a/src/test/ui/nll/issue-98170.stderr b/src/test/ui/nll/issue-98170.stderr new file mode 100644 index 0000000000000..0d17365e71b4a --- /dev/null +++ b/src/test/ui/nll/issue-98170.stderr @@ -0,0 +1,44 @@ +error: lifetime may not live long enough + --> $DIR/issue-98170.rs:7:9 + | +LL | impl MyStruct<'_> { + | -- lifetime `'1` appears in the `impl`'s self type +LL | pub fn new<'a>(field: &'a [u32]) -> MyStruct<'a> { + | -- lifetime `'a` defined here +LL | Self { field } + | ^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/issue-98170.rs:7:16 + | +LL | impl MyStruct<'_> { + | -- lifetime `'1` appears in the `impl`'s self type +LL | pub fn new<'a>(field: &'a [u32]) -> MyStruct<'a> { + | -- lifetime `'a` defined here +LL | Self { field } + | ^^^^^ this usage requires that `'a` must outlive `'1` + +error: lifetime may not live long enough + --> $DIR/issue-98170.rs:19:9 + | +LL | impl<'a> Trait<'a> for MyStruct<'_> { + | -- -- lifetime `'1` appears in the `impl`'s self type + | | + | lifetime `'a` defined here +LL | fn new(field: &'a [u32]) -> MyStruct<'a> { +LL | Self { field } + | ^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/issue-98170.rs:19:16 + | +LL | impl<'a> Trait<'a> for MyStruct<'_> { + | -- -- lifetime `'1` appears in the `impl`'s self type + | | + | lifetime `'a` defined here +LL | fn new(field: &'a [u32]) -> MyStruct<'a> { +LL | Self { field } + | ^^^^^ this usage requires that `'a` must outlive `'1` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/no-send-res-ports.stderr b/src/test/ui/no-send-res-ports.stderr index 80708c989fcf7..e4c57c04e7269 100644 --- a/src/test/ui/no-send-res-ports.stderr +++ b/src/test/ui/no-send-res-ports.stderr @@ -22,7 +22,16 @@ note: required because it appears within the type `Foo` | LL | struct Foo { | ^^^ - = note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6]` +note: required because it's used within this closure + --> $DIR/no-send-res-ports.rs:25:19 + | +LL | thread::spawn(move|| { + | ___________________^ +LL | | +LL | | let y = x; +LL | | println!("{:?}", y); +LL | | }); + | |_____^ note: required by a bound in `spawn` --> $SRC_DIR/std/src/thread/mod.rs:LL:COL | diff --git a/src/test/ui/not-clone-closure.stderr b/src/test/ui/not-clone-closure.stderr index 78b35569c2162..bebf561b120b5 100644 --- a/src/test/ui/not-clone-closure.stderr +++ b/src/test/ui/not-clone-closure.stderr @@ -10,7 +10,14 @@ LL | LL | let hello = hello.clone(); | ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 9:6]`, the trait `Clone` is not implemented for `S` | - = note: required because it appears within the type `[closure@$DIR/not-clone-closure.rs:7:17: 9:6]` +note: required because it's used within this closure + --> $DIR/not-clone-closure.rs:7:17 + | +LL | let hello = move || { + | _________________^ +LL | | println!("Hello {}", a.0); +LL | | }; + | |_____^ help: consider annotating `S` with `#[derive(Clone)]` | LL | #[derive(Clone)] diff --git a/src/test/ui/privacy/issue-79593.rs b/src/test/ui/privacy/issue-79593.rs index b94278bfdd221..39c222f7c3414 100644 --- a/src/test/ui/privacy/issue-79593.rs +++ b/src/test/ui/privacy/issue-79593.rs @@ -16,7 +16,7 @@ mod foo { fn correct() { foo::Pub {}; - //~^ ERROR cannot construct `Pub` with struct literal syntax due to inaccessible fields + //~^ ERROR cannot construct `Pub` with struct literal syntax due to private fields } fn wrong() { diff --git a/src/test/ui/privacy/issue-79593.stderr b/src/test/ui/privacy/issue-79593.stderr index b8c7d4f23a28f..21ba760ad0bcc 100644 --- a/src/test/ui/privacy/issue-79593.stderr +++ b/src/test/ui/privacy/issue-79593.stderr @@ -10,11 +10,13 @@ error[E0063]: missing field `y` in initializer of `Enum` LL | Enum::Variant { x: () }; | ^^^^^^^^^^^^^ missing `y` -error: cannot construct `Pub` with struct literal syntax due to inaccessible fields +error: cannot construct `Pub` with struct literal syntax due to private fields --> $DIR/issue-79593.rs:18:5 | LL | foo::Pub {}; | ^^^^^^^^ + | + = note: ... and other private field `private` that was not provided error[E0063]: missing field `y` in initializer of `Enum` --> $DIR/issue-79593.rs:23:5 diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs index e6f45036f8514..0031a4665c814 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.rs @@ -52,7 +52,7 @@ fn main() { // Tuple struct variant Enum::<()>::TSVariant::<()>(()); - //~^ ERROR type arguments are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on tuple variant `TSVariant` [E0109] Alias::TSVariant::<()>(()); //~^ ERROR type arguments are not allowed on this type [E0109] @@ -70,7 +70,7 @@ fn main() { // Struct variant Enum::<()>::SVariant::<()> { v: () }; - //~^ ERROR type arguments are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on variant `SVariant` [E0109] Alias::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this type [E0109] @@ -88,7 +88,7 @@ fn main() { // Unit variant Enum::<()>::UVariant::<()>; - //~^ ERROR type arguments are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on unit variant `UVariant` [E0109] Alias::UVariant::<()>; //~^ ERROR type arguments are not allowed on this type [E0109] diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr index 9601bdce4c503..5467f61bee40f 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr @@ -272,13 +272,13 @@ LL | Self::<()>::UVariant::<()>; | | | not allowed on this type -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on tuple variant `TSVariant` --> $DIR/enum-variant-generic-args.rs:54:29 | LL | Enum::<()>::TSVariant::<()>(()); | --------- ^^ type argument not allowed | | - | not allowed on this type + | not allowed on tuple variant `TSVariant` error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:57:24 @@ -340,13 +340,13 @@ LL | AliasFixed::<()>::TSVariant::<()>(()); | | | not allowed on this type -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on variant `SVariant` --> $DIR/enum-variant-generic-args.rs:72:28 | LL | Enum::<()>::SVariant::<()> { v: () }; | -------- ^^ type argument not allowed | | - | not allowed on this type + | not allowed on variant `SVariant` | = note: enum variants can't have type parameters @@ -438,13 +438,13 @@ LL - AliasFixed::<()>::SVariant::<()> { v: () }; LL + AliasFixed::<()>::SVariant { v: () }; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on unit variant `UVariant` --> $DIR/enum-variant-generic-args.rs:90:28 | LL | Enum::<()>::UVariant::<()>; | -------- ^^ type argument not allowed | | - | not allowed on this type + | not allowed on unit variant `UVariant` error[E0109]: type arguments are not allowed on this type --> $DIR/enum-variant-generic-args.rs:93:23 diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs index 745379efa6df9..fc89b0e870e39 100644 --- a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs @@ -4,7 +4,9 @@ mod m { use std::rc::Rc; - type Foo = impl std::fmt::Debug; + type Foo = impl std::fmt::Debug; //~ NOTE appears within the type + //~^ within this `Foo` + //~| expansion of desugaring pub fn foo() -> Foo { Rc::new(22_u32) @@ -12,8 +14,12 @@ mod m { } fn is_send(_: T) {} +//~^ required by this bound +//~| required by a bound fn main() { is_send(m::foo()); //~^ ERROR: `Rc` cannot be sent between threads safely [E0277] + //~| NOTE cannot be sent + //~| NOTE required by a bound } diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr index 0664275b2ad0a..d7247302dd1e0 100644 --- a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr +++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr @@ -1,5 +1,5 @@ error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/auto-trait-leakage2.rs:17:13 + --> $DIR/auto-trait-leakage2.rs:21:13 | LL | type Foo = impl std::fmt::Debug; | -------------------- within this `Foo` @@ -10,9 +10,13 @@ LL | is_send(m::foo()); | required by a bound introduced by this call | = help: within `Foo`, the trait `Send` is not implemented for `Rc` - = note: required because it appears within the type `Foo` +note: required because it appears within the type `Foo` + --> $DIR/auto-trait-leakage2.rs:7:16 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `is_send` - --> $DIR/auto-trait-leakage2.rs:14:15 + --> $DIR/auto-trait-leakage2.rs:16:15 | LL | fn is_send(_: T) {} | ^^^^ required by this bound in `is_send` diff --git a/src/test/ui/type/issue-91268.rs b/src/test/ui/type/issue-91268.rs index 01ed9ea9e231f..f1e16bc7bd3c1 100644 --- a/src/test/ui/type/issue-91268.rs +++ b/src/test/ui/type/issue-91268.rs @@ -1,7 +1,7 @@ // error-pattern: this file contains an unclosed delimiter // error-pattern: cannot find type `ţ` in this scope // error-pattern: parenthesized type parameters may only be used with a `Fn` trait -// error-pattern: type arguments are not allowed on this type +// error-pattern: type arguments are not allowed on builtin type `u8` // error-pattern: mismatched types // ignore-tidy-trailing-newlines // `ţ` must be the last character in this file, it cannot be followed by a newline diff --git a/src/test/ui/type/issue-91268.stderr b/src/test/ui/type/issue-91268.stderr index e426f450b11bb..6c9ee9945844d 100644 --- a/src/test/ui/type/issue-91268.stderr +++ b/src/test/ui/type/issue-91268.stderr @@ -35,13 +35,13 @@ help: use angle brackets instead LL | 0: u8<ţ> | ~ + -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `u8` --> $DIR/issue-91268.rs:9:11 | LL | 0: u8(ţ | -- ^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u8` | help: primitive type `u8` doesn't have generic parameters | diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.rs b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.rs index 3176144133760..326e958aaa94f 100644 --- a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.rs +++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.rs @@ -7,5 +7,5 @@ pub mod foo { fn main() { foo::Foo {}; - //~^ ERROR cannot construct `Foo` with struct literal syntax due to inaccessible fields + //~^ ERROR cannot construct `Foo` with struct literal syntax due to private fields } diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr index 81b73c00e8600..f0bd3e0ddf768 100644 --- a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr +++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr @@ -1,8 +1,10 @@ -error: cannot construct `Foo` with struct literal syntax due to inaccessible fields +error: cannot construct `Foo` with struct literal syntax due to private fields --> $DIR/issue-87872-missing-inaccessible-field-literal.rs:9:5 | LL | foo::Foo {}; | ^^^^^^^^ + | + = note: ... and other private field `you_cant_use_this_field` that was not provided error: aborting due to previous error diff --git a/src/test/ui/typeck/missing-private-fields-in-struct-literal.rs b/src/test/ui/typeck/missing-private-fields-in-struct-literal.rs new file mode 100644 index 0000000000000..9f1560bfb8dfe --- /dev/null +++ b/src/test/ui/typeck/missing-private-fields-in-struct-literal.rs @@ -0,0 +1,18 @@ +pub mod m { + pub struct S { + pub visible: bool, + a: (), + b: (), + c: (), + d: (), + e: (), + } +} + +fn main() { + let _ = m::S { //~ ERROR cannot construct `S` with struct literal syntax due to private fields + visible: true, + a: (), + b: (), + }; +} diff --git a/src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr b/src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr new file mode 100644 index 0000000000000..234110f31f79c --- /dev/null +++ b/src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr @@ -0,0 +1,15 @@ +error: cannot construct `S` with struct literal syntax due to private fields + --> $DIR/missing-private-fields-in-struct-literal.rs:13:13 + | +LL | let _ = m::S { + | ^^^^ +LL | visible: true, +LL | a: (), + | ----- private field +LL | b: (), + | ----- private field + | + = note: ... and other private fields `c`, `d` and `e` that were not provided + +error: aborting due to previous error + diff --git a/src/test/ui/typeck/prim-with-args.fixed b/src/test/ui/typeck/prim-with-args.fixed index 1c5fd7508676a..e3f99479a3809 100644 --- a/src/test/ui/typeck/prim-with-args.fixed +++ b/src/test/ui/typeck/prim-with-args.fixed @@ -1,28 +1,28 @@ // run-rustfix fn main() { -let _x: isize; //~ ERROR type arguments are not allowed on this type -let _x: i8; //~ ERROR type arguments are not allowed on this type -let _x: i16; //~ ERROR type arguments are not allowed on this type -let _x: i32; //~ ERROR type arguments are not allowed on this type -let _x: i64; //~ ERROR type arguments are not allowed on this type -let _x: usize; //~ ERROR type arguments are not allowed on this type -let _x: u8; //~ ERROR type arguments are not allowed on this type -let _x: u16; //~ ERROR type arguments are not allowed on this type -let _x: u32; //~ ERROR type arguments are not allowed on this type -let _x: u64; //~ ERROR type arguments are not allowed on this type -let _x: char; //~ ERROR type arguments are not allowed on this type +let _x: isize; //~ ERROR type arguments are not allowed on builtin type +let _x: i8; //~ ERROR type arguments are not allowed on builtin type +let _x: i16; //~ ERROR type arguments are not allowed on builtin type +let _x: i32; //~ ERROR type arguments are not allowed on builtin type +let _x: i64; //~ ERROR type arguments are not allowed on builtin type +let _x: usize; //~ ERROR type arguments are not allowed on builtin type +let _x: u8; //~ ERROR type arguments are not allowed on builtin type +let _x: u16; //~ ERROR type arguments are not allowed on builtin type +let _x: u32; //~ ERROR type arguments are not allowed on builtin type +let _x: u64; //~ ERROR type arguments are not allowed on builtin type +let _x: char; //~ ERROR type arguments are not allowed on builtin type -let _x: isize; //~ ERROR lifetime arguments are not allowed on this type -let _x: i8; //~ ERROR lifetime arguments are not allowed on this type -let _x: i16; //~ ERROR lifetime arguments are not allowed on this type -let _x: i32; //~ ERROR lifetime arguments are not allowed on this type -let _x: i64; //~ ERROR lifetime arguments are not allowed on this type -let _x: usize; //~ ERROR lifetime arguments are not allowed on this type -let _x: u8; //~ ERROR lifetime arguments are not allowed on this type -let _x: u16; //~ ERROR lifetime arguments are not allowed on this type -let _x: u32; //~ ERROR lifetime arguments are not allowed on this type -let _x: u64; //~ ERROR lifetime arguments are not allowed on this type -let _x: char; //~ ERROR lifetime arguments are not allowed on this type +let _x: isize; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i8; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i16; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i32; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i64; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: usize; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u8; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u16; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u32; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u64; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: char; //~ ERROR lifetime arguments are not allowed on builtin type } diff --git a/src/test/ui/typeck/prim-with-args.rs b/src/test/ui/typeck/prim-with-args.rs index b05d6c1cb4e4a..b10471eccee68 100644 --- a/src/test/ui/typeck/prim-with-args.rs +++ b/src/test/ui/typeck/prim-with-args.rs @@ -1,28 +1,28 @@ // run-rustfix fn main() { -let _x: isize; //~ ERROR type arguments are not allowed on this type -let _x: i8; //~ ERROR type arguments are not allowed on this type -let _x: i16; //~ ERROR type arguments are not allowed on this type -let _x: i32; //~ ERROR type arguments are not allowed on this type -let _x: i64; //~ ERROR type arguments are not allowed on this type -let _x: usize; //~ ERROR type arguments are not allowed on this type -let _x: u8; //~ ERROR type arguments are not allowed on this type -let _x: u16; //~ ERROR type arguments are not allowed on this type -let _x: u32; //~ ERROR type arguments are not allowed on this type -let _x: u64; //~ ERROR type arguments are not allowed on this type -let _x: char; //~ ERROR type arguments are not allowed on this type +let _x: isize; //~ ERROR type arguments are not allowed on builtin type +let _x: i8; //~ ERROR type arguments are not allowed on builtin type +let _x: i16; //~ ERROR type arguments are not allowed on builtin type +let _x: i32; //~ ERROR type arguments are not allowed on builtin type +let _x: i64; //~ ERROR type arguments are not allowed on builtin type +let _x: usize; //~ ERROR type arguments are not allowed on builtin type +let _x: u8; //~ ERROR type arguments are not allowed on builtin type +let _x: u16; //~ ERROR type arguments are not allowed on builtin type +let _x: u32; //~ ERROR type arguments are not allowed on builtin type +let _x: u64; //~ ERROR type arguments are not allowed on builtin type +let _x: char; //~ ERROR type arguments are not allowed on builtin type -let _x: isize<'static>; //~ ERROR lifetime arguments are not allowed on this type -let _x: i8<'static>; //~ ERROR lifetime arguments are not allowed on this type -let _x: i16<'static>; //~ ERROR lifetime arguments are not allowed on this type -let _x: i32<'static>; //~ ERROR lifetime arguments are not allowed on this type -let _x: i64<'static>; //~ ERROR lifetime arguments are not allowed on this type -let _x: usize<'static>; //~ ERROR lifetime arguments are not allowed on this type -let _x: u8<'static>; //~ ERROR lifetime arguments are not allowed on this type -let _x: u16<'static>; //~ ERROR lifetime arguments are not allowed on this type -let _x: u32<'static>; //~ ERROR lifetime arguments are not allowed on this type -let _x: u64<'static>; //~ ERROR lifetime arguments are not allowed on this type -let _x: char<'static>; //~ ERROR lifetime arguments are not allowed on this type +let _x: isize<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i8<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i16<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i32<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: i64<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: usize<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u8<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u16<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u32<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: u64<'static>; //~ ERROR lifetime arguments are not allowed on builtin type +let _x: char<'static>; //~ ERROR lifetime arguments are not allowed on builtin type } diff --git a/src/test/ui/typeck/prim-with-args.stderr b/src/test/ui/typeck/prim-with-args.stderr index c45fd00bae9a5..2ddad5ad71e46 100644 --- a/src/test/ui/typeck/prim-with-args.stderr +++ b/src/test/ui/typeck/prim-with-args.stderr @@ -1,10 +1,10 @@ -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `isize` --> $DIR/prim-with-args.rs:4:15 | LL | let _x: isize; | ----- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `isize` | help: primitive type `isize` doesn't have generic parameters | @@ -12,13 +12,13 @@ LL - let _x: isize; LL + let _x: isize; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `i8` --> $DIR/prim-with-args.rs:5:12 | LL | let _x: i8; | -- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `i8` | help: primitive type `i8` doesn't have generic parameters | @@ -26,13 +26,13 @@ LL - let _x: i8; LL + let _x: i8; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `i16` --> $DIR/prim-with-args.rs:6:13 | LL | let _x: i16; | --- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `i16` | help: primitive type `i16` doesn't have generic parameters | @@ -40,13 +40,13 @@ LL - let _x: i16; LL + let _x: i16; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `i32` --> $DIR/prim-with-args.rs:7:13 | LL | let _x: i32; | --- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `i32` | help: primitive type `i32` doesn't have generic parameters | @@ -54,13 +54,13 @@ LL - let _x: i32; LL + let _x: i32; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `i64` --> $DIR/prim-with-args.rs:8:13 | LL | let _x: i64; | --- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `i64` | help: primitive type `i64` doesn't have generic parameters | @@ -68,13 +68,13 @@ LL - let _x: i64; LL + let _x: i64; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `usize` --> $DIR/prim-with-args.rs:9:15 | LL | let _x: usize; | ----- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `usize` | help: primitive type `usize` doesn't have generic parameters | @@ -82,13 +82,13 @@ LL - let _x: usize; LL + let _x: usize; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `u8` --> $DIR/prim-with-args.rs:10:12 | LL | let _x: u8; | -- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u8` | help: primitive type `u8` doesn't have generic parameters | @@ -96,13 +96,13 @@ LL - let _x: u8; LL + let _x: u8; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `u16` --> $DIR/prim-with-args.rs:11:13 | LL | let _x: u16; | --- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u16` | help: primitive type `u16` doesn't have generic parameters | @@ -110,13 +110,13 @@ LL - let _x: u16; LL + let _x: u16; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `u32` --> $DIR/prim-with-args.rs:12:13 | LL | let _x: u32; | --- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u32` | help: primitive type `u32` doesn't have generic parameters | @@ -124,13 +124,13 @@ LL - let _x: u32; LL + let _x: u32; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `u64` --> $DIR/prim-with-args.rs:13:13 | LL | let _x: u64; | --- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u64` | help: primitive type `u64` doesn't have generic parameters | @@ -138,13 +138,13 @@ LL - let _x: u64; LL + let _x: u64; | -error[E0109]: type arguments are not allowed on this type +error[E0109]: type arguments are not allowed on builtin type `char` --> $DIR/prim-with-args.rs:14:14 | LL | let _x: char; | ---- ^^^^^ type argument not allowed | | - | not allowed on this type + | not allowed on builtin type `char` | help: primitive type `char` doesn't have generic parameters | @@ -152,13 +152,13 @@ LL - let _x: char; LL + let _x: char; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `isize` --> $DIR/prim-with-args.rs:16:15 | LL | let _x: isize<'static>; | ----- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `isize` | help: primitive type `isize` doesn't have generic parameters | @@ -166,13 +166,13 @@ LL - let _x: isize<'static>; LL + let _x: isize; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `i8` --> $DIR/prim-with-args.rs:17:12 | LL | let _x: i8<'static>; | -- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `i8` | help: primitive type `i8` doesn't have generic parameters | @@ -180,13 +180,13 @@ LL - let _x: i8<'static>; LL + let _x: i8; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `i16` --> $DIR/prim-with-args.rs:18:13 | LL | let _x: i16<'static>; | --- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `i16` | help: primitive type `i16` doesn't have generic parameters | @@ -194,13 +194,13 @@ LL - let _x: i16<'static>; LL + let _x: i16; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `i32` --> $DIR/prim-with-args.rs:19:13 | LL | let _x: i32<'static>; | --- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `i32` | help: primitive type `i32` doesn't have generic parameters | @@ -208,13 +208,13 @@ LL - let _x: i32<'static>; LL + let _x: i32; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `i64` --> $DIR/prim-with-args.rs:20:13 | LL | let _x: i64<'static>; | --- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `i64` | help: primitive type `i64` doesn't have generic parameters | @@ -222,13 +222,13 @@ LL - let _x: i64<'static>; LL + let _x: i64; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `usize` --> $DIR/prim-with-args.rs:21:15 | LL | let _x: usize<'static>; | ----- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `usize` | help: primitive type `usize` doesn't have generic parameters | @@ -236,13 +236,13 @@ LL - let _x: usize<'static>; LL + let _x: usize; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `u8` --> $DIR/prim-with-args.rs:22:12 | LL | let _x: u8<'static>; | -- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u8` | help: primitive type `u8` doesn't have generic parameters | @@ -250,13 +250,13 @@ LL - let _x: u8<'static>; LL + let _x: u8; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `u16` --> $DIR/prim-with-args.rs:23:13 | LL | let _x: u16<'static>; | --- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u16` | help: primitive type `u16` doesn't have generic parameters | @@ -264,13 +264,13 @@ LL - let _x: u16<'static>; LL + let _x: u16; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `u32` --> $DIR/prim-with-args.rs:24:13 | LL | let _x: u32<'static>; | --- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u32` | help: primitive type `u32` doesn't have generic parameters | @@ -278,13 +278,13 @@ LL - let _x: u32<'static>; LL + let _x: u32; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `u64` --> $DIR/prim-with-args.rs:25:13 | LL | let _x: u64<'static>; | --- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `u64` | help: primitive type `u64` doesn't have generic parameters | @@ -292,13 +292,13 @@ LL - let _x: u64<'static>; LL + let _x: u64; | -error[E0109]: lifetime arguments are not allowed on this type +error[E0109]: lifetime arguments are not allowed on builtin type `char` --> $DIR/prim-with-args.rs:26:14 | LL | let _x: char<'static>; | ---- ^^^^^^^ lifetime argument not allowed | | - | not allowed on this type + | not allowed on builtin type `char` | help: primitive type `char` doesn't have generic parameters | diff --git a/src/test/ui/usize-generic-argument-parent.rs b/src/test/ui/usize-generic-argument-parent.rs index 6d17ba9b5b261..4ab80d944a56f 100644 --- a/src/test/ui/usize-generic-argument-parent.rs +++ b/src/test/ui/usize-generic-argument-parent.rs @@ -1,5 +1,5 @@ fn foo() { - let x: usize; //~ ERROR const arguments are not allowed on this type + let x: usize; //~ ERROR const arguments are not allowed on builtin type `usize` } fn main() {} diff --git a/src/test/ui/usize-generic-argument-parent.stderr b/src/test/ui/usize-generic-argument-parent.stderr index abe8c09b739f7..131c476aa55c0 100644 --- a/src/test/ui/usize-generic-argument-parent.stderr +++ b/src/test/ui/usize-generic-argument-parent.stderr @@ -1,10 +1,10 @@ -error[E0109]: const arguments are not allowed on this type +error[E0109]: const arguments are not allowed on builtin type `usize` --> $DIR/usize-generic-argument-parent.rs:2:18 | LL | let x: usize; | ----- ^^^ const argument not allowed | | - | not allowed on this type + | not allowed on builtin type `usize` | help: primitive type `usize` doesn't have generic parameters | diff --git a/triagebot.toml b/triagebot.toml index 25e2c384624e9..cef78cc3b336e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1,14 +1,21 @@ [relabel] allow-unauthenticated = [ - "C-*", "A-*", "E-*", "NLL-*", "O-*", "S-*", "T-*", "WG-*", "F-*", + "A-*", + "C-*", "D-*", + "E-*", + "F-*", + "I-*", + "NLL-*", + "O-*", + "S-*", + "T-*", + "WG-*", "needs-fcp", "relnotes", "requires-nightly", "regression-*", "perf-*", - # I-* without I-*nominated - "I-*", "!I-*nominated", "AsyncAwait-OnDeck", ]