diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index af071c706856e..4e2bef94982cc 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -33,3 +33,6 @@ c682aa162b0d41e21cc6748f4fecfe01efb69d1f 1fcae03369abb4c2cc180cd5a49e1f4440a81300 # Breaking up of compiletest runtest.rs 60600a6fa403216bfd66e04f948b1822f6450af7 + +# std: move futex implementations into sys::sync::futex +7232830d10b6af772e0e4670a2ff61dd23830ed8 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 93388ddd24075..872c8a0ade1ab 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,16 @@ + +- [ ] I did not use an LLM to create a change in this PR. +- [ ] I used an LLM to create a change in this PR, and I have explained below how it was used. + [`fn inferred_outlives_of`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_hir_analysis/src/outlives/mod.rs#L20 [`fn inferred_outlives_crate`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_hir_analysis/src/outlives/mod.rs#L83 - [`fn insert_required_predicates_to_be_wf`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs#L89 - [`fn check_explicit_predicates`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs#L238 - [`fn insert_outlives_predicate`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_hir_analysis/src/outlives/utils.rs#L15 + [`fn insert_required_clauses_to_be_wf`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs#L89 + [`fn check_explicit_clauses`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs#L238 + [`fn insert_outlives_clause`]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_hir_analysis/src/outlives/utils.rs#L15 [nostatic]: https://github.com/rust-lang/rust/blob/5b8bc568d28b2e922290c9a966b3231d0ce9398b/compiler/rustc_hir_analysis/src/outlives/utils.rs#L159-L165 ## implicit implied bounds diff --git a/src/doc/rustc-dev-guide/src/typing-parameter-envs.md b/src/doc/rustc-dev-guide/src/typing-parameter-envs.md index f5a19ea328696..8e13f9fb43327 100644 --- a/src/doc/rustc-dev-guide/src/typing-parameter-envs.md +++ b/src/doc/rustc-dev-guide/src/typing-parameter-envs.md @@ -25,7 +25,7 @@ such as `ConstArgHasType` or (some) implied bounds. In most cases `ParamEnv`s are initially created via the [`param_env` query][query] which returns a `ParamEnv` derived from the provided item's where clauses. A `ParamEnv` can also be created with arbitrary sets of clauses that are not derived from a specific item, -such as in [`compare_method_predicate_entailment`][method_pred_entailment] where we create a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. +such as in [`compare_method_clause_entailment`][method_clause_entailment] where we create a hybrid `ParamEnv` consisting of the impl's where clauses and the trait definition's function's where clauses. --- @@ -76,7 +76,7 @@ fn foo2(a: T) { ``` [clauses_of]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/collect/clauses_of/fn.clauses_of.html -[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html +[method_clause_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_clause_entailment.html [query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.param_env [normalization]: normalization.md @@ -111,7 +111,7 @@ Creating an empty environment with `ParamEnv::empty` is typically only done eith or as part of some analysis that do not expect to ever encounter generic parameters (e.g. various parts of coherence/orphan check). -Creating an env from an arbitrary set of where clauses is usually unnecessary and should only be done if the environment you need does not correspond to an actual item in the source code (e.g. [`compare_method_predicate_entailment`][method_pred_entailment]). +Creating an env from an arbitrary set of where clauses is usually unnecessary and should only be done if the environment you need does not correspond to an actual item in the source code (e.g. [`compare_method_clause_entailment`][method_clause_entailment]). [param_env_new]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.new [normalize_env_or_error]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/traits/fn.normalize_param_env_or_error.html @@ -124,7 +124,7 @@ Creating an env from an arbitrary set of where clauses is usually unnecessary an [mirtypeck_param_env]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_borrowck/type_check/struct.TypeChecker.html#structfield.param_env [env_empty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.empty [param_env_query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_typeck/fn_ctxt/struct.FnCtxt.html#structfield.param_env -[method_pred_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_predicate_entailment.html +[method_clause_entailment]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/check/compare_impl_item/fn.compare_method_clause_entailment.html [predicate_emitting_relation]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/relate/combine/trait.PredicateEmittingRelation.html [tenv_mono]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypingEnv.html#method.fully_monomorphized [compiler_help]: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 3abeea4e41af3..ca5890840581c 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -77,7 +77,6 @@ - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md) - [armv7-rtems-eabihf](platform-support/armv7-rtems-eabihf.md) - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md) - - [armv7a-vex-v5](platform-support/armv7a-vex-v5.md) - [\*-android and \*-androideabi](platform-support/android.md) - [\*-linux-ohos](platform-support/openharmony.md) - [\*-hurd-gnu](platform-support/hurd.md) @@ -126,6 +125,7 @@ - [s390x-unknown-none-softfloat](platform-support/s390x-unknown-none-softfloat.md) - [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md) - [solaris](platform-support/solaris.md) + - [thumbv7a-vex-v5](platform-support/thumbv7a-vex-v5.md) - [\*-nto-qnx-\*](platform-support/nto-qnx.md) - [\*-unikraft-linux-musl](platform-support/unikraft-linux-musl.md) - [\*-unknown-helenos](platform-support/helenos.md) diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index f9e97530214fe..52dc58f65bb8b 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -516,10 +516,6 @@ Parallelism used by compilation stages converting backend IR to object files. In any case the parallelism here may be additionally limited dynamically by jobserver passed from a higher level build system like cargo. -Note: the backend parallelism limit may currently work incorrectly if `jobs-frontend` or `jobs` -have larger value than `jobs-backend`, or if the inherited jobserver can give a larger number -of tokens. - ### Linker parallelism Parallelism used by linker when combining object files into a final binary. diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 2137fa91bda67..81e843263487c 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -324,7 +324,6 @@ target | std | host | notes [`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ | | Armv7-A for VxWorks [`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3 [`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3, hardfloat -[`armv7a-vex-v5`](platform-support/armv7a-vex-v5.md) | ? | | Armv7-A Cortex-A9 VEX V5 Brain, VEXos [`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Armv7-A Apple WatchOS [`armv7s-apple-ios`](platform-support/apple-ios.md) | ✓ | | Armv7-A Apple-A6 Apple iOS [`armv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX @@ -435,6 +434,7 @@ target | std | host | notes [`thumbv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7-A with NuttX, hardfloat `thumbv7a-pc-windows-msvc` | | | [`thumbv7a-uwp-windows-msvc`](platform-support/uwp-windows-msvc.md) | | | +[`thumbv7a-vex-v5`](platform-support/thumbv7a-vex-v5.md) | ✓ | | Armv7-A Cortex-A9 VEX V5 Brain, VEXos [`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7EM with NuttX [`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv7EM with NuttX, hardfloat [`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv7M with NuttX diff --git a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md b/src/doc/rustc/src/platform-support/thumbv7a-vex-v5.md similarity index 95% rename from src/doc/rustc/src/platform-support/armv7a-vex-v5.md rename to src/doc/rustc/src/platform-support/thumbv7a-vex-v5.md index 8c192c6dbdf69..e51654f3b4c44 100644 --- a/src/doc/rustc/src/platform-support/armv7a-vex-v5.md +++ b/src/doc/rustc/src/platform-support/thumbv7a-vex-v5.md @@ -1,4 +1,4 @@ -# `armv7a-vex-v5` +# `thumbv7a-vex-v5` **Tier: 3** @@ -6,6 +6,8 @@ Allows compiling user programs for the [VEX V5 Brain](https://www.vexrobotics.co Rust support for this target is not affiliated with VEX Robotics or IFI, and does not link against any official VEX SDK. +This target was previously named `armv7a-vex-v5`. + ## Target maintainers This target is maintained by members of the [vexide](https://github.com/vexide) organization: @@ -48,7 +50,7 @@ Libraries may access symbols from the active VEX SDK without depending on a spec ## Building the target -You can build Rust with support for this target by adding it to the `target` list in `bootstrap.toml`, and then running `./x build --target armv7a-vex-v5 compiler`. +You can build Rust with support for this target by adding it to the `target` list in `bootstrap.toml`, and then running `./x build --target thumbv7a-vex-v5 compiler`. ## Building Rust programs @@ -113,13 +115,13 @@ This target can be cross-compiled from any host. The recommended configuration for compiling compatible C code is to use the [Arm Toolchain for Embedded](https://github.com/arm/arm-toolchain/tree/arm-software/arm-software/embedded#readme) with the following compilation flags: ```sh -clang --target=arm-none-eabi -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=hard -fno-pic -fno-exceptions -fno-rtti -funwind-tables +clang --target=thumbv7a-none-eabihf -mcpu=cortex-a9 -mfpu=neon -fno-pic -fno-exceptions -fno-rtti -funwind-tables ``` The following Cargo configuration can be used to link with picolibc (the libc used by the Arm Toolchain for Embedded): ```toml -[target.armv7a-vex-v5] +[target.thumbv7a-vex-v5] # We use ARM Clang as a linker because ld.lld by itself doesn't include the # multilib logic for resolving static libraries. linker = "clang" @@ -128,7 +130,9 @@ rustflags = [ # These link flags resolve to this sysroot: # `…/arm-none-eabi/armv7a_hard_vfpv3_d16_unaligned` # (hard float / VFP version 3 with 16 regs / unaligned access) - "-Clink-arg=--target=armv7a-none-eabihf", + "-Clink-arg=--target=thumbv7a-none-eabihf", + "-Clink-arg=-fno-rtti", + "-Clink-arg=-fno-exceptions", # To disable crt0 and use Rust's _boot implementation # (or something custom): diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1e0c06cb031a7..9186b76f5d2b2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -432,9 +432,9 @@ pub(crate) fn clean_clause<'tcx>( let bound_clause = clause.kind(); match bound_clause.skip_binder() { ty::ClauseKind::Trait(pred) => clean_poly_trait_predicate(bound_clause.rebind(pred), cx), - ty::ClauseKind::RegionOutlives(pred) => Some(clean_region_outlives_predicate(pred, cx.tcx)), + ty::ClauseKind::RegionOutlives(pred) => Some(clean_region_outlives_clause(pred, cx.tcx)), ty::ClauseKind::TypeOutlives(pred) => { - Some(clean_type_outlives_predicate(bound_clause.rebind(pred), cx)) + Some(clean_type_outlives_clause(bound_clause.rebind(pred), cx)) } ty::ClauseKind::Projection(pred) => { Some(clean_projection_predicate(bound_clause.rebind(pred), cx)) @@ -467,11 +467,11 @@ fn clean_poly_trait_predicate<'tcx>( }) } -fn clean_region_outlives_predicate<'tcx>( - pred: ty::RegionOutlivesPredicate<'tcx>, +fn clean_region_outlives_clause<'tcx>( + clause: ty::RegionOutlivesClause<'tcx>, tcx: TyCtxt<'tcx>, ) -> WherePredicate { - let ty::OutlivesPredicate(a, b) = pred; + let ty::OutlivesClause(a, b) = clause; WherePredicate::RegionPredicate { lifetime: clean_middle_region(a, tcx).expect("failed to clean lifetime"), @@ -481,14 +481,14 @@ fn clean_region_outlives_predicate<'tcx>( } } -fn clean_type_outlives_predicate<'tcx>( - pred: ty::Binder<'tcx, ty::TypeOutlivesPredicate<'tcx>>, +fn clean_type_outlives_clause<'tcx>( + clause: ty::Binder<'tcx, ty::TypeOutlivesClause<'tcx>>, cx: &mut DocContext<'tcx>, ) -> WherePredicate { - let ty::OutlivesPredicate(ty, lt) = pred.skip_binder(); + let ty::OutlivesClause(ty, lt) = clause.skip_binder(); WherePredicate::BoundPredicate { - ty: clean_middle_ty(pred.rebind(ty), cx, None, None), + ty: clean_middle_ty(clause.rebind(ty), cx, None, None), bounds: vec![GenericBound::Outlives( clean_middle_region(lt, cx.tcx).expect("failed to clean lifetimes"), )], @@ -903,7 +903,7 @@ fn clean_ty_generics_inner<'tcx>( ty::ClauseKind::Trait(pred) if let ty::Param(param) = pred.self_ty().kind() => { Some(param.index) } - ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) + ty::ClauseKind::TypeOutlives(ty::OutlivesClause(ty, _reg)) if let ty::Param(param) = ty.kind() => { Some(param.index) @@ -2401,7 +2401,7 @@ fn clean_middle_opaque_bounds<'tcx>( let bound_predicate = bound.kind(); let trait_ref = match bound_predicate.skip_binder() { ty::ClauseKind::Trait(tr) => bound_predicate.rebind(tr.trait_ref), - ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => { + ty::ClauseKind::TypeOutlives(ty::OutlivesClause(_ty, reg)) => { return clean_middle_region(reg, cx.tcx).map(GenericBound::Outlives); } _ => return None, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 2b7f9c4dbb7fa..7ba409626ea89 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -217,34 +217,37 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions let result = interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); - let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { - let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); - let opts = scrape_test_config(tcx, crate_name, args_path); - - let hir_collector = HirCollector::new( - ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()), - tcx, - ); - let tests = hir_collector.collect_crate(); - if extract_doctests { - let mut collector = extracted::ExtractedDocTests::new(); - tests.into_iter().for_each(|t| collector.add_test(t, &opts, &options)); - - let stdout = std::io::stdout(); - let mut stdout = stdout.lock(); - if let Err(error) = serde_json::ser::to_writer(&mut stdout, &collector) { - eprintln!(); - Err(format!("Failed to generate JSON output for doctests: {error:?}")) + let (collector, _incr_comp_session) = + rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { + let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); + let opts = scrape_test_config(tcx, crate_name, args_path); + + let hir_collector = HirCollector::new( + ErrorCodes::from(compiler.sess.opts.unstable_features.is_nightly_build()), + tcx, + ); + let tests = hir_collector.collect_crate(); + if extract_doctests { + let mut collector = extracted::ExtractedDocTests::new(); + tests.into_iter().for_each(|t| collector.add_test(t, &opts, &options)); + + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + if let Err(error) = serde_json::ser::to_writer(&mut stdout, &collector) { + eprintln!(); + Err(format!("Failed to generate JSON output for doctests: {error:?}")) + } else { + Ok(None) + } } else { - Ok(None) - } - } else { - let mut collector = CreateRunnableDocTests::new(options, opts); - tests.into_iter().for_each(|t| collector.add_test(t, Some(compiler.sess.dcx()))); + let mut collector = CreateRunnableDocTests::new(options, opts); + tests + .into_iter() + .for_each(|t| collector.add_test(t, Some(compiler.sess.dcx()))); - Ok(Some(collector)) - } - }); + Ok(Some(collector)) + } + }); compiler.sess.dcx().abort_if_errors(); collector diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 7e46b2f593e49..eb382f368905f 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -12,7 +12,8 @@ use rustc_hir::attrs::{ }; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::DefId; -use rustc_hir::{HeaderSafety, Safety, find_attr}; +use rustc_hir::{HeaderSafety, Safety, find_attr, intravisit}; +use rustc_hir_pretty::PpAnn; use rustc_metadata::rendered_const; use rustc_middle::ty::TyCtxt; use rustc_middle::{bug, ty}; @@ -1243,7 +1244,10 @@ fn maybe_from_hir_attr(attr: &hir::Attribute, item_id: ItemId, tcx: TyCtxt<'_>) } fn other_attr(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Attribute { - let mut s = rustc_hir_pretty::attribute_to_string(&tcx, attr); + let mut s = rustc_hir_pretty::attribute_to_string( + &(&tcx as &dyn intravisit::HirTyCtxt<'_>) as &dyn PpAnn, + attr, + ); assert_eq!(s.pop(), Some('\n')); Attribute::Other(s) } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 8bf0d7160db8e..fbb8492d8d3ec 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -874,21 +874,24 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { id: ast::DUMMY_NODE_ID, is_placeholder: false, }; - rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { - let has_dep_info = render_options.dep_info().is_some(); - if render_options.emit.contains(&EmitType::HtmlNonStaticFiles) { - markdown::render_and_write(file, render_options, edition)?; - } - if has_dep_info { - // Register the loaded external files in the source map so they show up in depinfo. - // We can't load them via the source map because it gets created after we process the options. - for external_path in &loaded_paths { - let _ = compiler.sess.source_map().load_binary_file(external_path); + let (res, _incr_comp_session) = + rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { + let has_dep_info = render_options.dep_info().is_some(); + if render_options.emit.contains(&EmitType::HtmlNonStaticFiles) { + markdown::render_and_write(file, render_options, edition)?; } - rustc_interface::passes::write_dep_info(tcx); - } - Ok(()) - }) + if has_dep_info { + // Register the loaded external files in the source map so they show up in depinfo. + // We can't load them via the source map because it gets created after we process the options. + for external_path in &loaded_paths { + let _ = + compiler.sess.source_map().load_binary_file(external_path); + } + rustc_interface::passes::write_dep_info(tcx); + } + Ok(()) + }); + res }), ); } @@ -997,7 +1000,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { unreachable!() } } - }) + }); }) } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs index e38ba801c0bf7..9fc9f9944465c 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs @@ -6,6 +6,7 @@ use clippy_utils::{is_in_const_context, is_wild, peel_blocks_with_stmt}; use rustc_hir::{Arm, Expr, PatKind}; use rustc_lint::LateContext; use rustc_span::symbol::{kw, sym}; +use rustc_hir::intravisit; use super::MATCH_WILD_ERR_ARM; @@ -19,7 +20,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<' if ex_ty.is_diag_item(cx, sym::Result) { for arm in arms { if let PatKind::TupleStruct(ref path, inner, _) = arm.pat.kind { - let path_str = rustc_hir_pretty::qpath_to_string(&cx.tcx, path); + let path_str = rustc_hir_pretty::qpath_to_string(#[allow(trivial_casts)] &(&cx.tcx as &dyn intravisit::HirTyCtxt<'_>), path); if path_str == "Err" { let mut matching_wild = inner.iter().any(is_wild); let mut ident_bind_name = kw::Underscore; diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_mut_passed.rs b/src/tools/clippy/clippy_lints/src/unnecessary_mut_passed.rs index 60a6688927ab5..43721fa252837 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_mut_passed.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_mut_passed.rs @@ -6,6 +6,8 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, Ty}; use rustc_session::declare_lint_pass; use std::iter; +use rustc_hir_pretty::PpAnn; +use rustc_hir::intravisit; declare_clippy_lint! { /// ### What it does @@ -51,7 +53,8 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { cx, &mut arguments.iter(), cx.typeck_results().expr_ty(fn_expr), - &rustc_hir_pretty::qpath_to_string(&cx.tcx, path), + #[allow(trivial_casts)] + &rustc_hir_pretty::qpath_to_string(&(&cx.tcx as &dyn intravisit::HirTyCtxt<'_>) as &dyn PpAnn, path), "function", ); } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index 8dc6b5f07b92e..6953a27a39df8 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -132,15 +132,7 @@ pub fn iter_exported_symbols<'tcx>( if !(used || codegen_attrs.contains_extern_indicator()) { continue; } - // FIXME: `#[no_mangle]` makes no sense on a generic item, but still causes it to be - // considered "extern". Remove this once `no_mangle_generic_items` is a hard error. - let mono = { - let generics = tcx.generics_of(def_id); - !generics.requires_monomorphization(tcx) - }; - if mono { - f(LOCAL_CRATE, def_id.into(), used)?; - } + f(LOCAL_CRATE, def_id.into(), used)?; } // Next, all our dependencies. diff --git a/src/tools/miri/test-cargo-miri/issue-rust-86261/src/lib.rs b/src/tools/miri/test-cargo-miri/issue-rust-86261/src/lib.rs index 1947c38b77455..ab0fa8f013968 100644 --- a/src/tools/miri/test-cargo-miri/issue-rust-86261/src/lib.rs +++ b/src/tools/miri/test-cargo-miri/issue-rust-86261/src/lib.rs @@ -1,4 +1,4 @@ -#![allow(unused_imports, unused_attributes, no_mangle_generic_items)] +#![allow(unused_imports, unused_attributes)] // Regression test for https://github.com/rust-lang/rust/issues/86261: // `#[no_mangle]` on a `use` item. @@ -14,10 +14,6 @@ pub struct NoMangleStruct; #[export_name = "NoMangleStruct"] fn no_mangle_struct() {} -// `#[no_mangle]` on a generic function can also cause ICEs. -#[no_mangle] -fn no_mangle_generic() {} - -// Same as `no_mangle_struct()` but for the `no_mangle_generic()` generic function. -#[export_name = "no_mangle_generic"] -fn no_mangle_generic2() {} +// Same as `no_mangle_struct()` but for the `no_mangle_struct()` function. +#[export_name = "no_mangle_struct"] +fn no_mangle_alias() {} diff --git a/src/tools/miri/test-cargo-miri/src/main.rs b/src/tools/miri/test-cargo-miri/src/main.rs index 1568da43afe30..ed16a14e3d60f 100644 --- a/src/tools/miri/test-cargo-miri/src/main.rs +++ b/src/tools/miri/test-cargo-miri/src/main.rs @@ -87,13 +87,13 @@ mod test { fn assoc_fn_as_exported_symbol() -> i32; fn make_true() -> bool; fn NoMangleStruct(); - fn no_mangle_generic(); + fn no_mangle_struct(); } assert_eq!(unsafe { exported_symbol() }, 123456); assert_eq!(unsafe { assoc_fn_as_exported_symbol() }, -123456); assert!(unsafe { make_true() }); unsafe { NoMangleStruct() } - unsafe { no_mangle_generic() } + unsafe { no_mangle_struct() } } } diff --git a/src/tools/miri/tests/pass/issues/issue-154385-no-mangle-generic.rs b/src/tools/miri/tests/pass/issues/issue-154385-no-mangle-generic.rs deleted file mode 100644 index 90fa021863990..0000000000000 --- a/src/tools/miri/tests/pass/issues/issue-154385-no-mangle-generic.rs +++ /dev/null @@ -1,22 +0,0 @@ -fn main() { - generic_type(123); - generic_const::<456>(); - generic_lifetime(&789); -} - -#[allow(no_mangle_generic_items)] -#[unsafe(no_mangle)] -fn generic_type(value: T) { - println!("{value:?}"); -} - -#[expect(no_mangle_generic_items)] -#[unsafe(no_mangle)] -fn generic_const() { - println!("{N}"); -} - -#[unsafe(no_mangle)] -fn generic_lifetime<'a>(x: &'a i32) { - println!("{x}"); -} diff --git a/src/tools/miri/tests/pass/issues/issue-154385-no-mangle-generic.stdout b/src/tools/miri/tests/pass/issues/issue-154385-no-mangle-generic.stdout deleted file mode 100644 index af7864ba2f038..0000000000000 --- a/src/tools/miri/tests/pass/issues/issue-154385-no-mangle-generic.stdout +++ /dev/null @@ -1,3 +0,0 @@ -123 -456 -789 diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 479199414d7ec..734ca79518090 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -719,8 +719,15 @@ fn check_proc_macro_dep_list(root: &Path, cargo: &Path, bless: bool, check: &mut // Remove the proc-macro crates themselves proc_macro_deps.retain(|pkg| !is_proc_macro_pkg(&metadata[pkg])); // Sort and deduplicate the crate names. - let proc_macro_deps = - proc_macro_deps.into_iter().map(|dep| metadata[dep].name.as_ref()).collect::>(); + // Cargo package names may contain `-`, but will normalize these to `_` before passing to rustc. + // As bootstrap parses the `--crate-name` flag, use the name of the actual lib target which has + // been normalized. + let proc_macro_deps = proc_macro_deps + .into_iter() + .filter_map(|dep| { + metadata[dep].targets.iter().find_map(|target| target.is_lib().then_some(&target.name)) + }) + .collect::>(); let expected = { use std::fmt::Write; diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index 15da022203ade..0f9f68cfde787 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -229,9 +229,9 @@ //@ revisions: armv7a_nuttx_eabihf //@ [armv7a_nuttx_eabihf] compile-flags: --target armv7a-nuttx-eabihf //@ [armv7a_nuttx_eabihf] needs-llvm-components: arm -//@ revisions: armv7a_vex_v5 -//@ [armv7a_vex_v5] compile-flags: --target armv7a-vex-v5 -//@ [armv7a_vex_v5] needs-llvm-components: arm +//@ revisions: thumbv7a_vex_v5 +//@ [thumbv7a_vex_v5] compile-flags: --target thumbv7a-vex-v5 +//@ [thumbv7a_vex_v5] needs-llvm-components: arm //@ revisions: armv7r_none_eabi //@ [armv7r_none_eabi] compile-flags: --target armv7r-none-eabi //@ [armv7r_none_eabi] needs-llvm-components: arm diff --git a/tests/codegen-llvm/avr/avr-func-addrspace.rs b/tests/codegen-llvm/avr/avr-func-addrspace.rs index 2a40f0f247542..8812992050325 100644 --- a/tests/codegen-llvm/avr/avr-func-addrspace.rs +++ b/tests/codegen-llvm/avr/avr-func-addrspace.rs @@ -30,7 +30,6 @@ fn arbitrary_black_box(ptr: &usize, _: &mut u32) -> Result<(), ()> { } #[inline(never)] -#[no_mangle] fn call_through_fn_trait(a: &mut impl Fn<(), Output = ()>) { (*a)() } @@ -49,7 +48,7 @@ pub extern "C" fn test() { // A call through the Fn trait must use address space 1. // - // CHECK: call{{.+}}addrspace(1) void @call_through_fn_trait({{.*}}) + // CHECK: call{{.+}}addrspace(1) void @{{.*call_through_fn_trait.*}}({{.*}}) call_through_fn_trait(&mut update_bar_value); // A call through a global variable must use address space 1. diff --git a/tests/crashes/126268.rs b/tests/crashes/102252-2.rs similarity index 86% rename from tests/crashes/126268.rs rename to tests/crashes/102252-2.rs index 82e52fa115dc9..ccb15b82736e2 100644 --- a/tests/crashes/126268.rs +++ b/tests/crashes/102252-2.rs @@ -1,4 +1,5 @@ -//@ known-bug: #126268 +//@ known-bug: #102252 + #![feature(min_specialization)] trait Trait {} @@ -16,3 +17,5 @@ struct DatasetIter<'a, R: Data> { pub struct ArrayBase {} impl<'a> Trait for DatasetIter<'a, ArrayBase> {} + +fn main() {} diff --git a/tests/crashes/125014.rs b/tests/crashes/125014.rs deleted file mode 100644 index b29042ee5983a..0000000000000 --- a/tests/crashes/125014.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: rust-lang/rust#125014 -//@ compile-flags: -Znext-solver=coherence -#![feature(specialization)] - -trait Foo {} - -impl Foo for ::Output {} - -impl Foo for u32 {} - -trait Assoc { - type Output; -} -impl Output for u32 {} -impl Assoc for ::Output { - default type Output = bool; -} diff --git a/tests/run-make/autodiff/type-trees/slice-dst-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/slice-dst-typetree/rmake.rs new file mode 100644 index 0000000000000..e0c8c87ca9e33 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/slice-dst-typetree/rmake.rs @@ -0,0 +1,19 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + rustc() + .input("test.rs") + .arg("-Zautodiff=Enable,NoPostopt") + .opt_level("0") + .arg("-Clto=fat") + .emit("llvm-ir") + .run(); + + let ir = rfs::read("test.ll"); + llvm_filecheck().patterns("slice-dst.check").check_prefix("OSSTR").stdin_buf(&ir).run(); + llvm_filecheck().patterns("slice-dst.check").check_prefix("HEADER").stdin_buf(&ir).run(); + llvm_filecheck().patterns("slice-dst.check").check_prefix("ZST").stdin_buf(&ir).run(); +} diff --git a/tests/run-make/autodiff/type-trees/slice-dst-typetree/slice-dst.check b/tests/run-make/autodiff/type-trees/slice-dst-typetree/slice-dst.check new file mode 100644 index 0000000000000..4b149c9ee090c --- /dev/null +++ b/tests/run-make/autodiff/type-trees/slice-dst-typetree/slice-dst.check @@ -0,0 +1,14 @@ +; Preserve element metadata for the `OsStr` regression from #160327. +OSSTR-LABEL: define void @split_once( +OSSTR-NOT: define +OSSTR: call void @llvm.memcpy{{.*}}"enzyme_type"="{[0]:Pointer, [0,0]:Pointer, [0,0,-1]:Integer, [0,16]:Pointer, [0,16,-1]:Integer}" + +; Preserve both data layout and length metadata for a prefixed slice-tail DST. +HEADER-LABEL: define{{.*}}@header_sum( +HEADER-SAME: ptr{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@float, [-1,4]:Float@float}" +HEADER-SAME: i64 "enzyme_type"="{[0]:Integer}" + +; ZST elements produce no child metadata under the slice data pointer. +ZST-LABEL: define{{.*}}@zst_slice_len( +ZST-SAME: ptr{{.*}}"enzyme_type"="{[-1]:Pointer}" +ZST-SAME: i64 "enzyme_type"="{[0]:Integer}" diff --git a/tests/run-make/autodiff/type-trees/slice-dst-typetree/test.rs b/tests/run-make/autodiff/type-trees/slice-dst-typetree/test.rs new file mode 100644 index 0000000000000..e34a8c71f4cc5 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/slice-dst-typetree/test.rs @@ -0,0 +1,51 @@ +#![crate_type = "lib"] +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; +use std::ffi::OsStr; + +// Reduced from `clap_lex::OsStrExt::split_once`. +#[no_mangle] +#[inline(never)] +pub fn split_once<'s>(arg: &'s OsStr, needle: &str) -> Option<(&'s OsStr, &'s OsStr)> { + let bytes = arg.as_encoded_bytes(); + let index = bytes.windows(needle.len()).position(|window| window == needle.as_bytes())?; + let (first, second) = bytes.split_at(index + needle.len()); + unsafe { + Some(( + OsStr::from_encoded_bytes_unchecked(first), + OsStr::from_encoded_bytes_unchecked(second), + )) + } +} + +#[repr(C)] +pub struct Header { + tag: f32, + data: T, +} + +#[autodiff_reverse(d_header_sum, Duplicated, Active)] +#[no_mangle] +#[inline(never)] +pub fn header_sum(value: &Header<[f32]>) -> f32 { + value.tag + value.data.iter().sum::() +} + +#[no_mangle] +pub fn exercise_header_sum(value: &Header<[f32]>, derivative: &mut Header<[f32]>) -> f32 { + d_header_sum(value, derivative, 1.0) +} + +// ZST slice elements yield an empty child TypeTree; element size 0 is expected. +#[autodiff_reverse(d_zst_slice_len, Duplicated, Active)] +#[no_mangle] +#[inline(never)] +pub fn zst_slice_len(slice: &[()]) -> f32 { + slice.len() as f32 +} + +#[no_mangle] +pub fn exercise_zst_slice_len(slice: &[()], derivative: &mut [()]) -> f32 { + d_zst_slice_len(slice, derivative, 1.0) +} diff --git a/tests/rustdoc-js/auxiliary/interner.rs b/tests/rustdoc-js/auxiliary/interner.rs index 8af3b732ef7a0..c61d5a4dfec72 100644 --- a/tests/rustdoc-js/auxiliary/interner.rs +++ b/tests/rustdoc-js/auxiliary/interner.rs @@ -68,8 +68,8 @@ pub trait Interner: Sized { type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike; type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable + Flags; type TraitPredicate: Copy + Debug + Hash + Eq; - type RegionOutlivesPredicate: Copy + Debug + Hash + Eq; - type TypeOutlivesPredicate: Copy + Debug + Hash + Eq; + type RegionOutlivesClause: Copy + Debug + Hash + Eq; + type TypeOutlivesClause: Copy + Debug + Hash + Eq; type ProjectionPredicate: Copy + Debug + Hash + Eq; type NormalizesTo: Copy + Debug + Hash + Eq; type SubtypePredicate: Copy + Debug + Hash + Eq; diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index 610a4990a5a4b..5ddaed75aa323 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -16,8 +16,8 @@ use rustc_codegen_ssa::{CompiledModules, CrateInfo}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::WorkProductMap; use rustc_middle::ty::TyCtxt; -use rustc_session::Session; use rustc_session::config::OutputFilenames; +use rustc_session::{IncrCompSession, Session}; struct TheBackend; @@ -38,6 +38,7 @@ impl CodegenBackend for TheBackend { &self, ongoing_codegen: Box, _sess: &Session, + _incr_comp_session: Option<&IncrCompSession>, _outputs: &OutputFilenames, _crate_info: &CrateInfo, ) -> (CompiledModules, WorkProductMap) { diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs index d99d9c42d547f..ae0f41a205bf4 100644 --- a/tests/ui-fulldeps/run-compiler-twice.rs +++ b/tests/ui-fulldeps/run-compiler-twice.rs @@ -76,10 +76,11 @@ fn compile(code: String, output: PathBuf, sysroot: Sysroot, linker: Option<&Path interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); - let linker = rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { - let _ = tcx.analysis(()); - Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend) - }); - linker.link(&compiler.sess, &*compiler.codegen_backend); + let (linker, incr_comp_session) = + rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + let _ = tcx.analysis(()); + Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend) + }); + linker.link(&compiler.sess, incr_comp_session, &*compiler.codegen_backend); }); } diff --git a/tests/ui/associated-types/normalization-generality-2.rs b/tests/ui/associated-types/normalization-generality-2.rs index 2a50f7e449add..2e7f317bd6f68 100644 --- a/tests/ui/associated-types/normalization-generality-2.rs +++ b/tests/ui/associated-types/normalization-generality-2.rs @@ -5,7 +5,7 @@ // Ensures that we don't regress on "implementation is not general enough" when // normalizating under binders. Unlike `normalization-generality.rs`, this also produces -// type outlives predicates that we must ignore. +// type outlives clauses that we must ignore. pub unsafe trait Yokeable<'a> { type Output: 'a; diff --git a/tests/ui/backtrace/auxiliary/line-tables-only-helper.rs b/tests/ui/backtrace/auxiliary/line-tables-only-helper.rs index a9d555feb86b3..993632ea1a112 100644 --- a/tests/ui/backtrace/auxiliary/line-tables-only-helper.rs +++ b/tests/ui/backtrace/auxiliary/line-tables-only-helper.rs @@ -1,16 +1,13 @@ //@ compile-flags: -Cstrip=none -Cdebuginfo=line-tables-only -#[no_mangle] pub fn backtrace_with_baz_in_it(mut cb: F, data: u32) where F: FnMut(u32) { cb(data); } -#[no_mangle] pub fn backtrace_with_bar_in_it(cb: F, data: u32) where F: FnMut(u32) { backtrace_with_baz_in_it(cb, data); } -#[no_mangle] pub fn backtrace_with_foo_in_it(cb: F, data: u32) where F: FnMut(u32) { backtrace_with_bar_in_it(cb, data); } diff --git a/tests/ui/backtrace/line-tables-only.rs b/tests/ui/backtrace/line-tables-only.rs index 320ad93393c71..33d5774079d94 100644 --- a/tests/ui/backtrace/line-tables-only.rs +++ b/tests/ui/backtrace/line-tables-only.rs @@ -32,9 +32,7 @@ fn assert_contains( expected_line: u32, ) { // The formatted frames look like this: - // `{ fn: "backtrace_with_baz_in_it", file: ".../tests/ui/backtrace/auxiliary/line-tables-only-helper.rs", line: 5 }` - // or this: - // `{ fn: "line_tables_only_helper::backtrace_with_baz_in_it", file: "...\tests\ui\backtrace\auxiliary\line-tables-only-helper.rs", line: 5 },` + // `{ fn: "line_tables_only_helper::backtrace_with_baz_in_it::", file: ".../tests/ui/backtrace/auxiliary/line-tables-only-helper.rs", line: 4 }, // Make sure we match the right part when searching for the function name and line number. let expected_line_str = format!("line: {expected_line} "); eprintln!("{:#?}", backtrace); @@ -63,8 +61,8 @@ fn main() { // And with #143208 we also lost `bar` in the line tables. #[cfg(not(all(target_pointer_width = "32", target_env = "msvc")))] { - assert_contains(&backtrace, "backtrace_with_foo_in_it", "line-tables-only-helper.rs", 15); - assert_contains(&backtrace, "backtrace_with_bar_in_it", "line-tables-only-helper.rs", 10); + assert_contains(&backtrace, "backtrace_with_foo_in_it", "line-tables-only-helper.rs", 12); + assert_contains(&backtrace, "backtrace_with_bar_in_it", "line-tables-only-helper.rs", 8); } - assert_contains(&backtrace, "backtrace_with_baz_in_it", "line-tables-only-helper.rs", 5); + assert_contains(&backtrace, "backtrace_with_baz_in_it", "line-tables-only-helper.rs", 4); } diff --git a/tests/ui/compile-flags/jobs/jobs-pass-link.rs b/tests/ui/compile-flags/jobs/jobs-pass-link.rs index 70058dfcf7bf6..847a0d10ff977 100644 --- a/tests/ui/compile-flags/jobs/jobs-pass-link.rs +++ b/tests/ui/compile-flags/jobs/jobs-pass-link.rs @@ -1,4 +1,4 @@ //@ build-pass -//@ compile-flags: -Z unstable-options --jobs-linker 2 +//@ compile-flags: -Z unstable-options --jobs-linker 2 --jobs-backend 1 fn main() {} diff --git a/tests/ui/const-generics/mgca/opaque-ty-assoc-const-equality-117923.rs b/tests/ui/const-generics/mgca/opaque-ty-assoc-const-equality-117923.rs new file mode 100644 index 0000000000000..37f32038c55f4 --- /dev/null +++ b/tests/ui/const-generics/mgca/opaque-ty-assoc-const-equality-117923.rs @@ -0,0 +1,22 @@ +//! Regression test for . +//@ check-pass +#![feature(min_generic_const_args, macroless_generic_const_args)] +#![allow(incomplete_features, dead_code)] + +trait Trait { + type const CT: usize; +} + +struct Type { + field: [u8; N], +} + +impl Trait for Type { + type const CT: usize = N; +} + +fn func() -> impl Trait as Trait>::CT }> { + Type { field: [0; N] } +} + +fn main() {} diff --git a/tests/ui/fmt/no-inline-literals-out-of-range.stderr b/tests/ui/fmt/no-inline-literals-out-of-range.stderr index 0800fb2497619..744a4e5625fef 100644 --- a/tests/ui/fmt/no-inline-literals-out-of-range.stderr +++ b/tests/ui/fmt/no-inline-literals-out-of-range.stderr @@ -13,8 +13,9 @@ LL + format_args!("{}", 0x8f_u8); // issue #115423 | help: to use as a negative number (decimal `-113`), consider using the type `u8` for the literal and cast it to `i8` | -LL | format_args!("{}", 0x8f_u8 as i8); // issue #115423 - | +++++ +LL - format_args!("{}", 0x8f_i8); // issue #115423 +LL + format_args!("{}", 0x8f_u8.cast_signed()); // issue #115423 + | error: literal out of range for `u8` --> $DIR/no-inline-literals-out-of-range.rs:6:24 @@ -50,8 +51,8 @@ LL | format_args!("{}", 0xffff_ffff); // treat unsuffixed literals as i32 = help: consider using the type `u32` instead help: to use as a negative number (decimal `-1`), consider using the type `u32` for the literal and cast it to `i32` | -LL | format_args!("{}", 0xffff_ffffu32 as i32); // treat unsuffixed literals as i32 - | ++++++++++ +LL | format_args!("{}", 0xffff_ffffu32.cast_signed()); // treat unsuffixed literals as i32 + | +++++++++++++++++ error: aborting due to 5 previous errors diff --git a/tests/ui/generics/export-name-on-generics.fixed b/tests/ui/generics/export-name-on-generics.fixed deleted file mode 100644 index c8a3fd5798f86..0000000000000 --- a/tests/ui/generics/export-name-on-generics.fixed +++ /dev/null @@ -1,157 +0,0 @@ -//@ run-rustfix -#![allow(dead_code, mismatched_lifetime_syntaxes)] -#![deny(no_mangle_generic_items)] - -pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled - -pub extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - -#[export_name = "baz"] -pub fn baz(x: &i32) -> &i32 { x } - -#[export_name = "qux"] -pub fn qux<'a>(x: &'a i32) -> &i32 { x } - -pub struct Foo; - -impl Foo { - - pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled - - - pub extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - - #[export_name = "baz"] - pub fn baz(x: &i32) -> &i32 { x } - - #[export_name = "qux"] - pub fn qux<'a>(x: &'a i32) -> &i32 { x } -} - -trait Trait1 { - fn foo(); - extern "C" fn bar(); - fn baz(x: &i32) -> &i32; - fn qux<'a>(x: &'a i32) -> &i32; -} - -impl Trait1 for Foo { - - fn foo() {} //~ ERROR functions generic over types or consts must be mangled - - - extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - - #[export_name = "baz"] - fn baz(x: &i32) -> &i32 { x } - - #[export_name = "qux"] - fn qux<'a>(x: &'a i32) -> &i32 { x } -} - -trait Trait2 { - fn foo(); - fn foo2(); - extern "C" fn bar(); - fn baz(x: &i32) -> &i32; - fn qux<'a>(x: &'a i32) -> &i32; -} - -impl Trait2 for Foo { - - fn foo() {} //~ ERROR functions generic over types or consts must be mangled - - - fn foo2() {} //~ ERROR functions generic over types or consts must be mangled - - - extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - - - fn baz(x: &i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled - - - fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled -} - -pub struct Bar(#[allow(dead_code)] T); - -impl Bar { - - pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled - - - pub extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - - - pub fn baz() {} //~ ERROR functions generic over types or consts must be mangled -} - -impl Bar { - #[export_name = "qux"] - pub fn qux() {} -} - -trait Trait3 { - fn foo(); - extern "C" fn bar(); - fn baz(); -} - -impl Trait3 for Bar { - - fn foo() {} //~ ERROR functions generic over types or consts must be mangled - - - extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - - - fn baz() {} //~ ERROR functions generic over types or consts must be mangled -} - -pub struct Baz<'a>(#[allow(dead_code)] &'a i32); - -impl<'a> Baz<'a> { - #[export_name = "foo"] - pub fn foo() {} - - #[export_name = "bar"] - pub fn bar<'b>(x: &'b i32) -> &i32 { x } -} - -trait Trait4 { - fn foo(); - fn bar<'a>(x: &'a i32) -> &i32; -} - -impl Trait4 for Bar { - #[export_name = "foo"] - fn foo() {} - - #[export_name = "bar"] - fn bar<'b>(x: &'b i32) -> &i32 { x } -} - -impl<'a> Trait4 for Baz<'a> { - #[export_name = "foo"] - fn foo() {} - - #[export_name = "bar"] - fn bar<'b>(x: &'b i32) -> &i32 { x } -} - -trait Trait5 { - fn foo(); -} - -impl Trait5 for Foo { - #[export_name = "foo"] - fn foo() {} -} - -impl Trait5 for Bar { - #[export_name = "foo"] - fn foo() {} -} - -fn main() {} diff --git a/tests/ui/generics/export-name-on-generics.rs b/tests/ui/generics/export-name-on-generics.rs index 8b38037fe12fb..8178fee78a30c 100644 --- a/tests/ui/generics/export-name-on-generics.rs +++ b/tests/ui/generics/export-name-on-generics.rs @@ -1,6 +1,4 @@ -//@ run-rustfix #![allow(dead_code, mismatched_lifetime_syntaxes)] -#![deny(no_mangle_generic_items)] #[export_name = "foo"] pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled diff --git a/tests/ui/generics/export-name-on-generics.stderr b/tests/ui/generics/export-name-on-generics.stderr index e08b2b1c8f319..d680430ca867d 100644 --- a/tests/ui/generics/export-name-on-generics.stderr +++ b/tests/ui/generics/export-name-on-generics.stderr @@ -1,19 +1,13 @@ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:6:1 + --> $DIR/export-name-on-generics.rs:4:1 | LL | #[export_name = "foo"] | ---------------------- help: remove this attribute LL | pub fn foo() {} | ^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/export-name-on-generics.rs:3:9 - | -LL | #![deny(no_mangle_generic_items)] - | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:9:1 + --> $DIR/export-name-on-generics.rs:7:1 | LL | #[export_name = "bar"] | ---------------------- help: remove this attribute @@ -21,7 +15,7 @@ LL | pub extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:21:5 + --> $DIR/export-name-on-generics.rs:19:5 | LL | #[export_name = "foo"] | ---------------------- help: remove this attribute @@ -29,7 +23,7 @@ LL | pub fn foo() {} | ^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:24:5 + --> $DIR/export-name-on-generics.rs:22:5 | LL | #[export_name = "bar"] | ---------------------- help: remove this attribute @@ -37,7 +31,7 @@ LL | pub extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:42:5 + --> $DIR/export-name-on-generics.rs:40:5 | LL | #[export_name = "foo"] | ---------------------- help: remove this attribute @@ -45,7 +39,7 @@ LL | fn foo() {} | ^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:45:5 + --> $DIR/export-name-on-generics.rs:43:5 | LL | #[export_name = "bar"] | ---------------------- help: remove this attribute @@ -53,7 +47,7 @@ LL | extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:64:5 + --> $DIR/export-name-on-generics.rs:62:5 | LL | #[export_name = "foo"] | ---------------------- help: remove this attribute @@ -61,7 +55,7 @@ LL | fn foo() {} | ^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:67:5 + --> $DIR/export-name-on-generics.rs:65:5 | LL | #[export_name = "foo2"] | ----------------------- help: remove this attribute @@ -69,7 +63,7 @@ LL | fn foo2() {} | ^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:70:5 + --> $DIR/export-name-on-generics.rs:68:5 | LL | #[export_name = "baz"] | ---------------------- help: remove this attribute @@ -77,7 +71,7 @@ LL | extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:73:5 + --> $DIR/export-name-on-generics.rs:71:5 | LL | #[export_name = "baz"] | ---------------------- help: remove this attribute @@ -85,7 +79,7 @@ LL | fn baz(x: &i32) -> &i32 { x } | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:76:5 + --> $DIR/export-name-on-generics.rs:74:5 | LL | #[export_name = "qux"] | ---------------------- help: remove this attribute @@ -93,7 +87,7 @@ LL | fn qux<'a>(x: &'a i32) -> &i32 { x } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:83:5 + --> $DIR/export-name-on-generics.rs:81:5 | LL | #[export_name = "foo"] | ---------------------- help: remove this attribute @@ -101,7 +95,7 @@ LL | pub fn foo() {} | ^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:86:5 + --> $DIR/export-name-on-generics.rs:84:5 | LL | #[export_name = "bar"] | ---------------------- help: remove this attribute @@ -109,7 +103,7 @@ LL | pub extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:89:5 + --> $DIR/export-name-on-generics.rs:87:5 | LL | #[export_name = "baz"] | ---------------------- help: remove this attribute @@ -117,7 +111,7 @@ LL | pub fn baz() {} | ^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:105:5 + --> $DIR/export-name-on-generics.rs:103:5 | LL | #[export_name = "foo"] | ---------------------- help: remove this attribute @@ -125,7 +119,7 @@ LL | fn foo() {} | ^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:108:5 + --> $DIR/export-name-on-generics.rs:106:5 | LL | #[export_name = "bar"] | ---------------------- help: remove this attribute @@ -133,7 +127,7 @@ LL | extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/export-name-on-generics.rs:111:5 + --> $DIR/export-name-on-generics.rs:109:5 | LL | #[export_name = "baz"] | ---------------------- help: remove this attribute diff --git a/tests/ui/generics/generic-no-mangle.fixed b/tests/ui/generics/generic-no-mangle.fixed deleted file mode 100644 index e3e41eb9d0db1..0000000000000 --- a/tests/ui/generics/generic-no-mangle.fixed +++ /dev/null @@ -1,157 +0,0 @@ -//@ run-rustfix -#![allow(dead_code, mismatched_lifetime_syntaxes)] -#![deny(no_mangle_generic_items)] - -pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled - -pub extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - -#[no_mangle] -pub fn baz(x: &i32) -> &i32 { x } - -#[no_mangle] -pub fn qux<'a>(x: &'a i32) -> &i32 { x } - -pub struct Foo; - -impl Foo { - - pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled - - - pub extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - - #[no_mangle] - pub fn baz(x: &i32) -> &i32 { x } - - #[no_mangle] - pub fn qux<'a>(x: &'a i32) -> &i32 { x } -} - -trait Trait1 { - fn foo(); - extern "C" fn bar(); - fn baz(x: &i32) -> &i32; - fn qux<'a>(x: &'a i32) -> &i32; -} - -impl Trait1 for Foo { - - fn foo() {} //~ ERROR functions generic over types or consts must be mangled - - - extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - - #[no_mangle] - fn baz(x: &i32) -> &i32 { x } - - #[no_mangle] - fn qux<'a>(x: &'a i32) -> &i32 { x } -} - -trait Trait2 { - fn foo(); - fn foo2(); - extern "C" fn bar(); - fn baz(x: &i32) -> &i32; - fn qux<'a>(x: &'a i32) -> &i32; -} - -impl Trait2 for Foo { - - fn foo() {} //~ ERROR functions generic over types or consts must be mangled - - - fn foo2() {} //~ ERROR functions generic over types or consts must be mangled - - - extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - - - fn baz(x: &i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled - - - fn qux<'a>(x: &'a i32) -> &i32 { x } //~ ERROR functions generic over types or consts must be mangled -} - -pub struct Bar(#[allow(dead_code)] T); - -impl Bar { - - pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled - - - pub extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - - - pub fn baz() {} //~ ERROR functions generic over types or consts must be mangled -} - -impl Bar { - #[no_mangle] - pub fn qux() {} -} - -trait Trait3 { - fn foo(); - extern "C" fn bar(); - fn baz(); -} - -impl Trait3 for Bar { - - fn foo() {} //~ ERROR functions generic over types or consts must be mangled - - - extern "C" fn bar() {} //~ ERROR functions generic over types or consts must be mangled - - - fn baz() {} //~ ERROR functions generic over types or consts must be mangled -} - -pub struct Baz<'a>(#[allow(dead_code)] &'a i32); - -impl<'a> Baz<'a> { - #[no_mangle] - pub fn foo() {} - - #[no_mangle] - pub fn bar<'b>(x: &'b i32) -> &i32 { x } -} - -trait Trait4 { - fn foo(); - fn bar<'a>(x: &'a i32) -> &i32; -} - -impl Trait4 for Bar { - #[no_mangle] - fn foo() {} - - #[no_mangle] - fn bar<'b>(x: &'b i32) -> &i32 { x } -} - -impl<'a> Trait4 for Baz<'a> { - #[no_mangle] - fn foo() {} - - #[no_mangle] - fn bar<'b>(x: &'b i32) -> &i32 { x } -} - -trait Trait5 { - fn foo(); -} - -impl Trait5 for Foo { - #[no_mangle] - fn foo() {} -} - -impl Trait5 for Bar { - #[no_mangle] - fn foo() {} -} - -fn main() {} diff --git a/tests/ui/generics/generic-no-mangle.rs b/tests/ui/generics/generic-no-mangle.rs index 085f8610a548e..b3313538a9905 100644 --- a/tests/ui/generics/generic-no-mangle.rs +++ b/tests/ui/generics/generic-no-mangle.rs @@ -1,6 +1,4 @@ -//@ run-rustfix #![allow(dead_code, mismatched_lifetime_syntaxes)] -#![deny(no_mangle_generic_items)] #[no_mangle] pub fn foo() {} //~ ERROR functions generic over types or consts must be mangled @@ -14,6 +12,9 @@ pub fn baz(x: &i32) -> &i32 { x } #[no_mangle] pub fn qux<'a>(x: &'a i32) -> &i32 { x } +#[no_mangle] +pub fn generic_const() {} //~ ERROR functions generic over types or consts must be mangled + pub struct Foo; impl Foo { diff --git a/tests/ui/generics/generic-no-mangle.stderr b/tests/ui/generics/generic-no-mangle.stderr index 39fbe4dd76da1..4b267d0dcc55f 100644 --- a/tests/ui/generics/generic-no-mangle.stderr +++ b/tests/ui/generics/generic-no-mangle.stderr @@ -1,19 +1,13 @@ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:6:1 + --> $DIR/generic-no-mangle.rs:4:1 | LL | #[no_mangle] | ------------ help: remove this attribute LL | pub fn foo() {} | ^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/generic-no-mangle.rs:3:9 - | -LL | #![deny(no_mangle_generic_items)] - | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:9:1 + --> $DIR/generic-no-mangle.rs:7:1 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -21,7 +15,15 @@ LL | pub extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:21:5 + --> $DIR/generic-no-mangle.rs:16:1 + | +LL | #[no_mangle] + | ------------ help: remove this attribute +LL | pub fn generic_const() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: functions generic over types or consts must be mangled + --> $DIR/generic-no-mangle.rs:22:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -29,7 +31,7 @@ LL | pub fn foo() {} | ^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:24:5 + --> $DIR/generic-no-mangle.rs:25:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -37,7 +39,7 @@ LL | pub extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:42:5 + --> $DIR/generic-no-mangle.rs:43:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -45,7 +47,7 @@ LL | fn foo() {} | ^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:45:5 + --> $DIR/generic-no-mangle.rs:46:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -53,7 +55,7 @@ LL | extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:64:5 + --> $DIR/generic-no-mangle.rs:65:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -61,7 +63,7 @@ LL | fn foo() {} | ^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:67:5 + --> $DIR/generic-no-mangle.rs:68:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -69,7 +71,7 @@ LL | fn foo2() {} | ^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:70:5 + --> $DIR/generic-no-mangle.rs:71:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -77,7 +79,7 @@ LL | extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:73:5 + --> $DIR/generic-no-mangle.rs:74:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -85,7 +87,7 @@ LL | fn baz(x: &i32) -> &i32 { x } | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:76:5 + --> $DIR/generic-no-mangle.rs:77:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -93,7 +95,7 @@ LL | fn qux<'a>(x: &'a i32) -> &i32 { x } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:83:5 + --> $DIR/generic-no-mangle.rs:84:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -101,7 +103,7 @@ LL | pub fn foo() {} | ^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:86:5 + --> $DIR/generic-no-mangle.rs:87:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -109,7 +111,7 @@ LL | pub extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:89:5 + --> $DIR/generic-no-mangle.rs:90:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -117,7 +119,7 @@ LL | pub fn baz() {} | ^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:105:5 + --> $DIR/generic-no-mangle.rs:106:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -125,7 +127,7 @@ LL | fn foo() {} | ^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:108:5 + --> $DIR/generic-no-mangle.rs:109:5 | LL | #[no_mangle] | ------------ help: remove this attribute @@ -133,12 +135,12 @@ LL | extern "C" fn bar() {} | ^^^^^^^^^^^^^^^^^^^ error: functions generic over types or consts must be mangled - --> $DIR/generic-no-mangle.rs:111:5 + --> $DIR/generic-no-mangle.rs:112:5 | LL | #[no_mangle] | ------------ help: remove this attribute LL | fn baz() {} | ^^^^^^^^^^^ -error: aborting due to 17 previous errors +error: aborting due to 18 previous errors diff --git a/tests/ui/higher-ranked/hrtb-projection-closure-return-34430.rs b/tests/ui/higher-ranked/hrtb-projection-closure-return-34430.rs new file mode 100644 index 0000000000000..abdaed95007e2 --- /dev/null +++ b/tests/ui/higher-ranked/hrtb-projection-closure-return-34430.rs @@ -0,0 +1,41 @@ +//! Regression test for . +//! +//! An associated-type projection under a higher-ranked binder +//! (`for<'a> FnOnce(&'a Foo) -> >::Type`) failed to normalize, +//! so returning `&'a Foo` from the closure was rejected even though +//! `>::Type` *is* `&'a Foo`. + +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ check-pass + +#![allow(unused)] + +trait WithLifetime<'a> { + type Type; +} + +struct Foo; + +enum FooRef {} + +impl<'a> WithLifetime<'a> for FooRef { + type Type = &'a Foo; +} + +fn wub(f: F) +where + T: for<'a> WithLifetime<'a>, + F: for<'a> FnOnce(&'a Foo) -> >::Type, +{ +} + +fn main() { + wub::(|foo| foo); + + // Annotating the closure's return type used to ICE instead. Both the concrete + // and the projected spelling are checked, since either could regress alone. + wub::(|foo| -> &Foo { foo }); + wub::(|foo| -> ::Type { foo }); +} diff --git a/tests/ui/lint/suggestions.fixed b/tests/ui/lint/suggestions.fixed index 698cc3f34499f..6fd991e60d4c4 100644 --- a/tests/ui/lint/suggestions.fixed +++ b/tests/ui/lint/suggestions.fixed @@ -9,7 +9,7 @@ //~^ HELP remove this attribute pub fn defiant(_t: T) {} -//~^ WARN functions generic over types or consts must be mangled +//~^ ERROR functions generic over types or consts must be mangled #[no_mangle] fn rio_grande() {} @@ -23,7 +23,7 @@ mod badlands { //~| HELP try a static value #[allow(dead_code)] // for rustfix pub fn val_jean() {} - //~^ WARN functions generic over types or consts must be mangled + //~^ ERROR functions generic over types or consts must be mangled //~| HELP remove this attribute // ... but we can suggest just-`pub` instead of restricted @@ -32,7 +32,7 @@ mod badlands { //~| HELP try a static value #[allow(dead_code)] // for rustfix pub(crate) fn crossfield() {} - //~^ WARN functions generic over types or consts must be mangled + //~^ ERROR functions generic over types or consts must be mangled //~| HELP remove this attribute } diff --git a/tests/ui/lint/suggestions.rs b/tests/ui/lint/suggestions.rs index 6e4c389a9c8c2..c2d422828649a 100644 --- a/tests/ui/lint/suggestions.rs +++ b/tests/ui/lint/suggestions.rs @@ -10,7 +10,7 @@ #[no_mangle] //~^ HELP remove this attribute pub fn defiant(_t: T) {} -//~^ WARN functions generic over types or consts must be mangled +//~^ ERROR functions generic over types or consts must be mangled #[no_mangle] fn rio_grande() {} @@ -24,7 +24,7 @@ mod badlands { //~| HELP try a static value #[allow(dead_code)] // for rustfix #[no_mangle] pub fn val_jean() {} - //~^ WARN functions generic over types or consts must be mangled + //~^ ERROR functions generic over types or consts must be mangled //~| HELP remove this attribute // ... but we can suggest just-`pub` instead of restricted @@ -33,7 +33,7 @@ mod badlands { //~| HELP try a static value #[allow(dead_code)] // for rustfix #[no_mangle] pub(crate) fn crossfield() {} - //~^ WARN functions generic over types or consts must be mangled + //~^ ERROR functions generic over types or consts must be mangled //~| HELP remove this attribute } diff --git a/tests/ui/lint/suggestions.stderr b/tests/ui/lint/suggestions.stderr index c6a7de51da2e6..68bf80e89e1bd 100644 --- a/tests/ui/lint/suggestions.stderr +++ b/tests/ui/lint/suggestions.stderr @@ -58,7 +58,7 @@ LL | #[no_mangle] const DISCOVERY: usize = 1; | = note: `#[deny(no_mangle_const_items)]` on by default -warning: functions generic over types or consts must be mangled +error: functions generic over types or consts must be mangled --> $DIR/suggestions.rs:12:1 | LL | #[no_mangle] @@ -66,8 +66,6 @@ LL | #[no_mangle] LL | LL | pub fn defiant(_t: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(no_mangle_generic_items)]` on by default warning: the `warp_factor:` in this pattern is redundant --> $DIR/suggestions.rs:61:23 @@ -85,7 +83,7 @@ LL | #[no_mangle] pub const DAUNTLESS: bool = true; | | | help: try a static value: `pub static` -warning: functions generic over types or consts must be mangled +error: functions generic over types or consts must be mangled --> $DIR/suggestions.rs:26:18 | LL | #[no_mangle] pub fn val_jean() {} @@ -101,7 +99,7 @@ LL | #[no_mangle] pub(crate) const VETAR: bool = true; | | | help: try a static value: `pub static` -warning: functions generic over types or consts must be mangled +error: functions generic over types or consts must be mangled --> $DIR/suggestions.rs:35:18 | LL | #[no_mangle] pub(crate) fn crossfield() {} @@ -109,5 +107,5 @@ LL | #[no_mangle] pub(crate) fn crossfield() {} | | | help: remove this attribute -error: aborting due to 3 previous errors; 8 warnings emitted +error: aborting due to 6 previous errors; 5 warnings emitted diff --git a/tests/ui/lint/type-overflow.stderr b/tests/ui/lint/type-overflow.stderr index 065c530adcf57..66d856dac3bdf 100644 --- a/tests/ui/lint/type-overflow.stderr +++ b/tests/ui/lint/type-overflow.stderr @@ -26,8 +26,9 @@ LL + let fail = 0b1000_0001u8; | help: to use as a negative number (decimal `-127`), consider using the type `u8` for the literal and cast it to `i8` | -LL | let fail = 0b1000_0001u8 as i8; - | +++++ +LL - let fail = 0b1000_0001i8; +LL + let fail = 0b1000_0001u8.cast_signed(); + | warning: literal out of range for `i64` --> $DIR/type-overflow.rs:15:16 @@ -43,8 +44,9 @@ LL + let fail = 0x8000_0000_0000_0000u64; | help: to use as a negative number (decimal `-9223372036854775808`), consider using the type `u64` for the literal and cast it to `i64` | -LL | let fail = 0x8000_0000_0000_0000u64 as i64; - | ++++++ +LL - let fail = 0x8000_0000_0000_0000i64; +LL + let fail = 0x8000_0000_0000_0000u64.cast_signed(); + | warning: literal out of range for `u32` --> $DIR/type-overflow.rs:19:16 @@ -64,8 +66,8 @@ LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; = help: consider using the type `u128` instead help: to use as a negative number (decimal `-170141183460469231731687303715884105728`), consider using the type `u128` for the literal and cast it to `i128` | -LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128 as i128; - | ++++++++++++ +LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128.cast_signed(); + | ++++++++++++++++++ warning: literal out of range for `i32` --> $DIR/type-overflow.rs:27:16 diff --git a/tests/ui/resolve/macro-determinacy-non-module-issue-160195.env_first.stderr b/tests/ui/resolve/macro-determinacy-non-module-issue-160195.env_first.stderr new file mode 100644 index 0000000000000..cf8c7221c2367 --- /dev/null +++ b/tests/ui/resolve/macro-determinacy-non-module-issue-160195.env_first.stderr @@ -0,0 +1,8 @@ +error: `env!()` takes 1 or 2 arguments + --> $DIR/macro-determinacy-non-module-issue-160195.rs:12:22 + | +LL | include!(concat!(env!())); + | ^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/resolve/macro-determinacy-non-module-issue-160195.env_second.stderr b/tests/ui/resolve/macro-determinacy-non-module-issue-160195.env_second.stderr new file mode 100644 index 0000000000000..cf8c7221c2367 --- /dev/null +++ b/tests/ui/resolve/macro-determinacy-non-module-issue-160195.env_second.stderr @@ -0,0 +1,8 @@ +error: `env!()` takes 1 or 2 arguments + --> $DIR/macro-determinacy-non-module-issue-160195.rs:12:22 + | +LL | include!(concat!(env!())); + | ^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/resolve/macro-determinacy-non-module-issue-160195.rs b/tests/ui/resolve/macro-determinacy-non-module-issue-160195.rs new file mode 100644 index 0000000000000..ca08a665e907b --- /dev/null +++ b/tests/ui/resolve/macro-determinacy-non-module-issue-160195.rs @@ -0,0 +1,21 @@ +//@ revisions: env_first env_second + +#[cfg(env_first)] +pub mod env { + #[derive(Default)] + pub struct BusinessData; +} + +pub mod interface { + use crate::env::{self}; + + include!(concat!(env!())); //~ ERROR `env!()` takes 1 or 2 arguments +} + +#[cfg(env_second)] +pub mod env { + #[derive(Default)] + pub struct BusinessData; +} + +fn main() {} diff --git a/tests/ui/specialization/associated-types-in-default-impl-bounds.rs b/tests/ui/specialization/associated-types-in-default-impl-bounds.rs new file mode 100644 index 0000000000000..ea7188810db07 --- /dev/null +++ b/tests/ui/specialization/associated-types-in-default-impl-bounds.rs @@ -0,0 +1,18 @@ +//@ check-pass + +#![allow(incomplete_features)] +#![feature(specialization)] + +// Tests that you can use a trait's associated types in the bounds of a default impl. +// Regression test for #52396. + +trait Foo { + type Baz; + fn bar(&self, _: Self::Baz); +} + +default impl> Foo for A { + fn bar(&self, _: isize) { } +} + +fn main() {} diff --git a/tests/ui/specialization/default-assoc-type-recursion-issue-80700.rs b/tests/ui/specialization/default-assoc-type-recursion-issue-80700.rs new file mode 100644 index 0000000000000..e013610121efe --- /dev/null +++ b/tests/ui/specialization/default-assoc-type-recursion-issue-80700.rs @@ -0,0 +1,35 @@ +//@ check-pass + +#![feature(specialization)] +#![allow(incomplete_features)] + +// Tests that a blanket impl supplying a `default type` does not make a +// recursive trait requirement diverge. +// Regression test for #80700. + +use std::marker::PhantomData; + +struct Nil; +struct Cons(PhantomData<(Head, Tail)>); +struct Error; + +trait GetLast { + type Output; +} + +impl GetLast for T { + default type Output = Error; +} + +impl GetLast for Cons { + type Output = Nil; +} + +impl GetLast for Cons> +where + Cons: GetLast, +{ + type Output = as GetLast>::Output; +} + +fn main() {} diff --git a/tests/ui/specialization/default-impl-coherence-overlap-issue-77026.rs b/tests/ui/specialization/default-impl-coherence-overlap-issue-77026.rs new file mode 100644 index 0000000000000..6d610805608af --- /dev/null +++ b/tests/ui/specialization/default-impl-coherence-overlap-issue-77026.rs @@ -0,0 +1,27 @@ +//@ check-fail + +#![feature(specialization)] +#![allow(incomplete_features)] + +// `default impl` still participates in coherence. However, we shouldn't get an overflow here. +// Regresion test for #77026. + +pub enum Either { + Left(L), + Right(R), +} + +default impl From for Either { + fn from(l: L) -> Self { + Either::Left(l) + } +} + +impl From for Either { + //~^ ERROR conflicting implementations of trait `From<_>` for type `Either<_, _>` + fn from(r: R) -> Self { + Either::Right(r) + } +} + +fn main() {} diff --git a/tests/ui/specialization/default-impl-coherence-overlap-issue-77026.stderr b/tests/ui/specialization/default-impl-coherence-overlap-issue-77026.stderr new file mode 100644 index 0000000000000..c9b30bf2f6495 --- /dev/null +++ b/tests/ui/specialization/default-impl-coherence-overlap-issue-77026.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `From<_>` for type `Either<_, _>` + --> $DIR/default-impl-coherence-overlap-issue-77026.rs:20:1 + | +LL | default impl From for Either { + | ------------------------------------------- first implementation here +... +LL | impl From for Either { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Either<_, _>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/specialization/default-impl-not-a-candidate-issue-48515.rs b/tests/ui/specialization/default-impl-not-a-candidate-issue-48515.rs new file mode 100644 index 0000000000000..4e31dcf117daa --- /dev/null +++ b/tests/ui/specialization/default-impl-not-a-candidate-issue-48515.rs @@ -0,0 +1,64 @@ +//@ check-fail + +#![feature(specialization)] +#![allow(incomplete_features)] + +// Tests that we don't overflow when using `default impl`. +// Regression test for #48515, #98478, and #117909. + +// #48515 + +trait TypeString { + fn type_string() -> &'static str; +} + +default impl TypeString for T { + fn type_string() -> &'static str { + "unknown type" + } +} + +impl TypeString for () { + fn type_string() -> &'static str { + "()" + } +} + +// #98478 + +trait Spam {} + +trait SpamMore: Spam {} + +default impl Spam for T where T: SpamMore {} + +struct A; + +impl SpamMore for A {} +//~^ ERROR the trait bound `A: Spam` is not satisfied + +fn needs_spam() {} + +// #117909 + +trait Set { + fn contains(&self, bit: T); +} + +default impl Set<&T> for S +where + S: Set, +{ + fn contains(&self, _: &T) {} +} + +fn main() { + let _ = ::type_string(); + //~^ ERROR the trait bound `usize: TypeString` is not satisfied + + needs_spam::(); + //~^ ERROR the trait bound `A: Spam` is not satisfied + + 0u32.contains(()); + //~^ ERROR no method named `contains` found for type `u32` in the current scope +} diff --git a/tests/ui/specialization/default-impl-not-a-candidate-issue-48515.stderr b/tests/ui/specialization/default-impl-not-a-candidate-issue-48515.stderr new file mode 100644 index 0000000000000..91df5005d7095 --- /dev/null +++ b/tests/ui/specialization/default-impl-not-a-candidate-issue-48515.stderr @@ -0,0 +1,63 @@ +error[E0277]: the trait bound `A: Spam` is not satisfied + --> $DIR/default-impl-not-a-candidate-issue-48515.rs:37:19 + | +LL | impl SpamMore for A {} + | ^ unsatisfied trait bound + | +help: the trait `Spam` is not implemented for `A` + --> $DIR/default-impl-not-a-candidate-issue-48515.rs:35:1 + | +LL | struct A; + | ^^^^^^^^ +note: required by a bound in `SpamMore` + --> $DIR/default-impl-not-a-candidate-issue-48515.rs:31:17 + | +LL | trait SpamMore: Spam {} + | ^^^^ required by this bound in `SpamMore` + +error[E0277]: the trait bound `usize: TypeString` is not satisfied + --> $DIR/default-impl-not-a-candidate-issue-48515.rs:56:14 + | +LL | let _ = ::type_string(); + | ^^^^^ the trait `TypeString` is not implemented for `usize` + | +help: the trait `TypeString` is implemented for `()` + --> $DIR/default-impl-not-a-candidate-issue-48515.rs:21:1 + | +LL | impl TypeString for () { + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `A: Spam` is not satisfied + --> $DIR/default-impl-not-a-candidate-issue-48515.rs:59:18 + | +LL | needs_spam::(); + | ^ unsatisfied trait bound + | +help: the trait `Spam` is not implemented for `A` + --> $DIR/default-impl-not-a-candidate-issue-48515.rs:35:1 + | +LL | struct A; + | ^^^^^^^^ +note: required by a bound in `needs_spam` + --> $DIR/default-impl-not-a-candidate-issue-48515.rs:40:18 + | +LL | fn needs_spam() {} + | ^^^^ required by this bound in `needs_spam` + +error[E0599]: no method named `contains` found for type `u32` in the current scope + --> $DIR/default-impl-not-a-candidate-issue-48515.rs:62:10 + | +LL | 0u32.contains(()); + | ^^^^^^^^ method not found in `u32` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Set` defines an item `contains`, perhaps you need to implement it + --> $DIR/default-impl-not-a-candidate-issue-48515.rs:44:1 + | +LL | trait Set { + | ^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/specialization/default-impl-not-an-impl.rs b/tests/ui/specialization/default-impl-not-an-impl.rs new file mode 100644 index 0000000000000..2b0902173158e --- /dev/null +++ b/tests/ui/specialization/default-impl-not-an-impl.rs @@ -0,0 +1,71 @@ +//@ check-fail + +#![feature(specialization)] +#![allow(incomplete_features)] + +// Tests that a `default impl` does not count as an *actual* impl, so it cannot +// be used to satisfy trait bounds. + +// A `default impl` may omit trait items, but a real impl may not. + +trait Gapped { + fn a(&self) -> u32; + fn b(&self) -> u32; +} + +default impl Gapped for T { + fn a(&self) -> u32 { + 1 + } +} + +impl Gapped for u8 {} +//~^ ERROR not all trait items implemented, missing: `b` + +// A `default impl` that defines *every* trait item is still not an impl. + +trait Foo { + fn f(&self) -> u32; +} + +default impl Foo for T { + fn f(&self) -> u32 { + 1 + } +} + +fn need_foo(t: &T) -> u32 { + t.f() +} + +trait Bar { + fn b(&self) -> u32; +} + +impl Bar for T { + fn b(&self) -> u32 { + self.f() + } +} + +fn need_bar(t: &T) -> u32 { + t.b() +} + +fn main() { + // as a bound (UFCS `::f` is the same trait-selection path, omitted) + need_foo(&0u32); + //~^ ERROR the trait bound `u32: Foo` is not satisfied + + // as a method-probe candidate + 0u32.f(); + //~^ ERROR no method named `f` found for type `u32` in the current scope + + // when building a vtable + let _: &dyn Foo = &0u32; + //~^ ERROR the trait bound `u32: Foo` is not satisfied + + // transitively, as another impl's where-clause + need_bar(&0i64); + //~^ ERROR the trait bound `i64: Bar` is not satisfied +} diff --git a/tests/ui/specialization/default-impl-not-an-impl.stderr b/tests/ui/specialization/default-impl-not-an-impl.stderr new file mode 100644 index 0000000000000..cde757b3f98a7 --- /dev/null +++ b/tests/ui/specialization/default-impl-not-an-impl.stderr @@ -0,0 +1,69 @@ +error[E0046]: not all trait items implemented, missing: `b` + --> $DIR/default-impl-not-an-impl.rs:22:1 + | +LL | fn b(&self) -> u32; + | ------------------- `b` from trait +... +LL | impl Gapped for u8 {} + | ^^^^^^^^^^^^^^^^^^ missing `b` in implementation + +error[E0277]: the trait bound `u32: Foo` is not satisfied + --> $DIR/default-impl-not-an-impl.rs:57:14 + | +LL | need_foo(&0u32); + | -------- ^^^^^ the trait `Foo` is not implemented for `u32` + | | + | required by a bound introduced by this call + | +note: required by a bound in `need_foo` + --> $DIR/default-impl-not-an-impl.rs:37:16 + | +LL | fn need_foo(t: &T) -> u32 { + | ^^^ required by this bound in `need_foo` + +error[E0599]: no method named `f` found for type `u32` in the current scope + --> $DIR/default-impl-not-an-impl.rs:61:10 + | +LL | 0u32.f(); + | ^ method not found in `u32` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Foo` defines an item `f`, perhaps you need to implement it + --> $DIR/default-impl-not-an-impl.rs:27:1 + | +LL | trait Foo { + | ^^^^^^^^^ + +error[E0277]: the trait bound `u32: Foo` is not satisfied + --> $DIR/default-impl-not-an-impl.rs:65:23 + | +LL | let _: &dyn Foo = &0u32; + | ^^^^^ the trait `Foo` is not implemented for `u32` + | + = note: required for the cast from `&u32` to `&dyn Foo` + +error[E0277]: the trait bound `i64: Bar` is not satisfied + --> $DIR/default-impl-not-an-impl.rs:69:14 + | +LL | need_bar(&0i64); + | -------- ^^^^^ the trait `Foo` is not implemented for `i64` + | | + | required by a bound introduced by this call + | +note: required for `i64` to implement `Bar` + --> $DIR/default-impl-not-an-impl.rs:45:14 + | +LL | impl Bar for T { + | --- ^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `need_bar` + --> $DIR/default-impl-not-an-impl.rs:51:16 + | +LL | fn need_bar(t: &T) -> u32 { + | ^^^ required by this bound in `need_bar` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0046, E0277, E0599. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/specialization/default-impl-partial-and-inherits.rs b/tests/ui/specialization/default-impl-partial-and-inherits.rs new file mode 100644 index 0000000000000..a2c622daafb08 --- /dev/null +++ b/tests/ui/specialization/default-impl-partial-and-inherits.rs @@ -0,0 +1,111 @@ +//@ run-pass + +#![feature(specialization)] +#![allow(incomplete_features)] + +// Tests that a `default impl` does not need all items, but does contribute to +// the chain of specialization. + +// A partial `default impl` at each level of a 3-level chain. + +trait Foo { + type Assoc; + const N: u32; + fn from_root(&self) -> &'static str; + fn from_mid(&self) -> &'static str; + fn from_leaf(&self) -> &'static str; + fn from_trait(&self) -> &'static str { + "trait body" + } +} + +// root: assoc type, assoc const, one method +default impl Foo for T { + type Assoc = u8; + const N: u32 = 1; + fn from_root(&self) -> &'static str { + "root" + } +} + +// middle: one method +default impl Foo for T { + fn from_mid(&self) -> &'static str { + "mid" + } +} + +// leaf: one method. Everything else must come from the two ancestors, except +// `from_trait`, which no impl in the chain defines. +impl Foo for u32 { + fn from_leaf(&self) -> &'static str { + "leaf" + } +} + +// sibling leaf: overrides every inherited item, including assoc type and const +impl Foo for i8 { + type Assoc = bool; + const N: u32 = 2; + fn from_root(&self) -> &'static str { + "i8 root" + } + fn from_mid(&self) -> &'static str { + "i8 mid" + } + fn from_leaf(&self) -> &'static str { + "i8 leaf" + } + fn from_trait(&self) -> &'static str { + "i8 trait" + } +} + +fn generic(t: &T) -> [&'static str; 4] { + [t.from_root(), t.from_mid(), t.from_leaf(), t.from_trait()] +} + +// An empty `default impl`, and an empty real impl that inherits every item. + +trait Marker { + type A; + fn m(&self) -> &'static str; +} + +// Contributes nothing at all, and is still accepted. +default impl Marker for T {} + +// Covers every item of the trait. +default impl Marker for T { + type A = u8; + fn m(&self) -> &'static str { + "from default impl" + } +} + +// Declaration of intent and nothing else. This is what the `default impl` above +// is missing, and the only thing it is missing. +impl Marker for u32 {} + +fn main() { + // inherited across the chain, via a concrete receiver... + assert_eq!(0u32.from_root(), "root"); + assert_eq!(0u32.from_mid(), "mid"); + assert_eq!(0u32.from_leaf(), "leaf"); + assert_eq!(0u32.from_trait(), "trait body"); + assert_eq!(::N, 1); + // The omitting impl finalizes the ancestor's definition, so this normalizes. + let _: ::Assoc = 0u8; + + // ...and through a generic bound + assert_eq!(generic(&0u32), ["root", "mid", "leaf", "trait body"]); + assert_eq!(generic(&0i8), ["i8 root", "i8 mid", "i8 leaf", "i8 trait"]); + assert_eq!(::N, 2); + let _: ::Assoc = true; + + // empty impl really does implement: method, projection, and vtable + assert_eq!(0u32.m(), "from default impl"); + let _: ::A = 0u8; + let _: &dyn Marker = &0u32; + +} diff --git a/tests/ui/specialization/default-type-normalize-issue-50318.rs b/tests/ui/specialization/default-type-normalize-issue-50318.rs new file mode 100644 index 0000000000000..b69acfe47a929 --- /dev/null +++ b/tests/ui/specialization/default-type-normalize-issue-50318.rs @@ -0,0 +1,24 @@ +//@ check-fail +//@ known-bug: #50318 + +#![feature(specialization)] +#![allow(incomplete_features)] + +// Tests that we can normalize a `default type`. + +trait Trait { + type AssocType; +} + +struct Struct {} + +impl Trait for Struct { + default type AssocType = i32; +} + +type AssocType = ::AssocType; + +fn main() { + assert_eq!(std::any::type_name::(), "i32"); + let x: AssocType = 0; +} diff --git a/tests/ui/specialization/default-type-normalize-issue-50318.stderr b/tests/ui/specialization/default-type-normalize-issue-50318.stderr new file mode 100644 index 0000000000000..b0d69287adac2 --- /dev/null +++ b/tests/ui/specialization/default-type-normalize-issue-50318.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/default-type-normalize-issue-50318.rs:23:24 + | +LL | let x: AssocType = 0; + | --------- ^ expected associated type, found integer + | | + | expected due to this + | + = note: expected associated type `::AssocType` + found type `{integer}` + = help: consider constraining the associated type `::AssocType` to `{integer}` or calling a method that returns `::AssocType` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `::AssocType` is defined as `{integer}` in the implementation, but the where-bound `Struct` shadows this definition + see issue #152409 for more information + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/specialization/default-type-self-projection-ice-issue-125014.next.stderr b/tests/ui/specialization/default-type-self-projection-ice-issue-125014.next.stderr new file mode 100644 index 0000000000000..7280c8213e5dd --- /dev/null +++ b/tests/ui/specialization/default-type-self-projection-ice-issue-125014.next.stderr @@ -0,0 +1,66 @@ +error[E0277]: the trait bound `u16: A` is not satisfied + --> $DIR/default-type-self-projection-ice-issue-125014.rs:18:12 + | +LL | impl A for ::B { + | ^^^^^^^^^^^^^ the trait `A` is not implemented for `u16` + | +help: the trait `A` is implemented for `::B` + --> $DIR/default-type-self-projection-ice-issue-125014.rs:18:1 + | +LL | impl A for ::B { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `u16: A` is not satisfied + --> $DIR/default-type-self-projection-ice-issue-125014.rs:18:12 + | +LL | impl A for ::B { + | ^^^^^^^^^^^^^ the trait `A` is not implemented for `u16` + | +help: the trait `A` is implemented for `::B` + --> $DIR/default-type-self-projection-ice-issue-125014.rs:18:1 + | +LL | impl A for ::B { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: the trait bound `u16: A` is not satisfied + --> $DIR/default-type-self-projection-ice-issue-125014.rs:23:22 + | +LL | default type B = (); + | ^^ the trait `A` is not implemented for `u16` + | +help: the trait `A` is implemented for `::B` + --> $DIR/default-type-self-projection-ice-issue-125014.rs:18:1 + | +LL | impl A for ::B { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `u16: A` is not satisfied + --> $DIR/default-type-self-projection-ice-issue-125014.rs:18:12 + | +LL | impl A for ::B { + | ^^^^^^^^^^^^^ the trait `A` is not implemented for `u16` + | +help: the trait `A` is implemented for `::B` + --> $DIR/default-type-self-projection-ice-issue-125014.rs:18:1 + | +LL | impl A for ::B { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: the trait bound `u16: A` is not satisfied + --> $DIR/default-type-self-projection-ice-issue-125014.rs:18:12 + | +LL | impl A for ::B { + | ^^^^^^^^^^^^^ the trait `A` is not implemented for `u16` + | +help: the trait `A` is implemented for `::B` + --> $DIR/default-type-self-projection-ice-issue-125014.rs:18:1 + | +LL | impl A for ::B { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/specialization/default-type-self-projection-ice-issue-125014.rs b/tests/ui/specialization/default-type-self-projection-ice-issue-125014.rs new file mode 100644 index 0000000000000..9b4e3eade03b6 --- /dev/null +++ b/tests/ui/specialization/default-type-self-projection-ice-issue-125014.rs @@ -0,0 +1,27 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[current] known-bug: #125014 +//@[current] failure-status: 101 +//@[current] dont-check-compiler-stderr + +// Tests that we don't ICE when a `default type` is potentially used as a self-type in an impl. +// Regression for #125014. + +#![feature(specialization)] +#![allow(incomplete_features)] + +trait A { + type B; +} + +impl A for ::B { + //[next]~^ ERROR the trait bound `u16: A` is not satisfied + //[next]~^^ ERROR the trait bound `u16: A` is not satisfied + //[next]~^^^ ERROR the trait bound `u16: A` is not satisfied + //[next]~^^^^ ERROR the trait bound `u16: A` is not satisfied + default type B = (); + //[next]~^ ERROR the trait bound `u16: A` is not satisfied +} + +fn main() {} diff --git a/tests/ui/specialization/min_specialization/spec-marker-supertraits.rs b/tests/ui/specialization/min_specialization/spec-marker-supertraits.rs index 3bb2480e9e2be..57319e0e7bb21 100644 --- a/tests/ui/specialization/min_specialization/spec-marker-supertraits.rs +++ b/tests/ui/specialization/min_specialization/spec-marker-supertraits.rs @@ -8,7 +8,7 @@ trait HasMethod { fn method(&self); } -#[rustc_unsafe_specialization_marker] +#[unsafe(rustc_allow_lifetime_dependent_specialization)] trait Marker: HasMethod {} trait Spec { diff --git a/tests/ui/specialization/min_specialization/specialization_marker.rs b/tests/ui/specialization/min_specialization/specialization_marker.rs index 93462d02ea578..55de99d7557f4 100644 --- a/tests/ui/specialization/min_specialization/specialization_marker.rs +++ b/tests/ui/specialization/min_specialization/specialization_marker.rs @@ -1,14 +1,14 @@ -// Test that `rustc_unsafe_specialization_marker` is only allowed on marker traits. +// Test that `rustc_allow_lifetime_dependent_specialization` is only allowed on marker traits. #![feature(rustc_attrs)] -#[rustc_unsafe_specialization_marker] +#[unsafe(rustc_allow_lifetime_dependent_specialization)] trait SpecMarker { fn f(); //~^ ERROR marker traits } -#[rustc_unsafe_specialization_marker] +#[unsafe(rustc_allow_lifetime_dependent_specialization)] trait SpecMarker2 { type X; //~^ ERROR marker traits diff --git a/tests/ui/specialization/min_specialization/specialize_on_marker.rs b/tests/ui/specialization/min_specialization/specialize_on_marker.rs index f7bc057d3ba8a..8e1acf319f340 100644 --- a/tests/ui/specialization/min_specialization/specialize_on_marker.rs +++ b/tests/ui/specialization/min_specialization/specialize_on_marker.rs @@ -1,4 +1,4 @@ -// Test that specializing on a `rustc_unsafe_specialization_marker` trait is +// Test that specializing on a `rustc_allow_lifetime_dependent_specialization` trait is // allowed. //@ check-pass @@ -6,7 +6,7 @@ #![feature(min_specialization)] #![feature(rustc_attrs)] -#[rustc_unsafe_specialization_marker] +#[unsafe(rustc_allow_lifetime_dependent_specialization)] trait SpecMarker {} trait X { diff --git a/tests/ui/specialization/spec-influences-inference-issue-36262.rs b/tests/ui/specialization/spec-influences-inference-issue-36262.rs new file mode 100644 index 0000000000000..1e96fd5065097 --- /dev/null +++ b/tests/ui/specialization/spec-influences-inference-issue-36262.rs @@ -0,0 +1,128 @@ +//@ edition: 2021 +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@[next] check-pass +//@[current] known-bug: #36262 +//@[current] dont-check-compiler-stderr + +// Tests that specialization does not leak into type inference. +// Regression for #36262 and duplicate issues. + +#![feature(specialization)] +#![allow(incomplete_features)] + +// Site 1: the receiver's type parameter, observed through a return position (#36262). +mod receiver_return { + struct My(T); + + trait Conv { + fn conv(self) -> T; + } + + impl Conv for My { + default fn conv(self) -> T { + self.0 + } + } + + impl Conv for My { + fn conv(self) -> u32 { + self.0 + } + } + + fn use_it() { + // Should infer `i32`; the sole `My` impl steers it to `u32`. + let x = My(0); + let _ = x.conv() + 0i32; + } +} + +// Site 2: a method argument's trait type parameter (#91973, #38516, #67918). +mod method_arg { + struct Foo; + + trait Bar { + fn bar(&self, _: T); + } + + impl Bar for Foo { + default fn bar(&self, _: T) {} + } + + impl Bar for Foo { + fn bar(&self, _: bool) {} + } + + fn use_it() { + // Should infer `{integer}`; the sole `Bar` impl steers it to `bool`. + Foo.bar(42); + } +} + +// Site 3: an explicit `_` in a UFCS trait reference (#40718). +mod ufcs_infer { + use std::vec; + + struct Foo(T); + + impl Foo { + fn build>(it: I) -> Foo { + // The second argument should infer to `I::IntoIter`; the sole + // `vec::IntoIter` impl steers it there. + >::from_iter(it.into_iter()) + } + } + + trait SpecExtend { + fn from_iter(iter: I) -> Self; + } + + impl SpecExtend for Foo + where + I: Iterator, + { + default fn from_iter(_: I) -> Self { + panic!() + } + } + + impl SpecExtend> for Foo { + fn from_iter(_: vec::IntoIter) -> Self { + panic!() + } + } +} + +// Site 4: an operator, where the sole specialization is derive-generated (#55243). +mod derived_specializer { + use std::borrow::Borrow; + + #[derive(PartialEq)] + struct MyString(String); + + impl Borrow for MyString { + fn borrow(&self) -> &str { + &self.0 + } + } + + impl PartialEq for MyString + where + Rhs: ?Sized + Borrow, + { + default fn eq(&self, rhs: &Rhs) -> bool { + self.0 == rhs.borrow() + } + } + + fn use_it() { + // Should select `PartialEq`; the derived `PartialEq` is the + // sole specialization and inference commits `Rhs = MyString`. + let s = MyString(String::from("Hello, world!")); + let _ = s == "Hello, world!"; + } +} + +fn main() {} diff --git a/tests/ui/specialization/specialized-impl-projection-issue-32483.rs b/tests/ui/specialization/specialized-impl-projection-issue-32483.rs new file mode 100644 index 0000000000000..5b26679422a40 --- /dev/null +++ b/tests/ui/specialization/specialized-impl-projection-issue-32483.rs @@ -0,0 +1,27 @@ +//@ check-pass + +#![allow(incomplete_features)] +#![feature(specialization)] + +// Tests that we allow some projections in specialized impls. +// Regression test for issue #32483. + +pub trait Foo { + type TypeA; + type TypeB: Bar; +} + +pub trait Bar { +} + +pub struct ImplsBar; +impl Bar for ImplsBar { +} + +impl Foo for T { + type TypeA = u8; + // WF checking `TypeB` here requires us to project `Self::TypeA` + default type TypeB = ImplsBar; +} + +fn main() {} diff --git a/tests/ui/specialization/trait-alias-specialization-issue-74809.rs b/tests/ui/specialization/trait-alias-specialization-issue-74809.rs new file mode 100644 index 0000000000000..e62532e8ab033 --- /dev/null +++ b/tests/ui/specialization/trait-alias-specialization-issue-74809.rs @@ -0,0 +1,44 @@ +//@ check-pass + +#![feature(specialization)] +#![feature(trait_alias)] +#![allow(incomplete_features)] + +// Tests that we can specialize on a trait alias. +// Regression test for #74809. + +pub trait Marker1 {} +pub trait Marker2 {} + +pub trait CombinedMarker = Marker1 + Marker2; + +pub struct Container { + p: std::marker::PhantomData<(T, U)>, +} + +pub struct Struct; +impl Marker1 for Struct {} + +pub trait Trait { + fn do_thing(&self); +} + +impl> Trait for Container { + default fn do_thing(&self) { + println!("default behavior"); + } +} + +impl> Trait for Container { + default fn do_thing(&self) { + println!("partially specialized behavior"); + } +} + +impl Trait for Container { + fn do_thing(&self) { + println!("fully specialized behavior") + } +} + +fn main() {} diff --git a/tests/ui/traits/const-traits/unconstrained-var-specialization.rs b/tests/ui/traits/const-traits/unconstrained-var-specialization.rs index 4330e0aead1ac..d48880deefaf9 100644 --- a/tests/ui/traits/const-traits/unconstrained-var-specialization.rs +++ b/tests/ui/traits/const-traits/unconstrained-var-specialization.rs @@ -13,7 +13,7 @@ pub trait Iterator { type Item; } -#[rustc_unsafe_specialization_marker] +#[unsafe(rustc_allow_lifetime_dependent_specialization)] pub trait MoreSpecificThanIterator: Iterator {} pub trait Tr { diff --git a/tests/ui/traits/next-solver/global-where-bound-normalization.rs b/tests/ui/traits/next-solver/global-where-bound-normalization.rs index e57fbf378a0d2..914a54f1aabb0 100644 --- a/tests/ui/traits/next-solver/global-where-bound-normalization.rs +++ b/tests/ui/traits/next-solver/global-where-bound-normalization.rs @@ -20,7 +20,7 @@ impl Proj for MyField { type Assoc = u8; } -// While wf-checking the global bounds of `fn foo`, elaborating this outlives predicate triggered a +// While wf-checking the global bounds of `fn foo`, elaborating this outlives clause triggered a // cycle in the search graph along a particular probe path, which was not an actual solution. // That cycle then resulted in a forced false-positive ambiguity due to a performance hack in the // search graph and then ended up floundering the root goal evaluation.