diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 4d2e2989e834a..9512e74601784 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -94,11 +94,11 @@ jobs: uses: actions/checkout@v5 - name: download Cargo.lock from update job - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: Cargo-lock - name: download cargo-update log from update job - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: cargo-updates diff --git a/Cargo.lock b/Cargo.lock index f035068a600d9..3862f0b42cd0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,9 +64,9 @@ dependencies = [ [[package]] name = "annotate-snippets" -version = "0.12.15" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92570a3f9c98e7e84df84b71d0965ac99b1871fcd75a3773a3bd1bad13f64cf7" +checksum = "f211a51805bc641f3ad5b7664c77d2547af685cc33b4cd8d31964027a46f13f1" dependencies = [ "anstyle", "memchr", @@ -3958,7 +3958,7 @@ dependencies = [ name = "rustc_errors" version = "0.0.0" dependencies = [ - "annotate-snippets 0.12.15", + "annotate-snippets 0.12.16", "anstream", "anstyle", "derive_setters", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 8a342acbfa913..b8339c74dac03 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -509,8 +509,6 @@ pub enum WherePredicateKind { BoundPredicate(WhereBoundPredicate), /// A lifetime predicate (e.g., `'a: 'b + 'c`). RegionPredicate(WhereRegionPredicate), - /// An equality predicate (unsupported). - EqPredicate(WhereEqPredicate), } /// A type bound. diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 0e518c10e3bb7..8ae2f3bda9f92 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -2111,18 +2111,6 @@ impl<'hir> LoweringContext<'_, 'hir> { in_where_clause: true, }) } - WherePredicateKind::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty }) => { - hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { - lhs_ty: self.lower_ty_alloc( - lhs_ty, - ImplTraitContext::Disallowed(ImplTraitPosition::Bound), - ), - rhs_ty: self.lower_ty_alloc( - rhs_ty, - ImplTraitContext::Disallowed(ImplTraitPosition::Bound), - ), - }) - } }); hir::WherePredicate { hir_id, span, kind } } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index db0c5256184c5..081de1ac2de6b 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -17,7 +17,6 @@ //! require name resolution or type checking, or other kinds of complex analysis. use std::mem; -use std::ops::{Deref, DerefMut}; use std::str::FromStr; use itertools::{Either, Itertools}; @@ -37,7 +36,6 @@ use rustc_session::lint::builtin::{ }; use rustc_span::{Ident, Span, kw, sym}; use rustc_target::spec::{AbiMap, AbiMapping}; -use thin_vec::thin_vec; use crate::diagnostics::{self, TildeConstReason}; @@ -1593,14 +1591,8 @@ impl Visitor<'_> for AstValidator<'_> { } validate_generic_param_order(self.dcx(), &generics.params, generics.span); - - for predicate in &generics.where_clause.predicates { - let span = predicate.span; - if let WherePredicateKind::EqPredicate(predicate) = &predicate.kind { - deny_equality_constraints(self, predicate, span, generics); - } - } walk_list!(self, visit_generic_param, &generics.params); + for predicate in &generics.where_clause.predicates { match &predicate.kind { WherePredicateKind::BoundPredicate(bound_pred) => { @@ -1625,7 +1617,7 @@ impl Visitor<'_> for AstValidator<'_> { } } } - _ => {} + WherePredicateKind::RegionPredicate(_) => {} } self.visit_where_predicate(predicate); } @@ -1962,170 +1954,6 @@ impl Visitor<'_> for AstValidator<'_> { } } -/// When encountering an equality constraint in a `where` clause, emit an error. If the code seems -/// like it's setting an associated type, provide an appropriate suggestion. -fn deny_equality_constraints( - this: &AstValidator<'_>, - predicate: &WhereEqPredicate, - predicate_span: Span, - generics: &Generics, -) { - let mut err = diagnostics::EqualityInWhere { span: predicate_span, assoc: None, assoc2: None }; - - // Given `::Bar = RhsTy`, suggest `A: Foo`. - if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind - && let TyKind::Path(None, path) = &qself.ty.kind - && let [PathSegment { ident, args: None, .. }] = &path.segments[..] - { - for param in &generics.params { - if param.ident == *ident - && let [PathSegment { ident, args, .. }] = &full_path.segments[qself.position..] - { - // Make a new `Path` from `foo::Bar` to `Foo`. - let mut assoc_path = full_path.clone(); - // Remove `Bar` from `Foo::Bar`. - assoc_path.segments.pop(); - let len = assoc_path.segments.len() - 1; - let gen_args = args.as_deref().cloned(); - // Build ``. - let arg = AngleBracketedArg::Constraint(AssocItemConstraint { - id: rustc_ast::node_id::DUMMY_NODE_ID, - ident: *ident, - gen_args, - kind: AssocItemConstraintKind::Equality { - term: predicate.rhs_ty.clone().into(), - }, - span: ident.span, - }); - // Add `` to `Foo`. - match &mut assoc_path.segments[len].args { - Some(args) => match args.deref_mut() { - GenericArgs::Parenthesized(_) | GenericArgs::ParenthesizedElided(..) => { - continue; - } - GenericArgs::AngleBracketed(args) => { - args.args.push(arg); - } - }, - empty_args => { - *empty_args = Some( - AngleBracketedArgs { span: ident.span, args: thin_vec![arg] }.into(), - ); - } - } - err.assoc = Some(diagnostics::AssociatedSuggestion { - span: predicate_span, - ident: *ident, - param: param.ident, - path: pprust::path_to_string(&assoc_path), - }) - } - } - } - - let mut suggest = - |poly: &PolyTraitRef, potential_assoc: &PathSegment, predicate: &WhereEqPredicate| { - if let [trait_segment] = &poly.trait_ref.path.segments[..] { - let assoc = pprust::path_to_string(&ast::Path::from_ident(potential_assoc.ident)); - let ty = pprust::ty_to_string(&predicate.rhs_ty); - let (args, span) = match &trait_segment.args { - Some(args) => match args.deref() { - ast::GenericArgs::AngleBracketed(args) => { - let Some(arg) = args.args.last() else { - return; - }; - (format!(", {assoc} = {ty}"), arg.span().shrink_to_hi()) - } - _ => return, - }, - None => (format!("<{assoc} = {ty}>"), trait_segment.span().shrink_to_hi()), - }; - let removal_span = if generics.where_clause.predicates.len() == 1 { - // We're removing th eonly where bound left, remove the whole thing. - generics.where_clause.span - } else { - let mut span = predicate_span; - let mut prev_span: Option = None; - let mut preds = generics.where_clause.predicates.iter().peekable(); - // Find the predicate that shouldn't have been in the where bound list. - while let Some(pred) = preds.next() { - if let WherePredicateKind::EqPredicate(_) = pred.kind - && pred.span == predicate_span - { - if let Some(next) = preds.peek() { - // This is the first predicate, remove the trailing comma as well. - span = span.with_hi(next.span.lo()); - } else if let Some(prev_span) = prev_span { - // Remove the previous comma as well. - span = span.with_lo(prev_span.hi()); - } - } - prev_span = Some(pred.span); - } - span - }; - err.assoc2 = Some(diagnostics::AssociatedSuggestion2 { - span, - args, - predicate: removal_span, - trait_segment: trait_segment.ident, - potential_assoc: potential_assoc.ident, - }); - } - }; - - if let TyKind::Path(None, full_path) = &predicate.lhs_ty.kind { - // Given `A: Foo, Foo::Bar = RhsTy`, suggest `A: Foo`. - for bounds in generics.params.iter().map(|p| &p.bounds).chain( - generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind { - WherePredicateKind::BoundPredicate(p) => Some(&p.bounds), - _ => None, - }), - ) { - for bound in bounds { - if let GenericBound::Trait(poly) = bound - && poly.modifiers == TraitBoundModifiers::NONE - { - if full_path.segments[..full_path.segments.len() - 1] - .iter() - .map(|segment| segment.ident.name) - .zip(poly.trait_ref.path.segments.iter().map(|segment| segment.ident.name)) - .all(|(a, b)| a == b) - && let Some(potential_assoc) = full_path.segments.last() - { - suggest(poly, potential_assoc, predicate); - } - } - } - } - // Given `A: Foo, A::Bar = RhsTy`, suggest `A: Foo`. - if let [potential_param, potential_assoc] = &full_path.segments[..] { - for (ident, bounds) in generics.params.iter().map(|p| (p.ident, &p.bounds)).chain( - generics.where_clause.predicates.iter().filter_map(|pred| match &pred.kind { - WherePredicateKind::BoundPredicate(p) - if let ast::TyKind::Path(None, path) = &p.bounded_ty.kind - && let [segment] = &path.segments[..] => - { - Some((segment.ident, &p.bounds)) - } - _ => None, - }), - ) { - if ident == potential_param.ident { - for bound in bounds { - if let ast::GenericBound::Trait(poly) = bound - && poly.modifiers == TraitBoundModifiers::NONE - { - suggest(poly, potential_assoc, predicate); - } - } - } - } - } - } - this.dcx().emit_err(err); -} - pub fn check_crate( sess: &Session, features: &Features, diff --git a/compiler/rustc_ast_passes/src/diagnostics.rs b/compiler/rustc_ast_passes/src/diagnostics.rs index a6b75cb70a548..89284ca3524fd 100644 --- a/compiler/rustc_ast_passes/src/diagnostics.rs +++ b/compiler/rustc_ast_passes/src/diagnostics.rs @@ -878,49 +878,6 @@ pub(crate) struct PatternInBodiless { pub span: Span, } -#[derive(Diagnostic)] -#[diag("equality constraints are not yet supported in `where` clauses")] -#[note("see issue #20041 for more information")] -pub(crate) struct EqualityInWhere { - #[primary_span] - #[label("not supported")] - pub span: Span, - #[subdiagnostic] - pub assoc: Option, - #[subdiagnostic] - pub assoc2: Option, -} - -#[derive(Subdiagnostic)] -#[suggestion( - "if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax", - code = "{param}: {path}", - style = "verbose", - applicability = "maybe-incorrect" -)] -pub(crate) struct AssociatedSuggestion { - #[primary_span] - pub span: Span, - pub ident: Ident, - pub param: Ident, - pub path: String, -} - -#[derive(Subdiagnostic)] -#[multipart_suggestion( - "if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax", - applicability = "maybe-incorrect" -)] -pub(crate) struct AssociatedSuggestion2 { - #[suggestion_part(code = "{args}")] - pub span: Span, - pub args: String, - #[suggestion_part(code = "")] - pub predicate: Span, - pub trait_segment: Ident, - pub potential_assoc: Ident, -} - #[derive(Diagnostic)] #[diag("`#![feature]` may not be used on the {$channel} release channel", code = E0554)] pub(crate) struct FeatureOnNonNightly { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 820c49cd0612c..86fb0e62bdaa4 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -869,14 +869,6 @@ impl<'a> State<'a> { self.print_lifetime_bounds(bounds); } } - ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { - lhs_ty, rhs_ty, .. - }) => { - self.print_type(lhs_ty); - self.space(); - self.word_space("="); - self.print_type(rhs_ty); - } } } diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 4d714fccc3f61..799b5ccbe4e40 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -30,8 +30,8 @@ use thin_vec::ThinVec; use crate::ShouldEmit; use crate::session_diagnostics::{ - InvalidMetaItem, InvalidMetaItemQuoteIdentSugg, InvalidMetaItemRemoveNegSugg, MetaBadDelim, - MetaBadDelimSugg, SuffixedLiteralInAttribute, + ExpectedComma, InvalidMetaItem, InvalidMetaItemQuoteIdentSugg, InvalidMetaItemRemoveNegSugg, + MetaBadDelim, MetaBadDelimSugg, SuffixedLiteralInAttribute, }; #[derive(Clone, Debug)] @@ -704,6 +704,29 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { self.parser.dcx().create_err(err) } + fn should_continue_parsing_meta_items(&mut self) -> Result> { + if self.parser.eat(exp!(Comma)) { + return Ok(true); + } else if self.parser.token == token::Eof { + return Ok(false); + } + + let mut snapshot = self.parser.create_snapshot_for_diagnostic(); + if matches!(self.should_emit, ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed }) { + let span = self.parser.prev_token.span.shrink_to_hi(); + self.should_emit = ShouldEmit::Nothing; + match self.parse_meta_item_inner() { + Ok(_) => { + return Err(self.parser.dcx().create_err(ExpectedComma { span })); + } + Err(e) => { + e.cancel(); + } + } + } + snapshot.unexpected_any() + } + fn parse( tokens: TokenStream, psess: &'sess ParseSess, @@ -724,15 +747,11 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> { while this.parser.token != token::Eof { sub_parsers.push(this.parse_meta_item_inner()?); - if !this.parser.eat(exp!(Comma)) { + if !this.should_continue_parsing_meta_items()? { break; } } - if parser.token != token::Eof { - parser.unexpected()?; - } - Ok(MetaItemListParser { sub_parsers, span }) } } diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index b4afdfd7ce409..6dc629583cebe 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -1032,3 +1032,16 @@ pub(crate) struct SanitizeInvalidStatic { pub span: Span, pub field: &'static str, } + +#[derive(Diagnostic)] +#[diag("attribute items not separated with `,`")] +pub(crate) struct ExpectedComma { + #[primary_span] + #[suggestion( + "try adding `,` here", + code = ",", + applicability = "maybe-incorrect", + style = "short" + )] + pub span: Span, +} diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 43399b614b50a..80296a43ee490 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -396,8 +396,7 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> { self.visit_param_bound(bound, BoundKind::Bound) } } - rustc_ast::WherePredicateKind::RegionPredicate(_) - | rustc_ast::WherePredicateKind::EqPredicate(_) => {} + rustc_ast::WherePredicateKind::RegionPredicate(_) => {} } } } diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 38cb986034859..af783f31a2136 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -40,7 +40,7 @@ use cranelift_codegen::settings::{self, Configurable}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig, back}; use rustc_log::tracing::info; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::WorkProductMap; use rustc_session::Session; use rustc_session::config::OutputFilenames; use rustc_span::{Symbol, sym}; @@ -88,7 +88,7 @@ mod prelude { }; pub(crate) use cranelift_module::{self, DataDescription, FuncId, Linkage, Module}; pub(crate) use rustc_abi::{BackendRepr, FIRST_VARIANT, FieldIdx, Scalar, Size, VariantIdx}; - pub(crate) use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; + pub(crate) use rustc_data_structures::fx::FxHashMap; pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE}; pub(crate) use rustc_index::Idx; pub(crate) use rustc_middle::mir::{self, *}; @@ -235,7 +235,7 @@ impl CodegenBackend for CraneliftCodegenBackend { sess: &Session, _outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { + ) -> (CompiledModules, WorkProductMap) { ongoing_codegen .downcast::>() .unwrap() diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 9669f40166287..850b67c7b25af 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -89,11 +89,10 @@ use rustc_codegen_ssa::base::codegen_crate; use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, WriteBackendMethods}; use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; @@ -301,7 +300,7 @@ impl CodegenBackend for GccCodegenBackend { sess: &Session, _outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { + ) -> (CompiledModules, WorkProductMap) { ongoing_codegen .downcast::>() .expect("Expected GccCodegenBackend's OngoingCodegen, found Box") diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 7c05ecbab6d1c..c0593bb467796 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -32,11 +32,10 @@ use rustc_codegen_ssa::back::write::{ }; use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{CompiledModule, CompiledModules, CrateInfo, ModuleCodegen, TargetConfig}; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_errors::{DiagCtxt, DiagCtxtHandle}; use rustc_metadata::EncodedMetadata; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; @@ -358,7 +357,7 @@ impl CodegenBackend for LlvmCodegenBackend { sess: &Session, outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { + ) -> (CompiledModules, WorkProductMap) { let (compiled_modules, work_products) = ongoing_codegen .downcast::>() .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box") diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 1b7817cb17bfe..112cf45ebbf2e 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -6,7 +6,6 @@ use std::sync::mpsc::{Receiver, Sender, channel}; use std::{assert_matches, fs, io, mem, str, thread}; use rustc_abi::Size; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::{self, Acquired}; use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard}; use rustc_errors::emitter::Emitter; @@ -22,7 +21,7 @@ use rustc_incremental::{ use rustc_macros::{Decodable, Encodable}; use rustc_metadata::fs::copy_to_stdout; use rustc_middle::bug; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{WorkProduct, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{ @@ -460,8 +459,8 @@ pub(crate) fn start_async_codegen( fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( sess: &Session, compiled_modules: &CompiledModules, -) -> FxIndexMap { - let mut work_products = FxIndexMap::default(); +) -> WorkProductMap { + let mut work_products = WorkProductMap::default(); if sess.opts.incremental.is_none() || sess.opts.unstable_opts.disable_incr_comp_backend_caching { @@ -490,14 +489,13 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( if let Some(path) = &module.bytecode { files.push((OutputType::Bitcode.extension(), path.as_path())); } - if let Some((id, product)) = copy_cgu_workproduct_to_incr_comp_cache_dir( + let (id, product) = copy_cgu_workproduct_to_incr_comp_cache_dir( sess, &module.name, files.as_slice(), &module.links_from_incr_cache, - ) { - work_products.insert(id, product); - } + ); + work_products.insert(id, product); } work_products @@ -2099,11 +2097,7 @@ pub struct OngoingCodegen { } impl OngoingCodegen { - pub fn join( - self, - sess: &Session, - crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { + pub fn join(self, sess: &Session, crate_info: &CrateInfo) -> (CompiledModules, WorkProductMap) { self.shared_emitter_main.check(sess, true); let maybe_lto_modules = sess.time("join_worker_thread", || match self.coordinator.join() { diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 433964218e43b..2549d0a039109 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -105,7 +105,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { .layout_of(bx.typing_env().as_query_input(pointee)) .expect("expected pointee to have a layout"); let elem_size = pointee_layout.layout.size().bytes(); - let bytes = bx.mul(count, bx.const_usize(elem_size)); + let bytes = bx.unchecked_sumul(count, bx.const_usize(elem_size)); let align = pointee_layout.layout.align.abi; let dst = dst_val.immediate(); diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 6bee9f7cadee7..6014f1af4bfc3 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -2,11 +2,10 @@ use std::any::Any; use std::hash::Hash; use rustc_ast::expand::allocator::AllocatorMethod; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_metadata::EncodedMetadata; use rustc_metadata::creader::MetadataLoaderDyn; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::WorkProductMap; use rustc_middle::ty::TyCtxt; use rustc_middle::util::Providers; use rustc_session::Session; @@ -130,7 +129,7 @@ pub trait CodegenBackend { sess: &Session, outputs: &OutputFilenames, crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap); + ) -> (CompiledModules, WorkProductMap); fn print_pass_timings(&self) {} diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 386467c3e1edb..b0eed7ae2aad9 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -annotate-snippets = { version = "0.12.15", features = ["simd"] } +annotate-snippets = { version = "0.12.16", features = ["simd"] } anstream = "0.6.20" anstyle = "1.0.13" derive_setters = "0.1.6" diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ab2fa550c4f9a..53141dcc5042f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1193,8 +1193,6 @@ pub enum WherePredicateKind<'hir> { BoundPredicate(WhereBoundPredicate<'hir>), /// A lifetime predicate (e.g., `'a: 'b + 'c`). RegionPredicate(WhereRegionPredicate<'hir>), - /// An equality predicate (unsupported). - EqPredicate(WhereEqPredicate<'hir>), } impl<'hir> WherePredicateKind<'hir> { @@ -1202,7 +1200,6 @@ impl<'hir> WherePredicateKind<'hir> { match self { WherePredicateKind::BoundPredicate(p) => p.origin == PredicateOrigin::WhereClause, WherePredicateKind::RegionPredicate(p) => p.in_where_clause, - WherePredicateKind::EqPredicate(_) => false, } } @@ -1210,7 +1207,6 @@ impl<'hir> WherePredicateKind<'hir> { match self { WherePredicateKind::BoundPredicate(p) => p.bounds, WherePredicateKind::RegionPredicate(p) => p.bounds, - WherePredicateKind::EqPredicate(_) => &[], } } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 85f0e97a0a9d6..b0c6a136ba29f 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1200,10 +1200,6 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>( try_visit!(visitor.visit_lifetime(lifetime)); walk_list!(visitor, visit_param_bound, bounds); } - WherePredicateKind::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty }) => { - try_visit!(visitor.visit_ty_unambig(lhs_ty)); - try_visit!(visitor.visit_ty_unambig(rhs_ty)); - } } V::Result::output() } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 234231ed37fed..964f801e53819 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1202,7 +1202,6 @@ pub(super) fn check_number_of_early_bound_regions<'tcx>( } } } - _ => {} } } if let Some(impl_node) = tcx.hir_get_if_local(impl_def_id.into()) @@ -1225,7 +1224,6 @@ pub(super) fn check_number_of_early_bound_regions<'tcx>( } } } - _ => {} } } if impl_bounds == bounds_span.len() { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index cf29a76418792..01e78fbd2f63e 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -322,10 +322,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen (pred, span) })) } - - hir::WherePredicateKind::EqPredicate(..) => { - // FIXME(#20041) - } } } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 3e48bfe4bc252..adc8be18a0adb 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -999,12 +999,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { self.visit_lifetime(lifetime); walk_list!(self, visit_param_bound, bounds); } - &hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { - lhs_ty, rhs_ty, .. - }) => { - self.visit_ty_unambig(lhs_ty); - self.visit_ty_unambig(rhs_ty); - } } } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 637ae115131a1..0204c4c9ab5fa 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -2530,14 +2530,6 @@ impl<'a> State<'a> { } } } - hir::WherePredicateKind::EqPredicate(hir::WhereEqPredicate { - lhs_ty, rhs_ty, .. - }) => { - self.print_type(lhs_ty); - self.space(); - self.word_space("="); - self.print_type(rhs_ty); - } } } diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index ab695dddf06e6..69705f28aa114 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -1,8 +1,7 @@ use std::fs; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::par_join; -use rustc_middle::dep_graph::{DepGraph, WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::{DepGraph, WorkProductMap}; use rustc_middle::query::on_disk_cache; use rustc_middle::ty::TyCtxt; use rustc_serialize::Encodable as RustcEncodable; @@ -93,7 +92,7 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) { pub fn save_work_product_index( sess: &Session, dep_graph: &DepGraph, - new_work_products: FxIndexMap, + new_work_products: WorkProductMap, ) { if sess.opts.incremental.is_none() { return; @@ -126,18 +125,16 @@ pub fn save_work_product_index( // Check that we did not delete one of the current work-products: debug_assert!({ - new_work_products.iter().all(|(_, wp)| { + new_work_products.items().all(|(_, wp)| { wp.saved_files.items().all(|(_, path)| in_incr_comp_dir_sess(sess, path).exists()) }) }); } -fn encode_work_product_index( - work_products: &FxIndexMap, - encoder: &mut FileEncoder, -) { +fn encode_work_product_index(work_products: &WorkProductMap, encoder: &mut FileEncoder) { let serialized_products: Vec<_> = work_products - .iter() + .to_sorted_stable_ord() + .into_iter() .map(|(id, work_product)| SerializedWorkProduct { id: *id, work_product: work_product.clone(), diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs index 7b1eb0a82e397..64dae5c0869b9 100644 --- a/compiler/rustc_incremental/src/persist/work_product.rs +++ b/compiler/rustc_incremental/src/persist/work_product.rs @@ -16,14 +16,16 @@ use crate::persist::fs::*; /// Copies a CGU work product to the incremental compilation directory, so next compilation can /// find and reuse it. +/// +/// Panics when incr comp is disabled. pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( sess: &Session, cgu_name: &str, files: &[(&'static str, &Path)], known_links: &[PathBuf], -) -> Option<(WorkProductId, WorkProduct)> { +) -> (WorkProductId, WorkProduct) { debug!(?cgu_name, ?files); - sess.opts.incremental.as_ref()?; + assert!(sess.opts.incremental.is_some()); let mut saved_files = UnordMap::default(); for (ext, path) in files { @@ -50,7 +52,7 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( let work_product = WorkProduct { cgu_name: cgu_name.to_string(), saved_files }; debug!(?work_product); let work_product_id = WorkProductId::from_cgu_name(cgu_name); - Some((work_product_id, work_product)) + (work_product_id, work_product) } /// Removes files for a given work product. diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 20ac6e258ed16..6026cfd5f71fe 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -3,12 +3,11 @@ use std::sync::Arc; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo}; -use rustc_data_structures::indexmap::IndexMap; use rustc_data_structures::svh::Svh; use rustc_errors::timings::TimingSection; use rustc_hir::def_id::LOCAL_CRATE; use rustc_metadata::EncodedMetadata; -use rustc_middle::dep_graph::DepGraph; +use rustc_middle::dep_graph::{DepGraph, WorkProductMap}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{self, OutputFilenames, OutputType}; @@ -51,7 +50,7 @@ impl Linker { let (compiled_modules, mut work_products) = sess.time("finish_ongoing_codegen", || { match self.ongoing_codegen.downcast::() { // This was a check only build - Ok(compiled_modules) => (*compiled_modules, IndexMap::default()), + Ok(compiled_modules) => (*compiled_modules, WorkProductMap::default()), Err(ongoing_codegen) => codegen_backend.join_codegen( ongoing_codegen, @@ -90,14 +89,13 @@ impl Linker { if sess.opts.incremental.is_some() && let Some(path) = self.metadata.path() - && let Some((id, product)) = - rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( - sess, - "metadata", - &[("rmeta", path)], - &[], - ) { + let (id, product) = rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( + sess, + "metadata", + &[("rmeta", path)], + &[], + ); work_products.insert(id, product); } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index d7d306918fd0d..4cb4876284706 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -14,11 +14,10 @@ use rustc_codegen_ssa::target_features::cfg_target_feature; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo, TargetConfig}; use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN}; -use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::sync; use rustc_metadata::{DylibError, EncodedMetadata, load_symbol_from_dylib}; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::WorkProductMap; use rustc_middle::ty::{CurrentGcx, TyCtxt}; use rustc_query_impl::{CollectActiveJobsKind, collect_active_query_jobs}; use rustc_session::config::{ @@ -418,8 +417,8 @@ impl CodegenBackend for DummyCodegenBackend { _sess: &Session, _outputs: &OutputFilenames, _crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { - (*ongoing_codegen.downcast().unwrap(), FxIndexMap::default()) + ) -> (CompiledModules, WorkProductMap) { + (*ongoing_codegen.downcast().unwrap(), WorkProductMap::default()) } fn link( diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 2c7ccfb25ae9b..df78f854ca500 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2141,7 +2141,6 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { } } } - _ => continue, }; if relevant_lifetimes.is_empty() { continue; diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 969c8548f68b4..e2df607fd0f86 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -2,7 +2,7 @@ use rustc_ast::{ self as ast, AttrVec, DUMMY_NODE_ID, GenericBounds, GenericParam, GenericParamKind, TyKind, WhereClause, token, }; -use rustc_errors::{Applicability, PResult}; +use rustc_errors::{Applicability, Diag, PResult}; use rustc_span::{Ident, Span, kw, sym}; use thin_vec::ThinVec; @@ -592,25 +592,47 @@ impl<'a> Parser<'a> { // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>` let (bound_vars, _) = self.parse_higher_ranked_binder()?; - // Parse type with mandatory colon and (possibly empty) bounds, - // or with mandatory equality sign and the second type. let ty = self.parse_ty_for_where_clause()?; + if self.eat(exp!(Colon)) { + // The bounds may be empty; we intentionally accept predicates like `Ty:`. let bounds = self.parse_generic_bounds()?; - Ok(ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { + + return Ok(ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { bound_generic_params: bound_vars, bounded_ty: ty, bounds, - })) - // FIXME: Decide what should be used here, `=` or `==`. - // FIXME: We are just dropping the binders in lifetime_defs on the floor here. - } else if self.eat(exp!(Eq)) || self.eat(exp!(EqEq)) { + })); + } + + // NOTE: If we ever end up impl'ing and stabilizing equality predicates (#20041), + // we need to pick between `=` and `==`, both is not an option! + if self.eat(exp!(Eq)) || self.eat(exp!(EqEq)) { + let lhs_ty = ty; let rhs_ty = self.parse_ty()?; - Ok(ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { lhs_ty: ty, rhs_ty })) - } else { - self.maybe_recover_bounds_doubled_colon(&ty)?; - self.unexpected_any() + + // NOTE: If we ever end up impl'ing equality predicates, + // we ought to track the binder in the AST node! + let _ = bound_vars; + + let mut diag = self.dcx().struct_span_err( + lhs_ty.span.to(rhs_ty.span), + "general type equality constraints are not supported", + ); + diag.note( + "see issue #20041 \ + for more information", + ); + diag.span(lhs_ty.span.to(rhs_ty.span)); + diag.span_label(lhs_ty.span.to(rhs_ty.span), "not supported"); + + suggest_replacing_equality_pred_with_assoc_item_constraint(&mut diag, *lhs_ty, *rhs_ty); + + return Err(diag); } + + self.maybe_recover_bounds_doubled_colon(&ty)?; + self.unexpected_any() } pub(super) fn choose_generics_over_qpath(&self, start: usize) -> bool { @@ -644,3 +666,61 @@ impl<'a> Parser<'a> { || self.is_keyword_ahead(start + 1, &[kw::Const])) } } + +fn suggest_replacing_equality_pred_with_assoc_item_constraint( + diag: &mut Diag<'_>, + lhs_ty: ast::Ty, + rhs_ty: ast::Ty, +) { + let TyKind::Path(qself, ast::Path { segments, .. }) = lhs_ty.kind else { return }; + + let mut parts = Vec::new(); + let applicability = match qself { + // We have something like `Ty::Item = Rhs`. + None if let [self_ty_seg, assoc_item_seg] = &segments[..] + && self_ty_seg.ident.name != kw::PathRoot => + { + parts.push(( + self_ty_seg.span().between(assoc_item_seg.span()), + ": /* Trait */ { + parts.push((lhs_ty.span.until(qself.ty.span), String::new())); + + // We have something like ` as self::Trait>::Item = Rhs`. + if let trait_segs @ [.., final_trait_seg] = &segments[..qself.position] { + parts.push((qself.ty.span.between(trait_segs[0].span()), ": ".into())); + let (span, snippet) = match &final_trait_seg.args { + Some(args) => { + let ast::GenericArgs::AngleBracketed(args) = args else { return }; + let Some(args) = args.args.last() else { return }; + (args.span(), ", ") + } + None => (final_trait_seg.span(), "<"), + }; + parts.push((span.between(assoc_item_seg.span()), snippet.into())); + Applicability::MaybeIncorrect + } + // We have something like `<[u8]>::Item == Rhs`. + else { + parts.push(( + qself.ty.span.between(assoc_item_seg.span()), + ": /* Trait */ return, + }; + + parts.push((lhs_ty.span.between(rhs_ty.span), " = ".into())); + parts.push((rhs_ty.span.shrink_to_hi(), ">".into())); + + diag.multipart_suggestion( + "replace it with an associated item constraint if possible", + parts, + applicability, + ); +} diff --git a/compiler/rustc_passes/src/input_stats.rs b/compiler/rustc_passes/src/input_stats.rs index 9127e4936803d..2f3fbc28ad49d 100644 --- a/compiler/rustc_passes/src/input_stats.rs +++ b/compiler/rustc_passes/src/input_stats.rs @@ -430,7 +430,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { fn visit_where_predicate(&mut self, p: &'v hir::WherePredicate<'v>) { record_variants!( (self, p, p.kind, Some(p.hir_id), hir, WherePredicate, WherePredicateKind), - [BoundPredicate, RegionPredicate, EqPredicate] + [BoundPredicate, RegionPredicate] ); hir_visit::walk_where_predicate(self, p) } @@ -705,7 +705,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { fn visit_where_predicate(&mut self, p: &'v ast::WherePredicate) { record_variants!( (self, p, &p.kind, None, ast, WherePredicate, WherePredicateKind), - [BoundPredicate, RegionPredicate, EqPredicate] + [BoundPredicate, RegionPredicate] ); ast_visit::walk_where_predicate(self, p) } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 46cc163ca8ed2..9e0f5c24d1101 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -57,6 +57,16 @@ pub(crate) enum PendingDecl<'ra> { Pending, } +enum ImportResolutionKind<'ra> { + Single(PerNS>), + Glob(Vec<(Decl<'ra>, BindingKey, Span /* orig_ident_span */)>), +} + +struct ImportResolution<'ra> { + kind: ImportResolutionKind<'ra>, + imported_module: ModuleOrUniformRoot<'ra>, +} + impl<'ra> PendingDecl<'ra> { pub(crate) fn decl(self) -> Option> { match self { @@ -442,7 +452,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && (vis == import.vis || max_vis.get().is_none_or(|max_vis| vis.greater_than(max_vis, self.tcx))) { - max_vis.set_unchecked(Some(vis)) + // `set` can't fail because this can only happen during "write_import_resolutions" + max_vis.set(Some(vis), self) } self.arenas.alloc_decl(DeclData { @@ -559,7 +570,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && glob_decl.ambiguity.get().is_none() { // Do not lose glob ambiguities when re-fetching the glob. - glob_decl.ambiguity.set_unchecked(Some((old_ambig, true))); + glob_decl.ambiguity.set(Some((old_ambig, true)), self); } glob_decl } else if glob_decl.res() != old_glob_decl.res() { @@ -567,7 +578,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { || self.is_rustybuzz_0_4_0(old_glob_decl, glob_decl) || self.is_pdf_0_9_0(old_glob_decl, glob_decl) || self.is_net2_0_2_39(old_glob_decl, glob_decl); - old_glob_decl.ambiguity.set_unchecked(Some((glob_decl, warning))); + old_glob_decl.ambiguity.set(Some((glob_decl, warning)), self); old_glob_decl } else if let old_vis = old_glob_decl.vis() && let vis = glob_decl.vis() @@ -576,17 +587,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // We are glob-importing the same item but with a different visibility. // All visibilities here are ordered because all of them are ancestors of `module`. if vis.greater_than(old_vis, self.tcx) { - old_glob_decl.ambiguity_vis_max.set_unchecked(Some(glob_decl)); + old_glob_decl.ambiguity_vis_max.set(Some(glob_decl), self); } else if let old_min_vis = old_glob_decl.min_vis() && old_min_vis != vis && old_min_vis.greater_than(vis, self.tcx) { - old_glob_decl.ambiguity_vis_min.set_unchecked(Some(glob_decl)); + old_glob_decl.ambiguity_vis_min.set(Some(glob_decl), self); } old_glob_decl } else if glob_decl.is_ambiguity_recursive() && !old_glob_decl.is_ambiguity_recursive() { // Overwriting a non-ambiguous glob import with an ambiguous glob import. - old_glob_decl.ambiguity.set_unchecked(Some((glob_decl, true))); + old_glob_decl.ambiguity.set(Some((glob_decl, true)), self); old_glob_decl } else { old_glob_decl @@ -613,7 +624,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // because they can be fetched by glob imports from those modules, and bring traits // into scope both directly and through glob imports. let key = BindingKey::new_disambiguated(ident, ns, || { - module.underscore_disambiguator.update_unchecked(|d| d + 1); + module.underscore_disambiguator.update(self, |d| d + 1); module.underscore_disambiguator.get() }); self.update_local_resolution(module, key, orig_ident_span, |this, resolution| { @@ -650,7 +661,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let (binding, t) = { let resolution = &mut *self .resolution_or_default(module.to_module(), key, orig_ident_span) - .borrow_mut_unchecked(); + .borrow_mut(self); let old_decl = resolution.determined_decl(); let old_vis = old_decl.map(|d| d.vis()); @@ -665,7 +676,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } }; - let Ok(glob_importers) = module.glob_importers.try_borrow_mut_unchecked() else { + let Ok(glob_importers) = module.glob_importers.try_borrow_mut(self) else { return t; }; @@ -727,11 +738,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Import resolution // - // This is a fixed-point algorithm. We resolve imports until our efforts - // are stymied by an unresolved import; then we bail out of the current - // module and continue. We terminate successfully once no more imports - // remain or unsuccessfully when no forward progress in resolving imports - // is made. + // This is a batched fixed-point algorithm. Each import is resolved in + // isolation, with any resolutions collected for later. + // After a full pass over the current set of `indeterminate_imports`, + // the collected resolutions are committed together. The process + // repeats until either no imports remain or no further progress can + // be made. /// Resolves all imports for the crate. This method performs the fixed- /// point iteration. @@ -741,16 +753,125 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { while indeterminate_count < prev_indeterminate_count { prev_indeterminate_count = indeterminate_count; indeterminate_count = 0; + let mut resolutions = Vec::new(); self.assert_speculative = true; for import in mem::take(&mut self.indeterminate_imports) { - let import_indeterminate_count = self.cm().resolve_import(import); + let (resolution, import_indeterminate_count) = self.cm().resolve_import(import); indeterminate_count += import_indeterminate_count; match import_indeterminate_count { 0 => self.determined_imports.push(import), _ => self.indeterminate_imports.push(import), } + if let Some(resolution) = resolution { + resolutions.push((import, resolution)); + } } self.assert_speculative = false; + self.write_import_resolutions(resolutions); + } + } + + fn write_import_resolutions( + &mut self, + import_resolutions: Vec<(Import<'ra>, ImportResolution<'ra>)>, + ) { + for (import, resolution) in &import_resolutions { + let ImportResolution { imported_module, .. } = resolution; + import.imported_module.set(Some(*imported_module), self); + + if import.is_glob() + && let ModuleOrUniformRoot::Module(module) = imported_module + && import.parent_scope.module != *module + && module.is_local() + { + module.glob_importers.borrow_mut(self).push(*import); + } + } + + for (import, resolution) in import_resolutions { + let ImportResolution { imported_module, kind: resolution_kind } = resolution; + + match (&import.kind, resolution_kind) { + ( + ImportKind::Single { target, decls, .. }, + ImportResolutionKind::Single(import_decls), + ) => { + self.per_ns(|this, ns| { + match import_decls[ns] { + PendingDecl::Ready(Some(import_decl)) => { + if import_decl.is_assoc_item() + && !this.tcx.features().import_trait_associated_functions() + { + feature_err( + this.tcx.sess, + sym::import_trait_associated_functions, + import.span, + "`use` associated items of traits is unstable", + ) + .emit(); + } + this.plant_decl_into_local_module( + IdentKey::new(*target), + target.span, + ns, + import_decl, + ); + decls[ns].set(PendingDecl::Ready(Some(import_decl)), this); + } + PendingDecl::Ready(None) => { + // Don't remove underscores from `single_imports`, they were never added. + if target.name != kw::Underscore { + let key = BindingKey::new(IdentKey::new(*target), ns); + this.update_local_resolution( + import.parent_scope.module.expect_local(), + key, + target.span, + |_, resolution| { + resolution.single_imports.swap_remove(&import); + }, + ); + } + decls[ns].set(PendingDecl::Ready(None), this); + } + PendingDecl::Pending => {} + } + }); + } + (ImportKind::Glob { id, .. }, ImportResolutionKind::Glob(imported_decls)) => { + let ModuleOrUniformRoot::Module(module) = imported_module else { + self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span }); + continue; + }; + + if module.is_trait() && !self.tcx.features().import_trait_associated_functions() + { + feature_err( + self.tcx.sess, + sym::import_trait_associated_functions, + import.span, + "`use` associated items of traits is unstable", + ) + .emit(); + } + + for (binding, key, orig_ident_span) in imported_decls { + let import_decl = self.new_import_decl(binding, import); + let _ = self + .try_plant_decl_into_local_module( + key.ident, + orig_ident_span, + key.ns, + import_decl, + ) + .expect("planting a glob cannot fail"); + } + + self.record_partial_res(*id, PartialRes::new(module.res().unwrap())); + } + + // Something weird happened, which shouldn't have happened. + _ => unreachable!("mismatched import and resolution kind"), + } } } @@ -1085,12 +1206,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// - `0` means its resolution is determined. /// - Other values mean that indeterminate exists under certain namespaces. /// - /// Meanwhile, if resolve successful, the resolved bindings are written - /// into the module. - fn resolve_import<'r>(mut self: CmResolver<'r, 'ra, 'tcx>, import: Import<'ra>) -> usize { + /// Meanwhile, if resolution is successful, its result is returned. + fn resolve_import<'r>( + mut self: CmResolver<'r, 'ra, 'tcx>, + import: Import<'ra>, + ) -> (Option>, usize) { debug!( - "(resolving import for module) resolving import `{}::...` in `{}`", + "(resolving import for module) resolving import `{}::{}` in `{}`", Segment::names_to_string(&import.module_path), + import_kind_to_string(&import.kind), module_to_string(import.parent_scope.module).unwrap_or_else(|| "???".to_string()), ); let module = if let Some(module) = import.imported_module.get() { @@ -1105,21 +1229,24 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match path_res { PathResult::Module(module) => module, - PathResult::Indeterminate => return 3, - PathResult::NonModule(..) | PathResult::Failed { .. } => return 0, + PathResult::Indeterminate => return (None, 3), + PathResult::NonModule(..) | PathResult::Failed { .. } => return (None, 0), } }; - import.imported_module.set_unchecked(Some(module)); - let (source, target, bindings) = match import.kind { - ImportKind::Single { source, target, ref decls, .. } => (source, target, decls), + let (source, bindings) = match import.kind { + ImportKind::Single { source, ref decls, .. } => (source, decls), ImportKind::Glob { .. } => { - self.get_mut_unchecked().resolve_glob_import(import); - return 0; + let import_resolution = ImportResolution { + imported_module: module, + kind: self.resolve_glob_import(import, module), + }; + return (Some(import_resolution), 0); } _ => unreachable!(), }; + let mut import_decls = PerNS::default(); let mut indeterminate_count = 0; self.per_ns_cm(|mut this, ns| { if bindings[ns].get() != PendingDecl::Pending { @@ -1132,54 +1259,26 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &import.parent_scope, Some(import), ); - let parent = import.parent_scope.module; - let binding = match binding_result { + let pending_decl = match binding_result { Ok(binding) => { - if binding.is_assoc_item() - && !this.tcx.features().import_trait_associated_functions() - { - feature_err( - this.tcx.sess, - sym::import_trait_associated_functions, - import.span, - "`use` associated items of traits is unstable", - ) - .emit(); - } // We need the `target`, `source` can be extracted. let import_decl = this.new_import_decl(binding, import); - this.get_mut_unchecked().plant_decl_into_local_module( - IdentKey::new(target), - target.span, - ns, - import_decl, - ); PendingDecl::Ready(Some(import_decl)) } - Err(Determinacy::Determined) => { - // Don't remove underscores from `single_imports`, they were never added. - if target.name != kw::Underscore { - let key = BindingKey::new(IdentKey::new(target), ns); - this.get_mut_unchecked().update_local_resolution( - parent.expect_local(), - key, - target.span, - |_, resolution| { - resolution.single_imports.swap_remove(&import); - }, - ); - } - PendingDecl::Ready(None) - } + Err(Determinacy::Determined) => PendingDecl::Ready(None), Err(Determinacy::Undetermined) => { indeterminate_count += 1; PendingDecl::Pending } }; - bindings[ns].set_unchecked(binding); + import_decls[ns] = pending_decl; }); + let import_resolution = ImportResolution { + imported_module: module, + kind: ImportResolutionKind::Single(import_decls), + }; - indeterminate_count + (Some(import_resolution), indeterminate_count) } /// Performs final import resolution, consistency checks and error reporting. @@ -1799,68 +1898,72 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { false } - fn resolve_glob_import(&mut self, import: Import<'ra>) { - // This function is only called for glob imports. - let ImportKind::Glob { id, .. } = import.kind else { unreachable!() }; + fn resolve_glob_import( + &self, + import: Import<'ra>, + imported_module: ModuleOrUniformRoot<'ra>, + ) -> ImportResolutionKind<'ra> { + let import_bindings = match imported_module { + ModuleOrUniformRoot::Module(module) if module != import.parent_scope.module => self + .resolutions(module) + .borrow() + .iter() + .filter_map(|(key, resolution)| { + let res = resolution.borrow(); + let decl = res.determined_decl()?; + let mut key = *key; + let scope = match key.ident.ctxt.update_unchecked(|ctxt| { + ctxt.reverse_glob_adjust(module.expansion, import.span) + }) { + Some(Some(def)) => self.expn_def_scope(def), + Some(None) => import.parent_scope.module, + None => return None, + }; + self.is_accessible_from(decl.vis(), scope).then_some(( + decl, + key, + res.orig_ident_span, + )) + }) + .collect::>(), - let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else { - self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span }); - return; + // Errors are reported in `write_imports_resolutions` + _ => vec![], }; - if module.is_trait() && !self.tcx.features().import_trait_associated_functions() { - feature_err( - self.tcx.sess, - sym::import_trait_associated_functions, - import.span, - "`use` associated items of traits is unstable", - ) - .emit(); - } - - if module == import.parent_scope.module { - return; - } - - // Add to module's glob_importers - if module.is_local() { - module.glob_importers.borrow_mut_unchecked().push(import); - } + ImportResolutionKind::Glob(import_bindings) + } - // Ensure that `resolutions` isn't borrowed during `try_define`, - // since it might get updated via a glob cycle. - let bindings = self - .resolutions(module) - .borrow() - .iter() - .filter_map(|(key, resolution)| { - let resolution = resolution.borrow(); - resolution.determined_decl().map(|decl| (*key, decl, resolution.orig_ident_span)) - }) - .collect::>(); - for (mut key, binding, orig_ident_span) in bindings { - let scope = - match key.ident.ctxt.update_unchecked(|ctxt| { - ctxt.reverse_glob_adjust(module.expansion, import.span) - }) { - Some(Some(def)) => self.expn_def_scope(def), - Some(None) => import.parent_scope.module, - None => continue, - }; - if self.is_accessible_from(binding.vis(), scope) { - let import_decl = self.new_import_decl(binding, import); - self.try_plant_decl_into_local_module( - key.ident, - orig_ident_span, - key.ns, - import_decl, - ) - .expect("planting a glob cannot fail"); - } + // Hack for the `rust_embed` regression observed in the crater run of #145108. + fn rust_embed_hack(&self, module: LocalModule<'ra>, decl: Decl<'ra>) -> bool { + // We are looking for this pattern: + // ```rust + // #[macro_use] + // extern crate rust_embed_impl; + // pub use rust_embed_impl::*; + // + // pub use RustEmbed as Embed; + // ``` + if let DeclKind::Import { source_decl, import } = decl.kind + // Check that `decl` is the re-export: "pub use RustEmbed as Embed;" + && let ImportKind::Single { source, .. } = import.kind + && source.name == sym::RustEmbed + // make sure that the import points to the #[macro_use] import + && let DeclKind::Import { import, .. } = source_decl.kind + && matches!(import.kind, ImportKind::MacroUse { .. }) + && self.macro_use_prelude.contains_key(&source.name) // and that the name actually exists in the macro_use_prelude + // Then check that `RustEmbed` exists in the modules Macro namespace. + && let Some(y_decl) = self + .resolution(module.to_module(), BindingKey::new(IdentKey::new(source), MacroNS)) + .and_then(|res| res.best_decl()) + // which comes from "pub use rust_embed_impl::*" + && y_decl.is_glob_import() + && y_decl.vis().is_public() + { + return true; } - // Record the destination of this import - self.record_partial_res(id, PartialRes::new(module.res().unwrap())); + false } // Miscellaneous post-processing, including recording re-exports, @@ -1879,13 +1982,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut children = Vec::new(); let mut ambig_children = Vec::new(); - module.to_module().for_each_child(self, |_this, ident, orig_ident_span, _, binding| { - let res = binding.res().expect_non_local(); + module.to_module().for_each_child(self, |this, ident, orig_ident_span, _, decl| { + let res = decl.res().expect_non_local(); if res != def::Res::Err { + let vis = if this.rust_embed_hack(module, decl) { + Visibility::Public + } else { + decl.vis() + }; let ident = ident.orig(orig_ident_span); - let child = - |reexport_chain| ModChild { ident, res, vis: binding.vis(), reexport_chain }; - if let Some((ambig_binding1, ambig_binding2)) = binding.descent_to_ambiguity() { + let child = |reexport_chain| ModChild { ident, res, vis, reexport_chain }; + if let Some((ambig_binding1, ambig_binding2)) = decl.descent_to_ambiguity() { let main = child(ambig_binding1.reexport_chain()); let second = ModChild { ident, @@ -1895,7 +2002,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; ambig_children.push(AmbigModChild { main, second }) } else { - children.push(child(binding.reexport_chain())); + children.push(child(decl.reexport_chain())); } } }); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 9af55565d30b7..090722c496fd8 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2868,16 +2868,10 @@ mod ref_mut { #[track_caller] pub(crate) fn get_mut(&mut self) -> &mut T { match self.mutable { - false => panic!("Can't mutably borrow speculative resolver"), + false => panic!("can't mutably borrow speculative resolver"), true => self.p, } } - - /// Returns a mutable reference to the inner value without checking if - /// it's in a mutable state. - pub(crate) fn get_mut_unchecked(&mut self) -> &mut T { - self.p - } } /// A wrapper around a [`Cell`] that only allows mutation based on a condition in the resolver. @@ -2901,12 +2895,12 @@ mod ref_mut { self.0.get() } - pub(crate) fn update_unchecked(&self, f: impl FnOnce(T) -> T) + pub(crate) fn update<'ra, 'tcx>(&self, r: &Resolver<'ra, 'tcx>, f: impl FnOnce(T) -> T) where T: Copy, { let old = self.get(); - self.set_unchecked(f(old)); + self.set(f(old), r); } } @@ -2915,7 +2909,10 @@ mod ref_mut { CmCell(Cell::new(value)) } - pub(crate) fn set_unchecked(&self, val: T) { + pub(crate) fn set<'ra, 'tcx>(&self, val: T, r: &Resolver<'ra, 'tcx>) { + if r.assert_speculative { + panic!("not allowed to mutate a `CmCell` during speculative resolution") + } self.0.set(val); } @@ -2941,16 +2938,26 @@ mod ref_mut { #[track_caller] pub(crate) fn borrow_mut<'ra, 'tcx>(&self, r: &Resolver<'ra, 'tcx>) -> RefMut<'_, T> { if r.assert_speculative { - panic!("Not allowed to mutably borrow a CmRefCell during speculative resolution"); + panic!("not allowed to mutably borrow a `CmRefCell` during speculative resolution"); } - self.borrow_mut_unchecked() + self.0.borrow_mut() } - #[track_caller] pub(crate) fn try_borrow_mut_unchecked(&self) -> Result, BorrowMutError> { self.0.try_borrow_mut() } + #[track_caller] + pub(crate) fn try_borrow_mut<'ra, 'tcx>( + &self, + r: &Resolver<'ra, 'tcx>, + ) -> Result, BorrowMutError> { + if r.assert_speculative { + panic!("not allowed to mutably borrow a `CmRefCell` during speculative resolution"); + } + self.0.try_borrow_mut() + } + #[track_caller] pub(crate) fn borrow(&self) -> Ref<'_, T> { self.0.borrow() @@ -2960,7 +2967,7 @@ mod ref_mut { impl CmRefCell { pub(crate) fn take<'ra, 'tcx>(&self, r: &Resolver<'ra, 'tcx>) -> T { if r.assert_speculative { - panic!("Not allowed to mutate a CmRefCell during speculative resolution"); + panic!("not allowed to mutate a CmRefCell during speculative resolution"); } self.0.take() } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9313e869278db..02fe3171cd9f4 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -294,6 +294,8 @@ symbols! { ResumeTy, Reverse, Rust, + // Temporary name for the rust_embed hack introduced in #145108 + RustEmbed, RustaceansAreAwesome, RwLock, RwLockReadGuard, diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 358374f11d747..b2b1073f2d15c 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -650,9 +650,9 @@ static RISCV_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[ ("a", Stable, &["zaamo", "zalrsc"]), ("b", Stable, &["zba", "zbb", "zbs"]), ("c", Stable, &["zca"]), - ("d", Unstable(sym::riscv_target_feature), &["f"]), - ("e", Unstable(sym::riscv_target_feature), &[]), - ("f", Unstable(sym::riscv_target_feature), &["zicsr"]), + ("d", CfgStableToggleUnstable(sym::riscv_target_feature), &["f"]), + ("e", CfgStableToggleUnstable(sym::riscv_target_feature), &[]), + ("f", CfgStableToggleUnstable(sym::riscv_target_feature), &["zicsr"]), ( "forced-atomics", Stability::Forbidden { diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 34cf9c5d0a5b2..ae8458c199503 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -43,6 +43,8 @@ mod num; #[unstable(feature = "convert_float_to_int", issue = "67057")] pub use num::FloatToInt; +#[unstable(feature = "integer_casts", issue = "157388")] +pub use num::{BoundedCastFromInt, CheckedCastFromInt}; /// The identity function. /// diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index 7179512e126ed..19398b4680583 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -630,3 +630,98 @@ impl_nonzero_int_try_from_nonzero_int!(i32 => u8, u16, u32, u64, u128, usize); impl_nonzero_int_try_from_nonzero_int!(i64 => u8, u16, u32, u64, u128, usize); impl_nonzero_int_try_from_nonzero_int!(i128 => u8, u16, u32, u64, u128, usize); impl_nonzero_int_try_from_nonzero_int!(isize => u8, u16, u32, u64, u128, usize); + +/// Conversion between integers, wrapping around or saturating at the target type's boundaries. +#[unstable(feature = "integer_casts", issue = "157388")] +#[rustc_const_unstable(feature = "integer_casts", issue = "157388")] +pub impl(self) const trait BoundedCastFromInt: Sized { + /// Converts `value` to this type, wrapping around at the boundary of the type. + #[unstable(feature = "integer_casts", issue = "157388")] + fn wrapping_cast_from(value: T) -> Self; + + /// Converts `value` to this type, saturating at the numeric bounds instead of overflowing. + #[unstable(feature = "integer_casts", issue = "157388")] + fn saturating_cast_from(value: T) -> Self; +} + +/// Fallible conversion between integers. +#[unstable(feature = "integer_casts", issue = "157388")] +#[rustc_const_unstable(feature = "integer_casts", issue = "157388")] +pub impl(self) const trait CheckedCastFromInt: Sized { + /// Converts `value` to this type, returning `None` if overflow would have occurred. + #[unstable(feature = "integer_casts", issue = "157388")] + fn checked_cast_from(value: T) -> Option; + + /// Converts `value` to this type, assuming overflow cannot occur. + /// + /// # Safety + /// + /// This results in undefined behavior when `value` will overflow when + /// converted to this type. + #[unstable(feature = "integer_casts", issue = "157388")] + unsafe fn unchecked_cast_from(value: T) -> Self; + + /// Converts `value` to this type, panicking on overflow. + /// + /// # Panics + /// + /// This function will always panic on overflow, regardless of whether overflow checks are enabled. + #[unstable(feature = "integer_casts", issue = "157388")] + fn strict_cast_from(value: T) -> Self; +} + +macro_rules! impl_int_cast { + ($Src:ty as [$($Dst:ty),*]) => {$( + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + impl const CheckedCastFromInt<$Src> for $Dst { + #[inline] + fn checked_cast_from(value: $Src) -> Option { + value.try_into().ok() + } + + #[inline(always)] + unsafe fn unchecked_cast_from(value: $Src) -> Self { + // SAFETY: the safety contract must be upheld by the caller. + unsafe { value.try_into().unwrap_unchecked() } + } + + #[inline] + #[track_caller] + fn strict_cast_from(value: $Src) -> Self { + match value.try_into() { + Ok(x) => x, + Err(_) => core::num::imp::overflow_panic::cast_integer() + } + } + } + + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + impl const BoundedCastFromInt<$Src> for $Dst { + #[inline(always)] + fn wrapping_cast_from(value: $Src) -> Self { + value as Self + } + + #[inline] + #[allow(unused_comparisons)] + #[allow(irrefutable_let_patterns)] + fn saturating_cast_from(value: $Src) -> Self { + if let Ok(x) = value.try_into() { + return x; + } + + if value < 0 { <$Dst>::MIN } else { <$Dst>::MAX } + } + } + )*}; +} + +macro_rules! impl_all_int_casts { + ([$($Src:ty),*]) => {$( + impl_int_cast!($Src as [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize]); + )*}; +} + +impl_all_int_casts!([u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize]); diff --git a/library/core/src/iter/sources/repeat.rs b/library/core/src/iter/sources/repeat.rs index f578ae86a9fce..bdad4adccabac 100644 --- a/library/core/src/iter/sources/repeat.rs +++ b/library/core/src/iter/sources/repeat.rs @@ -101,11 +101,21 @@ impl Iterator for Repeat { Some(self.element.clone()) } + /// Consumes the iterator and panics. + /// + /// # Panics + /// + /// This method always panics because `Repeat` is infinite. #[track_caller] fn last(self) -> Option { panic!("iterator is infinite"); } + /// Consumes the iterator and panics. + /// + /// # Panics + /// + /// This method always panics because `Repeat` is infinite. #[track_caller] fn count(self) -> usize { panic!("iterator is infinite"); diff --git a/library/core/src/mem/alignment.rs b/library/core/src/mem/alignment.rs index 08ce7fcd55523..8f453685a6f92 100644 --- a/library/core/src/mem/alignment.rs +++ b/library/core/src/mem/alignment.rs @@ -58,7 +58,13 @@ impl Alignment { /// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to. /// - /// Every reference to a value of the type `T` must be a multiple of this number. + /// This function is identical to [`Alignment::of::()`][Self::of] whenever + /// T: [Sized], + /// but also supports determining the alignment required by a `dyn Trait` value, which is the + /// alignment of the underlying concrete type. + /// + /// This provides the same numerical value as [`align_of_val`], + /// but in an `Alignment` instead of a `usize`. /// /// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface /// @@ -70,6 +76,25 @@ impl Alignment { /// /// assert_eq!(Alignment::of_val(&5i32).as_usize(), 4); /// ``` + /// + /// (Caution: [it is not guaranteed][type-layout] that the alignment of `i32` is `4`; + /// that is, the above assertion does not pass on all platforms.) + /// + /// `dyn` types may have different alignments for different values; + /// `Alignment::of_val()` can be used to learn those alignments: + /// + /// ``` + /// #![feature(ptr_alignment_type)] + /// use std::mem::Alignment; + /// + /// let a: &dyn ToString = &1234u16; + /// let b: &dyn ToString = &String::from("abcd"); + /// + /// assert_eq!(Alignment::of_val(a), Alignment::of::()); + /// assert_eq!(Alignment::of_val(b), Alignment::of::()); + /// ``` + /// + /// [type-layout]: ../../reference/type-layout.html#r-layout.primitive #[inline] #[must_use] #[unstable(feature = "ptr_alignment_type", issue = "102070")] @@ -81,7 +106,9 @@ impl Alignment { /// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to. /// - /// Every reference to a value of the type `T` must be a multiple of this number. + /// This function is identical to [`Alignment::of_val()`], except that it can be used with raw + /// pointers in situations where it would be unsound or undesirable to convert them to + /// [`&` references][primitive@reference] and impose the aliasing rules that come with that. /// /// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface /// @@ -117,6 +144,11 @@ impl Alignment { /// /// assert_eq!(unsafe { Alignment::of_val_raw(&5i32) }.as_usize(), 4); /// ``` + /// + /// (Caution: [it is not guaranteed][type-layout] that the alignment of `i32` is `4`; + /// that is, the above assertion does not pass on all platforms.) + /// + /// [type-layout]: ../../reference/type-layout.html#r-layout.primitive #[inline] #[must_use] #[unstable(feature = "ptr_alignment_type", issue = "102070")] diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 7e2c6b9b3bcb2..9889f32c502ad 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -437,7 +437,8 @@ impl MaybeUninit { /// be null. /// /// Note that if `T` has padding bytes, those bytes are *not* preserved when the - /// `MaybeUninit` value is returned from this function, so those bytes will *not* be zeroed. + /// `MaybeUninit` value is returned from this function, so those bytes are not + /// guaranteed to be zeroed. /// /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. /// It is your responsibility to make sure `T` gets dropped if it got initialized. diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 62c612e7ba2a6..9a54cfad40b1a 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -506,7 +506,7 @@ pub fn min_align_of_val(val: &T) -> usize { unsafe { intrinsics::align_of_val(val) } } -/// Returns the [ABI]-required minimum alignment of a type in bytes. +/// Returns the [ABI]-required minimum alignment of a type, in bytes. /// /// Every reference to a value of the type `T` must be a multiple of this number. /// @@ -519,6 +519,11 @@ pub fn min_align_of_val(val: &T) -> usize { /// ``` /// assert_eq!(4, align_of::()); /// ``` +/// +/// (Caution: [it is not guaranteed][type-layout] that the alignment of `i32` is `4`; +/// that is, the above assertion does not pass on all platforms.) +/// +/// [type-layout]: ../../reference/type-layout.html#r-layout.primitive #[inline(always)] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] @@ -529,10 +534,12 @@ pub const fn align_of() -> usize { ::ALIGN } -/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to in +/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to, in /// bytes. /// -/// Every reference to a value of the type `T` must be a multiple of this number. +/// This function is identical to [`align_of::()`][align_of] whenever T: [Sized], +/// but also supports determining the alignment required by a `dyn Trait` value, which is the +/// alignment of the underlying concrete type. /// /// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface /// @@ -541,6 +548,22 @@ pub const fn align_of() -> usize { /// ``` /// assert_eq!(4, align_of_val(&5i32)); /// ``` +/// +/// (Caution: [it is not guaranteed][type-layout] that the alignment of `i32` is `4`; +/// that is, this example assertion does not pass on all platforms.) +/// +/// `dyn` types may have different alignments for different values; +/// `align_of_val` can be used to learn those alignments: +/// +/// ``` +/// let a: &dyn ToString = &1234u16; +/// let b: &dyn ToString = &String::from("abcd"); +/// +/// assert_eq!(align_of_val(a), align_of::()); +/// assert_eq!(align_of_val(b), align_of::()); +/// ``` +/// +/// [type-layout]: ../../reference/type-layout.html#r-layout.primitive #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] @@ -550,10 +573,12 @@ pub const fn align_of_val(val: &T) -> usize { unsafe { intrinsics::align_of_val(val) } } -/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to in +/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to, in /// bytes. /// -/// Every reference to a value of the type `T` must be a multiple of this number. +/// This function is identical to [`align_of_val()`], except that it can be used with raw pointers +/// in situations where it would be unsound or undesirable to convert them to +/// [`&` references][primitive@reference] and impose the aliasing rules that come with that. /// /// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface /// @@ -589,6 +614,11 @@ pub const fn align_of_val(val: &T) -> usize { /// /// assert_eq!(4, unsafe { mem::align_of_val_raw(&5i32) }); /// ``` +/// +/// (Caution: [it is not guaranteed][type-layout] that the alignment of `i32` is `4`; +/// that is, the above assertion does not pass on all platforms.) +/// +/// [type-layout]: ../../reference/type-layout.html#r-layout.primitive #[inline] #[must_use] #[unstable(feature = "layout_for_ptr", issue = "69835")] diff --git a/library/core/src/num/imp/overflow_panic.rs b/library/core/src/num/imp/overflow_panic.rs index 2b699fa61f871..ec5624f91fa28 100644 --- a/library/core/src/num/imp/overflow_panic.rs +++ b/library/core/src/num/imp/overflow_panic.rs @@ -52,6 +52,6 @@ pub(in crate::num) const fn shl() -> ! { #[cold] #[track_caller] -pub(in crate::num) const fn cast_integer() -> ! { +pub(crate) const fn cast_integer() -> ! { panic!("attempt to cast integer with overflow") } diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 01b846548547f..0ee3d11e3b8a3 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -210,6 +210,9 @@ macro_rules! int_impl { /// Returns the index of the highest bit set to one in `self`, or `None` /// if `self` is `0`. /// + /// Note that for non-negative numbers, this is equivalent to + /// [`checked_ilog2`](Self::checked_ilog2). + /// /// # Examples /// /// ``` @@ -3575,6 +3578,9 @@ macro_rules! int_impl { /// /// Returns `None` if the number is negative or zero. /// + /// Note that for non-negative numbers, this is equivalent to + /// [`highest_one`](Self::highest_one). + /// /// # Examples /// /// ``` @@ -4068,5 +4074,123 @@ macro_rules! int_impl { { traits::WidenTarget::internal_widen(self) } + + + /// Converts `self` to the target integer type, saturating at the numeric + /// bounds instead of overflowing. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_casts)] + #[doc = concat!("assert_eq!(i8::MAX, ", stringify!($SelfT), "::MAX.saturating_cast());")] + #[doc = concat!("assert_eq!(i8::MIN, ", stringify!($SelfT), "::MIN.saturating_cast());")] + #[doc = concat!("assert_eq!(42u8, 42", stringify!($SelfT), ".saturating_cast());")] + #[doc = concat!("assert_eq!(0u8, (-42", stringify!($SelfT), ").saturating_cast());")] + /// ``` + #[must_use = "this returns the cast result and does not modify the original"] + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + #[inline(always)] + pub const fn saturating_cast>(self) -> T { + T::saturating_cast_from(self) + } + + /// Converts `self` to the target integer type, wrapping around at the + /// boundary of the target type. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_casts)] + #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX as i8, ", stringify!($SelfT), "::MAX.wrapping_cast());")] + #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN as i8, ", stringify!($SelfT), "::MIN.wrapping_cast());")] + #[doc = concat!("assert_eq!(42u8, 42", stringify!($SelfT), ".wrapping_cast());")] + #[doc = concat!("assert_eq!(u8::MAX - 41, (-42", stringify!($SelfT), ").wrapping_cast());")] + /// ``` + #[must_use = "this returns the cast result and does not modify the original"] + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + #[inline(always)] + pub const fn wrapping_cast>(self) -> T { + T::wrapping_cast_from(self) + } + + /// Converts `self` to the target integer type, returning `None` if the value + /// is not representable by the target type. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_casts)] + #[doc = concat!("assert_eq!(Some(42u8), 42", stringify!($SelfT), ".checked_cast());")] + #[doc = concat!("assert_eq!((-42", stringify!($SelfT), ").checked_cast::(), None);")] + /// ``` + #[must_use = "this returns the cast result and does not modify the original"] + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + #[inline(always)] + pub const fn checked_cast>(self) -> Option { + T::checked_cast_from(self) + } + + /// Converts `self` to the target integer type, panicking if the value + /// is not representable by the target type. + /// + /// # Panics + /// + /// This function will panic if the value is not representable by the target type. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_casts)] + #[doc = concat!("assert_eq!(42u8, 42", stringify!($SelfT), ".strict_cast());")] + /// ``` + /// + /// The following will panic: + /// + /// ```should_panic + /// #![feature(integer_casts)] + #[doc = concat!("let _ = (-42", stringify!($SelfT), ").strict_cast::();")] + /// ``` + #[must_use = "this returns the cast result and does not modify the original"] + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + #[inline(always)] + #[track_caller] + pub const fn strict_cast>(self) -> T { + T::strict_cast_from(self) + } + + /// Converts `self` to the target integer type, assuming the value is + /// representable by the target type. + /// + /// # Safety + /// + /// This results in undefined behavior if the integer value of `self` is bigger than `T::MAX`, + /// or smaller than `T::MIN`, where `T` is the target type. + #[must_use = "this returns the cast result and does not modify the original"] + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + #[inline(always)] + pub const unsafe fn unchecked_cast>(self) -> T { + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_cast must fit in the target type"), + ( + // Check has to be performed up-front because it depends on generic T. + in_bounds: bool = { + let cast_val = self.checked_cast::(); + let ret = cast_val.is_some(); + core::mem::forget(cast_val); // We don't have const Drop, but we know it's an int. + ret + }, + ) => in_bounds, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { T::unchecked_cast_from(self) } + } } } diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index ed91c1e6a4ff1..59c2b11470f4a 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -2,6 +2,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::convert::{BoundedCastFromInt, CheckedCastFromInt}; use crate::panic::const_panic; use crate::str::FromStr; use crate::ub_checks::assert_unsafe_precondition; diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index fdff6ceba6a4a..7362bb77b1684 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -692,6 +692,16 @@ macro_rules! nonzero_integer { /// Returns the index of the highest bit set to one in `self`. /// + #[doc = sign_dependent_expr!{ + $signedness ? + if signed { + "" + } + if unsigned { + "Note that this is equivalent to [`ilog2`](Self::ilog2)." + } + }] + /// /// # Examples /// /// ``` @@ -1758,6 +1768,8 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// except that it has no failure cases to worry about /// since this value can never be zero. /// + /// Note that this is equivalent to [`highest_one`](Self::highest_one). + /// /// # Examples /// /// ``` diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 3170143da9b30..38d053d985c02 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -289,6 +289,8 @@ macro_rules! uint_impl { /// Returns the index of the highest bit set to one in `self`, or `None` /// if `self` is `0`. /// + /// Note that this is equivalent to [`checked_ilog2`](Self::checked_ilog2). + /// /// # Examples /// /// ``` @@ -1865,6 +1867,8 @@ macro_rules! uint_impl { /// /// Returns `None` if the number is zero. /// + /// Note that this is equivalent to [`highest_one`](Self::highest_one). + /// /// # Examples /// /// ``` @@ -4229,5 +4233,120 @@ macro_rules! uint_impl { { traits::WidenTarget::internal_widen(self) } + + /// Converts `self` to the target integer type, saturating at the numeric + /// bounds instead of overflowing. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_casts)] + #[doc = concat!("assert_eq!(255u8, ", stringify!($SelfT), "::MAX.saturating_cast());")] + #[doc = concat!("assert_eq!(127i8, ", stringify!($SelfT), "::MAX.saturating_cast());")] + #[doc = concat!("assert_eq!(42i8, 42", stringify!($SelfT), ".saturating_cast());")] + /// ``` + #[must_use = "this returns the cast result and does not modify the original"] + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + #[inline(always)] + pub const fn saturating_cast>(self) -> T { + T::saturating_cast_from(self) + } + + /// Converts `self` to the target integer type, wrapping around at the + /// boundary of the target type. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_casts)] + #[doc = concat!("assert_eq!(255u8, ", stringify!($SelfT), "::MAX.wrapping_cast());")] + #[doc = concat!("assert_eq!(42i8, 42", stringify!($SelfT), ".wrapping_cast());")] + #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX as i8, ", stringify!($SelfT), "::MAX.wrapping_cast());")] + /// ``` + #[must_use = "this returns the cast result and does not modify the original"] + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + #[inline(always)] + pub const fn wrapping_cast>(self) -> T { + T::wrapping_cast_from(self) + } + + /// Converts `self` to the target integer type, returning `None` if the value + /// is not representable by the target type. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_casts)] + #[doc = concat!("assert_eq!(Some(42u8), 42", stringify!($SelfT), ".checked_cast());")] + #[doc = concat!("assert_eq!(128", stringify!($SelfT), ".checked_cast::(), None);")] + /// ``` + #[must_use = "this returns the cast result and does not modify the original"] + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + #[inline(always)] + pub const fn checked_cast>(self) -> Option { + T::checked_cast_from(self) + } + + /// Converts `self` to the target integer type, panicking if the value + /// is not representable by the target type. + /// + /// # Panics + /// + /// This function will panic if the value is not representable by the target type. + /// + /// # Examples + /// + /// ``` + /// #![feature(integer_casts)] + #[doc = concat!("assert_eq!(42u8, 42", stringify!($SelfT), ".strict_cast());")] + /// ``` + /// + /// The following will panic: + /// + /// ```should_panic + /// #![feature(integer_casts)] + #[doc = concat!("let _ = 128", stringify!($SelfT), ".strict_cast::();")] + /// ``` + #[must_use = "this returns the cast result and does not modify the original"] + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + #[inline(always)] + #[track_caller] + pub const fn strict_cast>(self) -> T { + T::strict_cast_from(self) + } + + /// Converts `self` to the target integer type, assuming the value is + /// representable by the target type. + /// + /// # Safety + /// + /// This results in undefined behavior if the integer value of `self` is bigger than `T::MAX`, + /// or smaller than `T::MIN`, where `T` is the target type. + #[must_use = "this returns the cast result and does not modify the original"] + #[unstable(feature = "integer_casts", issue = "157388")] + #[rustc_const_unstable(feature = "integer_casts", issue = "157388")] + #[inline(always)] + pub const unsafe fn unchecked_cast>(self) -> T { + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_cast must fit in the target type"), + ( + // Check has to be performed up-front because it depends on generic T. + in_bounds: bool = { + let cast_val = self.checked_cast::(); + let ret = cast_val.is_some(); + core::mem::forget(cast_val); // We don't have const Drop, but we know it's an int. + ret + }, + ) => in_bounds, + ); + + // SAFETY: this is guaranteed to be safe by the caller. + unsafe { T::unchecked_cast_from(self) } + } } } diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index fb0fee3cb0869..e4bf752ad2ae6 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -118,6 +118,35 @@ const unsafe impl SliceIndex for ops::RangeFull { } } +/// Check that a range is in bounds for slicing a string. +/// If this returns true, it is safe to call `slice.get_unchecked(range)` or +/// `slice.get_unchecked_mut(range)`. +#[inline(always)] +const fn check_range(slice: &str, range: crate::range::Range) -> bool { + let crate::range::Range { start, end } = range; + let bytes = slice.as_bytes(); + + if start > end || end > slice.len() { + return false; + } + + if start == slice.len() { + // If `start == slice.len()`, then `end == slice.len()` must also be true. + return true; + } + + // SAFETY: + // `start > end || end > slice.len()` is false, so `start <= end <= slice.len()` is true. + // `start == slice.len()` is false, so `start < slice.len()` is also true. + // + // No need to check for `end == 0`, because if `end == 0` is true then `start == slice.len()` + // would also be true, which is already handled above. + unsafe { + (start == 0 || bytes.as_ptr().add(start).read().is_utf8_char_boundary()) + && (end == slice.len() || bytes.as_ptr().add(end).read().is_utf8_char_boundary()) + } +} + /// Implements substring slicing with syntax `&self[begin .. end]` or `&mut /// self[begin .. end]`. /// @@ -159,30 +188,11 @@ const unsafe impl SliceIndex for ops::Range { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { - if self.start <= self.end - && slice.is_char_boundary(self.start) - && slice.is_char_boundary(self.end) - { - // SAFETY: just checked that `start` and `end` are on a char boundary, - // and we are passing in a safe reference, so the return value will also be one. - // We also checked char boundaries, so this is valid UTF-8. - Some(unsafe { &*self.get_unchecked(slice) }) - } else { - None - } + range::Range::from(self).get(slice) } #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { - if self.start <= self.end - && slice.is_char_boundary(self.start) - && slice.is_char_boundary(self.end) - { - // SAFETY: just checked that `start` and `end` are on a char boundary. - // We know the pointer is unique because we got it from `slice`. - Some(unsafe { &mut *self.get_unchecked_mut(slice) }) - } else { - None - } + range::Range::from(self).get_mut(slice) } #[inline] #[track_caller] @@ -235,26 +245,11 @@ const unsafe impl SliceIndex for ops::Range { } #[inline] fn index(self, slice: &str) -> &Self::Output { - let (start, end) = (self.start, self.end); - match self.get(slice) { - Some(s) => s, - None => super::slice_error_fail(slice, start, end), - } + range::Range::from(self).index(slice) } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - // is_char_boundary checks that the index is in [0, .len()] - // cannot reuse `get` as above, because of NLL trouble - if self.start <= self.end - && slice.is_char_boundary(self.start) - && slice.is_char_boundary(self.end) - { - // SAFETY: just checked that `start` and `end` are on a char boundary, - // and we are passing in a safe reference, so the return value will also be one. - unsafe { &mut *self.get_unchecked_mut(slice) } - } else { - super::slice_error_fail(slice, self.start, self.end) - } + range::Range::from(self).index_mut(slice) } } @@ -264,11 +259,8 @@ const unsafe impl SliceIndex for range::Range { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { - if self.start <= self.end - && slice.is_char_boundary(self.start) - && slice.is_char_boundary(self.end) - { - // SAFETY: just checked that `start` and `end` are on a char boundary, + if check_range(slice, self) { + // SAFETY: just checked that `self` is in bounds, // and we are passing in a safe reference, so the return value will also be one. // We also checked char boundaries, so this is valid UTF-8. Some(unsafe { &*self.get_unchecked(slice) }) @@ -278,11 +270,8 @@ const unsafe impl SliceIndex for range::Range { } #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { - if self.start <= self.end - && slice.is_char_boundary(self.start) - && slice.is_char_boundary(self.end) - { - // SAFETY: just checked that `start` and `end` are on a char boundary. + if check_range(slice, self) { + // SAFETY: just checked that `self` is in bounds. // We know the pointer is unique because we got it from `slice`. Some(unsafe { &mut *self.get_unchecked_mut(slice) }) } else { @@ -348,13 +337,9 @@ const unsafe impl SliceIndex for range::Range { } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - // is_char_boundary checks that the index is in [0, .len()] // cannot reuse `get` as above, because of NLL trouble - if self.start <= self.end - && slice.is_char_boundary(self.start) - && slice.is_char_boundary(self.end) - { - // SAFETY: just checked that `start` and `end` are on a char boundary, + if check_range(slice, self) { + // SAFETY: just checked that `self` is in bounds, // and we are passing in a safe reference, so the return value will also be one. unsafe { &mut *self.get_unchecked_mut(slice) } } else { diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index c30ed92b0e946..1799da9d4abc2 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -68,6 +68,7 @@ #![feature(hashmap_internals)] #![feature(int_from_ascii)] #![feature(int_roundings)] +#![feature(integer_casts)] #![feature(io_slice_as_bytes)] #![feature(ip)] #![feature(is_ascii_octdigit)] @@ -83,6 +84,7 @@ #![feature(iterator_try_collect)] #![feature(iterator_try_reduce)] #![feature(layout_for_ptr)] +#![feature(macro_metavar_expr_concat)] #![feature(maybe_uninit_fill)] #![feature(maybe_uninit_uninit_array_transpose)] #![feature(min_specialization)] diff --git a/library/coretests/tests/num/cast.rs b/library/coretests/tests/num/cast.rs new file mode 100644 index 0000000000000..dddfd3a02ee64 --- /dev/null +++ b/library/coretests/tests/num/cast.rs @@ -0,0 +1,101 @@ +use std::sync::LazyLock; + +// All (negative) integers which are at or near a power of two to test +// boundary conditions. We use strings so we can convert to any type using +// parsing, while still being able to use the *position* in ORDERED_VALS for +// comparisons. +static ORDERED_VALS: LazyLock> = LazyLock::new(|| { + let mut pos_int_vals = Vec::new(); + for exp in 0..=127 { + let val = 1_u128 << exp; + pos_int_vals.push(val.saturating_sub(2)); + pos_int_vals.push(val.saturating_sub(1)); + pos_int_vals.push(val); + pos_int_vals.push(val.saturating_add(1)); + pos_int_vals.push(val.saturating_add(2)); + } + pos_int_vals.sort(); + pos_int_vals.dedup(); + + let mut pos_str_vals: Vec<_> = pos_int_vals.iter().map(|i| i.to_string()).collect(); + + // These are manual because the upper ones overflow even u128. + pos_str_vals.push("340282366920938463463374607431768211454".to_owned()); // 2**128 - 2 + pos_str_vals.push("340282366920938463463374607431768211455".to_owned()); // 2**128 - 1 + pos_str_vals.push("340282366920938463463374607431768211456".to_owned()); // 2**128 + pos_str_vals.push("340282366920938463463374607431768211457".to_owned()); // 2**128 + 1 + pos_str_vals.push("340282366920938463463374607431768211458".to_owned()); // 2**128 + 2 + + let mut out = Vec::new(); + for val in pos_str_vals[1..].iter().rev() { + out.push(format!("-{val}")); + } + out.extend(pos_str_vals); + out +}); + +macro_rules! make_checked_cast_test { + ($Src:ident as [$($Dst:ident),*]) => {$( + #[test] + #[allow(non_snake_case)] + fn ${concat(test_checked_cast_, $Src, _to_, $Dst)}() { + for val in ORDERED_VALS.iter() { + if let Some(src) = val.parse::<$Src>().ok() { + let dst: Option<$Dst> = val.parse().ok(); + assert_eq!(src.checked_cast::<$Dst>(), dst); + } + } + } + )*} +} + +macro_rules! make_bounded_cast_test { + (|$src:ident| $raw:expr, $Src:ident as [$($Dst:ident),*]) => {$( + #[test] + #[allow(non_snake_case)] + fn ${concat(test_bounded_cast_, $Src, _to_, $Dst)}() { + let ord_idx = |s| ORDERED_VALS.iter().position(|v| *v == s).unwrap(); + let dst_min_idx = ord_idx(<$Dst>::MIN.to_string()); + let dst_max_idx = ord_idx(<$Dst>::MAX.to_string()); + for (val_idx, val) in ORDERED_VALS.iter().enumerate() { + if let Some($src) = val.parse::<$Src>().ok() { + let dst: Option<$Dst> = val.parse().ok(); + + assert_eq!($src.wrapping_cast::<$Dst>(), $raw as $Dst); + + if val_idx > dst_max_idx { + assert_eq!($src.saturating_cast::<$Dst>(), <$Dst>::MAX); + } else if val_idx < dst_min_idx { + assert_eq!($src.saturating_cast::<$Dst>(), <$Dst>::MIN); + } else { + assert_eq!($src.saturating_cast::<$Dst>(), dst.unwrap()); + } + } + } + } + )*} +} + +macro_rules! make_tests_for_src { + (|$src:ident| $raw:expr, [$($Src:ident),*]) => {$( + make_checked_cast_test!( $Src as [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize]); + make_bounded_cast_test!(|$src| $raw, $Src as [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize]); + + // NonZero types are not (yet) implemented. + // make_checked_cast_test!($Src as [ + // NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize, + // NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize + // ]); + )*} +} + +make_tests_for_src!(|x| x, [u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize]); + +// NonZero types are not (yet) implemented. +// make_tests_for_src!( +// |x| x.get(), +// [ +// NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize, +// NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize +// ] +// ); diff --git a/library/coretests/tests/num/mod.rs b/library/coretests/tests/num/mod.rs index a82ac6fcd45f0..90666fc0b1ad2 100644 --- a/library/coretests/tests/num/mod.rs +++ b/library/coretests/tests/num/mod.rs @@ -23,6 +23,7 @@ mod u8; mod bignum; mod carryless_mul; +mod cast; mod const_from; mod dec2flt; mod float_ieee754_flt2dec_dec2flt; diff --git a/library/std/src/io/buffered/linewritershim.rs b/library/std/src/io/buffered/linewritershim.rs index 967e24812b9ff..2135eb6d2e578 100644 --- a/library/std/src/io/buffered/linewritershim.rs +++ b/library/std/src/io/buffered/linewritershim.rs @@ -49,6 +49,78 @@ impl<'a, W: ?Sized + Write> LineWriterShim<'a, W> { _ => Ok(()), } } + + /// Vectored line-buffered write over an already-capped list of buffers. + /// + /// The caller is responsible for trimming `bufs` to the prefix it is + /// willing to scan (see `MAX_BUFS_TO_SCAN`). This method only ever writes + /// or buffers bytes from `bufs`, so any newline it might bury in the + /// `BufWriter` is one it has itself scanned for -- buffers the caller + /// dropped past the cap can never end up stuck in the buffer. Bytes not + /// accounted for in the return value are left for the next call. + fn write_vectored_scanned(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + // Find the buffer containing the last newline. + let last_newline_buf_idx = bufs + .iter() + .enumerate() + .rev() + .find_map(|(i, buf)| memchr::memchr(b'\n', buf).map(|_| i)); + + // If there are no new newlines (that is, if this write is less than + // one line), just do a regular buffered write. + let last_newline_buf_idx = match last_newline_buf_idx { + None => { + self.flush_if_completed_line()?; + return self.buffer.write_vectored(bufs); + } + Some(i) => i, + }; + + // Flush existing content to prepare for our write. + self.buffer.flush_buf()?; + + // This is what we're going to try to write directly to the inner + // writer. The rest will be buffered, if nothing goes wrong. + let (lines, tail) = bufs.split_at(last_newline_buf_idx + 1); + + // Write `lines` directly to the inner writer. In keeping with the + // `write` convention, make at most one attempt to add new (unbuffered) + // data. Because this write doesn't touch the BufWriter state directly, + // and the buffer is known to be empty, we don't need to worry about + // self.panicked here. + let flushed = self.inner_mut().write_vectored(lines)?; + + // If inner returns Ok(0), propagate that to the caller without + // doing additional buffering; otherwise we're just guaranteeing + // an "ErrorKind::WriteZero" later. + if flushed == 0 { + return Ok(0); + } + + // Don't try to reconstruct the exact amount written; just bail + // in the event of a partial write. + let mut lines_len: usize = 0; + for buf in lines { + // With overlapping/duplicate slices the total length may in theory + // exceed usize::MAX + lines_len = lines_len.saturating_add(buf.len()); + if flushed < lines_len { + return Ok(flushed); + } + } + + // Now that the write has succeeded, buffer the rest (or as much of the + // rest as possible). `tail` is the part of the scanned prefix after the + // last newline, so it cannot contain a newline of its own. + let buffered: usize = tail + .iter() + .filter(|buf| !buf.is_empty()) + .map(|buf| self.buffer.write_to_buf(buf)) + .take_while(|&n| n > 0) + .sum(); + + Ok(flushed + buffered) + } } impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> { @@ -185,71 +257,26 @@ impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> { }; } - // Find the buffer containing the last newline - // FIXME: This is overly slow if there are very many bufs and none contain - // newlines. e.g. writev() on Linux only writes up to 1024 slices, so - // scanning the rest is wasted effort. This makes write_all_vectored() - // quadratic. - let last_newline_buf_idx = bufs - .iter() - .enumerate() - .rev() - .find_map(|(i, buf)| memchr::memchr(b'\n', buf).map(|_| i)); - - // If there are no new newlines (that is, if this write is less than - // one line), just do a regular buffered write - let last_newline_buf_idx = match last_newline_buf_idx { - // No newlines; just do a normal buffered write - None => { - self.flush_if_completed_line()?; - return self.buffer.write_vectored(bufs); - } - Some(i) => i, - }; - - // Flush existing content to prepare for our write - self.buffer.flush_buf()?; - - // This is what we're going to try to write directly to the inner - // writer. The rest will be buffered, if nothing goes wrong. - let (lines, tail) = bufs.split_at(last_newline_buf_idx + 1); - - // Write `lines` directly to the inner writer. In keeping with the - // `write` convention, make at most one attempt to add new (unbuffered) - // data. Because this write doesn't touch the BufWriter state directly, - // and the buffer is known to be empty, we don't need to worry about - // self.panicked here. - let flushed = self.inner_mut().write_vectored(lines)?; - - // If inner returns Ok(0), propagate that to the caller without - // doing additional buffering; otherwise we're just guaranteeing - // an "ErrorKind::WriteZero" later. - if flushed == 0 { - return Ok(0); - } - - // Don't try to reconstruct the exact amount written; just bail - // in the event of a partial write - let mut lines_len: usize = 0; - for buf in lines { - // With overlapping/duplicate slices the total length may in theory - // exceed usize::MAX - lines_len = lines_len.saturating_add(buf.len()); - if flushed < lines_len { - return Ok(flushed); - } - } - - // Now that the write has succeeded, buffer the rest (or as much of the - // rest as possible) - let buffered: usize = tail - .iter() - .filter(|buf| !buf.is_empty()) - .map(|buf| self.buffer.write_to_buf(buf)) - .take_while(|&n| n > 0) - .sum(); - - Ok(flushed + buffered) + // Only scan (and operate on) the first MAX_BUFS_TO_SCAN slices. The cap + // is what keeps write_all_vectored() from going quadratic when callers + // pass many newline-free slices -- without it, every iteration of the + // outer loop rescans every remaining buffer. 1024 is a portable, + // generous upper bound: it is the value of UIO_MAXIOV / IOV_MAX on + // Linux and the BSDs (and the hardcoded cap in + // sys::net::connection::socket::solid), so on those platforms it also + // lines up with the most a single writev() can retire. On platforms + // whose syscall cap is smaller (POSIX requires only 16) or that have no + // cap at all (Windows), the constant still serves its primary purpose + // of bounding scan work. + // + // Everything past the cap is left untouched for the next call; the + // outer loop in write_all_vectored() makes forward progress via the + // short return value, and correctness is preserved everywhere. We hand + // the capped prefix to a helper so the rest of the logic can only ever + // see -- and therefore only ever write or buffer -- buffers we have + // actually scanned for newlines. + const MAX_BUFS_TO_SCAN: usize = 1024; + self.write_vectored_scanned(&bufs[..bufs.len().min(MAX_BUFS_TO_SCAN)]) } fn is_write_vectored(&self) -> bool { diff --git a/library/std/src/io/buffered/tests.rs b/library/std/src/io/buffered/tests.rs index 742e753f9b951..8888ffa0c4cb7 100644 --- a/library/std/src/io/buffered/tests.rs +++ b/library/std/src/io/buffered/tests.rs @@ -752,6 +752,133 @@ fn line_vectored_partial_and_errors() { } } +/// Regression test for the quadratic scan in `LineWriterShim::write_vectored`. +/// +/// When given a long list of newline-free buffers and a sink that only +/// retires a few slices per call, the previous implementation rescanned all +/// remaining buffers on every iteration of `write_all_vectored`, producing +/// O(N^2) work. The fix caps the scan to a constant prefix; this test +/// verifies that bytes still come out in order when the only newline lives +/// past that cap. +#[test] +fn line_vectored_long_input_past_scan_cap() { + /// Vectored sink that retires at most one non-empty slice per call, + /// mimicking a writev() bounded by IOV_MAX. + #[derive(Default)] + struct OneSliceSink { + buffer: Vec, + } + + impl Write for OneSliceSink { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.buffer.extend_from_slice(buf); + Ok(buf.len()) + } + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + for b in bufs { + if !b.is_empty() { + self.buffer.extend_from_slice(b); + return Ok(b.len()); + } + } + Ok(0) + } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + fn is_write_vectored(&self) -> bool { + true + } + } + + // Place the only newline well past the 1024-slice scan cap. + const N: usize = 1500; + const NEWLINE_AT: usize = 1400; + let bytes: Vec = (0..N).map(|i| if i == NEWLINE_AT { b'\n' } else { b'a' }).collect(); + let mut io_slices: Vec> = bytes.chunks(1).map(IoSlice::new).collect(); + + let mut writer = LineWriter::new(OneSliceSink::default()); + writer.write_all_vectored(&mut io_slices).unwrap(); + + // The newline past the scan cap must still trigger a flush through + // the inner writer; only the tail after the newline may remain buffered. + assert_eq!(writer.get_ref().buffer, bytes[..=NEWLINE_AT]); + + writer.flush().unwrap(); + assert_eq!(writer.get_ref().buffer, bytes); +} + +/// Regression test for newlines buried past the `write_vectored` scan cap. +/// +/// `LineWriterShim::write_vectored` only scans a bounded prefix of the slice +/// list for newlines. An earlier version computed the head/tail split against +/// the *full* list, so when more than the cap's worth of slices were passed in +/// a single call and one of the unscanned slices held a newline, that newline +/// was silently copied into the inner `BufWriter` instead of being flushed -- +/// leaving a completed line stuck in the buffer. +/// +/// The invariant this checks is the core line-buffering guarantee: once all +/// input has been written, everything up to and including the *last* newline +/// must have reached the inner writer, and only the trailing partial line may +/// remain buffered. It holds regardless of the exact scan-cap value, and it is +/// driven through the public `write_all_vectored` entry point so the cap +/// boundary is crossed naturally. +#[test] +fn line_vectored_flushes_newline_past_scan_cap() { + /// Vectored sink that accepts every slice in full, so any data that fails + /// to reach it must have been (incorrectly) left in the LineWriter buffer. + #[derive(Default)] + struct FullSink { + buffer: Vec, + } + + impl Write for FullSink { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.buffer.extend_from_slice(buf); + Ok(buf.len()) + } + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result { + let mut written = 0; + for b in bufs { + self.buffer.extend_from_slice(b); + written += b.len(); + } + Ok(written) + } + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + fn is_write_vectored(&self) -> bool { + true + } + } + + // Two newlines: one comfortably inside the scan cap and one well past it, + // so a single `write_vectored` call sees the first but not the second. + const N: usize = 1100; + const FIRST_NEWLINE: usize = 5; + const LAST_NEWLINE: usize = 1050; + let bytes: Vec = (0..N) + .map(|i| if i == FIRST_NEWLINE || i == LAST_NEWLINE { b'\n' } else { b'a' }) + .collect(); + let mut io_slices: Vec> = bytes.chunks(1).map(IoSlice::new).collect(); + + // The buffer has to be large enough to hold the whole tail past the first + // newline; otherwise it fills up before the buggy split would even reach + // the second newline, masking the bug. + let mut writer = LineWriter::with_capacity(4096, FullSink::default()); + writer.write_all_vectored(&mut io_slices).unwrap(); + + // Everything up to and including the last newline must have been flushed; + // only the trailing partial line is allowed to remain buffered. The buggy + // version left the last newline buried in the buffer, so the sink only saw + // up to the first newline. + assert_eq!(writer.get_ref().buffer, bytes[..=LAST_NEWLINE]); + + writer.flush().unwrap(); + assert_eq!(writer.get_ref().buffer, bytes); +} + /// Test that, in cases where vectored writing is not enabled, the /// LineWriter uses the normal `write` call, which more-correctly handles /// partial lines diff --git a/library/stdarch/crates/core_arch/src/aarch64/sve/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/sve/generated.rs index 6c6a2476a43fd..e1157f3440cfb 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/sve/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/sve/generated.rs @@ -12,6 +12,7 @@ use stdarch_test::assert_instr; use super::*; use crate::core_arch::arch::aarch64::*; +use super::{AsSigned, AsUnsigned}; #[doc = "Absolute difference"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/svabd[_f32]_m)"] diff --git a/library/stdarch/crates/stdarch-gen-arm/src/main.rs b/library/stdarch/crates/stdarch-gen-arm/src/main.rs index b7e2aa416fb59..717a1707aafe3 100644 --- a/library/stdarch/crates/stdarch-gen-arm/src/main.rs +++ b/library/stdarch/crates/stdarch-gen-arm/src/main.rs @@ -166,7 +166,7 @@ use super::*;{uses_neon} "#, uses_neon = if generated_input.ctx.uses_neon_types { - "\nuse crate::core_arch::arch::aarch64::*;" + "\nuse crate::core_arch::arch::aarch64::*;\nuse super::{AsSigned, AsUnsigned};" } else { "" }, diff --git a/src/etc/lldb_batchmode/runner.py b/src/etc/lldb_batchmode/runner.py index e9b106390f6f9..cdc5458606858 100644 --- a/src/etc/lldb_batchmode/runner.py +++ b/src/etc/lldb_batchmode/runner.py @@ -98,7 +98,7 @@ def execute_command(command_interpreter, command): "registering breakpoint callback, id = " + str(breakpoint_id) ) callback_command = f"breakpoint command add -s python {str(breakpoint_id)} -o \ - 'import lldb_batchmode; lldb_batchmode.breakpoint_callback'" +'import lldb_batchmode; lldb_batchmode.runner.breakpoint_callback'" command_interpreter.HandleCommand(callback_command, res) if res.Succeeded(): diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py index cc3e8411306d9..77c508f3ebb77 100644 --- a/src/etc/lldb_lookup.py +++ b/src/etc/lldb_lookup.py @@ -114,6 +114,8 @@ def __lldb_init_module(debugger: lldb.SBDebugger, _dict: LLDBOpaque): FEATURE_FLAGS |= LLDBFeature.StaticFields if getattr(lldb, "eFormatterMatchCallback", None) is not None: FEATURE_FLAGS |= LLDBFeature.TypeRecognizers + if getattr(lldb, "eBasicTypeFloat128", None) is not None: + FEATURE_FLAGS |= LLDBFeature.Float128 register_providers_compatibility() diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 81841dcc4cbb1..f6c2ab8f2b8c7 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -1,6 +1,6 @@ from __future__ import annotations import sys -from typing import Generator, List, TYPE_CHECKING, Optional +from typing import Generator, Dict, List, TYPE_CHECKING, Optional from enum import Flag, auto from lldb import ( @@ -9,6 +9,15 @@ eBasicTypeLong, eBasicTypeUnsignedLong, eBasicTypeUnsignedChar, + eBasicTypeUnsignedShort, + eBasicTypeUnsignedLongLong, + eBasicTypeSignedChar, + eBasicTypeShort, + eBasicTypeLongLong, + eBasicTypeFloat, + eBasicTypeDouble, + eBasicTypeHalf, + eBasicTypeChar32, eFormatChar, eTypeIsInteger, ) @@ -67,6 +76,9 @@ class LLDBFeature(Flag): """Added in LLDB 18. Adds functions to `SBType` the inspection of a struct's static fields.""" TypeRecognizers = auto() """Added in LLDB 19. Callback-based type matching for synthetic/summary providers.""" + Float128 = auto() + """Added in LLDB 22.1. Adds builtin support for Float 128's, including an `eBasicTypeFloat128`, + a formatter, and handlers in `TypeSystemClang`""" FEATURE_FLAGS: LLDBFeature = LLDBFeature(0) @@ -198,6 +210,21 @@ def get_template_args(type_name: str) -> Generator[str, None, None]: MSVC_PTR_PREFIX: List[str] = ["ref$<", "ref_mut$<", "ptr_const$<", "ptr_mut$<"] +PRIMITIVE_TYPES: Dict[str, int] = { + "u8": eBasicTypeUnsignedChar, + "u16": eBasicTypeUnsignedShort, + "u32": eBasicTypeUnsignedLong, + "u64": eBasicTypeUnsignedLongLong, + "i8": eBasicTypeSignedChar, + "i16": eBasicTypeShort, + "i32": eBasicTypeLong, + "i64": eBasicTypeLongLong, + "f16": eBasicTypeHalf, + "f32": eBasicTypeFloat, + "f64": eBasicTypeDouble, + "char": eBasicTypeChar32, +} + def resolve_msvc_template_arg(arg_name: str, target: SBTarget) -> SBType: """ @@ -214,6 +241,22 @@ def resolve_msvc_template_arg(arg_name: str, target: SBTarget) -> SBType: current version of LLDB, so instead the types are generated via `base_type.GetPointerType()` and `base_type.GetArrayType()`, which bypass the PDB file and ask clang directly for the type node. """ + + # As of LLDB 22, finding primitives based on `FindFirstType` with their rust name no longer + # works. Instead, we can look them up by their `eBasicType` equivalent. For usize and isize, + # we convert them to their bit-sized counterpart before the lookup + if arg_name == "isize" or arg_name == "usize": + equivalent = f"{arg_name[0]}{target.GetAddressByteSize() * 8}" + return target.GetBasicType(PRIMITIVE_TYPES[equivalent]) + + if (basic_type := PRIMITIVE_TYPES.get(arg_name)) is not None: + return target.GetBasicType(basic_type) + + if arg_name == "f128" and LLDBFeature.Float128 in FEATURE_FLAGS: + from lldb import eBasicTypeFloat128 + + return target.GetBasicType(eBasicTypeFloat128) + result = target.FindFirstType(arg_name) if result.IsValid(): diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7442ec99d90eb..c2fd72e96b2de 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -417,15 +417,10 @@ fn clean_where_predicate<'tcx>( bound_params, } } - hir::WherePredicateKind::RegionPredicate(wrp) => WherePredicate::RegionPredicate { lifetime: clean_lifetime(wrp.lifetime, cx), bounds: wrp.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(), }, - - // We should never actually reach this case because these predicates should've already been - // rejected in an earlier compiler pass. This feature isn't fully implemented (#20041). - hir::WherePredicateKind::EqPredicate(_) => bug!("EqPredicate"), }) } @@ -530,7 +525,7 @@ fn clean_projection_predicate<'tcx>( pred: ty::Binder<'tcx, ty::ProjectionPredicate<'tcx>>, cx: &mut DocContext<'tcx>, ) -> WherePredicate { - WherePredicate::EqPredicate { + WherePredicate::ProjectionPredicate { lhs: clean_projection(pred.map_bound(|p| p.projection_term), cx, None), rhs: clean_middle_term(pred.map_bound(|p| p.term), cx), } @@ -797,8 +792,8 @@ pub(crate) fn clean_generics<'tcx>( } } } - WherePredicate::EqPredicate { lhs, rhs } => { - eq_predicates.push(WherePredicate::EqPredicate { lhs, rhs }); + WherePredicate::ProjectionPredicate { lhs, rhs } => { + eq_predicates.push(WherePredicate::ProjectionPredicate { lhs, rhs }); } } } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index a5b5660589f29..fecbc913771b2 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -40,7 +40,7 @@ pub(crate) fn where_clauses(tcx: TyCtxt<'_>, clauses: ThinVec) -> ThinVec { lifetimes.push((lifetime, bounds)); } - WP::EqPredicate { lhs, rhs } => equalities.push((lhs, rhs)), + WP::ProjectionPredicate { lhs, rhs } => equalities.push((lhs, rhs)), } } @@ -61,7 +61,7 @@ pub(crate) fn where_clauses(tcx: TyCtxt<'_>, clauses: ThinVec) -> ThinVec, bound_params: Vec }, RegionPredicate { lifetime: Lifetime, bounds: Vec }, - EqPredicate { lhs: QPathData, rhs: Term }, + ProjectionPredicate { lhs: QPathData, rhs: Term }, } impl WherePredicate { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0b94d2bf1e641..8172ef1848e80 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -138,7 +138,7 @@ fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> } Ok(()) } - clean::WherePredicate::EqPredicate { lhs, rhs } => { + clean::WherePredicate::ProjectionPredicate { lhs, rhs } => { let opts = WithOpts::from(f); write!( f, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index fd6d389542b99..4de2a46007877 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -40,6 +40,7 @@ mod type_layout; mod write_shared; use std::borrow::Cow; +use std::cmp::Ordering; use std::collections::VecDeque; use std::fmt::{self, Display as _, Write}; use std::iter::Peekable; @@ -79,7 +80,7 @@ use crate::html::format::{ use crate::html::markdown::{ HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine, short_markdown_summary, }; -use crate::html::render::print_item::compare_names; +use crate::html::render::print_item::ImplString; use crate::html::render::search_index::get_function_type_for_search; use crate::html::static_files::SCRAPE_EXAMPLES_HELP_MD; use crate::html::{highlight, sources}; @@ -954,46 +955,50 @@ fn impl_trait_key(cx: &Context<'_>, i: &Impl) -> Option { // Render the list of items inside one of the sections "Trait Implementations", // "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages). -fn render_impls( - cx: &Context<'_>, - mut w: impl Write, - impls: &[&Impl], - containing_item: &clean::Item, +fn render_impls<'a, 'cx>( + cx: &'a Context<'cx>, + mut impls: Vec<&'a Impl>, + containing_item: &'a clean::Item, toggle_open_by_default: bool, -) -> fmt::Result { +) -> impl fmt::Display + use<'a, 'cx> { + impls.sort_by_cached_key(|imp| { + let prefix = match imp.inner_impl().polarity { + ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => Ordering::Greater, + ty::ImplPolarity::Negative => Ordering::Less, + }; + (prefix, ImplString::new_path(imp, cx)) + }); // Render each impl alongside its `impl_trait_key`, which is used as the primary sorting key // to match the impl order in the sidebar. - let mut keyed_rendered_impls = impls - .iter() - .map(|i| { - let did = i.trait_did().unwrap(); - let provided_trait_methods = i.inner_impl().provided_trait_methods(cx.tcx()); - let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_trait_methods); - let imp = render_impl( - cx, - i, - containing_item, - assoc_link, - RenderMode::Normal, - None, - &[], - ImplRenderingParameters { - show_def_docs: true, - show_default_items: true, - show_non_assoc_items: true, - toggle_open_by_default, - }, - ); - (impl_trait_key(cx, i).unwrap(), imp.to_string()) - }) - .collect::>(); - // Sort and then remove the `impl_trait_key`s, which are no longer needed after sorting. - keyed_rendered_impls - .sort_by(|(k1, h1), (k2, h2)| compare_names(k1, k2).then_with(|| h1.cmp(h2))); - let joined: String = keyed_rendered_impls.into_iter().map(|a| a.1).collect(); - - w.write_str(&joined) + fmt::from_fn(move |f| { + impls + .iter() + .map(|i| { + fmt::from_fn(|f| { + let did = i.trait_did().unwrap(); + let provided_trait_methods = i.inner_impl().provided_trait_methods(cx.tcx()); + let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_trait_methods); + render_impl( + cx, + i, + containing_item, + assoc_link, + RenderMode::Normal, + None, + &[], + ImplRenderingParameters { + show_def_docs: true, + show_default_items: true, + show_non_assoc_items: true, + toggle_open_by_default, + }, + ) + .fmt(f) + }) + }) + .joined("", f) + }) } /// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item. @@ -1415,16 +1420,12 @@ fn render_all_impls( mut w: impl Write, cx: &Context<'_>, containing_item: &clean::Item, - concrete_impls: &[&Impl], - auto_trait_impls: &[&Impl], - blanket_impls: &[&Impl], + concrete_impls: Vec<&Impl>, + auto_trait_impls: Vec<&Impl>, + blanket_impls: Vec<&Impl>, ) -> fmt::Result { - let impls = { - let mut buf = String::new(); - render_impls(cx, &mut buf, concrete_impls, containing_item, true)?; - buf - }; - if !impls.is_empty() { + if !concrete_impls.is_empty() { + let impls = render_impls(cx, concrete_impls, containing_item, true); write!( w, "{}
{impls}
", @@ -1433,25 +1434,24 @@ fn render_all_impls( } if !auto_trait_impls.is_empty() { + let impls = render_impls(cx, auto_trait_impls, containing_item, false); // FIXME: Change the ID to `auto-trait-implementations-list`! write!( w, - "{}
", + "{}
{impls}
", write_impl_section_heading("Auto Trait Implementations", "synthetic-implementations",) )?; - render_impls(cx, &mut w, auto_trait_impls, containing_item, false)?; - w.write_str("
")?; } if !blanket_impls.is_empty() { + let impls = render_impls(cx, blanket_impls, containing_item, false); write!( w, - "{}
", + "{}
{impls}
", write_impl_section_heading("Blanket Implementations", "blanket-implementations") )?; - render_impls(cx, &mut w, blanket_impls, containing_item, false)?; - w.write_str("
")?; } + Ok(()) } @@ -1588,14 +1588,7 @@ fn render_assoc_items_inner( let (blanket_impls, concrete_impls): (Vec<&Impl>, _) = trait_impls.into_iter().partition(|t| t.inner_impl().kind.is_blanket()); - render_all_impls( - w, - cx, - containing_item, - &concrete_impls, - &auto_trait_impls, - &blanket_impls, - )?; + render_all_impls(w, cx, containing_item, concrete_impls, auto_trait_impls, blanket_impls)?; } Ok(()) } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 8385e691ed385..7469b08b4b424 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -32,8 +32,8 @@ use crate::formats::item_type::ItemType; use crate::html::escape::{Escape, EscapeBodyTextWithWbr}; use crate::html::format::{ Ending, PrintWithSpace, full_print_fn_decl, print_abi_with_space, print_constness_with_space, - print_generic_bound, print_generics, print_impl, print_import, print_type, print_where_clause, - visibility_print_with_space, + print_generic_bound, print_generics, print_impl, print_import, print_path, print_type, + print_where_clause, visibility_print_with_space, }; use crate::html::markdown::{HeadingOffset, MarkdownSummaryLine}; use crate::html::render::sidebar::filters; @@ -1016,9 +1016,9 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt: let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter().partition(|i| i.inner_impl().kind.is_auto()); - synthetic.sort_by_cached_key(|i| ImplString::new(i, cx)); - concrete.sort_by_cached_key(|i| ImplString::new(i, cx)); - foreign.sort_by_cached_key(|i| ImplString::new(i, cx)); + synthetic.sort_by_cached_key(|i| ImplString::new_impl(i, cx)); + concrete.sort_by_cached_key(|i| ImplString::new_impl(i, cx)); + foreign.sort_by_cached_key(|i| ImplString::new_impl(i, cx)); if !foreign.is_empty() { write!( @@ -1969,7 +1969,7 @@ fn item_primitive(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { let (concrete, synthetic, blanket_impl) = get_filtered_impls_for_reference(&cx.shared, it); - render_all_impls(w, cx, it, &concrete, &synthetic, &blanket_impl) + render_all_impls(w, cx, it, concrete, synthetic, blanket_impl) } }) } @@ -2346,16 +2346,21 @@ where } #[derive(PartialEq, Eq)] -struct ImplString { +pub(super) struct ImplString { // Plain text (not HTML text) because this is only used for sorting purposes, and the plain // text is much shorter and thus faster to compare. cmp_text: String, } impl ImplString { - fn new(i: &Impl, cx: &Context<'_>) -> ImplString { + fn new_impl(i: &Impl, cx: &Context<'_>) -> Self { let impl_ = i.inner_impl(); - ImplString { cmp_text: format!("{:#}", print_impl(impl_, false, cx)) } + Self { cmp_text: format!("{:#}", print_impl(impl_, false, cx)) } + } + + pub(super) fn new_path(i: &Impl, cx: &Context<'_>) -> Option { + let path = i.inner_impl().trait_.as_ref()?; + Some(Self { cmp_text: format!("{:#}", print_path(path, cx)) }) } } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 84faa98384cc4..d2bf6900c276d 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -497,7 +497,7 @@ impl FromClean for WherePredicate { }) .collect(), }, - EqPredicate { lhs, rhs } => WherePredicate::EqPredicate { + ProjectionPredicate { lhs, rhs } => WherePredicate::EqPredicate { // The LHS currently has type `Type` but it should be a `QualifiedPath` since it may // refer to an associated const. However, `EqPredicate` shouldn't exist in the first // place: . diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index ea99b523f09b0..8b50ce279b4b1 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -551,14 +551,6 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_ } } }, - WherePredicateKind::EqPredicate(ref pred) => { - let mut visitor = RefVisitor::new(cx); - walk_unambig_ty(&mut visitor, pred.lhs_ty); - walk_unambig_ty(&mut visitor, pred.rhs_ty); - if !visitor.lts.is_empty() { - return true; - } - }, } } false diff --git a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs index 5b6b4f112455a..8b02c4865d138 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs @@ -69,7 +69,6 @@ impl EarlyLintPass for MultipleBoundLocations { emit_lint(cx, *bound_span, pred.lifetime.ident.span); } }, - WherePredicateKind::EqPredicate(_) => {}, } } } diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index e0a182523f673..fa93cf208c9d9 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -787,7 +787,6 @@ fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool { (RegionPredicate(l), RegionPredicate(r)) => { eq_id(l.lifetime.ident, r.lifetime.ident) && over(&l.bounds, &r.bounds, eq_generic_bound) }, - (EqPredicate(l), EqPredicate(r)) => eq_ty(&l.lhs_ty, &r.lhs_ty) && eq_ty(&l.rhs_ty, &r.rhs_ty), _ => false, } } diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 7590090f9be40..38724a1053f65 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -301,9 +301,6 @@ impl HirEqInterExpr<'_, '_, '_> { Self::eq_lifetime(l_region.lifetime, r_region.lifetime) && self.eq_generics_bound(l_region.bounds, r_region.bounds) }, - (WherePredicateKind::EqPredicate(l_eq), WherePredicateKind::EqPredicate(r_eq)) => { - self.eq_ty(l_eq.lhs_ty, r_eq.lhs_ty) - }, _ => false, }) } diff --git a/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs b/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs index 608c6605304f4..9116b38ed0796 100644 --- a/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs +++ b/src/tools/llvm-bitcode-linker/src/bin/llvm-bitcode-linker.rs @@ -1,7 +1,9 @@ use std::path::PathBuf; -use clap::Parser; +use anyhow::anyhow; +use clap::{ArgAction, Parser}; use llvm_bitcode_linker::{Optimization, Session, Target}; +use tracing::level_filters::LevelFilter; #[derive(Debug, Parser)] /// Linker for embedded code without any system dependencies @@ -46,13 +48,29 @@ pub struct Args { /// The optimization level #[arg(short = 'O', value_enum, default_value = "0")] optimization: Optimization, + + /// Increase linker diagnostic verbosity (-v = info, -vv = debug) + #[arg(short = 'v', long = "verbose", action = ArgAction::Count)] + verbose: u8, } fn main() -> anyhow::Result<()> { - tracing_subscriber::FmtSubscriber::builder().with_max_level(tracing::Level::DEBUG).init(); - let args = Args::parse(); + let max_tracing_level = match args.verbose { + 0 => LevelFilter::OFF, + 1 => LevelFilter::INFO, + _ => LevelFilter::TRACE, + }; + + tracing_subscriber::FmtSubscriber::builder() + .with_max_level(max_tracing_level) + .with_target(false) + .without_time() + .with_level(false) + .with_ansi(false) + .init(); + let mut linker = Session::new(args.target, args.target_cpu, args.target_feature, args.output); linker.add_exported_symbols(args.export_symbol); @@ -61,5 +79,11 @@ fn main() -> anyhow::Result<()> { linker.add_file(rlib); } - linker.lto(args.optimization, args.debug) + let hint = if max_tracing_level < LevelFilter::ERROR { + "Pass `-v` to llvm-bitcode-linker for additional diagnostic output." + } else { + "" + }; + + linker.lto(args.optimization, args.debug).map_err(|err| anyhow!("{err}\n{hint}")) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs index bb00a79480d84..71014eb661742 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/as_place.rs @@ -1,7 +1,7 @@ //! MIR lowering for places use hir_def::FunctionId; -use rustc_type_ir::inherent::{Region as _, Ty as _}; +use rustc_type_ir::inherent::Region as _; use super::*; use crate::{ diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index e574a9d278265..2dfb5e5b28f61 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -484,16 +484,6 @@ impl Rewrite for ast::WherePredicate { ref lifetime, ref bounds, }) => rewrite_bounded_lifetime(lifetime, bounds, self.span, context, shape)?, - ast::WherePredicateKind::EqPredicate(ast::WhereEqPredicate { - ref lhs_ty, - ref rhs_ty, - .. - }) => { - let lhs_ty_str = lhs_ty - .rewrite_result(context, shape) - .map(|lhs| lhs + " =")?; - rewrite_assign_rhs(context, lhs_ty_str, &**rhs_ty, &RhsAssignKind::Ty, shape)? - } }; let mut result = String::with_capacity(attrs_str.len() + pred_str.len() + 1); diff --git a/tests/codegen-llvm/intrinsics/copy_nonoverlapping.rs b/tests/codegen-llvm/intrinsics/copy_nonoverlapping.rs new file mode 100644 index 0000000000000..84a1f713ce68c --- /dev/null +++ b/tests/codegen-llvm/intrinsics/copy_nonoverlapping.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Copt-level=3 -C no-prepopulate-passes +//@ only-64bit (so I don't need to worry about usize) + +#![crate_type = "lib"] +#![feature(core_intrinsics)] + +// This deals in a count of elements, not bytes, so we need to multiply. +// Ensure we preserve UB from a count too high to be valid. +use std::intrinsics::copy_nonoverlapping; + +// CHECK-LABEL: @copy_u16( +#[no_mangle] +pub unsafe fn copy_u16(src: *const u16, dst: *mut u16, count: usize) { + // CHECK: [[BYTES:%.+]] = mul nuw nsw i64 %count, 2 + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 2 %dst, ptr align 2 %src, i64 [[BYTES]], i1 false) + copy_nonoverlapping(src, dst, count) +} diff --git a/tests/codegen-llvm/str-range-indexing.rs b/tests/codegen-llvm/str-range-indexing.rs index 5fa8e0dd17d3c..57fd886f9fc71 100644 --- a/tests/codegen-llvm/str-range-indexing.rs +++ b/tests/codegen-llvm/str-range-indexing.rs @@ -18,18 +18,19 @@ macro_rules! tests { }; } -// 9 comparisons required: -// start <= end -// && (start == 0 || (start >= len && start == len) || bytes[start] >= -0x40) -// && (end == 0 || (end >= len && end == len) || bytes[end] >= -0x40) +// 7 comparisons required: +// start <= end && end <= len +// && (start == len || +// ( (start == 0 || bytes[start] >= -0x40) +// && (end == len || bytes[end] >= -0x40))) // CHECK-LABEL: @get_range -// CHECK-COUNT-9: %{{.+}} = icmp +// CHECK-COUNT-7: %{{.+}} = icmp // CHECK-NOT: %{{.+}} = icmp // CHECK: ret // CHECK-LABEL: @index_range -// CHECK-COUNT-9: %{{.+}} = icmp +// CHECK-COUNT-7: %{{.+}} = icmp // CHECK-NOT: %{{.+}} = icmp // CHECK: ret tests!(Range, get_range, index_range); diff --git a/tests/rustdoc-html/macro/const-rendering-macros-33302.rs b/tests/rustdoc-html/macro/const-rendering-macros-33302.rs index 9fd45df08be34..26b7d3d008481 100644 --- a/tests/rustdoc-html/macro/const-rendering-macros-33302.rs +++ b/tests/rustdoc-html/macro/const-rendering-macros-33302.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/issues/33302 -#![crate_name="issue_33302"] +#![crate_name = "issue_33302"] // Ensure constant and array length values are not taken from source // code, which wreaks havoc with macros. @@ -25,11 +25,12 @@ macro_rules! make { } //@ has issue_33302/struct.S.html \ - // '//*[@class="impl"]' 'impl T<[i32; 16]> for S' - //@ has - '//*[@id="associatedconstant.C"]' 'const C: [i32; 16]' + // '//*[@class="impl"]' 'impl T<(i32, i32)> for S' + //@ has - '//*[@id="associatedconstant.C"]' 'const C: (i32, i32)' //@ has - '//*[@id="associatedconstant.D"]' 'const D: i32' - impl T<[i32; ($n * $n)]> for S { - const C: [i32; ($n * $n)] = [0; ($n * $n)]; + impl T<(i32, i32)> for S { + const C: (i32, i32) = ($n, $n); + const D: i32 = ($n / $n); } //@ has issue_33302/struct.S.html \ @@ -41,12 +42,11 @@ macro_rules! make { } //@ has issue_33302/struct.S.html \ - // '//*[@class="impl"]' 'impl T<(i32, i32)> for S' - //@ has - '//*[@id="associatedconstant.C-2"]' 'const C: (i32, i32)' + // '//*[@class="impl"]' 'impl T<[i32; 16]> for S' + //@ has - '//*[@id="associatedconstant.C-2"]' 'const C: [i32; 16]' //@ has - '//*[@id="associatedconstant.D-2"]' 'const D: i32' - impl T<(i32, i32)> for S { - const C: (i32, i32) = ($n, $n); - const D: i32 = ($n / $n); + impl T<[i32; ($n * $n)]> for S { + const C: [i32; ($n * $n)] = [0; ($n * $n)]; } }; } diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index 8a7cacf20e2e4..610a4990a5a4b 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -4,24 +4,17 @@ #![deny(warnings)] extern crate rustc_codegen_ssa; -extern crate rustc_data_structures; -extern crate rustc_driver; -extern crate rustc_errors; -extern crate rustc_hir; +extern crate rustc_driver as _; extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_session; -extern crate rustc_span; -extern crate rustc_symbol_mangling; -extern crate rustc_target; use std::any::Any; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CompiledModules, CrateInfo}; -use rustc_data_structures::fx::FxIndexMap; use rustc_metadata::EncodedMetadata; -use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; +use rustc_middle::dep_graph::WorkProductMap; use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::OutputFilenames; @@ -47,11 +40,11 @@ impl CodegenBackend for TheBackend { _sess: &Session, _outputs: &OutputFilenames, _crate_info: &CrateInfo, - ) -> (CompiledModules, FxIndexMap) { + ) -> (CompiledModules, WorkProductMap) { let codegen_results = ongoing_codegen .downcast::() .expect("in join_codegen: ongoing_codegen is not a CompiledModules"); - (*codegen_results, FxIndexMap::default()) + (*codegen_results, WorkProductMap::default()) } fn link( diff --git a/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs b/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs index b757521e0a452..0072c4c0f2b8b 100644 --- a/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs +++ b/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.rs @@ -29,12 +29,7 @@ fn paint(c: C, d: C::Color) { //~^ ERROR ambiguous associated type `Color` in bounds of `C` } -fn dent_object_2(c: &dyn BoxCar) where ::Color = COLOR { - //~^ ERROR the value of the associated types - //~| ERROR equality constraints are not yet supported in `where` clauses -} - -fn dent_object_3(c: X) +fn dent_object_2(c: X) where X: BoxCar, X: Vehicle, X: Box diff --git a/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr b/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr index 063623ebd123f..78a6d02611682 100644 --- a/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr +++ b/tests/ui/associated-types/associated-type-projection-from-multiple-supertraits.stderr @@ -1,11 +1,3 @@ -error: equality constraints are not yet supported in `where` clauses - --> $DIR/associated-type-projection-from-multiple-supertraits.rs:32:47 - | -LL | fn dent_object_2(c: &dyn BoxCar) where ::Color = COLOR { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information - error[E0221]: ambiguous associated type `Color` in bounds of `C` --> $DIR/associated-type-projection-from-multiple-supertraits.rs:19:32 | @@ -84,21 +76,7 @@ LL - fn paint(c: C, d: C::Color) { LL + fn paint(c: C, d: ::Color) { | -error[E0191]: the value of the associated types `Color` in `Box`, `Color` in `Vehicle` must be specified - --> $DIR/associated-type-projection-from-multiple-supertraits.rs:32:33 - | -LL | type Color; - | ---------- `Vehicle::Color` defined here -... -LL | type Color; - | ---------- `Box::Color` defined here -... -LL | fn dent_object_2(c: &dyn BoxCar) where ::Color = COLOR { - | ^^^^^^ associated types `Color` (from trait `Vehicle`), `Color` (from trait `Box`) must be specified - | - = help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types - -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0191, E0221, E0222. For more information about an error, try `rustc --explain E0191`. diff --git a/tests/ui/issues/auxiliary/issue-36954.rs b/tests/ui/cross-crate/auxiliary/const-fn-evaluated-cross-crate.rs similarity index 51% rename from tests/ui/issues/auxiliary/issue-36954.rs rename to tests/ui/cross-crate/auxiliary/const-fn-evaluated-cross-crate.rs index bc444a3817b88..9f0900809b18b 100644 --- a/tests/ui/issues/auxiliary/issue-36954.rs +++ b/tests/ui/cross-crate/auxiliary/const-fn-evaluated-cross-crate.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/36954 #![crate_type = "lib"] const fn foo(i: i32) -> i32 { diff --git a/tests/ui/issues/auxiliary/issue-3012-1.rs b/tests/ui/cross-crate/auxiliary/construct-extern-struct-with-destructor.rs similarity index 70% rename from tests/ui/issues/auxiliary/issue-3012-1.rs rename to tests/ui/cross-crate/auxiliary/construct-extern-struct-with-destructor.rs index 509af2a8d7df3..e01835cce563a 100644 --- a/tests/ui/issues/auxiliary/issue-3012-1.rs +++ b/tests/ui/cross-crate/auxiliary/construct-extern-struct-with-destructor.rs @@ -1,4 +1,5 @@ -#![crate_name="socketlib"] +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/3012 +#![crate_name="construct_extern_struct_with_destructor"] #![crate_type = "lib"] pub mod socket { diff --git a/tests/ui/issues/auxiliary/issue-29265.rs b/tests/ui/cross-crate/auxiliary/cross-crate-static-reference-and-field-access.rs similarity index 62% rename from tests/ui/issues/auxiliary/issue-29265.rs rename to tests/ui/cross-crate/auxiliary/cross-crate-static-reference-and-field-access.rs index 6d26002a2e707..5c50ee0d59ce6 100644 --- a/tests/ui/issues/auxiliary/issue-29265.rs +++ b/tests/ui/cross-crate/auxiliary/cross-crate-static-reference-and-field-access.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/29265 #![crate_type = "lib"] pub struct SomeType { diff --git a/tests/ui/issues/auxiliary/issue-3979-traits.rs b/tests/ui/cross-crate/auxiliary/cross-crate-trait-inheritance-on-default-method.rs similarity index 60% rename from tests/ui/issues/auxiliary/issue-3979-traits.rs rename to tests/ui/cross-crate/auxiliary/cross-crate-trait-inheritance-on-default-method.rs index 5d03a0e9e9931..17796ae23d4e2 100644 --- a/tests/ui/issues/auxiliary/issue-3979-traits.rs +++ b/tests/ui/cross-crate/auxiliary/cross-crate-trait-inheritance-on-default-method.rs @@ -1,4 +1,5 @@ -#![crate_name="issue_3979_traits"] +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/3979 +#![crate_name="cross_crate_trait_inheritance_on_default_method"] #![crate_type = "lib"] diff --git a/tests/ui/issues/auxiliary/issue-2526.rs b/tests/ui/cross-crate/auxiliary/cross-crate-type-alias-with-nested-destructors.rs similarity index 82% rename from tests/ui/issues/auxiliary/issue-2526.rs rename to tests/ui/cross-crate/auxiliary/cross-crate-type-alias-with-nested-destructors.rs index 3b27f658cdae5..879f215b24f4e 100644 --- a/tests/ui/issues/auxiliary/issue-2526.rs +++ b/tests/ui/cross-crate/auxiliary/cross-crate-type-alias-with-nested-destructors.rs @@ -1,4 +1,5 @@ -#![crate_name="issue_2526"] +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/2526 +#![crate_name="cross_crate_type_alias_with_nested_destructors"] #![crate_type = "lib"] use std::marker; diff --git a/tests/ui/issues/auxiliary/issue-38226-aux.rs b/tests/ui/cross-crate/auxiliary/default-trait-method-reachable-through-trait-object.rs similarity index 80% rename from tests/ui/issues/auxiliary/issue-38226-aux.rs rename to tests/ui/cross-crate/auxiliary/default-trait-method-reachable-through-trait-object.rs index a8e964e016fd1..b14a140de18f5 100644 --- a/tests/ui/issues/auxiliary/issue-38226-aux.rs +++ b/tests/ui/cross-crate/auxiliary/default-trait-method-reachable-through-trait-object.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/38226 #![crate_type="rlib"] #[inline(never)] diff --git a/tests/ui/cross-crate/auxiliary/extern-crate-and-impl-inside-method-body.rs b/tests/ui/cross-crate/auxiliary/extern-crate-and-impl-inside-method-body.rs new file mode 100644 index 0000000000000..cd011fc294c44 --- /dev/null +++ b/tests/ui/cross-crate/auxiliary/extern-crate-and-impl-inside-method-body.rs @@ -0,0 +1,2 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/41053 +pub struct Test; diff --git a/tests/ui/cross-crate/auxiliary/extern-generic-tuple-struct-construction.rs b/tests/ui/cross-crate/auxiliary/extern-generic-tuple-struct-construction.rs new file mode 100644 index 0000000000000..1a27ca252a30e --- /dev/null +++ b/tests/ui/cross-crate/auxiliary/extern-generic-tuple-struct-construction.rs @@ -0,0 +1,3 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/4545 +pub struct S(Option); +pub fn mk() -> S { S(None) } diff --git a/tests/ui/cross-crate/auxiliary/extern-repr-enum-with-discriminant-cast.rs b/tests/ui/cross-crate/auxiliary/extern-repr-enum-with-discriminant-cast.rs new file mode 100644 index 0000000000000..85819006c78ae --- /dev/null +++ b/tests/ui/cross-crate/auxiliary/extern-repr-enum-with-discriminant-cast.rs @@ -0,0 +1,5 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/42007 +#[repr(u8)] +pub enum E { + B = 1 as u8, +} diff --git a/tests/ui/cross-crate/auxiliary/extern-trait-bound-with-array-associated-type.rs b/tests/ui/cross-crate/auxiliary/extern-trait-bound-with-array-associated-type.rs new file mode 100644 index 0000000000000..d383b9ff64b80 --- /dev/null +++ b/tests/ui/cross-crate/auxiliary/extern-trait-bound-with-array-associated-type.rs @@ -0,0 +1,7 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/48984 +#![crate_type = "lib"] +#![crate_name = "extern_trait_bound_with_array_associated_type"] + +pub trait Foo { type Item; } + +pub trait Bar: Foo { } diff --git a/tests/ui/issues/auxiliary/issue-2723-a.rs b/tests/ui/cross-crate/auxiliary/fn-declared-inside-closure-body-cross-crate.rs similarity index 57% rename from tests/ui/issues/auxiliary/issue-2723-a.rs rename to tests/ui/cross-crate/auxiliary/fn-declared-inside-closure-body-cross-crate.rs index 661b46d829dfe..6346ebfb54dd4 100644 --- a/tests/ui/issues/auxiliary/issue-2723-a.rs +++ b/tests/ui/cross-crate/auxiliary/fn-declared-inside-closure-body-cross-crate.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/2723 pub unsafe fn f(xs: Vec ) { xs.iter().map(|_x| { unsafe fn q() { panic!(); } }).collect::>(); } diff --git a/tests/ui/issues/auxiliary/issue-2380.rs b/tests/ui/cross-crate/auxiliary/fn-local-impl-returned-as-trait-object.rs similarity index 72% rename from tests/ui/issues/auxiliary/issue-2380.rs rename to tests/ui/cross-crate/auxiliary/fn-local-impl-returned-as-trait-object.rs index 9ec829b417f81..420792577cf04 100644 --- a/tests/ui/issues/auxiliary/issue-2380.rs +++ b/tests/ui/cross-crate/auxiliary/fn-local-impl-returned-as-trait-object.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/2380 #![crate_name="a"] #![crate_type = "lib"] diff --git a/tests/ui/cross-crate/auxiliary/for-loop-in-match-on-self.rs b/tests/ui/cross-crate/auxiliary/for-loop-in-match-on-self.rs index 307f23c10e284..db1f5edb4507e 100644 --- a/tests/ui/cross-crate/auxiliary/for-loop-in-match-on-self.rs +++ b/tests/ui/cross-crate/auxiliary/for-loop-in-match-on-self.rs @@ -1,5 +1,4 @@ -//! Auxiliary crate for . - +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/16643 #![crate_type = "lib"] pub struct TreeBuilder { pub h: H } diff --git a/tests/ui/issues/auxiliary/issue-4208-cc.rs b/tests/ui/cross-crate/auxiliary/generic-fn-with-supertrait-bound-cross-crate.rs similarity index 52% rename from tests/ui/issues/auxiliary/issue-4208-cc.rs rename to tests/ui/cross-crate/auxiliary/generic-fn-with-supertrait-bound-cross-crate.rs index 7b4c8b01a9e2f..ad0fe922d6f2f 100644 --- a/tests/ui/issues/auxiliary/issue-4208-cc.rs +++ b/tests/ui/cross-crate/auxiliary/generic-fn-with-supertrait-bound-cross-crate.rs @@ -1,4 +1,5 @@ -#![crate_name="numeric"] +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/4208 +#![crate_name="generic_fn_with_supertrait_bound_cross_crate"] #![crate_type = "lib"] pub trait Trig { diff --git a/tests/ui/cross-crate/auxiliary/graceful-error-for-mistyped-assoc-const.rs b/tests/ui/cross-crate/auxiliary/graceful-error-for-mistyped-assoc-const.rs new file mode 100644 index 0000000000000..84ac2b5ae9de3 --- /dev/null +++ b/tests/ui/cross-crate/auxiliary/graceful-error-for-mistyped-assoc-const.rs @@ -0,0 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/41549 +pub trait Trait { + const CONST: u32; +} diff --git a/tests/ui/cross-crate/auxiliary/impl-extern-trait-with-associated-type.rs b/tests/ui/cross-crate/auxiliary/impl-extern-trait-with-associated-type.rs new file mode 100644 index 0000000000000..5d935380e0649 --- /dev/null +++ b/tests/ui/cross-crate/auxiliary/impl-extern-trait-with-associated-type.rs @@ -0,0 +1,5 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/20389 +pub trait T { + type C; + fn dummy(&self) { } +} diff --git a/tests/ui/cross-crate/auxiliary/imported-struct-not-confused-with-variant.rs b/tests/ui/cross-crate/auxiliary/imported-struct-not-confused-with-variant.rs new file mode 100644 index 0000000000000..4f70e98f22af9 --- /dev/null +++ b/tests/ui/cross-crate/auxiliary/imported-struct-not-confused-with-variant.rs @@ -0,0 +1,5 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/19293 +pub struct Foo (pub isize); +pub enum MyEnum { + Foo(Foo), +} diff --git a/tests/ui/issues/auxiliary/issue-2170-lib.rs b/tests/ui/cross-crate/auxiliary/link-extern-crate-with-drop-type.rs similarity index 68% rename from tests/ui/issues/auxiliary/issue-2170-lib.rs rename to tests/ui/cross-crate/auxiliary/link-extern-crate-with-drop-type.rs index a99385a834dfb..e498dd0758cef 100644 --- a/tests/ui/issues/auxiliary/issue-2170-lib.rs +++ b/tests/ui/cross-crate/auxiliary/link-extern-crate-with-drop-type.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/20389 fn foo(_x: i32) { } diff --git a/tests/ui/cross-crate/auxiliary/macro-generated-module-path-resolution.rs b/tests/ui/cross-crate/auxiliary/macro-generated-module-path-resolution.rs new file mode 100644 index 0000000000000..f808fa793e475 --- /dev/null +++ b/tests/ui/cross-crate/auxiliary/macro-generated-module-path-resolution.rs @@ -0,0 +1,3 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/38190 +#[macro_export] +macro_rules! m { ([$i:item]) => {} } diff --git a/tests/ui/cross-crate/auxiliary/method-call-on-extern-fn-return-value.rs b/tests/ui/cross-crate/auxiliary/method-call-on-extern-fn-return-value.rs new file mode 100644 index 0000000000000..02f85ee90ee6b --- /dev/null +++ b/tests/ui/cross-crate/auxiliary/method-call-on-extern-fn-return-value.rs @@ -0,0 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/51798 +#![crate_type = "lib"] + +pub fn vec() -> Vec { vec![] } diff --git a/tests/ui/issues/auxiliary/issue-2631-a.rs b/tests/ui/cross-crate/auxiliary/monomorphize-index-op-cross-crate.rs similarity index 81% rename from tests/ui/issues/auxiliary/issue-2631-a.rs rename to tests/ui/cross-crate/auxiliary/monomorphize-index-op-cross-crate.rs index 1e8211bfaa783..6ab538044fa5c 100644 --- a/tests/ui/issues/auxiliary/issue-2631-a.rs +++ b/tests/ui/cross-crate/auxiliary/monomorphize-index-op-cross-crate.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/2631 #![crate_name="req"] #![crate_type = "lib"] diff --git a/tests/ui/issues/auxiliary/issue-29485.rs b/tests/ui/cross-crate/auxiliary/mut-ref-write-visible-after-unwind.rs similarity index 58% rename from tests/ui/issues/auxiliary/issue-29485.rs rename to tests/ui/cross-crate/auxiliary/mut-ref-write-visible-after-unwind.rs index 1e8891c51206f..2545f4f0c48cc 100644 --- a/tests/ui/issues/auxiliary/issue-29485.rs +++ b/tests/ui/cross-crate/auxiliary/mut-ref-write-visible-after-unwind.rs @@ -1,4 +1,5 @@ -#![crate_name="a"] +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/29265 +#![crate_name="mut_ref_write_visible_after_unwind"] #![crate_type = "lib"] pub struct X(pub u8); diff --git a/tests/ui/issues/auxiliary/issue-3136-a.rs b/tests/ui/cross-crate/auxiliary/nested-struct-in-polymorphic-impl-method.rs similarity index 76% rename from tests/ui/issues/auxiliary/issue-3136-a.rs rename to tests/ui/cross-crate/auxiliary/nested-struct-in-polymorphic-impl-method.rs index 22bb1c8f97709..24f7601b67125 100644 --- a/tests/ui/issues/auxiliary/issue-3136-a.rs +++ b/tests/ui/cross-crate/auxiliary/nested-struct-in-polymorphic-impl-method.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/3136 #![crate_type = "lib"] trait x { diff --git a/tests/ui/issues/auxiliary/cgu_test_a.rs b/tests/ui/cross-crate/auxiliary/no-duplicate-symbols-with-codegen-units-cgu-test-a.rs similarity index 56% rename from tests/ui/issues/auxiliary/cgu_test_a.rs rename to tests/ui/cross-crate/auxiliary/no-duplicate-symbols-with-codegen-units-cgu-test-a.rs index 7998f1870b8fe..22618804fe629 100644 --- a/tests/ui/issues/auxiliary/cgu_test_a.rs +++ b/tests/ui/cross-crate/auxiliary/no-duplicate-symbols-with-codegen-units-cgu-test-a.rs @@ -1,7 +1,8 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/32518 //@ no-prefer-dynamic //@ compile-flags: -Ccodegen-units=2 --crate-type=lib -extern crate cgu_test; +extern crate no_duplicate_symbols_with_codegen_units_cgu_test as cgu_test; pub mod a { pub fn a() { diff --git a/tests/ui/issues/auxiliary/cgu_test_b.rs b/tests/ui/cross-crate/auxiliary/no-duplicate-symbols-with-codegen-units-cgu-test-b.rs similarity index 56% rename from tests/ui/issues/auxiliary/cgu_test_b.rs rename to tests/ui/cross-crate/auxiliary/no-duplicate-symbols-with-codegen-units-cgu-test-b.rs index 7998f1870b8fe..22618804fe629 100644 --- a/tests/ui/issues/auxiliary/cgu_test_b.rs +++ b/tests/ui/cross-crate/auxiliary/no-duplicate-symbols-with-codegen-units-cgu-test-b.rs @@ -1,7 +1,8 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/32518 //@ no-prefer-dynamic //@ compile-flags: -Ccodegen-units=2 --crate-type=lib -extern crate cgu_test; +extern crate no_duplicate_symbols_with_codegen_units_cgu_test as cgu_test; pub mod a { pub fn a() { diff --git a/tests/ui/issues/auxiliary/cgu_test.rs b/tests/ui/cross-crate/auxiliary/no-duplicate-symbols-with-codegen-units-cgu-test.rs similarity index 51% rename from tests/ui/issues/auxiliary/cgu_test.rs rename to tests/ui/cross-crate/auxiliary/no-duplicate-symbols-with-codegen-units-cgu-test.rs index 1103fcb1f0b28..73dd32b34ba8b 100644 --- a/tests/ui/issues/auxiliary/cgu_test.rs +++ b/tests/ui/cross-crate/auxiliary/no-duplicate-symbols-with-codegen-units-cgu-test.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/32518 //@ no-prefer-dynamic //@ compile-flags: --crate-type=lib diff --git a/tests/ui/issues/auxiliary/issue-31702-1.rs b/tests/ui/cross-crate/auxiliary/optimized-closure-with-debug-info-cross-crate-1.rs similarity index 74% rename from tests/ui/issues/auxiliary/issue-31702-1.rs rename to tests/ui/cross-crate/auxiliary/optimized-closure-with-debug-info-cross-crate-1.rs index a48d0dc2c6447..b14ce0b0dc190 100644 --- a/tests/ui/issues/auxiliary/issue-31702-1.rs +++ b/tests/ui/cross-crate/auxiliary/optimized-closure-with-debug-info-cross-crate-1.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/31702 #[derive(Copy)] pub struct U256(pub [u64; 4]); diff --git a/tests/ui/issues/auxiliary/issue-31702-2.rs b/tests/ui/cross-crate/auxiliary/optimized-closure-with-debug-info-cross-crate-2.rs similarity index 67% rename from tests/ui/issues/auxiliary/issue-31702-2.rs rename to tests/ui/cross-crate/auxiliary/optimized-closure-with-debug-info-cross-crate-2.rs index 16300b0f5d530..05da5e21824cd 100644 --- a/tests/ui/issues/auxiliary/issue-31702-2.rs +++ b/tests/ui/cross-crate/auxiliary/optimized-closure-with-debug-info-cross-crate-2.rs @@ -1,9 +1,10 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/31702 //@ compile-flags: -g -extern crate issue_31702_1; +extern crate optimized_closure_with_debug_info_cross_crate_1; use std::collections::HashMap; -use issue_31702_1::U256; +use optimized_closure_with_debug_info_cross_crate_1::U256; pub struct Ethash { engine_params: fn() -> Option<&'static Vec>, diff --git a/tests/ui/issues/auxiliary/issue-34796-aux.rs b/tests/ui/cross-crate/auxiliary/stable-hash-for-trait-object-type.rs similarity index 76% rename from tests/ui/issues/auxiliary/issue-34796-aux.rs rename to tests/ui/cross-crate/auxiliary/stable-hash-for-trait-object-type.rs index 0e91bb4bcdc1f..a3c278db38a60 100644 --- a/tests/ui/issues/auxiliary/issue-34796-aux.rs +++ b/tests/ui/cross-crate/auxiliary/stable-hash-for-trait-object-type.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate for regression test of https://github.com/rust-lang/rust/issues/34796 #![crate_type = "lib"] pub trait Future { type Item; diff --git a/tests/ui/issues/auxiliary/issue-25467.rs b/tests/ui/cross-crate/auxiliary/trait-object-projection-bounds-with-interning-order.rs similarity index 76% rename from tests/ui/issues/auxiliary/issue-25467.rs rename to tests/ui/cross-crate/auxiliary/trait-object-projection-bounds-with-interning-order.rs index 16c2869dc75cc..eb58bb5d29d06 100644 --- a/tests/ui/issues/auxiliary/issue-25467.rs +++ b/tests/ui/cross-crate/auxiliary/trait-object-projection-bounds-with-interning-order.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/25467 #![crate_type="lib"] pub trait Trait { diff --git a/tests/ui/issues/auxiliary/issue-2414-a.rs b/tests/ui/cross-crate/auxiliary/transitive-crate-dependency-with-trait-impl-a.rs similarity index 62% rename from tests/ui/issues/auxiliary/issue-2414-a.rs rename to tests/ui/cross-crate/auxiliary/transitive-crate-dependency-with-trait-impl-a.rs index b90ab32ddc4ad..58d79571f8d97 100644 --- a/tests/ui/issues/auxiliary/issue-2414-a.rs +++ b/tests/ui/cross-crate/auxiliary/transitive-crate-dependency-with-trait-impl-a.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/2414 #![crate_name="a"] #![crate_type = "lib"] diff --git a/tests/ui/cross-crate/auxiliary/transitive-crate-dependency-with-trait-impl-b.rs b/tests/ui/cross-crate/auxiliary/transitive-crate-dependency-with-trait-impl-b.rs new file mode 100644 index 0000000000000..eddb36bc4d0fa --- /dev/null +++ b/tests/ui/cross-crate/auxiliary/transitive-crate-dependency-with-trait-impl-b.rs @@ -0,0 +1,5 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/2414 +#![crate_name="b"] +#![crate_type = "lib"] + +extern crate a; diff --git a/tests/ui/issues/auxiliary/issue-30123-aux.rs b/tests/ui/cross-crate/auxiliary/type-default-applied-in-cross-crate-method-lookup.rs similarity index 85% rename from tests/ui/issues/auxiliary/issue-30123-aux.rs rename to tests/ui/cross-crate/auxiliary/type-default-applied-in-cross-crate-method-lookup.rs index 07c743eb2aa34..68b9f6843ddbd 100644 --- a/tests/ui/issues/auxiliary/issue-30123-aux.rs +++ b/tests/ui/cross-crate/auxiliary/type-default-applied-in-cross-crate-method-lookup.rs @@ -1,3 +1,4 @@ +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/30123 use std::marker::PhantomData; pub struct Directed; diff --git a/tests/ui/cross-crate/const-fn-evaluated-cross-crate.rs b/tests/ui/cross-crate/const-fn-evaluated-cross-crate.rs new file mode 100644 index 0000000000000..cf0843f01ce8a --- /dev/null +++ b/tests/ui/cross-crate/const-fn-evaluated-cross-crate.rs @@ -0,0 +1,12 @@ +//@ run-pass +//@ aux-build:const-fn-evaluated-cross-crate.rs +//! Regression test for https://github.com/rust-lang/rust/issues/36954 +//! Cross crate const fn evaluation failed because the compiler's +//! internal argument lookup table used crate local ids that didn't +//! exist when evaluating a const fn from another crate. + +extern crate const_fn_evaluated_cross_crate as lib; + +fn main() { + let _ = lib::FOO; +} diff --git a/tests/ui/cross-crate/construct-extern-struct-with-destructor.rs b/tests/ui/cross-crate/construct-extern-struct-with-destructor.rs new file mode 100644 index 0000000000000..d916305bbc764 --- /dev/null +++ b/tests/ui/cross-crate/construct-extern-struct-with-destructor.rs @@ -0,0 +1,14 @@ +//@ run-pass +//@ aux-build:construct-extern-struct-with-destructor.rs + +//! Regression test for https://github.com/rust-lang/rust/issues/3012 +//! Guarantees that you can construct cross crate structs. + +extern crate construct_extern_struct_with_destructor as socketlib; + +use socketlib::socket; + +pub fn main() { + let fd: u32 = 1 as u32; + let _sock: Box<_> = Box::new(socket::socket_handle(fd)); +} diff --git a/tests/ui/cross-crate/cross-crate-static-reference-and-field-access.rs b/tests/ui/cross-crate/cross-crate-static-reference-and-field-access.rs new file mode 100644 index 0000000000000..25e52c153ba0e --- /dev/null +++ b/tests/ui/cross-crate/cross-crate-static-reference-and-field-access.rs @@ -0,0 +1,14 @@ +//@ aux-build:cross-crate-static-reference-and-field-access.rs +//@ check-pass + +//! Regression test for https://github.com/rust-lang/rust/issues/29265 +//! Exposed an bug where referencing a static variable from another crate +//! was causing an error. + +extern crate cross_crate_static_reference_and_field_access as lib; + +static _UNUSED: &'static lib::SomeType = &lib::SOME_VALUE; + +fn main() { + vec![0u8; lib::SOME_VALUE.some_member]; +} diff --git a/tests/ui/issues/issue-3979-xcrate.rs b/tests/ui/cross-crate/cross-crate-trait-inheritance-on-default-method.rs similarity index 55% rename from tests/ui/issues/issue-3979-xcrate.rs rename to tests/ui/cross-crate/cross-crate-trait-inheritance-on-default-method.rs index 7660405929bfb..3ff481d2c17e9 100644 --- a/tests/ui/issues/issue-3979-xcrate.rs +++ b/tests/ui/cross-crate/cross-crate-trait-inheritance-on-default-method.rs @@ -1,8 +1,10 @@ //@ run-pass #![allow(dead_code)] -//@ aux-build:issue-3979-traits.rs +//@ aux-build:cross-crate-trait-inheritance-on-default-method.rs +//! Regression test for https://github.com/rust-lang/rust/issues/3979 +//! Exposed a bug where external traits on a default method were failing to typecheck. -extern crate issue_3979_traits; +extern crate cross_crate_trait_inheritance_on_default_method as issue_3979_traits; use issue_3979_traits::{Positioned, Movable}; struct Point { x: isize, y: isize } diff --git a/tests/ui/cross-crate/cross-crate-type-alias-with-nested-destructors.rs b/tests/ui/cross-crate/cross-crate-type-alias-with-nested-destructors.rs new file mode 100644 index 0000000000000..c12dc04f5ab4a --- /dev/null +++ b/tests/ui/cross-crate/cross-crate-type-alias-with-nested-destructors.rs @@ -0,0 +1,11 @@ +//@ run-pass +//@ aux-build:cross-crate-type-alias-with-nested-destructors.rs + +//! Regression test for https://github.com/rust-lang/rust/issues/2526 + +#![allow(unused_imports)] + +extern crate cross_crate_type_alias_with_nested_destructors; +use cross_crate_type_alias_with_nested_destructors::*; + +pub fn main() {} diff --git a/tests/ui/issues/issue-38226.rs b/tests/ui/cross-crate/default-trait-method-reachable-through-trait-object.rs similarity index 71% rename from tests/ui/issues/issue-38226.rs rename to tests/ui/cross-crate/default-trait-method-reachable-through-trait-object.rs index d8bd9d64a7c60..a7683252757e8 100644 --- a/tests/ui/issues/issue-38226.rs +++ b/tests/ui/cross-crate/default-trait-method-reachable-through-trait-object.rs @@ -2,13 +2,13 @@ // This test makes sure that we don't run into a linker error because of the // middle::reachable pass missing trait methods with default impls. -//@ aux-build:issue-38226-aux.rs +//@ aux-build:default-trait-method-reachable-through-trait-object.rs // Need -Cno-prepopulate-passes to really disable inlining, otherwise the faulty // code gets optimized out: //@ compile-flags: -Cno-prepopulate-passes -Cpasses=name-anon-globals -extern crate issue_38226_aux; +extern crate default_trait_method_reachable_through_trait_object as issue_38226_aux; fn main() { issue_38226_aux::foo::<()>(); diff --git a/tests/ui/issues/issue-41053.rs b/tests/ui/cross-crate/extern-crate-and-impl-inside-method-body.rs similarity index 51% rename from tests/ui/issues/issue-41053.rs rename to tests/ui/cross-crate/extern-crate-and-impl-inside-method-body.rs index 42b0b008ce9b5..15ce563d575d9 100644 --- a/tests/ui/issues/issue-41053.rs +++ b/tests/ui/cross-crate/extern-crate-and-impl-inside-method-body.rs @@ -1,5 +1,10 @@ //@ run-pass -//@ aux-build:issue-41053.rs +//@ aux-build:extern-crate-and-impl-inside-method-body.rs + +//! Regression test for https://github.com/rust-lang/rust/issues/41053 +//! An extern crate declaration and trait impl referencing that crate +//! inside an impl method body triggered a borrow conflict in the +//! compiler's visible_parent_map. #![allow(non_local_definitions)] @@ -10,7 +15,7 @@ pub struct Foo; impl Iterator for Foo { type Item = Box; fn next(&mut self) -> Option> { - extern crate issue_41053; + extern crate extern_crate_and_impl_inside_method_body as issue_41053; impl crate::Trait for issue_41053::Test { fn foo(&self) {} } diff --git a/tests/ui/cross-crate/extern-generic-tuple-struct-construction.rs b/tests/ui/cross-crate/extern-generic-tuple-struct-construction.rs new file mode 100644 index 0000000000000..98d1fec370da9 --- /dev/null +++ b/tests/ui/cross-crate/extern-generic-tuple-struct-construction.rs @@ -0,0 +1,6 @@ +//@ run-pass +//@ aux-build:extern-generic-tuple-struct-construction.rs +//! Regression test for https://github.com/rust-lang/rust/issues/4545 + +extern crate extern_generic_tuple_struct_construction as somelib; +pub fn main() { somelib::mk::(); } diff --git a/tests/ui/cross-crate/extern-repr-enum-with-discriminant-cast.rs b/tests/ui/cross-crate/extern-repr-enum-with-discriminant-cast.rs new file mode 100644 index 0000000000000..96f345d002d86 --- /dev/null +++ b/tests/ui/cross-crate/extern-repr-enum-with-discriminant-cast.rs @@ -0,0 +1,15 @@ +//@ run-pass +#![allow(dead_code)] +//@ aux-build:extern-repr-enum-with-discriminant-cast.rs +//! Regression test for https://github.com/rust-lang/rust/issues/42007 +//! This test exposes a bug that happens because the Session LintStore is emptied when linting +//! The LintStore is emptied because the checker wants ownership as it wants to +//! mutate the pass objects and lint levels. +//! The fix was not taking ownership of the entire store just the lint levels and pass objects. +extern crate extern_repr_enum_with_discriminant_cast as issue_42007_s; + +enum I { + E(issue_42007_s::E), +} + +fn main() {} diff --git a/tests/ui/cross-crate/extern-trait-bound-with-array-associated-type.rs b/tests/ui/cross-crate/extern-trait-bound-with-array-associated-type.rs new file mode 100644 index 0000000000000..a0b5d0e876963 --- /dev/null +++ b/tests/ui/cross-crate/extern-trait-bound-with-array-associated-type.rs @@ -0,0 +1,15 @@ +//@ run-pass +#![allow(dead_code)] +//@ aux-build:extern-trait-bound-with-array-associated-type.rs +//! Regression test for https://github.com/rust-lang/rust/issues/48984 +//! This test exposes an error that occurs when a base trait has at +//! least one associated type, and the extending trait specifies the +//! associated type as an array of some kind. In order to trigger the +//! error, the extending trait must be defined in an external crate, and +//! used to constrain a generic type parameter. +extern crate extern_trait_bound_with_array_associated_type as issue48984aux; +use issue48984aux::Bar; + +fn do_thing() { } + +fn main() { } diff --git a/tests/ui/cross-crate/fn-declared-inside-closure-body-cross-crate.rs b/tests/ui/cross-crate/fn-declared-inside-closure-body-cross-crate.rs new file mode 100644 index 0000000000000..9d47358777c53 --- /dev/null +++ b/tests/ui/cross-crate/fn-declared-inside-closure-body-cross-crate.rs @@ -0,0 +1,13 @@ +//@ run-pass +//@ aux-build:fn-declared-inside-closure-body-cross-crate.rs + +//! Regression test for https://github.com/rust-lang/rust/issues/2723 + +extern crate fn_declared_inside_closure_body_cross_crate; +use fn_declared_inside_closure_body_cross_crate::f; + +pub fn main() { + unsafe { + f(vec![2]); + } +} diff --git a/tests/ui/cross-crate/fn-local-impl-returned-as-trait-object.rs b/tests/ui/cross-crate/fn-local-impl-returned-as-trait-object.rs new file mode 100644 index 0000000000000..0fc404784e22b --- /dev/null +++ b/tests/ui/cross-crate/fn-local-impl-returned-as-trait-object.rs @@ -0,0 +1,12 @@ +//@ run-pass +//@ aux-build:fn-local-impl-returned-as-trait-object.rs +//! Regression test for https://github.com/rust-lang/rust/issues/2380 +//! This test exposes a bug where a function that defines a trait impl inside its body +//! and returns it as a trait object failed because the reachability pass skipped nested +//! items in function bodies. + +extern crate a; + +pub fn main() { + a::f::<()>(); +} diff --git a/tests/ui/cross-crate/generic-fn-with-supertrait-bound-cross-crate.rs b/tests/ui/cross-crate/generic-fn-with-supertrait-bound-cross-crate.rs new file mode 100644 index 0000000000000..bce55b2140068 --- /dev/null +++ b/tests/ui/cross-crate/generic-fn-with-supertrait-bound-cross-crate.rs @@ -0,0 +1,11 @@ +//@ run-pass +#![allow(dead_code)] +//@ aux-build:generic-fn-with-supertrait-bound-cross-crate.rs + +//! Regression test for https://github.com/rust-lang/rust/issues/4208 +extern crate generic_fn_with_supertrait_bound_cross_crate as numeric; +use numeric::{sin, Angle}; + +fn foo>(theta: A) -> T { sin(&theta) } + +pub fn main() {} diff --git a/tests/ui/cross-crate/graceful-error-for-mistyped-assoc-const.rs b/tests/ui/cross-crate/graceful-error-for-mistyped-assoc-const.rs new file mode 100644 index 0000000000000..238fb6bf0e738 --- /dev/null +++ b/tests/ui/cross-crate/graceful-error-for-mistyped-assoc-const.rs @@ -0,0 +1,13 @@ +//@ aux-build:graceful-error-for-mistyped-assoc-const.rs +//! Regression test for https://github.com/rust-lang/rust/issues/41549 +//! Mismatched types on exernal associated constants used to ice, +//! this test confirms that it errors correctly. +extern crate graceful_error_for_mistyped_assoc_const as issue_41549; + +struct S; + +impl issue_41549::Trait for S { + const CONST: () = (); //~ ERROR incompatible type for trait +} + +fn main() {} diff --git a/tests/ui/issues/issue-41549.stderr b/tests/ui/cross-crate/graceful-error-for-mistyped-assoc-const.stderr similarity index 81% rename from tests/ui/issues/issue-41549.stderr rename to tests/ui/cross-crate/graceful-error-for-mistyped-assoc-const.stderr index 55be59684b55d..18b06462de7b6 100644 --- a/tests/ui/issues/issue-41549.stderr +++ b/tests/ui/cross-crate/graceful-error-for-mistyped-assoc-const.stderr @@ -1,5 +1,5 @@ error[E0326]: implemented const `CONST` has an incompatible type for trait - --> $DIR/issue-41549.rs:9:18 + --> $DIR/graceful-error-for-mistyped-assoc-const.rs:10:18 | LL | const CONST: () = (); | ^^ expected `u32`, found `()` diff --git a/tests/ui/cross-crate/impl-extern-trait-with-associated-type.rs b/tests/ui/cross-crate/impl-extern-trait-with-associated-type.rs new file mode 100644 index 0000000000000..c6905e9002b29 --- /dev/null +++ b/tests/ui/cross-crate/impl-extern-trait-with-associated-type.rs @@ -0,0 +1,16 @@ +//@ run-pass +#![allow(dead_code)] +//@ aux-build:impl-extern-trait-with-associated-type.rs +//! Regression test for https://github.com/rust-lang/rust/issues/20389 +//! This test confirms that code implementing a trait with an associated type from an external crate +//! runs. + +extern crate impl_extern_trait_with_associated_type; + +struct Foo; + +impl impl_extern_trait_with_associated_type::T for Foo { + type C = (); +} + +fn main() {} diff --git a/tests/ui/cross-crate/imported-struct-not-confused-with-variant.rs b/tests/ui/cross-crate/imported-struct-not-confused-with-variant.rs new file mode 100644 index 0000000000000..458fc32be0cea --- /dev/null +++ b/tests/ui/cross-crate/imported-struct-not-confused-with-variant.rs @@ -0,0 +1,12 @@ +//@ run-pass +//@ aux-build:imported-struct-not-confused-with-variant.rs + +//! Regression test for https://github.com/rust-lang/rust/issues/19293 +//! This test ensures that cross crate variants are properly namespaced under their enum or struct. + +extern crate imported_struct_not_confused_with_variant; +use imported_struct_not_confused_with_variant::{Foo, MyEnum}; + +fn main() { + MyEnum::Foo(Foo(5)); +} diff --git a/tests/ui/cross-crate/link-extern-crate-with-drop-type.rs b/tests/ui/cross-crate/link-extern-crate-with-drop-type.rs new file mode 100644 index 0000000000000..623a644dcbf9f --- /dev/null +++ b/tests/ui/cross-crate/link-extern-crate-with-drop-type.rs @@ -0,0 +1,11 @@ +//@ run-pass +//@ aux-build:link-extern-crate-with-drop-type.rs +//! Regression test for https://github.com/rust-lang/rust/issues/2170 +//! This test just verifies that linking against an external crate works without +//! a metadata failure. Apparently, having a Drop that calls another function is the trigger. + +extern crate link_extern_crate_with_drop_type; + +pub fn main() { + // let _ = issue_2170_lib::rsrc(2); +} diff --git a/tests/ui/cross-crate/macro-generated-module-path-resolution.rs b/tests/ui/cross-crate/macro-generated-module-path-resolution.rs new file mode 100644 index 0000000000000..f785c24a83623 --- /dev/null +++ b/tests/ui/cross-crate/macro-generated-module-path-resolution.rs @@ -0,0 +1,18 @@ +//@ run-pass +//@ aux-build:macro-generated-module-path-resolution.rs +//! Regression test for https://github.com/rust-lang/rust/issues/38190 +//! Non inline modules parsed as macro item fragments used the wrong +//! directory for file resolution, because the fragment parser didn't +//! inherit the correct directory from the macro invocation context. + +#[macro_use] +extern crate macro_generated_module_path_resolution as aux; + +mod auxiliary { + m!([ + #[path = "macro-generated-module-path-resolution"] + mod aux; + ]); +} + +fn main() {} diff --git a/tests/ui/cross-crate/method-call-on-extern-fn-return-value.rs b/tests/ui/cross-crate/method-call-on-extern-fn-return-value.rs new file mode 100644 index 0000000000000..26a24aeb8ca99 --- /dev/null +++ b/tests/ui/cross-crate/method-call-on-extern-fn-return-value.rs @@ -0,0 +1,18 @@ +//@ edition:2018 +//@ aux-build:method-call-on-extern-fn-return-value.rs +//@ check-pass +//! Regression test for https://github.com/rust-lang/rust/issues/51798 +//! Calling a method on a value returned from an external crate function +//! caused the privacy checker to panic when looking up the method's +//! type dependent definition. Requires 2018 edition. + +extern crate method_call_on_extern_fn_return_value as issue_51798; + +mod server { + fn f() { + let mut v = issue_51798::vec(); + v.clear(); + } +} + +fn main() {} diff --git a/tests/ui/issues/issue-2631-b.rs b/tests/ui/cross-crate/monomorphize-index-op-cross-crate.rs similarity index 72% rename from tests/ui/issues/issue-2631-b.rs rename to tests/ui/cross-crate/monomorphize-index-op-cross-crate.rs index fb2ecd74a6595..b915bbebf785b 100644 --- a/tests/ui/issues/issue-2631-b.rs +++ b/tests/ui/cross-crate/monomorphize-index-op-cross-crate.rs @@ -1,6 +1,8 @@ //@ run-pass -//@ aux-build:issue-2631-a.rs +//@ aux-build:monomorphize-index-op-cross-crate.rs + +//! Regression test for https://github.com/rust-lang/rust/issues/2631 extern crate req; diff --git a/tests/ui/cross-crate/mut-ref-write-visible-after-unwind.rs b/tests/ui/cross-crate/mut-ref-write-visible-after-unwind.rs new file mode 100644 index 0000000000000..2e3073286f0f6 --- /dev/null +++ b/tests/ui/cross-crate/mut-ref-write-visible-after-unwind.rs @@ -0,0 +1,19 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/29485 +//! Exposed an LLVM bug that caused rustc to panic. +//@ run-pass +//@ aux-build:mut-ref-write-visible-after-unwind.rs +//@ needs-unwind +//@ needs-threads +//@ ignore-backends: gcc + +extern crate mut_ref_write_visible_after_unwind as lib; + +fn main() { + let _ = std::thread::spawn(move || { + lib::f(&mut lib::X(0), g); + }).join(); +} + +fn g() { + panic!(); +} diff --git a/tests/ui/cross-crate/nested-struct-in-polymorphic-impl-method.rs b/tests/ui/cross-crate/nested-struct-in-polymorphic-impl-method.rs new file mode 100644 index 0000000000000..12d09cdc84440 --- /dev/null +++ b/tests/ui/cross-crate/nested-struct-in-polymorphic-impl-method.rs @@ -0,0 +1,8 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/3136 +//@ run-pass +//@ aux-build:nested-struct-in-polymorphic-impl-method.rs + + +extern crate nested_struct_in_polymorphic_impl_method; + +pub fn main() {} diff --git a/tests/ui/cross-crate/no-duplicate-symbols-with-codegen-units.rs b/tests/ui/cross-crate/no-duplicate-symbols-with-codegen-units.rs new file mode 100644 index 0000000000000..f54c89a9162c3 --- /dev/null +++ b/tests/ui/cross-crate/no-duplicate-symbols-with-codegen-units.rs @@ -0,0 +1,14 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/32518 +//@ run-pass +//@ no-prefer-dynamic +//@ aux-build:no-duplicate-symbols-with-codegen-units-cgu-test.rs +//@ aux-build:no-duplicate-symbols-with-codegen-units-cgu-test-a.rs +//@ aux-build:no-duplicate-symbols-with-codegen-units-cgu-test-b.rs + +extern crate no_duplicate_symbols_with_codegen_units_cgu_test_a as cgu_test_a; +extern crate no_duplicate_symbols_with_codegen_units_cgu_test_b as cgu_test_b; + +fn main() { + cgu_test_a::a::a(); + cgu_test_b::a::a(); +} diff --git a/tests/ui/cross-crate/optimized-closure-with-debug-info-cross-crate.rs b/tests/ui/cross-crate/optimized-closure-with-debug-info-cross-crate.rs new file mode 100644 index 0000000000000..f0b34bdd86f0a --- /dev/null +++ b/tests/ui/cross-crate/optimized-closure-with-debug-info-cross-crate.rs @@ -0,0 +1,11 @@ +//@ run-pass +//@ aux-build:optimized-closure-with-debug-info-cross-crate-1.rs +//@ aux-build:optimized-closure-with-debug-info-cross-crate-2.rs + +//! Regression test for https://github.com/rust-lang/rust/issues/31702 +// this test is actually entirely in the linked library crates + +extern crate optimized_closure_with_debug_info_cross_crate_1; +extern crate optimized_closure_with_debug_info_cross_crate_2; + +fn main() {} diff --git a/tests/ui/issues/issue-34796.rs b/tests/ui/cross-crate/stable-hash-for-trait-object-type.rs similarity index 79% rename from tests/ui/issues/issue-34796.rs rename to tests/ui/cross-crate/stable-hash-for-trait-object-type.rs index 1a417b3483068..725469e4e4f91 100644 --- a/tests/ui/issues/issue-34796.rs +++ b/tests/ui/cross-crate/stable-hash-for-trait-object-type.rs @@ -1,5 +1,6 @@ //@ run-pass #![allow(dead_code)] +// Regression test for https://github.com/rust-lang/rust/issues/34796 // This test case exposes conditions where the encoding of a trait object type // with projection predicates would differ between this crate and the upstream // crate, because the predicates were encoded in different order within each @@ -8,8 +9,8 @@ // the symbol name. // The fix was to make the order in which predicates get encoded stable. -//@ aux-build:issue-34796-aux.rs -extern crate issue_34796_aux; +//@ aux-build:stable-hash-for-trait-object-type.rs +extern crate stable_hash_for_trait_object_type as issue_34796_aux; fn mk() -> T { loop {} } diff --git a/tests/ui/cross-crate/trait-object-projection-bounds-with-interning-order.rs b/tests/ui/cross-crate/trait-object-projection-bounds-with-interning-order.rs new file mode 100644 index 0000000000000..44aff69126c2a --- /dev/null +++ b/tests/ui/cross-crate/trait-object-projection-bounds-with-interning-order.rs @@ -0,0 +1,14 @@ +//@ run-pass +#![allow(unused_variables)] +//@ aux-build:trait-object-projection-bounds-with-interning-order.rs + +//! Regression test for https://github.com/rust-lang/rust/issues/25467 + +pub type Issue25467BarT = (); +pub type Issue25467FooT = (); + +extern crate trait_object_projection_bounds_with_interning_order as aux; + +fn main() { + let o: aux::Object = None; +} diff --git a/tests/ui/cross-crate/transitive-crate-dependency-with-trait-impl.rs b/tests/ui/cross-crate/transitive-crate-dependency-with-trait-impl.rs new file mode 100644 index 0000000000000..8d3b15cfd86bb --- /dev/null +++ b/tests/ui/cross-crate/transitive-crate-dependency-with-trait-impl.rs @@ -0,0 +1,9 @@ +//@ run-pass +//@ aux-build:transitive-crate-dependency-with-trait-impl-a.rs +//@ aux-build:transitive-crate-dependency-with-trait-impl-b.rs + +//! Regression test for https://github.com/rust-lang/rust/issues/2414 + +extern crate b; + +pub fn main() {} diff --git a/tests/ui/cross-crate/type-default-applied-in-cross-crate-method-lookup.rs b/tests/ui/cross-crate/type-default-applied-in-cross-crate-method-lookup.rs new file mode 100644 index 0000000000000..b0b6f05610d50 --- /dev/null +++ b/tests/ui/cross-crate/type-default-applied-in-cross-crate-method-lookup.rs @@ -0,0 +1,10 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/30123 +//@ aux-build:type-default-applied-in-cross-crate-method-lookup.rs + +extern crate type_default_applied_in_cross_crate_method_lookup; +use type_default_applied_in_cross_crate_method_lookup::*; + +fn main() { + let ug = Graph::::new_undirected(); + //~^ ERROR no associated function or constant named `new_undirected` found +} diff --git a/tests/ui/cross-crate/type-default-applied-in-cross-crate-method-lookup.stderr b/tests/ui/cross-crate/type-default-applied-in-cross-crate-method-lookup.stderr new file mode 100644 index 0000000000000..c5c5f206fe071 --- /dev/null +++ b/tests/ui/cross-crate/type-default-applied-in-cross-crate-method-lookup.stderr @@ -0,0 +1,16 @@ +error[E0599]: no associated function or constant named `new_undirected` found for struct `type_default_applied_in_cross_crate_method_lookup::Graph` in the current scope + --> $DIR/type-default-applied-in-cross-crate-method-lookup.rs:8:33 + | +LL | let ug = Graph::::new_undirected(); + | ^^^^^^^^^^^^^^ associated function or constant not found in `type_default_applied_in_cross_crate_method_lookup::Graph` + | +note: if you're trying to build a new `type_default_applied_in_cross_crate_method_lookup::Graph`, consider using `type_default_applied_in_cross_crate_method_lookup::Graph::::new` which returns `type_default_applied_in_cross_crate_method_lookup::Graph<_, _>` + --> $DIR/auxiliary/type-default-applied-in-cross-crate-method-lookup.rs:15:5 + | +LL | pub fn new() -> Self { + | ^^^^^^^^^^^^^^^^^^^^ + = note: the associated function or constant was found for `type_default_applied_in_cross_crate_method_lookup::Graph` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/issues/issue-19037.rs b/tests/ui/derives/clone-copy/clone-ref-to-dst.rs similarity index 78% rename from tests/ui/issues/issue-19037.rs rename to tests/ui/derives/clone-copy/clone-ref-to-dst.rs index 7f88a89a65702..3eb8bba709329 100644 --- a/tests/ui/issues/issue-19037.rs +++ b/tests/ui/derives/clone-copy/clone-ref-to-dst.rs @@ -1,3 +1,5 @@ +//! Regression test for . + //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/issues/issue-19380.rs b/tests/ui/dyn-compatibility/dyn-incompat-const-slice.rs similarity index 76% rename from tests/ui/issues/issue-19380.rs rename to tests/ui/dyn-compatibility/dyn-incompat-const-slice.rs index fce737cba18d2..d4cb2817d663b 100644 --- a/tests/ui/issues/issue-19380.rs +++ b/tests/ui/dyn-compatibility/dyn-incompat-const-slice.rs @@ -1,3 +1,5 @@ +//! Regression test for . + trait Qiz { fn qiz(); } diff --git a/tests/ui/issues/issue-19380.stderr b/tests/ui/dyn-compatibility/dyn-incompat-const-slice.stderr similarity index 91% rename from tests/ui/issues/issue-19380.stderr rename to tests/ui/dyn-compatibility/dyn-incompat-const-slice.stderr index 4c41d41ae3792..46ed6a48a77fa 100644 --- a/tests/ui/issues/issue-19380.stderr +++ b/tests/ui/dyn-compatibility/dyn-incompat-const-slice.stderr @@ -1,12 +1,12 @@ error[E0038]: the trait `Qiz` is not dyn compatible - --> $DIR/issue-19380.rs:11:29 + --> $DIR/dyn-incompat-const-slice.rs:13:29 | LL | foos: &'static [&'static (dyn Qiz + 'static)] | ^^^^^^^^^^^^^^^^^ `Qiz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/issue-19380.rs:2:6 + --> $DIR/dyn-incompat-const-slice.rs:4:6 | LL | trait Qiz { | --- this trait is not dyn compatible... @@ -23,14 +23,14 @@ LL | fn qiz() where Self: Sized; | +++++++++++++++++ error[E0038]: the trait `Qiz` is not dyn compatible - --> $DIR/issue-19380.rs:16:31 + --> $DIR/dyn-incompat-const-slice.rs:18:31 | LL | const BAR : Bar = Bar { foos: &[&FOO]}; | ^^^^^^^ `Qiz` is not dyn compatible | note: for a trait to be dyn compatible it needs to allow building a vtable for more information, visit - --> $DIR/issue-19380.rs:2:6 + --> $DIR/dyn-incompat-const-slice.rs:4:6 | LL | trait Qiz { | --- this trait is not dyn compatible... diff --git a/tests/ui/issues/issue-19982.rs b/tests/ui/fn_traits/manual-fn-impl-lifetime-elision.rs similarity index 84% rename from tests/ui/issues/issue-19982.rs rename to tests/ui/fn_traits/manual-fn-impl-lifetime-elision.rs index 4bace6d734ff1..550f917e72891 100644 --- a/tests/ui/issues/issue-19982.rs +++ b/tests/ui/fn_traits/manual-fn-impl-lifetime-elision.rs @@ -1,3 +1,5 @@ +//! Regression test for . + //@ check-pass #![feature(fn_traits, unboxed_closures)] diff --git a/tests/ui/generic-associated-types/equality-bound.rs b/tests/ui/generic-associated-types/equality-bound.rs deleted file mode 100644 index c136a6d4bdf2e..0000000000000 --- a/tests/ui/generic-associated-types/equality-bound.rs +++ /dev/null @@ -1,82 +0,0 @@ -fn sum>(i: I) -> i32 where I::Item = i32 { -//~^ ERROR equality constraints are not yet supported in `where` clauses - panic!() -} -fn sum2(i: I) -> i32 where I::Item = i32 { -//~^ ERROR equality constraints are not yet supported in `where` clauses - panic!() -} -fn sum3(i: J) -> i32 where I::Item = i32 { -//~^ ERROR equality constraints are not yet supported in `where` clauses -//~| ERROR cannot find type `I` - panic!() -} - -use std::iter::FromIterator; - -struct X {} - -impl FromIterator for X { - fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, - //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope - { - todo!() - } -} - -struct Y {} - -impl FromIterator for Y { - fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, - //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope - { - todo!() - } -} - -struct Z {} - -impl FromIterator for Z { - fn from_iter(_: T) -> Self where IntoIterator::Item = A, - //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope - { - todo!() - } -} - -struct K {} - -impl FromIterator for K { - fn from_iter(_: T) -> Self where T::Item = A, - //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope - { - todo!() - } -} - -struct L {} - -impl FromIterator for L { - fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, - //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope - { - todo!() - } -} - -struct M {} - -impl FromIterator for M { - fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, - //~^ ERROR equality constraints are not yet supported in `where` clauses - //~| ERROR cannot find type `A` in this scope - { - todo!() - } -} -fn main() {} diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr deleted file mode 100644 index 0ceb5e329ab3a..0000000000000 --- a/tests/ui/generic-associated-types/equality-bound.stderr +++ /dev/null @@ -1,218 +0,0 @@ -error: equality constraints are not yet supported in `where` clauses - --> $DIR/equality-bound.rs:1:51 - | -LL | fn sum>(i: I) -> i32 where I::Item = i32 { - | ^^^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information -help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax - | -LL - fn sum>(i: I) -> i32 where I::Item = i32 { -LL + fn sum>(i: I) -> i32 { - | - -error: equality constraints are not yet supported in `where` clauses - --> $DIR/equality-bound.rs:5:41 - | -LL | fn sum2(i: I) -> i32 where I::Item = i32 { - | ^^^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information -help: if `Iterator::Item` is an associated type you're trying to set, use the associated type binding syntax - | -LL - fn sum2(i: I) -> i32 where I::Item = i32 { -LL + fn sum2>(i: I) -> i32 { - | - -error: equality constraints are not yet supported in `where` clauses - --> $DIR/equality-bound.rs:9:41 - | -LL | fn sum3(i: J) -> i32 where I::Item = i32 { - | ^^^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information - -error: equality constraints are not yet supported in `where` clauses - --> $DIR/equality-bound.rs:20:58 - | -LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, - | ^^^^^^^^^^^^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax - | -LL - fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, -LL + fn from_iter(_: T) -> Self where T: IntoIterator, - | - -error: equality constraints are not yet supported in `where` clauses - --> $DIR/equality-bound.rs:31:58 - | -LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, - | ^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax - | -LL - fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, -LL + fn from_iter(_: T) -> Self where T: IntoIterator, - | - -error: equality constraints are not yet supported in `where` clauses - --> $DIR/equality-bound.rs:42:55 - | -LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, - | ^^^^^^^^^^^^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax - | -LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, -LL + fn from_iter>(_: T) -> Self - | - -error: equality constraints are not yet supported in `where` clauses - --> $DIR/equality-bound.rs:53:55 - | -LL | fn from_iter(_: T) -> Self where T::Item = A, - | ^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax - | -LL - fn from_iter(_: T) -> Self where T::Item = A, -LL + fn from_iter>(_: T) -> Self - | - -error: equality constraints are not yet supported in `where` clauses - --> $DIR/equality-bound.rs:64:41 - | -LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, - | ^^^^^^^^^^^^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax - | -LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, -LL + fn from_iter(_: T) -> Self where T: IntoIterator, - | - -error: equality constraints are not yet supported in `where` clauses - --> $DIR/equality-bound.rs:75:41 - | -LL | fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, - | ^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information -help: if `IntoIterator::Item` is an associated type you're trying to set, use the associated type binding syntax - | -LL - fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, -LL + fn from_iter(_: T) -> Self where T: IntoIterator, - | - -error[E0425]: cannot find type `A` in this scope - --> $DIR/equality-bound.rs:20:79 - | -LL | fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, - | ^ -... -LL | struct K {} - | -------- similarly named struct `K` defined here - | -help: a struct with a similar name exists - | -LL - fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = A, -LL + fn from_iter(_: T) -> Self where T: IntoIterator, IntoIterator::Item = K, - | - -error[E0425]: cannot find type `A` in this scope - --> $DIR/equality-bound.rs:31:68 - | -LL | fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, - | ^ -... -LL | struct K {} - | -------- similarly named struct `K` defined here - | -help: a struct with a similar name exists - | -LL - fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = A, -LL + fn from_iter(_: T) -> Self where T: IntoIterator, T::Item = K, - | - -error[E0425]: cannot find type `A` in this scope - --> $DIR/equality-bound.rs:42:76 - | -LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, - | ^ -... -LL | struct K {} - | -------- similarly named struct `K` defined here - | -help: a struct with a similar name exists - | -LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, -LL + fn from_iter(_: T) -> Self where IntoIterator::Item = K, - | - -error[E0425]: cannot find type `A` in this scope - --> $DIR/equality-bound.rs:53:65 - | -LL | struct K {} - | -------- similarly named struct `K` defined here -... -LL | fn from_iter(_: T) -> Self where T::Item = A, - | ^ - | -help: a struct with a similar name exists - | -LL - fn from_iter(_: T) -> Self where T::Item = A, -LL + fn from_iter(_: T) -> Self where T::Item = K, - | - -error[E0425]: cannot find type `A` in this scope - --> $DIR/equality-bound.rs:64:62 - | -LL | struct K {} - | -------- similarly named struct `K` defined here -... -LL | fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, - | ^ - | -help: a struct with a similar name exists - | -LL - fn from_iter(_: T) -> Self where IntoIterator::Item = A, T: IntoIterator, -LL + fn from_iter(_: T) -> Self where IntoIterator::Item = K, T: IntoIterator, - | - -error[E0425]: cannot find type `A` in this scope - --> $DIR/equality-bound.rs:75:51 - | -LL | struct K {} - | -------- similarly named struct `K` defined here -... -LL | fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, - | ^ - | -help: a struct with a similar name exists - | -LL - fn from_iter(_: T) -> Self where T::Item = A, T: IntoIterator, -LL + fn from_iter(_: T) -> Self where T::Item = K, T: IntoIterator, - | - -error[E0433]: cannot find type `I` in this scope - --> $DIR/equality-bound.rs:9:41 - | -LL | fn sum3(i: J) -> i32 where I::Item = i32 { - | ^ use of undeclared type `I` - | -help: a type parameter with a similar name exists - | -LL - fn sum3(i: J) -> i32 where I::Item = i32 { -LL + fn sum3(i: J) -> i32 where J::Item = i32 { - | - -error: aborting due to 16 previous errors - -Some errors have detailed explanations: E0425, E0433. -For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/generic-associated-types/missing-bounds.fixed b/tests/ui/generic-associated-types/missing-bounds.fixed index 15cdd44d7f1f9..7735031233340 100644 --- a/tests/ui/generic-associated-types/missing-bounds.fixed +++ b/tests/ui/generic-associated-types/missing-bounds.fixed @@ -36,12 +36,11 @@ impl> Add for D { struct E(B); -impl> Add for E where B: Add { - //~^ ERROR equality constraints are not yet supported in `where` clauses +impl Add for E where B: Add { type Output = Self; fn add(self, rhs: Self) -> Self { - Self(self.0 + rhs.0) //~ ERROR mismatched types + Self(self.0 + rhs.0) } } diff --git a/tests/ui/generic-associated-types/missing-bounds.rs b/tests/ui/generic-associated-types/missing-bounds.rs index dad111c8c15cf..0957674d83d2b 100644 --- a/tests/ui/generic-associated-types/missing-bounds.rs +++ b/tests/ui/generic-associated-types/missing-bounds.rs @@ -36,12 +36,11 @@ impl Add for D { struct E(B); -impl Add for E where ::Output = B { - //~^ ERROR equality constraints are not yet supported in `where` clauses +impl Add for E where B: Add { type Output = Self; fn add(self, rhs: Self) -> Self { - Self(self.0 + rhs.0) //~ ERROR mismatched types + Self(self.0 + rhs.0) } } diff --git a/tests/ui/generic-associated-types/missing-bounds.stderr b/tests/ui/generic-associated-types/missing-bounds.stderr index 97b88c26e3b38..b930cfb3f806b 100644 --- a/tests/ui/generic-associated-types/missing-bounds.stderr +++ b/tests/ui/generic-associated-types/missing-bounds.stderr @@ -1,16 +1,3 @@ -error: equality constraints are not yet supported in `where` clauses - --> $DIR/missing-bounds.rs:39:33 - | -LL | impl Add for E where ::Output = B { - | ^^^^^^^^^^^^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information -help: if `Output` is an associated type you're trying to set, use the associated type binding syntax - | -LL - impl Add for E where ::Output = B { -LL + impl Add for E where B: Add { - | - error[E0308]: mismatched types --> $DIR/missing-bounds.rs:13:11 | @@ -77,30 +64,7 @@ help: consider restricting type parameter `B` with trait `Add` LL | impl> Add for D { | +++++++++++++++++++++++++++ -error[E0308]: mismatched types - --> $DIR/missing-bounds.rs:44:14 - | -LL | impl Add for E where ::Output = B { - | - expected this type parameter -... -LL | Self(self.0 + rhs.0) - | ---- ^^^^^^^^^^^^^^ expected type parameter `B`, found associated type - | | - | arguments to this function are incorrect - | - = note: expected type parameter `B` - found associated type `::Output` -note: tuple struct defined here - --> $DIR/missing-bounds.rs:37:8 - | -LL | struct E(B); - | ^ -help: consider further restricting this bound - | -LL | impl> Add for E where ::Output = B { - | ++++++++++++ - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0308, E0369. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-19135.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-closure-lifetime-infer.rs similarity index 79% rename from tests/ui/issues/issue-19135.rs rename to tests/ui/higher-ranked/trait-bounds/hrtb-closure-lifetime-infer.rs index 42288511ab588..d4d81a31d4197 100644 --- a/tests/ui/issues/issue-19135.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-closure-lifetime-infer.rs @@ -1,3 +1,5 @@ +//! Regression test for . + //@ run-pass use std::marker::PhantomData; diff --git a/tests/ui/issues/issue-19098.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-unused-lifetime.rs similarity index 62% rename from tests/ui/issues/issue-19098.rs rename to tests/ui/higher-ranked/trait-bounds/hrtb-unused-lifetime.rs index 97e8ca17de1ec..576d59d401881 100644 --- a/tests/ui/issues/issue-19098.rs +++ b/tests/ui/higher-ranked/trait-bounds/hrtb-unused-lifetime.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Tests that we don't ICE from unused lifetime in HRTB. + //@ check-pass pub trait Handler { fn handle(&self, _: &mut String); diff --git a/tests/ui/imports/ambiguous-14.rs b/tests/ui/imports/ambiguous-14.rs index ba2d7dc4e0166..b7203a2cb6fb4 100644 --- a/tests/ui/imports/ambiguous-14.rs +++ b/tests/ui/imports/ambiguous-14.rs @@ -22,5 +22,4 @@ mod g { fn main() { g::foo(); //~^ ERROR `foo` is ambiguous - //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/imports/ambiguous-14.stderr b/tests/ui/imports/ambiguous-14.stderr index 2ca10d2d6a848..327dd075945a4 100644 --- a/tests/ui/imports/ambiguous-14.stderr +++ b/tests/ui/imports/ambiguous-14.stderr @@ -1,4 +1,4 @@ -error: `foo` is ambiguous +error[E0659]: `foo` is ambiguous --> $DIR/ambiguous-14.rs:23:8 | LL | g::foo(); @@ -6,44 +6,18 @@ LL | g::foo(); | = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/ambiguous-14.rs:18:13 + --> $DIR/ambiguous-14.rs:13:13 | LL | pub use a::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/ambiguous-14.rs:19:13 + --> $DIR/ambiguous-14.rs:14:13 | -LL | pub use f::*; +LL | pub use b::*; | ^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #114095 - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default error: aborting due to 1 previous error -Future incompatibility report: Future breakage diagnostic: -error: `foo` is ambiguous - --> $DIR/ambiguous-14.rs:23:8 - | -LL | g::foo(); - | ^^^ ambiguous name - | - = note: ambiguous because of multiple glob imports of a name in the same module -note: `foo` could refer to the function imported here - --> $DIR/ambiguous-14.rs:18:13 - | -LL | pub use a::*; - | ^^^^ - = help: consider adding an explicit import of `foo` to disambiguate -note: `foo` could also refer to the function imported here - --> $DIR/ambiguous-14.rs:19:13 - | -LL | pub use f::*; - | ^^^^ - = help: consider adding an explicit import of `foo` to disambiguate - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #114095 - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default - +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/ambiguous-9.rs b/tests/ui/imports/ambiguous-9.rs index 58796031bf18f..0e60a2929c024 100644 --- a/tests/ui/imports/ambiguous-9.rs +++ b/tests/ui/imports/ambiguous-9.rs @@ -4,16 +4,16 @@ pub mod dsl { mod range { pub fn date_range() {} } - pub use self::range::*; //~ WARNING ambiguous glob re-exports + pub use self::range::*; use super::prelude::*; } pub mod prelude { mod t { - pub fn date_range() {} + pub fn date_range() {} } - pub use self::t::*; //~ WARNING ambiguous glob re-exports - pub use super::dsl::*; + pub use self::t::*; + pub use super::dsl::*; //~ WARNING ambiguous glob re-exports } use dsl::*; @@ -22,5 +22,4 @@ use prelude::*; fn main() { date_range(); //~^ ERROR `date_range` is ambiguous - //~| ERROR `date_range` is ambiguous } diff --git a/tests/ui/imports/ambiguous-9.stderr b/tests/ui/imports/ambiguous-9.stderr index b6e4c30a8d410..0ffbeb7c89509 100644 --- a/tests/ui/imports/ambiguous-9.stderr +++ b/tests/ui/imports/ambiguous-9.stderr @@ -6,56 +6,28 @@ LL | date_range(); | = note: ambiguous because of multiple glob imports of a name in the same module note: `date_range` could refer to the function imported here - --> $DIR/ambiguous-9.rs:19:5 + --> $DIR/ambiguous-9.rs:16:13 | -LL | use dsl::*; - | ^^^^^^ - = help: consider adding an explicit import of `date_range` to disambiguate -note: `date_range` could also refer to the function imported here - --> $DIR/ambiguous-9.rs:20:5 - | -LL | use prelude::*; - | ^^^^^^^^^^ - = help: consider adding an explicit import of `date_range` to disambiguate - -error[E0659]: `date_range` is ambiguous - --> $DIR/ambiguous-9.rs:23:5 - | -LL | date_range(); - | ^^^^^^^^^^ ambiguous name - | - = note: ambiguous because of multiple glob imports of a name in the same module -note: `date_range` could refer to the function imported here - --> $DIR/ambiguous-9.rs:7:13 - | -LL | pub use self::range::*; - | ^^^^^^^^^^^^^^ +LL | pub use super::dsl::*; + | ^^^^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate note: `date_range` could also refer to the function imported here - --> $DIR/ambiguous-9.rs:8:9 + --> $DIR/ambiguous-9.rs:15:13 | -LL | use super::prelude::*; - | ^^^^^^^^^^^^^^^^^ +LL | pub use self::t::*; + | ^^^^^^^^^^ = help: consider adding an explicit import of `date_range` to disambiguate warning: ambiguous glob re-exports - --> $DIR/ambiguous-9.rs:7:13 - | -LL | pub use self::range::*; - | ^^^^^^^^^^^^^^ the name `date_range` in the value namespace is first re-exported here -LL | use super::prelude::*; - | ----------------- but the name `date_range` in the value namespace is also re-exported here - | - = note: `#[warn(ambiguous_glob_reexports)]` on by default - -warning: ambiguous glob re-exports - --> $DIR/ambiguous-9.rs:15:13 + --> $DIR/ambiguous-9.rs:16:13 | LL | pub use self::t::*; - | ^^^^^^^^^^ the name `date_range` in the value namespace is first re-exported here + | ---------- but the name `date_range` in the value namespace is also re-exported here LL | pub use super::dsl::*; - | ------------- but the name `date_range` in the value namespace is also re-exported here + | ^^^^^^^^^^^^^ the name `date_range` in the value namespace is first re-exported here + | + = note: `#[warn(ambiguous_glob_reexports)]` on by default -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/duplicate.rs b/tests/ui/imports/duplicate.rs index 0a652889ca8ad..be089dbf5a4af 100644 --- a/tests/ui/imports/duplicate.rs +++ b/tests/ui/imports/duplicate.rs @@ -35,7 +35,6 @@ fn main() { f::foo(); //~ ERROR `foo` is ambiguous g::foo(); //~^ ERROR `foo` is ambiguous - //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } mod ambiguous_module_errors { diff --git a/tests/ui/imports/duplicate.stderr b/tests/ui/imports/duplicate.stderr index f02d35b1d28ce..7bff44109e40b 100644 --- a/tests/ui/imports/duplicate.stderr +++ b/tests/ui/imports/duplicate.stderr @@ -9,20 +9,20 @@ LL | use crate::a::foo; = note: `foo` must be defined only once in the value namespace of this module error[E0659]: `foo` is ambiguous - --> $DIR/duplicate.rs:48:15 + --> $DIR/duplicate.rs:47:15 | LL | use self::foo::bar; | ^^^ ambiguous name | = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the module imported here - --> $DIR/duplicate.rs:45:9 + --> $DIR/duplicate.rs:44:9 | LL | use self::m1::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the module imported here - --> $DIR/duplicate.rs:46:9 + --> $DIR/duplicate.rs:45:9 | LL | use self::m2::*; | ^^^^^^^^^^^ @@ -49,26 +49,6 @@ LL | pub use crate::b::*; = help: consider adding an explicit import of `foo` to disambiguate error[E0659]: `foo` is ambiguous - --> $DIR/duplicate.rs:51:9 - | -LL | foo::bar(); - | ^^^ ambiguous name - | - = note: ambiguous because of multiple glob imports of a name in the same module -note: `foo` could refer to the module imported here - --> $DIR/duplicate.rs:45:9 - | -LL | use self::m1::*; - | ^^^^^^^^^^^ - = help: consider adding an explicit import of `foo` to disambiguate -note: `foo` could also refer to the module imported here - --> $DIR/duplicate.rs:46:9 - | -LL | use self::m2::*; - | ^^^^^^^^^^^ - = help: consider adding an explicit import of `foo` to disambiguate - -error: `foo` is ambiguous --> $DIR/duplicate.rs:36:8 | LL | g::foo(); @@ -76,46 +56,39 @@ LL | g::foo(); | = note: ambiguous because of multiple glob imports of a name in the same module note: `foo` could refer to the function imported here - --> $DIR/duplicate.rs:29:13 + --> $DIR/duplicate.rs:24:13 | LL | pub use crate::a::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate note: `foo` could also refer to the function imported here - --> $DIR/duplicate.rs:30:13 + --> $DIR/duplicate.rs:25:13 | -LL | pub use crate::f::*; +LL | pub use crate::b::*; | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #114095 - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default - -error: aborting due to 5 previous errors -Some errors have detailed explanations: E0252, E0659. -For more information about an error, try `rustc --explain E0252`. -Future incompatibility report: Future breakage diagnostic: -error: `foo` is ambiguous - --> $DIR/duplicate.rs:36:8 +error[E0659]: `foo` is ambiguous + --> $DIR/duplicate.rs:50:9 | -LL | g::foo(); - | ^^^ ambiguous name +LL | foo::bar(); + | ^^^ ambiguous name | = note: ambiguous because of multiple glob imports of a name in the same module -note: `foo` could refer to the function imported here - --> $DIR/duplicate.rs:29:13 +note: `foo` could refer to the module imported here + --> $DIR/duplicate.rs:44:9 | -LL | pub use crate::a::*; - | ^^^^^^^^^^^ +LL | use self::m1::*; + | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate -note: `foo` could also refer to the function imported here - --> $DIR/duplicate.rs:30:13 +note: `foo` could also refer to the module imported here + --> $DIR/duplicate.rs:45:9 | -LL | pub use crate::f::*; - | ^^^^^^^^^^^ +LL | use self::m2::*; + | ^^^^^^^^^^^ = help: consider adding an explicit import of `foo` to disambiguate - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #114095 - = note: `#[deny(ambiguous_glob_imports)]` (part of `#[deny(future_incompatible)]`) on by default +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0252, E0659. +For more information about an error, try `rustc --explain E0252`. diff --git a/tests/ui/imports/import-loop-2.rs b/tests/ui/imports/import-loop-2.rs index 42f9a07fff389..af5c6509d38b6 100644 --- a/tests/ui/imports/import-loop-2.rs +++ b/tests/ui/imports/import-loop-2.rs @@ -1,9 +1,9 @@ mod a { - pub use crate::b::x; + pub use crate::b::x; //~ ERROR unresolved import `crate::b::x` } mod b { - pub use crate::a::x; //~ ERROR unresolved import `crate::a::x` + pub use crate::a::x; fn main() { let y = x; } } diff --git a/tests/ui/imports/import-loop-2.stderr b/tests/ui/imports/import-loop-2.stderr index 2ef40c4e21829..dfa7cf35eaac2 100644 --- a/tests/ui/imports/import-loop-2.stderr +++ b/tests/ui/imports/import-loop-2.stderr @@ -1,8 +1,8 @@ -error[E0432]: unresolved import `crate::a::x` - --> $DIR/import-loop-2.rs:6:13 +error[E0432]: unresolved import `crate::b::x` + --> $DIR/import-loop-2.rs:2:13 | -LL | pub use crate::a::x; - | ^^^^^^^^^^^ no `x` in `a` +LL | pub use crate::b::x; + | ^^^^^^^^^^^ no `x` in `b` error: aborting due to 1 previous error diff --git a/tests/ui/imports/import4.rs b/tests/ui/imports/import4.rs index f670cc06201c0..76a9887534c34 100644 --- a/tests/ui/imports/import4.rs +++ b/tests/ui/imports/import4.rs @@ -1,4 +1,4 @@ -mod a { pub use crate::b::foo; } -mod b { pub use crate::a::foo; } //~ ERROR unresolved import `crate::a::foo` +mod a { pub use crate::b::foo; } //~ ERROR unresolved import `crate::b::foo` +mod b { pub use crate::a::foo; } fn main() { println!("loop"); } diff --git a/tests/ui/imports/import4.stderr b/tests/ui/imports/import4.stderr index 4faa5f0520a9d..07fdc6a3d0ced 100644 --- a/tests/ui/imports/import4.stderr +++ b/tests/ui/imports/import4.stderr @@ -1,8 +1,8 @@ -error[E0432]: unresolved import `crate::a::foo` - --> $DIR/import4.rs:2:17 +error[E0432]: unresolved import `crate::b::foo` + --> $DIR/import4.rs:1:17 | -LL | mod b { pub use crate::a::foo; } - | ^^^^^^^^^^^^^ no `foo` in `a` +LL | mod a { pub use crate::b::foo; } + | ^^^^^^^^^^^^^ no `foo` in `b` error: aborting due to 1 previous error diff --git a/tests/ui/imports/same-res-ambigious.fail.stderr b/tests/ui/imports/same-res-ambigious.fail.stderr deleted file mode 100644 index dfd7c5a5f94e0..0000000000000 --- a/tests/ui/imports/same-res-ambigious.fail.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0603]: derive macro `Embed` is private - --> $DIR/same-res-ambigious.rs:8:28 - | -LL | #[derive(ambigious_extern::Embed)] - | ^^^^^ private derive macro - | -note: the derive macro `Embed` is defined here - --> $DIR/auxiliary/same-res-ambigious-extern-fail.rs:16:9 - | -LL | pub use RustEmbed as Embed; - | ^^^^^^^^^ -help: import `Embed` directly - | -LL - #[derive(ambigious_extern::Embed)] -LL + #[derive(same_res_ambigious_extern_macro::RustEmbed)] - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/imports/same-res-ambigious.rs b/tests/ui/imports/same-res-ambigious.rs index b5c13a15b7c9c..0bfd10f18ada8 100644 --- a/tests/ui/imports/same-res-ambigious.rs +++ b/tests/ui/imports/same-res-ambigious.rs @@ -1,11 +1,11 @@ +//@ check-pass //@ edition: 2018 //@ revisions: fail pass -//@[pass] check-pass //@[pass] aux-crate: ambigious_extern=same-res-ambigious-extern.rs //@[fail] aux-crate: ambigious_extern=same-res-ambigious-extern-fail.rs // see https://github.com/rust-lang/rust/pull/147196 -#[derive(ambigious_extern::Embed)] //[fail]~ ERROR: derive macro `Embed` is private +#[derive(ambigious_extern::Embed)] struct Foo{} fn main(){} diff --git a/tests/ui/issues/auxiliary/issue-19293.rs b/tests/ui/issues/auxiliary/issue-19293.rs deleted file mode 100644 index 31359e86559dd..0000000000000 --- a/tests/ui/issues/auxiliary/issue-19293.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub struct Foo (pub isize); -pub enum MyEnum { - Foo(Foo), -} diff --git a/tests/ui/issues/auxiliary/issue-20389.rs b/tests/ui/issues/auxiliary/issue-20389.rs deleted file mode 100644 index ae6d44eeb7703..0000000000000 --- a/tests/ui/issues/auxiliary/issue-20389.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub trait T { - type C; - fn dummy(&self) { } -} diff --git a/tests/ui/issues/auxiliary/issue-2414-b.rs b/tests/ui/issues/auxiliary/issue-2414-b.rs deleted file mode 100644 index fc018349d80f1..0000000000000 --- a/tests/ui/issues/auxiliary/issue-2414-b.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![crate_name="b"] -#![crate_type = "lib"] - -extern crate a; diff --git a/tests/ui/issues/auxiliary/issue-38190.rs b/tests/ui/issues/auxiliary/issue-38190.rs deleted file mode 100644 index 373e646ba2c39..0000000000000 --- a/tests/ui/issues/auxiliary/issue-38190.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[macro_export] -macro_rules! m { ([$i:item]) => {} } diff --git a/tests/ui/issues/auxiliary/issue-41053.rs b/tests/ui/issues/auxiliary/issue-41053.rs deleted file mode 100644 index ae73c3e780fb3..0000000000000 --- a/tests/ui/issues/auxiliary/issue-41053.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct Test; diff --git a/tests/ui/issues/auxiliary/issue-41549.rs b/tests/ui/issues/auxiliary/issue-41549.rs deleted file mode 100644 index b7bd375250f0b..0000000000000 --- a/tests/ui/issues/auxiliary/issue-41549.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait Trait { - const CONST: u32; -} diff --git a/tests/ui/issues/auxiliary/issue-42007-s.rs b/tests/ui/issues/auxiliary/issue-42007-s.rs deleted file mode 100644 index 95119a589c99d..0000000000000 --- a/tests/ui/issues/auxiliary/issue-42007-s.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[repr(u8)] -pub enum E { - B = 1 as u8, -} diff --git a/tests/ui/issues/auxiliary/issue-4545.rs b/tests/ui/issues/auxiliary/issue-4545.rs deleted file mode 100644 index 2f60947507541..0000000000000 --- a/tests/ui/issues/auxiliary/issue-4545.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub struct S(Option); -pub fn mk() -> S { S(None) } diff --git a/tests/ui/issues/auxiliary/issue-48984-aux.rs b/tests/ui/issues/auxiliary/issue-48984-aux.rs deleted file mode 100644 index 7cc888cd4cb29..0000000000000 --- a/tests/ui/issues/auxiliary/issue-48984-aux.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![crate_type = "lib"] -#![crate_name = "issue48984aux"] - -pub trait Foo { type Item; } - -pub trait Bar: Foo { } diff --git a/tests/ui/issues/auxiliary/issue-51798.rs b/tests/ui/issues/auxiliary/issue-51798.rs deleted file mode 100644 index fef5213db9f7a..0000000000000 --- a/tests/ui/issues/auxiliary/issue-51798.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![crate_type = "lib"] - -pub fn vec() -> Vec { vec![] } diff --git a/tests/ui/issues/issue-19293.rs b/tests/ui/issues/issue-19293.rs deleted file mode 100644 index 42effe303d036..0000000000000 --- a/tests/ui/issues/issue-19293.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass -//@ aux-build:issue-19293.rs - -extern crate issue_19293; -use issue_19293::{Foo, MyEnum}; - -fn main() { - MyEnum::Foo(Foo(5)); -} diff --git a/tests/ui/issues/issue-20389.rs b/tests/ui/issues/issue-20389.rs deleted file mode 100644 index e201663afc522..0000000000000 --- a/tests/ui/issues/issue-20389.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -//@ aux-build:issue-20389.rs - - -extern crate issue_20389; - -struct Foo; - -impl issue_20389::T for Foo { - type C = (); -} - -fn main() {} diff --git a/tests/ui/issues/issue-2170-exe.rs b/tests/ui/issues/issue-2170-exe.rs deleted file mode 100644 index b66843d48cad6..0000000000000 --- a/tests/ui/issues/issue-2170-exe.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass -//@ aux-build:issue-2170-lib.rs - -extern crate issue_2170_lib; - -pub fn main() { - // let _ = issue_2170_lib::rsrc(2); -} diff --git a/tests/ui/issues/issue-2380-b.rs b/tests/ui/issues/issue-2380-b.rs deleted file mode 100644 index 503698f88c620..0000000000000 --- a/tests/ui/issues/issue-2380-b.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass -//@ aux-build:issue-2380.rs - - -extern crate a; - -pub fn main() { - a::f::<()>(); -} diff --git a/tests/ui/issues/issue-2414-c.rs b/tests/ui/issues/issue-2414-c.rs deleted file mode 100644 index ac75c5c51051c..0000000000000 --- a/tests/ui/issues/issue-2414-c.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass -//@ aux-build:issue-2414-a.rs -//@ aux-build:issue-2414-b.rs - - -extern crate b; - -pub fn main() {} diff --git a/tests/ui/issues/issue-2526-a.rs b/tests/ui/issues/issue-2526-a.rs deleted file mode 100644 index 379146d02b3de..0000000000000 --- a/tests/ui/issues/issue-2526-a.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -//@ aux-build:issue-2526.rs - - -#![allow(unused_imports)] - -extern crate issue_2526; -use issue_2526::*; - -pub fn main() {} diff --git a/tests/ui/issues/issue-25467.rs b/tests/ui/issues/issue-25467.rs deleted file mode 100644 index 1ba5a0ef697a1..0000000000000 --- a/tests/ui/issues/issue-25467.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass -#![allow(unused_variables)] -//@ aux-build:issue-25467.rs - -pub type Issue25467BarT = (); -pub type Issue25467FooT = (); - -extern crate issue_25467 as aux; - -fn main() { - let o: aux::Object = None; -} diff --git a/tests/ui/issues/issue-2723-b.rs b/tests/ui/issues/issue-2723-b.rs deleted file mode 100644 index 731e521f26f89..0000000000000 --- a/tests/ui/issues/issue-2723-b.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -//@ aux-build:issue-2723-a.rs - -extern crate issue_2723_a; -use issue_2723_a::f; - -pub fn main() { - unsafe { - f(vec![2]); - } -} diff --git a/tests/ui/issues/issue-29265.rs b/tests/ui/issues/issue-29265.rs deleted file mode 100644 index a3da9be3a3b65..0000000000000 --- a/tests/ui/issues/issue-29265.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ aux-build:issue-29265.rs -//@ check-pass - -extern crate issue_29265 as lib; - -static _UNUSED: &'static lib::SomeType = &lib::SOME_VALUE; - -fn main() { - vec![0u8; lib::SOME_VALUE.some_member]; -} diff --git a/tests/ui/issues/issue-29485.rs b/tests/ui/issues/issue-29485.rs deleted file mode 100644 index 843a684a85b5e..0000000000000 --- a/tests/ui/issues/issue-29485.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ run-pass -//@ aux-build:issue-29485.rs -//@ needs-unwind -//@ needs-threads -//@ ignore-backends: gcc - -extern crate a; - -fn main() { - let _ = std::thread::spawn(move || { - a::f(&mut a::X(0), g); - }).join(); -} - -fn g() { - panic!(); -} diff --git a/tests/ui/issues/issue-3012-2.rs b/tests/ui/issues/issue-3012-2.rs deleted file mode 100644 index fd090d5e7b50e..0000000000000 --- a/tests/ui/issues/issue-3012-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ run-pass -//@ aux-build:issue-3012-1.rs - - -extern crate socketlib; - -use socketlib::socket; - -pub fn main() { - let fd: u32 = 1 as u32; - let _sock: Box<_> = Box::new(socket::socket_handle(fd)); -} diff --git a/tests/ui/issues/issue-30123.rs b/tests/ui/issues/issue-30123.rs deleted file mode 100644 index 88fab44741f2e..0000000000000 --- a/tests/ui/issues/issue-30123.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ aux-build:issue-30123-aux.rs - -extern crate issue_30123_aux; -use issue_30123_aux::*; - -fn main() { - let ug = Graph::::new_undirected(); - //~^ ERROR no associated function or constant named `new_undirected` found -} diff --git a/tests/ui/issues/issue-30123.stderr b/tests/ui/issues/issue-30123.stderr deleted file mode 100644 index 1e2747407d1da..0000000000000 --- a/tests/ui/issues/issue-30123.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0599]: no associated function or constant named `new_undirected` found for struct `issue_30123_aux::Graph` in the current scope - --> $DIR/issue-30123.rs:7:33 - | -LL | let ug = Graph::::new_undirected(); - | ^^^^^^^^^^^^^^ associated function or constant not found in `issue_30123_aux::Graph` - | -note: if you're trying to build a new `issue_30123_aux::Graph`, consider using `issue_30123_aux::Graph::::new` which returns `issue_30123_aux::Graph<_, _>` - --> $DIR/auxiliary/issue-30123-aux.rs:14:5 - | -LL | pub fn new() -> Self { - | ^^^^^^^^^^^^^^^^^^^^ - = note: the associated function or constant was found for `issue_30123_aux::Graph` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/issues/issue-3136-b.rs b/tests/ui/issues/issue-3136-b.rs deleted file mode 100644 index bd6ea732643f1..0000000000000 --- a/tests/ui/issues/issue-3136-b.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass -//@ aux-build:issue-3136-a.rs - - -extern crate issue_3136_a; - -pub fn main() {} diff --git a/tests/ui/issues/issue-31702.rs b/tests/ui/issues/issue-31702.rs deleted file mode 100644 index 1cf01f7f04ecc..0000000000000 --- a/tests/ui/issues/issue-31702.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ run-pass -//@ aux-build:issue-31702-1.rs -//@ aux-build:issue-31702-2.rs - -// this test is actually entirely in the linked library crates - -extern crate issue_31702_1; -extern crate issue_31702_2; - -fn main() {} diff --git a/tests/ui/issues/issue-32518.rs b/tests/ui/issues/issue-32518.rs deleted file mode 100644 index 45a882850c009..0000000000000 --- a/tests/ui/issues/issue-32518.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ run-pass -//@ no-prefer-dynamic -//@ aux-build:cgu_test.rs -//@ aux-build:cgu_test_a.rs -//@ aux-build:cgu_test_b.rs - -extern crate cgu_test_a; -extern crate cgu_test_b; - -fn main() { - cgu_test_a::a::a(); - cgu_test_b::a::a(); -} diff --git a/tests/ui/issues/issue-36954.rs b/tests/ui/issues/issue-36954.rs deleted file mode 100644 index 411e99b603da4..0000000000000 --- a/tests/ui/issues/issue-36954.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ run-pass -//@ aux-build:issue-36954.rs - -extern crate issue_36954 as lib; - -fn main() { - let _ = lib::FOO; -} diff --git a/tests/ui/issues/issue-38190.rs b/tests/ui/issues/issue-38190.rs deleted file mode 100644 index 539d7f2ed3be4..0000000000000 --- a/tests/ui/issues/issue-38190.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ run-pass -//@ aux-build:issue-38190.rs - -#[macro_use] -extern crate issue_38190; - -mod auxiliary { - m!([ - #[path = "issue-38190.rs"] - mod issue_38190; - ]); -} - -fn main() {} diff --git a/tests/ui/issues/issue-41549.rs b/tests/ui/issues/issue-41549.rs deleted file mode 100644 index 8f57515415c6e..0000000000000 --- a/tests/ui/issues/issue-41549.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ aux-build:issue-41549.rs - - -extern crate issue_41549; - -struct S; - -impl issue_41549::Trait for S { - const CONST: () = (); //~ ERROR incompatible type for trait -} - -fn main() {} diff --git a/tests/ui/issues/issue-42007.rs b/tests/ui/issues/issue-42007.rs deleted file mode 100644 index b8ea7e871a736..0000000000000 --- a/tests/ui/issues/issue-42007.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -//@ aux-build:issue-42007-s.rs - -extern crate issue_42007_s; - -enum I { - E(issue_42007_s::E), -} - -fn main() {} diff --git a/tests/ui/issues/issue-4208.rs b/tests/ui/issues/issue-4208.rs deleted file mode 100644 index 84938bea022d1..0000000000000 --- a/tests/ui/issues/issue-4208.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -//@ aux-build:issue-4208-cc.rs - - -extern crate numeric; -use numeric::{sin, Angle}; - -fn foo>(theta: A) -> T { sin(&theta) } - -pub fn main() {} diff --git a/tests/ui/issues/issue-4545.rs b/tests/ui/issues/issue-4545.rs deleted file mode 100644 index dfb89136cbd22..0000000000000 --- a/tests/ui/issues/issue-4545.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ run-pass -//@ aux-build:issue-4545.rs - - -extern crate issue_4545 as somelib; -pub fn main() { somelib::mk::(); } diff --git a/tests/ui/issues/issue-48984.rs b/tests/ui/issues/issue-48984.rs deleted file mode 100644 index 0440789a480aa..0000000000000 --- a/tests/ui/issues/issue-48984.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ run-pass -#![allow(dead_code)] -//@ aux-build:issue-48984-aux.rs -extern crate issue48984aux; -use issue48984aux::Bar; - -fn do_thing() { } - -fn main() { } diff --git a/tests/ui/issues/issue-51798.rs b/tests/ui/issues/issue-51798.rs deleted file mode 100644 index f4d59f39952eb..0000000000000 --- a/tests/ui/issues/issue-51798.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ edition:2018 -//@ aux-build:issue-51798.rs -//@ check-pass - -extern crate issue_51798; - -mod server { - fn f() { - let mut v = issue_51798::vec(); - v.clear(); - } -} - -fn main() {} diff --git a/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-1.rs b/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-1.rs index 7b2bfbba12e6e..bac086ba0c054 100644 --- a/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-1.rs +++ b/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-1.rs @@ -1,5 +1,4 @@ -//! Auxiliary crate for . - +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/18913 //@ no-prefer-dynamic #![crate_type = "rlib"] diff --git a/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-2.rs b/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-2.rs index fc0d3d6ea4283..05dba52c6625e 100644 --- a/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-2.rs +++ b/tests/ui/linking/auxiliary/duplicate-rlib-crate-name-precedence-2.rs @@ -1,5 +1,4 @@ -//! Auxiliary crate for . - +//! Auxiliary crate testing this issue https://github.com/rust-lang/rust/issues/18913 //@ no-prefer-dynamic #![crate_type = "rlib"] diff --git a/tests/ui/issues/issue-19367.rs b/tests/ui/match/match-field-reassign.rs similarity index 74% rename from tests/ui/issues/issue-19367.rs rename to tests/ui/match/match-field-reassign.rs index 1cd6c483375ab..c7135ac92fbfd 100644 --- a/tests/ui/issues/issue-19367.rs +++ b/tests/ui/match/match-field-reassign.rs @@ -1,3 +1,8 @@ +//! Regression test for . +//! +//! Make sure we don't reuse the same alloca when matching +//! on field of struct or tuple which we reassign in the match body. + //@ run-pass #![allow(unused_assignments)] @@ -6,9 +11,6 @@ struct S { o: Option } -// Make sure we don't reuse the same alloca when matching -// on field of struct or tuple which we reassign in the match body. - fn main() { let mut a = (0, Some("right".to_string())); let b = match a.1 { diff --git a/tests/ui/on-unimplemented/expected-comma-found-token.rs b/tests/ui/on-unimplemented/expected-comma-found-token.rs index d60ab3341fd6d..09c293f7eba78 100644 --- a/tests/ui/on-unimplemented/expected-comma-found-token.rs +++ b/tests/ui/on-unimplemented/expected-comma-found-token.rs @@ -4,7 +4,7 @@ #![feature(rustc_attrs)] #[rustc_on_unimplemented( - message="the message" - label="the label" //~ ERROR expected `,`, found `label` + message="the message" //~ ERROR attribute items not separated with `,` + label="the label" )] trait T {} diff --git a/tests/ui/on-unimplemented/expected-comma-found-token.stderr b/tests/ui/on-unimplemented/expected-comma-found-token.stderr index 2717100a1dc64..cdc80a4d9267c 100644 --- a/tests/ui/on-unimplemented/expected-comma-found-token.stderr +++ b/tests/ui/on-unimplemented/expected-comma-found-token.stderr @@ -1,10 +1,8 @@ -error: expected `,`, found `label` - --> $DIR/expected-comma-found-token.rs:8:5 +error: attribute items not separated with `,` + --> $DIR/expected-comma-found-token.rs:7:26 | LL | message="the message" - | - expected `,` -LL | label="the label" - | ^^^^^ unexpected token + | ^ help: try adding `,` here error: aborting due to 1 previous error diff --git a/tests/ui/parser/equality-predicates-0.rs b/tests/ui/parser/equality-predicates-0.rs new file mode 100644 index 0000000000000..a720d963c220e --- /dev/null +++ b/tests/ui/parser/equality-predicates-0.rs @@ -0,0 +1,20 @@ +// Test that we syntactically reject *equality predicates*. +// +// It's a feature that was originally proposed as part of accepted RFC 135 (2014). It's never been +// fully implemented and in the meantime design & implementation concerns have been raised. +// Between Feb 2017 and Jun 2026 we accidentally accepted such predicates syntactically +// (indeed, without any pre-expansion feature gate). +// +// We *might* add a more restricted version of this feature to the language in the future. +// See discussions in tracking issue for details. + +#[cfg(false)] +fn f(mut xs: T) -> Option +where + T::Item = u8 + //~^ ERROR general type equality constraints are not supported +{ + xs.next() +} + +fn main() {} diff --git a/tests/ui/parser/equality-predicates-0.stderr b/tests/ui/parser/equality-predicates-0.stderr new file mode 100644 index 0000000000000..f5be5d156e0d9 --- /dev/null +++ b/tests/ui/parser/equality-predicates-0.stderr @@ -0,0 +1,15 @@ +error: general type equality constraints are not supported + --> $DIR/equality-predicates-0.rs:14:5 + | +LL | T::Item = u8 + | ^^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information +help: replace it with an associated item constraint if possible + | +LL - T::Item = u8 +LL + T: /* Trait */ + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/equality-predicates-1.rs b/tests/ui/parser/equality-predicates-1.rs new file mode 100644 index 0000000000000..b5dcc565fc208 --- /dev/null +++ b/tests/ui/parser/equality-predicates-1.rs @@ -0,0 +1,20 @@ +// Test that we syntactically reject *equality predicates*. +// +// It's a feature that was originally proposed as part of accepted RFC 135 (2014). It's never been +// fully implemented and in the meantime design & implementation concerns have been raised. +// Between Feb 2017 and Jun 2026 we accidentally accepted such predicates syntactically +// (indeed, without any pre-expansion feature gate). +// +// We *might* add a more restricted version of this feature to the language in the future. +// See discussions in tracking issue for details. + +#[cfg(false)] +fn f(mut xs: T) -> Option +where + ::Item == u8 + //~^ ERROR general type equality constraints are not supported +{ + xs.next() +} + +fn main() {} diff --git a/tests/ui/parser/equality-predicates-1.stderr b/tests/ui/parser/equality-predicates-1.stderr new file mode 100644 index 0000000000000..9e7a0b767239a --- /dev/null +++ b/tests/ui/parser/equality-predicates-1.stderr @@ -0,0 +1,15 @@ +error: general type equality constraints are not supported + --> $DIR/equality-predicates-1.rs:14:5 + | +LL | ::Item == u8 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported + | + = note: see issue #20041 for more information +help: replace it with an associated item constraint if possible + | +LL - ::Item == u8 +LL + T: Iterator + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/issues/issue-19086.rs b/tests/ui/pattern/struct-variant-as-tuple-variant.rs similarity index 77% rename from tests/ui/issues/issue-19086.rs rename to tests/ui/pattern/struct-variant-as-tuple-variant.rs index 42148c5f5a18d..944371ae9e952 100644 --- a/tests/ui/issues/issue-19086.rs +++ b/tests/ui/pattern/struct-variant-as-tuple-variant.rs @@ -1,3 +1,5 @@ +//! Regression test for . + use Foo::FooB; enum Foo { diff --git a/tests/ui/issues/issue-19086.stderr b/tests/ui/pattern/struct-variant-as-tuple-variant.stderr similarity index 89% rename from tests/ui/issues/issue-19086.stderr rename to tests/ui/pattern/struct-variant-as-tuple-variant.stderr index 03b9249bb1e3d..1cd063e453100 100644 --- a/tests/ui/issues/issue-19086.stderr +++ b/tests/ui/pattern/struct-variant-as-tuple-variant.stderr @@ -1,5 +1,5 @@ error[E0532]: expected tuple struct or tuple variant, found variant `FooB` - --> $DIR/issue-19086.rs:10:9 + --> $DIR/struct-variant-as-tuple-variant.rs:12:9 | LL | FooB { x: i32, y: i32 } | ----------------------- `FooB` defined here diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr index 5d1e003c703b4..22cc16b12af79 100644 --- a/tests/ui/privacy/privacy1.stderr +++ b/tests/ui/privacy/privacy1.stderr @@ -34,18 +34,6 @@ note: the module `baz` is defined here LL | mod baz { | ^^^^^^^ -error[E0603]: module `baz` is private - --> $DIR/privacy1.rs:148:18 - | -LL | use bar::baz; - | ^^^ private module - | -note: the module `baz` is defined here - --> $DIR/privacy1.rs:57:5 - | -LL | mod baz { - | ^^^^^^^ - error[E0603]: module `i` is private --> $DIR/privacy1.rs:172:20 | @@ -60,6 +48,18 @@ note: the module `i` is defined here LL | mod i { | ^^^^^ +error[E0603]: module `baz` is private + --> $DIR/privacy1.rs:148:18 + | +LL | use bar::baz; + | ^^^ private module + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:57:5 + | +LL | mod baz { + | ^^^^^^^ + error[E0603]: module `baz` is private --> $DIR/privacy1.rs:111:21 | diff --git a/tests/ui/issues/issue-19811-escape-unicode.rs b/tests/ui/str/char-escape-unicode.rs similarity index 71% rename from tests/ui/issues/issue-19811-escape-unicode.rs rename to tests/ui/str/char-escape-unicode.rs index 7be77b88494b2..11975e15c1d38 100644 --- a/tests/ui/issues/issue-19811-escape-unicode.rs +++ b/tests/ui/str/char-escape-unicode.rs @@ -1,3 +1,4 @@ +//! Regression test for . //@ run-pass fn main() { diff --git a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr index 11ec86b1e6d85..2183513bf3b97 100644 --- a/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr +++ b/tests/ui/target-feature/abi-incompatible-target-feature-flag-enable.riscv.stderr @@ -1,6 +1,6 @@ warning: unstable feature specified for `-Ctarget-feature`: `d` | - = note: this feature is not stably supported; its behavior can change in the future + = note: this feature is allowed in cfg but unstable otherwise; its behavior can change in the future warning: target feature `d` must be disabled to ensure that the ABI of the current target can be implemented correctly | diff --git a/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr b/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr index cc225b353df13..7fa1cc299b229 100644 --- a/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr +++ b/tests/ui/target-feature/abi-required-target-feature-flag-disable.riscv.stderr @@ -1,6 +1,6 @@ warning: unstable feature specified for `-Ctarget-feature`: `d` | - = note: this feature is not stably supported; its behavior can change in the future + = note: this feature is allowed in cfg but unstable otherwise; its behavior can change in the future warning: target feature `d` must be enabled to ensure that the ABI of the current target can be implemented correctly | diff --git a/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-attribute-riscv.rs b/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-attribute-riscv.rs new file mode 100644 index 0000000000000..24d42e3df44d3 --- /dev/null +++ b/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-attribute-riscv.rs @@ -0,0 +1,17 @@ +//! Ensure cfg-only stable target_features trigger errors when enabled via attribute. +//@ compile-flags: --crate-type=lib +//@ compile-flags: --target=riscv64gc-unknown-none-elf +//@ needs-llvm-components: riscv +//@ add-minicore +//@ ignore-backends: gcc +#![feature(no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[target_feature(enable = "v")] +//~^ERROR: the target feature `v` is currently unstable +#[target_feature(enable = "f")] +//~^ERROR: the target feature `f` is allowed in cfg but unstable otherwise +pub unsafe fn my_fun() {} diff --git a/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-attribute-riscv.stderr b/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-attribute-riscv.stderr new file mode 100644 index 0000000000000..7f13c11798fcf --- /dev/null +++ b/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-attribute-riscv.stderr @@ -0,0 +1,23 @@ +error[E0658]: the target feature `v` is currently unstable + --> $DIR/cfg-stable-toggle-unstable-target-feature-attribute-riscv.rs:13:18 + | +LL | #[target_feature(enable = "v")] + | ^^^^^^^^^^^^ + | + = note: see issue #150257 for more information + = help: add `#![feature(riscv_target_feature)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: the target feature `f` is allowed in cfg but unstable otherwise + --> $DIR/cfg-stable-toggle-unstable-target-feature-attribute-riscv.rs:15:18 + | +LL | #[target_feature(enable = "f")] + | ^^^^^^^^^^^^ + | + = note: see issue #150257 for more information + = help: add `#![feature(riscv_target_feature)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-flag-enable-riscv.rs b/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-flag-enable-riscv.rs new file mode 100644 index 0000000000000..ab2b75ed5190f --- /dev/null +++ b/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-flag-enable-riscv.rs @@ -0,0 +1,17 @@ +//! Ensure cfg-only stable target_features trigger warnings when enabled via compile flag. +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ compile-flags: --target=riscv64gc-unknown-none-elf -Ctarget-feature=+v -Ctarget-feature=+f +// FIXME(#147881): *disable* the feature again for minicore as otherwise that will fail to build. +//@ minicore-compile-flags: -Ctarget-feature=-v -Ctarget-feature=-f +//@ needs-llvm-components: riscv +//@ ignore-backends: gcc +//@ add-minicore +#![feature(no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; + +//~? WARN unstable feature specified for `-Ctarget-feature` +//~? WARN unstable feature specified for `-Ctarget-feature` diff --git a/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-flag-enable-riscv.stderr b/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-flag-enable-riscv.stderr new file mode 100644 index 0000000000000..b0167221aabaa --- /dev/null +++ b/tests/ui/target-feature/cfg-stable-toggle-unstable-target-feature-flag-enable-riscv.stderr @@ -0,0 +1,10 @@ +warning: unstable feature specified for `-Ctarget-feature`: `v` + | + = note: this feature is not stably supported; its behavior can change in the future + +warning: unstable feature specified for `-Ctarget-feature`: `f` + | + = note: this feature is allowed in cfg but unstable otherwise; its behavior can change in the future + +warning: 2 warnings emitted + diff --git a/tests/ui/issues/issue-21332.rs b/tests/ui/traits/error-reporting/incompatible-method-multiline.rs similarity index 64% rename from tests/ui/issues/issue-21332.rs rename to tests/ui/traits/error-reporting/incompatible-method-multiline.rs index ad764f84aa81a..950ee9d9e0b1c 100644 --- a/tests/ui/issues/issue-21332.rs +++ b/tests/ui/traits/error-reporting/incompatible-method-multiline.rs @@ -1,3 +1,6 @@ +//! Regression test for . +//! Ensure multi-line error formatting for "method has incompatible type for trait" diagnostics. + struct S; impl Iterator for S { diff --git a/tests/ui/issues/issue-21332.stderr b/tests/ui/traits/error-reporting/incompatible-method-multiline.stderr similarity index 92% rename from tests/ui/issues/issue-21332.stderr rename to tests/ui/traits/error-reporting/incompatible-method-multiline.stderr index 237b3acc9b4df..4f797dedfa846 100644 --- a/tests/ui/issues/issue-21332.stderr +++ b/tests/ui/traits/error-reporting/incompatible-method-multiline.stderr @@ -1,5 +1,5 @@ error[E0053]: method `next` has an incompatible type for trait - --> $DIR/issue-21332.rs:5:27 + --> $DIR/incompatible-method-multiline.rs:8:27 | LL | fn next(&mut self) -> Result { Ok(7) } | ^^^^^^^^^^^^^^^^ expected `Option`, found `Result` diff --git a/tests/ui/issues/issue-19404.rs b/tests/ui/traits/object/inherent-method-on-dyn-with-rc-coercion.rs similarity index 90% rename from tests/ui/issues/issue-19404.rs rename to tests/ui/traits/object/inherent-method-on-dyn-with-rc-coercion.rs index ff9bb1f2e037e..fc8715e8d513a 100644 --- a/tests/ui/issues/issue-19404.rs +++ b/tests/ui/traits/object/inherent-method-on-dyn-with-rc-coercion.rs @@ -1,3 +1,5 @@ +//! Regression test for + //@ build-pass #![allow(dead_code)] #![allow(unused_variables)] diff --git a/tests/ui/where-clauses/where-equality-constraints.rs b/tests/ui/where-clauses/where-equality-constraints.rs deleted file mode 100644 index 8828f09d92d33..0000000000000 --- a/tests/ui/where-clauses/where-equality-constraints.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn f() where u8 = u16 {} -//~^ ERROR equality constraints are not yet supported in `where` clauses -fn g() where for<'a> &'static (u8,) == u16, {} -//~^ ERROR equality constraints are not yet supported in `where` clauses - -fn main() {} diff --git a/tests/ui/where-clauses/where-equality-constraints.stderr b/tests/ui/where-clauses/where-equality-constraints.stderr deleted file mode 100644 index 9d8fac02ed33b..0000000000000 --- a/tests/ui/where-clauses/where-equality-constraints.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error: equality constraints are not yet supported in `where` clauses - --> $DIR/where-equality-constraints.rs:1:14 - | -LL | fn f() where u8 = u16 {} - | ^^^^^^^^ not supported - | - = note: see issue #20041 for more information - -error: equality constraints are not yet supported in `where` clauses - --> $DIR/where-equality-constraints.rs:3:14 - | -LL | fn g() where for<'a> &'static (u8,) == u16, {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported - | - = note: see issue #20041 for more information - -error: aborting due to 2 previous errors - diff --git a/triagebot.toml b/triagebot.toml index 5a7d5698652d1..d50d74210c1ee 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -951,11 +951,21 @@ Issue #{number} "{title}" has been added. # ------------------------------------------------------------------------------ [mentions."compiler/rustc_codegen_cranelift"] -message = "The Cranelift subtree was changed" +message = """ +`rustc_codegen_cranelift` is developed in its own repository. If possible, consider \ +making this change to \ +[rust-lang/rustc_codegen_cranelift](https://github.com/rust-lang/rustc_codegen_cranelift) \ +instead. +""" cc = ["@bjorn3"] [mentions."compiler/rustc_codegen_gcc"] -message = "The GCC codegen subtree was changed" +message = """ +`rustc_codegen_gcc` is developed in its own repository. If possible, consider \ +making this change to \ +[rust-lang/rustc_codegen_gcc](https://github.com/rust-lang/rustc_codegen_gcc) \ +instead. +""" cc = ["@antoyo", "@GuillaumeGomez"] [mentions."compiler/rustc_const_eval/src/"] @@ -1109,8 +1119,9 @@ cc = ["@tgross35"] [mentions."library/portable-simd"] message = """ -Portable SIMD is developed in its own repository. If possible, consider \ -making this change to [rust-lang/portable-simd](https://github.com/rust-lang/portable-simd) \ +`portable-simd` is developed in its own repository. If possible, consider \ +making this change to \ +[rust-lang/portable-simd](https://github.com/rust-lang/portable-simd) \ instead. """ cc = ["@calebzulawski", "@programmerjake"] @@ -1153,7 +1164,12 @@ cc = [ cc = ["@ehuss"] [mentions."src/tools/clippy"] -message = "The Clippy subtree was changed" +message = """ +`clippy` is developed in its own repository. If possible, consider \ +making this change to \ +[rust-lang/rust-clippy](https://github.com/rust-lang/rust-clippy) \ +instead. +""" cc = ["@rust-lang/clippy"] [mentions."src/tools/compiletest"] @@ -1166,7 +1182,12 @@ new or modified directive in `src/doc/rustc-dev-guide/`. """ [mentions."src/tools/miri"] -message = "The Miri subtree was changed" +message = """ +`miri` is developed in its own repository. If possible, consider \ +making this change to \ +[rust-lang/miri](https://github.com/rust-lang/miri) \ +instead. +""" cc = ["@rust-lang/miri"] [mentions."src/tools/run-make-support"] @@ -1175,15 +1196,20 @@ cc = ["@jieyouxu"] [mentions."src/tools/rust-analyzer"] message = """ -rust-analyzer is developed in its own repository. If possible, consider making \ -this change to [rust-lang/rust-analyzer] instead. - -[rust-lang/rust-analyzer]: https://github.com/rust-lang/rust-analyzer +`rust-analyzer` is developed in its own repository. If possible, consider \ +making this change to \ +[rust-lang/rust-analyzer](https://github.com/rust-lang/rust-analyzer) \ +instead. """ cc = ["@rust-lang/rust-analyzer"] [mentions."src/tools/rustfmt"] -message = "The Rustfmt subtree was changed" +message = """ +`rustfmt` is developed in its own repository. If possible, consider \ +making this change to \ +[rust-lang/rustfmt](https://github.com/rust-lang/rustfmt) \ +instead. +""" cc = ["@rust-lang/rustfmt"] [mentions."compiler/rustc_middle/src/mir/syntax.rs"] @@ -1395,7 +1421,12 @@ https://github.com/rust-lang/reference/blob/HEAD/src/identifiers.md. cc = ["@ehuss"] [mentions."src/doc/rustc-dev-guide"] -message = "The rustc-dev-guide subtree was changed. If this PR *only* touches the dev guide consider submitting a PR directly to [rust-lang/rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide/pulls) otherwise thank you for updating the dev guide with your changes." +message = """ +`rustc-dev-guide` is developed in its own repository. If possible, consider \ +making this change to \ +[rust-lang/rustc-dev-guide](https://github.com/rust-lang/rustc-dev-guide) \ +instead. +""" cc = ["@BoxyUwU", "@tshepang"] [mentions."compiler/rustc_passes/src/check_attr.rs"]