diff options
24 files changed, 308 insertions, 140 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/metadata.ftl b/compiler/rustc_error_messages/locales/en-US/metadata.ftl index d1e1fd54db9..b3ca540417d 100644 --- a/compiler/rustc_error_messages/locales/en-US/metadata.ftl +++ b/compiler/rustc_error_messages/locales/en-US/metadata.ftl @@ -166,12 +166,6 @@ metadata_conflicting_alloc_error_handler = metadata_global_alloc_required = no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait -metadata_alloc_func_required = - `#[alloc_error_handler]` function required, but not found - -metadata_missing_alloc_error_handler = - use `#![feature(default_alloc_error_handler)]` for a default error handler - metadata_no_transitive_needs_dep = the crate `{$crate_name}` cannot depend on a crate that needs {$needs_crate_name}, but it depends on `{$deps_crate_name}` diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 7678ce323df..e5348039edd 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -126,6 +126,8 @@ declare_features! ( (accepted, copy_closures, "1.26.0", Some(44490), None), /// Allows `crate` in paths. (accepted, crate_in_paths, "1.30.0", Some(45477), None), + /// Allows rustc to inject a default alloc_error_handler + (accepted, default_alloc_error_handler, "CURRENT_RUSTC_VERSION", Some(66741), None), /// Allows using assigning a default type to type parameters in algebraic data type definitions. (accepted, default_type_params, "1.0.0", None, None), /// Allows `#[deprecated]` attribute. diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 69c5297bf6b..a616dd70f8e 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -368,8 +368,6 @@ declare_features! ( (active, debugger_visualizer, "1.62.0", Some(95939), None), /// Allows declarative macros 2.0 (`macro`). (active, decl_macro, "1.17.0", Some(39412), None), - /// Allows rustc to inject a default alloc_error_handler - (active, default_alloc_error_handler, "1.48.0", Some(66741), None), /// Allows default type parameters to influence type inference. (active, default_type_parameter_fallback, "1.3.0", Some(27336), None), /// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index 6b9ce9a4599..b69728c24aa 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -405,6 +405,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>( tcx.fn_sig(impl_m.def_id), ), ); + impl_sig.error_reported()?; let impl_return_ty = impl_sig.output(); // Normalize the trait signature with liberated bound vars, passing it through @@ -419,6 +420,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>( ) .fold_with(&mut collector); let trait_sig = ocx.normalize(&norm_cause, param_env, unnormalized_trait_sig); + trait_sig.error_reported()?; let trait_return_ty = trait_sig.output(); let wf_tys = FxIndexSet::from_iter( diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index b050ad20afb..042a50f2fd4 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -847,13 +847,15 @@ impl<'a, 'tcx> CastCheck<'tcx> { (Int(_) | Float, Int(_) | Float) => Ok(CastKind::NumericCast), - (_, DynStar) | (DynStar, _) => { + (_, DynStar) => { if fcx.tcx.features().dyn_star { bug!("should be handled by `try_coerce`") } else { Err(CastError::IllegalCast) } } + + (DynStar, _) => Err(CastError::IllegalCast), } } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 7e50801f80c..91fcd6d690e 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -175,13 +175,23 @@ impl EarlyLintPass for NonCamelCaseTypes { return; } - match it.kind { + match &it.kind { ast::ItemKind::TyAlias(..) | ast::ItemKind::Enum(..) | ast::ItemKind::Struct(..) | ast::ItemKind::Union(..) => self.check_case(cx, "type", &it.ident), ast::ItemKind::Trait(..) => self.check_case(cx, "trait", &it.ident), ast::ItemKind::TraitAlias(..) => self.check_case(cx, "trait alias", &it.ident), + + // N.B. This check is only for inherent associated types, so that we don't lint against + // trait impls where we should have warned for the trait definition already. + ast::ItemKind::Impl(box ast::Impl { of_trait: None, items, .. }) => { + for it in items { + if let ast::AssocItemKind::Type(..) = it.kind { + self.check_case(cx, "associated type", &it.ident); + } + } + } _ => (), } } diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 01d7f3e03c5..9ce3ff98ba9 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -1,10 +1,9 @@ //! Validates all used crates and extern libraries and loads their metadata use crate::errors::{ - AllocFuncRequired, ConflictingAllocErrorHandler, ConflictingGlobalAlloc, CrateNotPanicRuntime, - GlobalAllocRequired, MissingAllocErrorHandler, NoMultipleAllocErrorHandler, - NoMultipleGlobalAlloc, NoPanicStrategy, NoTransitiveNeedsDep, NotProfilerRuntime, - ProfilerBuiltinsNeedsCore, + ConflictingAllocErrorHandler, ConflictingGlobalAlloc, CrateNotPanicRuntime, + GlobalAllocRequired, NoMultipleAllocErrorHandler, NoMultipleGlobalAlloc, NoPanicStrategy, + NoTransitiveNeedsDep, NotProfilerRuntime, ProfilerBuiltinsNeedsCore, }; use crate::locator::{CrateError, CrateLocator, CratePaths}; use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob}; @@ -895,10 +894,6 @@ impl<'a> CrateLoader<'a> { } else { // The alloc crate provides a default allocation error handler if // one isn't specified. - if !self.sess.features_untracked().default_alloc_error_handler { - self.sess.emit_err(AllocFuncRequired); - self.sess.emit_note(MissingAllocErrorHandler); - } self.cstore.alloc_error_handler_kind = Some(AllocatorKind::Default); } } diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 6f7e6e09ca5..de2a879f1d7 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -372,14 +372,6 @@ pub struct ConflictingAllocErrorHandler { pub struct GlobalAllocRequired; #[derive(Diagnostic)] -#[diag(metadata_alloc_func_required)] -pub struct AllocFuncRequired; - -#[derive(Diagnostic)] -#[diag(metadata_missing_alloc_error_handler)] -pub struct MissingAllocErrorHandler; - -#[derive(Diagnostic)] #[diag(metadata_no_transitive_needs_dep)] pub struct NoTransitiveNeedsDep<'a> { pub crate_name: Symbol, diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 880632561b9..e4bb3ce3d5a 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -15,7 +15,15 @@ use rustc_span::{Span, DUMMY_SP}; /// The `Key` trait controls what types can legally be used as the key /// for a query. pub trait Key: Sized { - type CacheSelector = DefaultCacheSelector<Self>; + // N.B. Most of the keys down below have `type CacheSelector = DefaultCacheSelector<Self>;`, + // it would be reasonable to use associated type defaults, to remove the duplication... + // + // ...But r-a doesn't support them yet and using a default here causes r-a to not infer + // return types of queries which is very annoying. Thus, until r-a support associated + // type defaults, plese restrain from using them here <3 + // + // r-a issue: <https://github.com/rust-lang/rust-analyzer/issues/13693> + type CacheSelector; /// Given an instance of this key, what crate is it referring to? /// This is used to find the provider. @@ -37,6 +45,8 @@ pub trait Key: Sized { } impl Key for () { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -48,6 +58,8 @@ impl Key for () { } impl<'tcx> Key for ty::InstanceDef<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -59,6 +71,8 @@ impl<'tcx> Key for ty::InstanceDef<'tcx> { } impl<'tcx> Key for ty::Instance<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -70,6 +84,8 @@ impl<'tcx> Key for ty::Instance<'tcx> { } impl<'tcx> Key for mir::interpret::GlobalId<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -81,6 +97,8 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> { } impl<'tcx> Key for (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -92,6 +110,8 @@ impl<'tcx> Key for (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>) { } impl<'tcx> Key for mir::interpret::LitToConstInput<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -145,6 +165,8 @@ impl Key for LocalDefId { } impl Key for DefId { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.krate == LOCAL_CRATE @@ -159,6 +181,8 @@ impl Key for DefId { } impl Key for ty::WithOptConstParam<LocalDefId> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -169,6 +193,8 @@ impl Key for ty::WithOptConstParam<LocalDefId> { } impl Key for SimplifiedType { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -179,6 +205,8 @@ impl Key for SimplifiedType { } impl Key for (DefId, DefId) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.0.krate == LOCAL_CRATE @@ -189,6 +217,8 @@ impl Key for (DefId, DefId) { } impl<'tcx> Key for (ty::Instance<'tcx>, LocalDefId) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -199,6 +229,8 @@ impl<'tcx> Key for (ty::Instance<'tcx>, LocalDefId) { } impl Key for (DefId, LocalDefId) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.0.krate == LOCAL_CRATE @@ -209,6 +241,8 @@ impl Key for (DefId, LocalDefId) { } impl Key for (LocalDefId, DefId) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -219,6 +253,8 @@ impl Key for (LocalDefId, DefId) { } impl Key for (LocalDefId, LocalDefId) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -229,6 +265,8 @@ impl Key for (LocalDefId, LocalDefId) { } impl Key for (DefId, Option<Ident>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.0.krate == LOCAL_CRATE @@ -243,6 +281,8 @@ impl Key for (DefId, Option<Ident>) { } impl Key for (DefId, LocalDefId, Ident) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.0.krate == LOCAL_CRATE @@ -253,6 +293,8 @@ impl Key for (DefId, LocalDefId, Ident) { } impl Key for (CrateNum, DefId) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.0 == LOCAL_CRATE @@ -263,6 +305,8 @@ impl Key for (CrateNum, DefId) { } impl Key for (CrateNum, SimplifiedType) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.0 == LOCAL_CRATE @@ -273,6 +317,8 @@ impl Key for (CrateNum, SimplifiedType) { } impl Key for (DefId, SimplifiedType) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.0.krate == LOCAL_CRATE @@ -283,6 +329,8 @@ impl Key for (DefId, SimplifiedType) { } impl<'tcx> Key for SubstsRef<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -293,6 +341,8 @@ impl<'tcx> Key for SubstsRef<'tcx> { } impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.0.krate == LOCAL_CRATE @@ -303,6 +353,8 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { } impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { (self.0).def.did.krate == LOCAL_CRATE @@ -313,6 +365,8 @@ impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) { } impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -323,6 +377,8 @@ impl<'tcx> Key for (LocalDefId, DefId, SubstsRef<'tcx>) { } impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.1.def_id().krate == LOCAL_CRATE @@ -333,6 +389,8 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { } impl<'tcx> Key for (ty::Const<'tcx>, mir::Field) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -343,6 +401,8 @@ impl<'tcx> Key for (ty::Const<'tcx>, mir::Field) { } impl<'tcx> Key for mir::interpret::ConstAlloc<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -353,6 +413,8 @@ impl<'tcx> Key for mir::interpret::ConstAlloc<'tcx> { } impl<'tcx> Key for ty::PolyTraitRef<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.def_id().krate == LOCAL_CRATE @@ -363,6 +425,8 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx> { } impl<'tcx> Key for ty::PolyExistentialTraitRef<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.def_id().krate == LOCAL_CRATE @@ -373,6 +437,8 @@ impl<'tcx> Key for ty::PolyExistentialTraitRef<'tcx> { } impl<'tcx> Key for (ty::PolyTraitRef<'tcx>, ty::PolyTraitRef<'tcx>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.0.def_id().krate == LOCAL_CRATE @@ -383,6 +449,8 @@ impl<'tcx> Key for (ty::PolyTraitRef<'tcx>, ty::PolyTraitRef<'tcx>) { } impl<'tcx> Key for GenericArg<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -393,6 +461,8 @@ impl<'tcx> Key for GenericArg<'tcx> { } impl<'tcx> Key for mir::ConstantKind<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -403,6 +473,8 @@ impl<'tcx> Key for mir::ConstantKind<'tcx> { } impl<'tcx> Key for ty::Const<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -413,6 +485,8 @@ impl<'tcx> Key for ty::Const<'tcx> { } impl<'tcx> Key for Ty<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -429,6 +503,8 @@ impl<'tcx> Key for Ty<'tcx> { } impl<'tcx> Key for TyAndLayout<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -439,6 +515,8 @@ impl<'tcx> Key for TyAndLayout<'tcx> { } impl<'tcx> Key for (Ty<'tcx>, Ty<'tcx>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -449,6 +527,8 @@ impl<'tcx> Key for (Ty<'tcx>, Ty<'tcx>) { } impl<'tcx> Key for &'tcx ty::List<ty::Predicate<'tcx>> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -459,6 +539,8 @@ impl<'tcx> Key for &'tcx ty::List<ty::Predicate<'tcx>> { } impl<'tcx> Key for ty::ParamEnv<'tcx> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -469,6 +551,8 @@ impl<'tcx> Key for ty::ParamEnv<'tcx> { } impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { self.value.query_crate_is_local() @@ -479,6 +563,8 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> { } impl Key for Symbol { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -489,6 +575,8 @@ impl Key for Symbol { } impl Key for Option<Symbol> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -501,6 +589,8 @@ impl Key for Option<Symbol> { /// Canonical query goals correspond to abstract trait operations that /// are not tied to any crate in particular. impl<'tcx, T> Key for Canonical<'tcx, T> { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -512,6 +602,8 @@ impl<'tcx, T> Key for Canonical<'tcx, T> { } impl Key for (Symbol, u32, u32) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -523,6 +615,8 @@ impl Key for (Symbol, u32, u32) { } impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -534,6 +628,8 @@ impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) { } impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -545,6 +641,8 @@ impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) { } impl<'tcx> Key for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -556,6 +654,8 @@ impl<'tcx> Key for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) { } impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -567,6 +667,8 @@ impl<'tcx> Key for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) { } impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true @@ -578,6 +680,8 @@ impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) { } impl Key for HirId { + type CacheSelector = DefaultCacheSelector<Self>; + #[inline(always)] fn query_crate_is_local(&self) -> bool { true diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index b141820fe42..aeaee524fd4 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -567,11 +567,12 @@ struct SummaryLine<'a, I: Iterator<Item = Event<'a>>> { inner: I, started: bool, depth: u32, + skipped_tags: u32, } impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> { fn new(iter: I) -> Self { - SummaryLine { inner: iter, started: false, depth: 0 } + SummaryLine { inner: iter, started: false, depth: 0, skipped_tags: 0 } } } @@ -601,6 +602,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> { let is_allowed_tag = match event { Event::Start(ref c) => { if is_forbidden_tag(c) { + self.skipped_tags += 1; return None; } self.depth += 1; @@ -608,6 +610,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> { } Event::End(ref c) => { if is_forbidden_tag(c) { + self.skipped_tags += 1; return None; } self.depth -= 1; @@ -616,6 +619,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> { } _ => true, }; + if !is_allowed_tag { + self.skipped_tags += 1; + } return if !is_allowed_tag { if is_start { Some(Event::Start(Tag::Paragraph)) @@ -1096,11 +1102,11 @@ impl MarkdownItemInfo<'_> { } impl MarkdownSummaryLine<'_> { - pub(crate) fn into_string(self) -> String { + pub(crate) fn into_string_with_has_more_content(self) -> (String, bool) { let MarkdownSummaryLine(md, links) = self; // This is actually common enough to special-case if md.is_empty() { - return String::new(); + return (String::new(), false); } let mut replacer = |broken_link: BrokenLink<'_>| { @@ -1110,17 +1116,26 @@ impl MarkdownSummaryLine<'_> { .map(|link| (link.href.as_str().into(), link.new_text.as_str().into())) }; - let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer)); + let p = Parser::new_with_broken_link_callback(md, summary_opts(), Some(&mut replacer)) + .peekable(); + let mut summary = SummaryLine::new(p); let mut s = String::new(); - let without_paragraphs = LinkReplacer::new(SummaryLine::new(p), links).filter(|event| { + let without_paragraphs = LinkReplacer::new(&mut summary, links).filter(|event| { !matches!(event, Event::Start(Tag::Paragraph) | Event::End(Tag::Paragraph)) }); html::push_html(&mut s, without_paragraphs); - s + let has_more_content = + matches!(summary.inner.peek(), Some(Event::Start(_))) || summary.skipped_tags > 0; + + (s, has_more_content) + } + + pub(crate) fn into_string(self) -> String { + self.into_string_with_has_more_content().0 } } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 80fbe9c1f06..146e5010e4e 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -467,9 +467,10 @@ fn document_short( return; } if let Some(s) = item.doc_value() { - let mut summary_html = MarkdownSummaryLine(&s, &item.links(cx)).into_string(); + let (mut summary_html, has_more_content) = + MarkdownSummaryLine(&s, &item.links(cx)).into_string_with_has_more_content(); - if s.contains('\n') { + if has_more_content { let link = format!(r#" <a{}>Read more</a>"#, assoc_href_attr(item, link, cx)); if let Some(idx) = summary_html.rfind("</p>") { diff --git a/src/test/codegen/enum-match.rs b/src/test/codegen/enum-match.rs index 44f1b408d21..827eb20154a 100644 --- a/src/test/codegen/enum-match.rs +++ b/src/test/codegen/enum-match.rs @@ -34,8 +34,8 @@ pub enum Enum1 { // CHECK: define i8 @match1{{.*}} // CHECK-NEXT: start: -// CHECK-NEXT: %1 = {{.*}}call i8 @llvm.usub.sat.i8(i8 %0, i8 1) -// CHECK-NEXT: switch i8 %1, label {{.*}} [ +// CHECK-NEXT: [[DISCR:%.*]] = {{.*}}call i8 @llvm.usub.sat.i8(i8 %0, i8 1) +// CHECK-NEXT: switch i8 [[DISCR]], label {{.*}} [ #[no_mangle] pub fn match1(e: Enum1) -> u8 { use Enum1::*; diff --git a/src/test/rustdoc/read-more-unneeded.rs b/src/test/rustdoc/read-more-unneeded.rs new file mode 100644 index 00000000000..0303e444261 --- /dev/null +++ b/src/test/rustdoc/read-more-unneeded.rs @@ -0,0 +1,34 @@ +// Regression test for https://github.com/rust-lang/rust/issues/105677. +// This test ensures that the "Read more" link is only generated when +// there is actually more documentation to read after the short summary. + +#![crate_name = "foo"] + +pub trait MyFrom { + /// # Hello + /// ## Yolo + /// more! + fn try_from1(); + /// a + /// b + /// c + fn try_from2(); + /// a + /// + /// b + /// + /// c + fn try_from3(); +} + +pub struct NonZero; + +// @has 'foo/struct.NonZero.html' +impl MyFrom for NonZero { + // @matches - '//*[@class="docblock"]' '^Hello Read more$' + fn try_from1() {} + // @matches - '//*[@class="docblock"]' '^a\sb\sc$' + fn try_from2() {} + // @matches - '//*[@class="docblock"]' '^a Read more$' + fn try_from3() {} +} diff --git a/src/test/rustdoc/trait-impl.rs b/src/test/rustdoc/trait-impl.rs index 195cdf009b9..9cf3226f738 100644 --- a/src/test/rustdoc/trait-impl.rs +++ b/src/test/rustdoc/trait-impl.rs @@ -30,8 +30,6 @@ impl Trait for Struct { // @has - '//*[@id="method.b"]/../../div[@class="docblock"]' 'These docs contain' // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a' 'reference link' // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a/@href' 'https://example.com' - // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a' 'Read more' - // @has - '//*[@id="method.b"]/../../div[@class="docblock"]/a/@href' 'trait.Trait.html#tymethod.b' fn b() {} // @!has - '//*[@id="method.c"]/../../div[@class="docblock"]' 'code block' diff --git a/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs b/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs index 851da231a73..28926243390 100644 --- a/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs +++ b/src/test/ui/allocator/no_std-alloc-error-handler-custom.rs @@ -7,9 +7,10 @@ // compile-flags:-C panic=abort // aux-build:helper.rs -#![feature(start, rustc_private, new_uninit, panic_info_message, lang_items)] +#![feature(rustc_private, lang_items)] #![feature(alloc_error_handler)] #![no_std] +#![no_main] extern crate alloc; extern crate libc; @@ -21,35 +22,30 @@ pub fn __aeabi_unwind_cpp_pr0() {} #[no_mangle] pub fn __aeabi_unwind_cpp_pr1() {} -use core::ptr::null_mut; -use core::alloc::{GlobalAlloc, Layout}; use alloc::boxed::Box; +use alloc::string::ToString; +use core::alloc::{GlobalAlloc, Layout}; +use core::ptr::null_mut; extern crate helper; struct MyAllocator; #[alloc_error_handler] -fn my_oom(layout: Layout) -> ! -{ +fn my_oom(layout: Layout) -> ! { use alloc::fmt::write; unsafe { let size = layout.size(); let mut s = alloc::string::String::new(); write(&mut s, format_args!("My OOM: failed to allocate {} bytes!\n", size)).unwrap(); - let s = s.as_str(); - libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); + libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len()); libc::exit(0) } } unsafe impl GlobalAlloc for MyAllocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - if layout.size() < 4096 { - libc::malloc(layout.size()) as _ - } else { - null_mut() - } + if layout.size() < 4096 { libc::malloc(layout.size()) as _ } else { null_mut() } } unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} } @@ -60,26 +56,12 @@ static A: MyAllocator = MyAllocator; #[panic_handler] fn panic(panic_info: &core::panic::PanicInfo) -> ! { unsafe { - if let Some(s) = panic_info.payload().downcast_ref::<&str>() { - const PSTR: &str = "panic occurred: "; - const CR: &str = "\n"; - libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); - libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); - libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); - } - if let Some(args) = panic_info.message() { - let mut s = alloc::string::String::new(); - alloc::fmt::write(&mut s, *args).unwrap(); - let s = s.as_str(); - const PSTR: &str = "panic occurred: "; - const CR: &str = "\n"; - libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); - libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); - libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); - } else { - const PSTR: &str = "panic occurred\n"; - libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); - } + let s = panic_info.to_string(); + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR.as_ptr() as *const _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len()); + libc::write(libc::STDERR_FILENO, CR.as_ptr() as *const _, CR.len()); libc::exit(1) } } @@ -89,15 +71,14 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! { // in these libraries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't // unwind. So, for this test case we will define the symbol. #[lang = "eh_personality"] -extern fn rust_eh_personality() {} +extern "C" fn rust_eh_personality() {} -#[derive(Debug)] +#[derive(Default, Debug)] struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]); -#[start] -pub fn main(_argc: isize, _argv: *const *const u8) -> isize { - let zero = Box::<Page>::new_zeroed(); - let zero = unsafe { zero.assume_init() }; +#[no_mangle] +fn main(_argc: i32, _argv: *const *const u8) -> isize { + let zero = Box::<Page>::new(Default::default()); helper::work_with(&zero); 1 } diff --git a/src/test/ui/allocator/no_std-alloc-error-handler-default.rs b/src/test/ui/allocator/no_std-alloc-error-handler-default.rs index 30ce0f162c7..56409e71339 100644 --- a/src/test/ui/allocator/no_std-alloc-error-handler-default.rs +++ b/src/test/ui/allocator/no_std-alloc-error-handler-default.rs @@ -6,11 +6,10 @@ // only-linux // compile-flags:-C panic=abort // aux-build:helper.rs -// gate-test-default_alloc_error_handler -#![feature(start, rustc_private, new_uninit, panic_info_message, lang_items)] -#![feature(default_alloc_error_handler)] +#![feature(rustc_private, lang_items)] #![no_std] +#![no_main] extern crate alloc; extern crate libc; @@ -23,6 +22,7 @@ pub fn __aeabi_unwind_cpp_pr0() {} pub fn __aeabi_unwind_cpp_pr1() {} use alloc::boxed::Box; +use alloc::string::ToString; use core::alloc::{GlobalAlloc, Layout}; use core::ptr::null_mut; @@ -32,11 +32,7 @@ struct MyAllocator; unsafe impl GlobalAlloc for MyAllocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - if layout.size() < 4096 { - libc::malloc(layout.size()) as _ - } else { - null_mut() - } + if layout.size() < 4096 { libc::malloc(layout.size()) as _ } else { null_mut() } } unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} } @@ -47,26 +43,12 @@ static A: MyAllocator = MyAllocator; #[panic_handler] fn panic(panic_info: &core::panic::PanicInfo) -> ! { unsafe { - if let Some(s) = panic_info.payload().downcast_ref::<&str>() { - const PSTR: &str = "panic occurred: "; - const CR: &str = "\n"; - libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); - libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); - libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); - } - if let Some(args) = panic_info.message() { - let mut s = alloc::string::String::new(); - alloc::fmt::write(&mut s, *args).unwrap(); - let s = s.as_str(); - const PSTR: &str = "panic occurred: "; - const CR: &str = "\n"; - libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); - libc::write(libc::STDERR_FILENO, s as *const _ as _, s.len()); - libc::write(libc::STDERR_FILENO, CR as *const _ as _, CR.len()); - } else { - const PSTR: &str = "panic occurred\n"; - libc::write(libc::STDERR_FILENO, PSTR as *const _ as _, PSTR.len()); - } + let s = panic_info.to_string(); + const PSTR: &str = "panic occurred: "; + const CR: &str = "\n"; + libc::write(libc::STDERR_FILENO, PSTR.as_ptr() as *const _, PSTR.len()); + libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len()); + libc::write(libc::STDERR_FILENO, CR.as_ptr() as *const _, CR.len()); libc::exit(0) } } @@ -76,15 +58,14 @@ fn panic(panic_info: &core::panic::PanicInfo) -> ! { // in these libraries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't // unwind. So, for this test case we will define the symbol. #[lang = "eh_personality"] -extern fn rust_eh_personality() {} +extern "C" fn rust_eh_personality() {} -#[derive(Debug)] +#[derive(Default, Debug)] struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]); -#[start] -pub fn main(_argc: isize, _argv: *const *const u8) -> isize { - let zero = Box::<Page>::new_zeroed(); - let zero = unsafe { zero.assume_init() }; +#[no_mangle] +fn main(_argc: i32, _argv: *const *const u8) -> isize { + let zero = Box::<Page>::new(Default::default()); helper::work_with(&zero); 1 } diff --git a/src/test/ui/associated-inherent-types/style.rs b/src/test/ui/associated-inherent-types/style.rs new file mode 100644 index 00000000000..8775bd19e1f --- /dev/null +++ b/src/test/ui/associated-inherent-types/style.rs @@ -0,0 +1,12 @@ +#![feature(inherent_associated_types)] +#![allow(incomplete_features, dead_code)] +#![deny(non_camel_case_types)] + +struct S; + +impl S { + type typ = (); + //~^ ERROR associated type `typ` should have an upper camel case name +} + +fn main() {} diff --git a/src/test/ui/associated-inherent-types/style.stderr b/src/test/ui/associated-inherent-types/style.stderr new file mode 100644 index 00000000000..f83061f8c42 --- /dev/null +++ b/src/test/ui/associated-inherent-types/style.stderr @@ -0,0 +1,14 @@ +error: associated type `typ` should have an upper camel case name + --> $DIR/style.rs:8:10 + | +LL | type typ = (); + | ^^^ help: convert the identifier to upper camel case: `Typ` + | +note: the lint level is defined here + --> $DIR/style.rs:3:9 + | +LL | #![deny(non_camel_case_types)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/async-await/in-trait/bad-signatures.rs b/src/test/ui/async-await/in-trait/bad-signatures.rs new file mode 100644 index 00000000000..b86f1d1c135 --- /dev/null +++ b/src/test/ui/async-await/in-trait/bad-signatures.rs @@ -0,0 +1,16 @@ +// edition:2021 + +#![feature(async_fn_in_trait)] +//~^ WARN the feature `async_fn_in_trait` is incomplete + +trait MyTrait { + async fn bar(&abc self); + //~^ ERROR expected identifier, found keyword `self` + //~| ERROR expected one of `:`, `@`, or `|`, found keyword `self` +} + +impl MyTrait for () { + async fn bar(&self) {} +} + +fn main() {} diff --git a/src/test/ui/async-await/in-trait/bad-signatures.stderr b/src/test/ui/async-await/in-trait/bad-signatures.stderr new file mode 100644 index 00000000000..e0ba7b53ec4 --- /dev/null +++ b/src/test/ui/async-await/in-trait/bad-signatures.stderr @@ -0,0 +1,26 @@ +error: expected identifier, found keyword `self` + --> $DIR/bad-signatures.rs:7:23 + | +LL | async fn bar(&abc self); + | ^^^^ expected identifier, found keyword + +error: expected one of `:`, `@`, or `|`, found keyword `self` + --> $DIR/bad-signatures.rs:7:23 + | +LL | async fn bar(&abc self); + | -----^^^^ + | | | + | | expected one of `:`, `@`, or `|` + | help: declare the type after the parameter binding: `<identifier>: <type>` + +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bad-signatures.rs:3:12 + | +LL | #![feature(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 2 previous errors; 1 warning emitted + diff --git a/src/test/ui/dyn-star/dyn-to-rigid.rs b/src/test/ui/dyn-star/dyn-to-rigid.rs new file mode 100644 index 00000000000..e80ee15902e --- /dev/null +++ b/src/test/ui/dyn-star/dyn-to-rigid.rs @@ -0,0 +1,11 @@ +#![feature(dyn_star)] +#![allow(incomplete_features)] + +trait Tr {} + +fn f(x: dyn* Tr) -> usize { + x as usize + //~^ ERROR casting `(dyn* Tr + 'static)` as `usize` is invalid +} + +fn main() {} diff --git a/src/test/ui/dyn-star/dyn-to-rigid.stderr b/src/test/ui/dyn-star/dyn-to-rigid.stderr new file mode 100644 index 00000000000..588e6d97e5c --- /dev/null +++ b/src/test/ui/dyn-star/dyn-to-rigid.stderr @@ -0,0 +1,9 @@ +error[E0606]: casting `(dyn* Tr + 'static)` as `usize` is invalid + --> $DIR/dyn-to-rigid.rs:7:5 + | +LL | x as usize + | ^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0606`. diff --git a/src/test/ui/missing/missing-alloc_error_handler.rs b/src/test/ui/missing/missing-alloc_error_handler.rs deleted file mode 100644 index 4d378f010ed..00000000000 --- a/src/test/ui/missing/missing-alloc_error_handler.rs +++ /dev/null @@ -1,23 +0,0 @@ -// compile-flags: -C panic=abort -// no-prefer-dynamic - -#![no_std] -#![crate_type = "staticlib"] -#![feature(alloc_error_handler)] - -#[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { - loop {} -} - -extern crate alloc; - -#[global_allocator] -static A: MyAlloc = MyAlloc; - -struct MyAlloc; - -unsafe impl core::alloc::GlobalAlloc for MyAlloc { - unsafe fn alloc(&self, _: core::alloc::Layout) -> *mut u8 { 0 as _ } - unsafe fn dealloc(&self, _: *mut u8, _: core::alloc::Layout) {} -} diff --git a/src/test/ui/missing/missing-alloc_error_handler.stderr b/src/test/ui/missing/missing-alloc_error_handler.stderr deleted file mode 100644 index 995fa7cf85e..00000000000 --- a/src/test/ui/missing/missing-alloc_error_handler.stderr +++ /dev/null @@ -1,6 +0,0 @@ -error: `#[alloc_error_handler]` function required, but not found - -note: use `#![feature(default_alloc_error_handler)]` for a default error handler - -error: aborting due to previous error - |
