From 912783402fe2f0d1fff41b047b0918e7e58e18ae Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 8 Feb 2023 13:25:38 +0000 Subject: [PATCH 01/12] const_eval: `implies_by` in `rustc_const_unstable` Extend support for `implies_by` (from `#[stable]` and `#[unstable]`) to `#[rustc_const_stable]` and `#[rustc_const_unstable]`. Signed-off-by: David Wood --- .../src/const_eval/fn_queries.rs | 13 ++++++++--- .../src/transform/check_consts/check.rs | 16 ++++++++++---- compiler/rustc_passes/src/stability.rs | 9 ++++++++ .../const-stability-attribute-implies.rs | 12 ++++++++++ ...nst-stability-attribute-implies-missing.rs | 16 ++++++++++++++ ...stability-attribute-implies-missing.stderr | 8 +++++++ ...-stability-attribute-implies-no-feature.rs | 16 ++++++++++++++ ...bility-attribute-implies-no-feature.stderr | 10 +++++++++ ...tability-attribute-implies-using-stable.rs | 19 ++++++++++++++++ ...lity-attribute-implies-using-stable.stderr | 22 +++++++++++++++++++ ...bility-attribute-implies-using-unstable.rs | 21 ++++++++++++++++++ ...ty-attribute-implies-using-unstable.stderr | 22 +++++++++++++++++++ 12 files changed, 177 insertions(+), 7 deletions(-) create mode 100644 tests/ui/stability-attribute/auxiliary/const-stability-attribute-implies.rs create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.rs create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.stderr create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.rs create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.stderr create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.rs create mode 100644 tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.stderr diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index f92277b111374..b7e05376c0e2c 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -1,3 +1,4 @@ +use rustc_attr as attr; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -5,11 +6,17 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::{DefIdTree, TyCtxt}; use rustc_span::symbol::Symbol; -/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it -pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { +/// Whether the `def_id` is an unstable const fn and what feature gate(s) are necessary to enable +/// it. +pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<(Symbol, Option)> { if tcx.is_const_fn_raw(def_id) { let const_stab = tcx.lookup_const_stability(def_id)?; - if const_stab.is_const_unstable() { Some(const_stab.feature) } else { None } + match const_stab.level { + attr::StabilityLevel::Unstable { implied_by, .. } => { + Some((const_stab.feature, implied_by)) + } + attr::StabilityLevel::Stable { .. } => None, + } } else { None } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 1a23b06d2e89c..d11cc65da16da 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -926,15 +926,24 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // If the `const fn` we are trying to call is not const-stable, ensure that we have // the proper feature gate enabled. - if let Some(gate) = is_unstable_const_fn(tcx, callee) { + if let Some((gate, implied_by)) = is_unstable_const_fn(tcx, callee) { trace!(?gate, "calling unstable const fn"); if self.span.allows_unstable(gate) { return; } + if let Some(implied_by_gate) = implied_by && self.span.allows_unstable(implied_by_gate) { + return; + } // Calling an unstable function *always* requires that the corresponding gate - // be enabled, even if the function has `#[rustc_allow_const_fn_unstable(the_gate)]`. - if !tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate) { + // (or implied gate) be enabled, even if the function has + // `#[rustc_allow_const_fn_unstable(the_gate)]`. + let gate_declared = |gate| { + tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate) + }; + let feature_gate_declared = gate_declared(gate); + let implied_gate_declared = implied_by.map(gate_declared).unwrap_or(false); + if !feature_gate_declared && !implied_gate_declared { self.check_op(ops::FnCallUnstable(callee, Some(gate))); return; } @@ -947,7 +956,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } // Otherwise, we are something const-stable calling a const-unstable fn. - if super::rustc_allow_const_fn_unstable(tcx, caller, gate) { trace!("rustc_allow_const_fn_unstable gate active"); return; diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 7299fc9705cc6..7617818f64280 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -265,6 +265,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { self.index.implications.insert(implied_by, feature); } + if let Some(ConstStability { + level: Unstable { implied_by: Some(implied_by), .. }, + feature, + .. + }) = const_stab + { + self.index.implications.insert(implied_by, feature); + } + self.index.stab_map.insert(def_id, stab); stab }); diff --git a/tests/ui/stability-attribute/auxiliary/const-stability-attribute-implies.rs b/tests/ui/stability-attribute/auxiliary/const-stability-attribute-implies.rs new file mode 100644 index 0000000000000..f78871b5a1d66 --- /dev/null +++ b/tests/ui/stability-attribute/auxiliary/const-stability-attribute-implies.rs @@ -0,0 +1,12 @@ +#![crate_type = "lib"] +#![feature(staged_api)] +#![stable(feature = "stability_attribute_implies", since = "1.0.0")] +#![rustc_const_stable(feature = "stability_attribute_implies", since = "1.0.0")] + +#[stable(feature = "stability_attribute_implies", since = "1.0.0")] +#[rustc_const_stable(feature = "const_foo", since = "1.62.0")] +pub const fn foo() {} + +#[stable(feature = "stability_attribute_implies", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_foobar", issue = "1", implied_by = "const_foo")] +pub const fn foobar() {} diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs new file mode 100644 index 0000000000000..6d6d793c62b76 --- /dev/null +++ b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs @@ -0,0 +1,16 @@ +#![crate_type = "lib"] +#![feature(staged_api)] +#![stable(feature = "stability_attribute_implies", since = "1.0.0")] +#![rustc_const_stable(feature = "stability_attribute_implies", since = "1.0.0")] + +// Tests that `implied_by = "const_bar"` results in an error being emitted if `const_bar` does not +// exist. + +#[stable(feature = "stability_attribute_implies", since = "1.0.0")] +#[rustc_const_unstable(feature = "const_foobar", issue = "1", implied_by = "const_bar")] +//~^ ERROR feature `const_bar` implying `const_foobar` does not exist +pub const fn foobar() -> u32 { + 0 +} + +const VAR: u32 = foobar(); diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr new file mode 100644 index 0000000000000..6d8b01a549523 --- /dev/null +++ b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr @@ -0,0 +1,8 @@ +error: feature `const_bar` implying `const_foobar` does not exist + --> $DIR/const-stability-attribute-implies-missing.rs:10:1 + | +LL | #[rustc_const_unstable(feature = "const_foobar", issue = "1", implied_by = "const_bar")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.rs b/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.rs new file mode 100644 index 0000000000000..47e8d2b3609c5 --- /dev/null +++ b/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.rs @@ -0,0 +1,16 @@ +// aux-build:const-stability-attribute-implies.rs +#![crate_type = "lib"] + +// Tests that despite the `const_foobar` feature being implied by now-stable feature `const_foo`, +// if `const_foobar` isn't allowed in this crate then an error will be emitted. + +extern crate const_stability_attribute_implies; +use const_stability_attribute_implies::{foo, foobar}; + +pub const fn bar() -> u32 { + foo(); // no error - stable + foobar(); //~ ERROR `foobar` is not yet stable as a const fn + 0 +} + +pub const VAR: u32 = bar(); diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.stderr b/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.stderr new file mode 100644 index 0000000000000..8ef5a364ecc45 --- /dev/null +++ b/tests/ui/stability-attribute/const-stability-attribute-implies-no-feature.stderr @@ -0,0 +1,10 @@ +error: `foobar` is not yet stable as a const fn + --> $DIR/const-stability-attribute-implies-no-feature.rs:12:5 + | +LL | foobar(); + | ^^^^^^^^ + | + = help: add `#![feature(const_foobar)]` to the crate attributes to enable + +error: aborting due to previous error + diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.rs b/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.rs new file mode 100644 index 0000000000000..ffaa171d8a5f7 --- /dev/null +++ b/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.rs @@ -0,0 +1,19 @@ +// aux-build:const-stability-attribute-implies.rs +#![crate_type = "lib"] +#![deny(stable_features)] +#![feature(const_foo)] +//~^ ERROR the feature `const_foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `const_foobar` + +// Tests that the use of `implied_by` in the `#[rustc_const_unstable]` attribute results in a +// diagnostic mentioning partial stabilization, and that given the implied unstable feature is +// unused (there is no `foobar` call), that the compiler suggests removing the flag. + +extern crate const_stability_attribute_implies; +use const_stability_attribute_implies::foo; + +pub const fn bar() -> u32 { + foo(); + 0 +} + +pub const VAR: u32 = bar(); diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.stderr b/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.stderr new file mode 100644 index 0000000000000..f6a099cd25e7a --- /dev/null +++ b/tests/ui/stability-attribute/const-stability-attribute-implies-using-stable.stderr @@ -0,0 +1,22 @@ +error: the feature `const_foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `const_foobar` + --> $DIR/const-stability-attribute-implies-using-stable.rs:4:12 + | +LL | #![feature(const_foo)] + | ^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/const-stability-attribute-implies-using-stable.rs:3:9 + | +LL | #![deny(stable_features)] + | ^^^^^^^^^^^^^^^ +help: if you are using features which are still unstable, change to using `const_foobar` + | +LL | #![feature(const_foobar)] + | ~~~~~~~~~~~~ +help: if you are using features which are now stable, remove this line + | +LL - #![feature(const_foo)] + | + +error: aborting due to previous error + diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.rs b/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.rs new file mode 100644 index 0000000000000..2061c5c75bd81 --- /dev/null +++ b/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.rs @@ -0,0 +1,21 @@ +// aux-build:const-stability-attribute-implies.rs +#![crate_type = "lib"] +#![deny(stable_features)] +#![feature(const_foo)] +//~^ ERROR the feature `const_foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `const_foobar` + +// Tests that the use of `implied_by` in the `#[rustc_const_unstable]` attribute results in a +// diagnostic mentioning partial stabilization and that given the implied unstable feature is +// used (there is a `const_foobar` call), that the compiler suggests changing to that feature and +// doesn't error about its use. + +extern crate const_stability_attribute_implies; +use const_stability_attribute_implies::{foo, foobar}; + +pub const fn bar() -> u32 { + foo(); + foobar(); // no error! + 0 +} + +pub const VAR: u32 = bar(); diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.stderr b/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.stderr new file mode 100644 index 0000000000000..0638566765822 --- /dev/null +++ b/tests/ui/stability-attribute/const-stability-attribute-implies-using-unstable.stderr @@ -0,0 +1,22 @@ +error: the feature `const_foo` has been partially stabilized since 1.62.0 and is succeeded by the feature `const_foobar` + --> $DIR/const-stability-attribute-implies-using-unstable.rs:4:12 + | +LL | #![feature(const_foo)] + | ^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/const-stability-attribute-implies-using-unstable.rs:3:9 + | +LL | #![deny(stable_features)] + | ^^^^^^^^^^^^^^^ +help: if you are using features which are still unstable, change to using `const_foobar` + | +LL | #![feature(const_foobar)] + | ~~~~~~~~~~~~ +help: if you are using features which are now stable, remove this line + | +LL - #![feature(const_foo)] + | + +error: aborting due to previous error + From b2f8f60c070ca369d07fd4bae6fb6e3d8fd97cb9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 21 Feb 2023 05:16:35 +0000 Subject: [PATCH 02/12] Place binder correctly for arbitrary trait bound suggestion --- compiler/rustc_middle/src/ty/diagnostics.rs | 4 ++-- ...correct-binder-for-arbitrary-bound-sugg.rs | 16 ++++++++++++++ ...ect-binder-for-arbitrary-bound-sugg.stderr | 22 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs create mode 100644 tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index a029c1b209df4..ba58f2df376e7 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -118,7 +118,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>( } let param_name = trait_pred.skip_binder().self_ty().to_string(); - let mut constraint = trait_pred.print_modifiers_and_trait_path().to_string(); + let mut constraint = trait_pred.to_string(); if let Some((name, term)) = associated_ty { // FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err. @@ -145,7 +145,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>( this requirement", if generics.where_clause_span.is_empty() { "introducing a" } else { "extending the" }, ), - format!("{} {}: {}", generics.add_where_or_trailing_comma(), param_name, constraint), + format!("{} {constraint}", generics.add_where_or_trailing_comma()), Applicability::MaybeIncorrect, ); true diff --git a/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs new file mode 100644 index 0000000000000..e56c8622ece03 --- /dev/null +++ b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs @@ -0,0 +1,16 @@ +trait Foo +where + for<'a> &'a Self: Bar, +{ +} + +impl Foo for () {} + +trait Bar {} + +impl Bar for &() {} + +fn foo() {} +//~^ ERROR the trait bound `for<'a> &'a T: Bar` is not satisfied + +fn main() {} diff --git a/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr new file mode 100644 index 0000000000000..e024cbb161074 --- /dev/null +++ b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `for<'a> &'a T: Bar` is not satisfied + --> $DIR/correct-binder-for-arbitrary-bound-sugg.rs:13:11 + | +LL | fn foo() {} + | ^^^ the trait `for<'a> Bar` is not implemented for `&'a T` + | +note: required by a bound in `Foo` + --> $DIR/correct-binder-for-arbitrary-bound-sugg.rs:3:23 + | +LL | trait Foo + | --- required by a bound in this +LL | where +LL | for<'a> &'a Self: Bar, + | ^^^ required by this bound in `Foo` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn foo() where for<'a> &'a T: Bar {} + | ++++++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 1f92c61e733482b08bed894c069a5f2ba38292da Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 4 Mar 2023 20:57:30 +0000 Subject: [PATCH 03/12] sub is not sup --- compiler/rustc_trait_selection/src/traits/engine.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index b20636174eeac..62d5e50dbc548 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -158,7 +158,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { self.infcx .at(cause, param_env) .define_opaque_types(true) - .sup(expected, actual) + .sub(expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } From beebd3a4c6ab38a71d4ff7cafcd1bf37def5b721 Mon Sep 17 00:00:00 2001 From: Giacomo Pasini Date: Sun, 5 Mar 2023 16:56:57 +0100 Subject: [PATCH 04/12] Add regression tests for issue 70919 Desugaring DropAndReplace at MIR build (#107844) fixed issue 70919. Add regressions tests, borrowed from #102078, to ensure we check for this in the future. Co-authored-by: Aaron Hill --- tests/ui/borrowck/drop-in-loop.rs | 24 ++++++++++++++++++ tests/ui/borrowck/drop-in-loop.stderr | 14 +++++++++++ tests/ui/borrowck/issue-70919-drop-in-loop.rs | 25 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 tests/ui/borrowck/drop-in-loop.rs create mode 100644 tests/ui/borrowck/drop-in-loop.stderr create mode 100644 tests/ui/borrowck/issue-70919-drop-in-loop.rs diff --git a/tests/ui/borrowck/drop-in-loop.rs b/tests/ui/borrowck/drop-in-loop.rs new file mode 100644 index 0000000000000..866c27ef20324 --- /dev/null +++ b/tests/ui/borrowck/drop-in-loop.rs @@ -0,0 +1,24 @@ +// A version of `issue-70919-drop-in-loop`, but without +// the necessary `drop` call. +// +// This should fail to compile, since the `Drop` impl +// for `WrapperWithDrop` could observe the changed +// `base` value. + +struct WrapperWithDrop<'a>(&'a mut bool); +impl<'a> Drop for WrapperWithDrop<'a> { + fn drop(&mut self) { + } +} + +fn drop_in_loop() { + let mut base = true; + let mut wrapper = WrapperWithDrop(&mut base); + loop { + base = false; //~ ERROR: cannot assign to `base` + wrapper = WrapperWithDrop(&mut base); + } +} + +fn main() { +} diff --git a/tests/ui/borrowck/drop-in-loop.stderr b/tests/ui/borrowck/drop-in-loop.stderr new file mode 100644 index 0000000000000..d5734e7ec9770 --- /dev/null +++ b/tests/ui/borrowck/drop-in-loop.stderr @@ -0,0 +1,14 @@ +error[E0506]: cannot assign to `base` because it is borrowed + --> $DIR/drop-in-loop.rs:18:9 + | +LL | let mut wrapper = WrapperWithDrop(&mut base); + | --------- `base` is borrowed here +LL | loop { +LL | base = false; + | ^^^^^^^^^^^^ `base` is assigned to here but it was already borrowed +LL | wrapper = WrapperWithDrop(&mut base); + | ------- borrow might be used here, when `wrapper` is dropped and runs the `Drop` code for type `WrapperWithDrop` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0506`. diff --git a/tests/ui/borrowck/issue-70919-drop-in-loop.rs b/tests/ui/borrowck/issue-70919-drop-in-loop.rs new file mode 100644 index 0000000000000..a8d5849a31c0b --- /dev/null +++ b/tests/ui/borrowck/issue-70919-drop-in-loop.rs @@ -0,0 +1,25 @@ +// Regression test for issue #70919 +// Tests that we don't emit a spurious "borrow might be used" error +// when we have an explicit `drop` in a loop + +// check-pass + +struct WrapperWithDrop<'a>(&'a mut bool); +impl<'a> Drop for WrapperWithDrop<'a> { + fn drop(&mut self) { + } +} + +fn drop_in_loop() { + let mut base = true; + let mut wrapper = WrapperWithDrop(&mut base); + loop { + drop(wrapper); + + base = false; + wrapper = WrapperWithDrop(&mut base); + } +} + +fn main() { +} From cb4ebc1453a69145d6602de798dc704871a200da Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sun, 5 Mar 2023 13:20:17 -0500 Subject: [PATCH 05/12] Check for free regions in MIR validation --- compiler/rustc_const_eval/src/transform/validate.rs | 11 +++++++++++ compiler/rustc_mir_transform/src/lib.rs | 6 ------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index fb37eb79a335f..272fe3d1b3109 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -72,6 +72,17 @@ impl<'tcx> MirPass<'tcx> for Validator { }; checker.visit_body(body); checker.check_cleanup_control_flow(); + + if let MirPhase::Runtime(_) = body.phase { + if let ty::InstanceDef::Item(_) = body.source.instance { + if body.has_free_regions() { + checker.fail( + Location::START, + format!("Free regions in optimized {} MIR", body.phase.name()), + ); + } + } + } } } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index cdd28ae0c0197..5fd923190ef59 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -416,8 +416,6 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) - pm::run_passes(tcx, &mut body, &[&ctfe_limit::CtfeLimit], None); - debug_assert!(!body.has_free_regions(), "Free regions in MIR for CTFE"); - body } @@ -626,8 +624,6 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { debug!("body: {:#?}", body); run_optimization_passes(tcx, &mut body); - debug_assert!(!body.has_free_regions(), "Free regions in optimized MIR"); - body } @@ -651,7 +647,5 @@ fn promoted_mir( run_analysis_to_runtime_passes(tcx, body); } - debug_assert!(!promoted.has_free_regions(), "Free regions in promoted MIR"); - tcx.arena.alloc(promoted) } From 5d7234abb65fa8cf0007ed03dfd8448eb9128f5d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 5 Mar 2023 20:55:29 +0000 Subject: [PATCH 06/12] Add test. --- tests/ui/mir/unsize-trait.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/ui/mir/unsize-trait.rs diff --git a/tests/ui/mir/unsize-trait.rs b/tests/ui/mir/unsize-trait.rs new file mode 100644 index 0000000000000..45b5308c0938f --- /dev/null +++ b/tests/ui/mir/unsize-trait.rs @@ -0,0 +1,15 @@ +// Check that the interpreter does not ICE when trying to unsize `B` to `[u8]`. +// This is a `build` test to ensure that const-prop-lint runs. +// build-pass + +#![feature(unsize)] + +fn foo(buffer: &mut [B; 2]) + where B: std::marker::Unsize<[u8]>, +{ + let buffer: &[u8] = &buffer[0]; +} + +fn main() { + foo(&mut [[0], [5]]); +} From 858eab63912db10ee5e6706724df9c909c6502e7 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 10 Feb 2023 18:17:52 +0000 Subject: [PATCH 07/12] Do not ICE when casting polymorphic values. --- .../rustc_const_eval/src/interpret/cast.rs | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 2be5ed896ec80..c14152a916a29 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -67,12 +67,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } Pointer(PointerCast::ReifyFnPointer) => { + // All reifications must be monomorphic, bail out otherwise. + ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; + // The src operand does not matter, just its type match *src.layout.ty.kind() { ty::FnDef(def_id, substs) => { - // All reifications must be monomorphic, bail out otherwise. - ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; - let instance = ty::Instance::resolve_for_fn_ptr( *self.tcx, self.param_env, @@ -100,12 +100,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } Pointer(PointerCast::ClosureFnPointer(_)) => { + // All reifications must be monomorphic, bail out otherwise. + ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; + // The src operand does not matter, just its type match *src.layout.ty.kind() { ty::Closure(def_id, substs) => { - // All reifications must be monomorphic, bail out otherwise. - ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; - let instance = ty::Instance::resolve_closure( *self.tcx, def_id, @@ -359,8 +359,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val = Immediate::new_dyn_trait(ptr, vtable, &*self.tcx); self.write_immediate(val, dest) } - _ => { + // Do not ICE if we are not monomorphic enough. + ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; + ensure_monomorphic_enough(*self.tcx, cast_ty)?; + span_bug!( self.cur_span(), "invalid pointer unsizing {:?} -> {:?}", @@ -404,12 +407,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } Ok(()) } - _ => span_bug!( - self.cur_span(), - "unsize_into: invalid conversion: {:?} -> {:?}", - src.layout, - dest.layout - ), + _ => { + // Do not ICE if we are not monomorphic enough. + ensure_monomorphic_enough(*self.tcx, src.layout.ty)?; + ensure_monomorphic_enough(*self.tcx, cast_ty.ty)?; + + span_bug!( + self.cur_span(), + "unsize_into: invalid conversion: {:?} -> {:?}", + src.layout, + dest.layout + ) + } } } } From 8c0cbd87671c283707cbaf4f60db36a5184d8cef Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 6 Mar 2023 09:24:46 +0000 Subject: [PATCH 08/12] Do not ICE when failing to normalize in ConstProp. --- .../rustc_const_eval/src/interpret/eval_context.rs | 11 ++--------- tests/ui/associated-types/issue-67684.rs | 8 +++++++- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 3db102e484dfa..39c7419125829 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -7,7 +7,7 @@ use either::{Either, Left, Right}; use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; use rustc_index::vec::IndexVec; use rustc_middle::mir; -use rustc_middle::mir::interpret::{ErrorHandled, InterpError, InvalidProgramInfo}; +use rustc_middle::mir::interpret::{ErrorHandled, InterpError}; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout, @@ -508,14 +508,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { frame .instance .try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value) - .map_err(|e| { - self.tcx.sess.delay_span_bug( - self.cur_span(), - format!("failed to normalize {}", e.get_type_for_failure()).as_str(), - ); - - InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric) - }) + .map_err(|_| err_inval!(TooGeneric)) } /// The `substs` are assumed to already be in our interpreter "universe" (param_env). diff --git a/tests/ui/associated-types/issue-67684.rs b/tests/ui/associated-types/issue-67684.rs index 49efe8a1bdaac..c6920cf8d40c1 100644 --- a/tests/ui/associated-types/issue-67684.rs +++ b/tests/ui/associated-types/issue-67684.rs @@ -1,4 +1,10 @@ -// check-pass +// revisions: check build +// [check]check-pass +// +// This second configuration aims to verify that we do not ICE in ConstProp because of +// normalization failure. +// [build]build-pass +// [build]compile-flags: -Zmir-opt-level=3 --emit=mir #![allow(dead_code)] From 2fe288fd2974a781991f6050cdc13bd39e97563d Mon Sep 17 00:00:00 2001 From: Mu42 Date: Mon, 6 Mar 2023 20:04:33 +0800 Subject: [PATCH 09/12] emit the suspicious_auto_trait_impls for negative impls as well --- .../src/coherence/orphan.rs | 4 -- tests/ui/auto-traits/suspicious-impls-lint.rs | 10 +++ .../auto-traits/suspicious-impls-lint.stderr | 69 +++++++++++++++---- 3 files changed, 67 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 1f2de3f21f8d9..47c47de8cedba 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -478,10 +478,6 @@ fn lint_auto_trait_impl<'tcx>( trait_ref: ty::TraitRef<'tcx>, impl_def_id: LocalDefId, ) { - if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive { - return; - } - assert_eq!(trait_ref.substs.len(), 1); let self_ty = trait_ref.self_ty(); let (self_type_did, substs) = match self_ty.kind() { diff --git a/tests/ui/auto-traits/suspicious-impls-lint.rs b/tests/ui/auto-traits/suspicious-impls-lint.rs index 7712e84f4a243..86ee2fd67039d 100644 --- a/tests/ui/auto-traits/suspicious-impls-lint.rs +++ b/tests/ui/auto-traits/suspicious-impls-lint.rs @@ -1,3 +1,4 @@ +#![feature(negative_impls)] #![deny(suspicious_auto_trait_impls)] use std::marker::PhantomData; @@ -21,6 +22,9 @@ struct ContainsVec(Vec); unsafe impl Send for ContainsVec {} //~^ ERROR //~| WARNING this will change its meaning +impl !Send for ContainsVec {} +//~^ ERROR +//~| WARNING this will change its meaning struct TwoParams(T, U); unsafe impl Send for TwoParams {} // ok @@ -40,11 +44,17 @@ pub struct WithPhantomDataSend(PhantomData, U); unsafe impl Send for WithPhantomDataSend<*const T, i8> {} //~^ ERROR //~| WARNING this will change its meaning +impl !Send for WithPhantomDataSend<*const T, u8> {} +//~^ ERROR +//~| WARNING this will change its meaning pub struct WithLifetime<'a, T>(&'a (), T); unsafe impl Send for WithLifetime<'static, T> {} // ok unsafe impl Sync for WithLifetime<'static, Vec> {} //~^ ERROR //~| WARNING this will change its meaning +impl !Sync for WithLifetime<'static, Option> {} +//~^ ERROR +//~| WARNING this will change its meaning fn main() {} diff --git a/tests/ui/auto-traits/suspicious-impls-lint.stderr b/tests/ui/auto-traits/suspicious-impls-lint.stderr index 9cd4e79f851eb..d4e7fe636e677 100644 --- a/tests/ui/auto-traits/suspicious-impls-lint.stderr +++ b/tests/ui/auto-traits/suspicious-impls-lint.stderr @@ -1,5 +1,5 @@ error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:9:1 + --> $DIR/suspicious-impls-lint.rs:10:1 | LL | unsafe impl Send for MayImplementSendErr<&T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,18 +8,18 @@ LL | unsafe impl Send for MayImplementSendErr<&T> {} = note: for more information, see issue #93367 = note: `&T` is not a generic parameter note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:8:1 + --> $DIR/suspicious-impls-lint.rs:9:1 | LL | struct MayImplementSendErr(T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/suspicious-impls-lint.rs:1:9 + --> $DIR/suspicious-impls-lint.rs:2:9 | LL | #![deny(suspicious_auto_trait_impls)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:21:1 + --> $DIR/suspicious-impls-lint.rs:22:1 | LL | unsafe impl Send for ContainsVec {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,13 +28,28 @@ LL | unsafe impl Send for ContainsVec {} = note: for more information, see issue #93367 = note: `i32` is not a generic parameter note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:20:1 + --> $DIR/suspicious-impls-lint.rs:21:1 | LL | struct ContainsVec(Vec); | ^^^^^^^^^^^^^^^^^^^^^ error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:32:1 + --> $DIR/suspicious-impls-lint.rs:25:1 + | +LL | impl !Send for ContainsVec {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `u32` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-impls-lint.rs:21:1 + | +LL | struct ContainsVec(Vec); + | ^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/suspicious-impls-lint.rs:36:1 | LL | unsafe impl Send for TwoParamsSame {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,13 +58,13 @@ LL | unsafe impl Send for TwoParamsSame {} = note: for more information, see issue #93367 = note: `T` is mentioned multiple times note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:31:1 + --> $DIR/suspicious-impls-lint.rs:35:1 | LL | struct TwoParamsSame(T, U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:40:1 + --> $DIR/suspicious-impls-lint.rs:44:1 | LL | unsafe impl Send for WithPhantomDataSend<*const T, i8> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -58,13 +73,28 @@ LL | unsafe impl Send for WithPhantomDataSend<*const T, i8> {} = note: for more information, see issue #93367 = note: `*const T` is not a generic parameter note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:39:1 + --> $DIR/suspicious-impls-lint.rs:43:1 + | +LL | pub struct WithPhantomDataSend(PhantomData, U); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/suspicious-impls-lint.rs:47:1 + | +LL | impl !Send for WithPhantomDataSend<*const T, u8> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `*const T` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-impls-lint.rs:43:1 | LL | pub struct WithPhantomDataSend(PhantomData, U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cross-crate traits with a default impl, like `Sync`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:46:1 + --> $DIR/suspicious-impls-lint.rs:53:1 | LL | unsafe impl Sync for WithLifetime<'static, Vec> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,10 +103,25 @@ LL | unsafe impl Sync for WithLifetime<'static, Vec> {} = note: for more information, see issue #93367 = note: `Vec` is not a generic parameter note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:44:1 + --> $DIR/suspicious-impls-lint.rs:51:1 + | +LL | pub struct WithLifetime<'a, T>(&'a (), T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Sync`, should not be specialized + --> $DIR/suspicious-impls-lint.rs:56:1 + | +LL | impl !Sync for WithLifetime<'static, Option> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `Option` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-impls-lint.rs:51:1 | LL | pub struct WithLifetime<'a, T>(&'a (), T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 8 previous errors From 5c0f55d508b49dbea5b5d69a41d998a00e7d95d2 Mon Sep 17 00:00:00 2001 From: Mu42 Date: Mon, 6 Mar 2023 21:05:23 +0800 Subject: [PATCH 10/12] Moves the negative impls into a separate test file --- tests/ui/auto-traits/suspicious-impls-lint.rs | 10 --- .../auto-traits/suspicious-impls-lint.stderr | 69 +++------------- .../suspicious-negative-impls-lint.rs | 21 +++++ .../suspicious-negative-impls-lint.stderr | 82 +++++++++++++++++++ 4 files changed, 115 insertions(+), 67 deletions(-) create mode 100644 tests/ui/auto-traits/suspicious-negative-impls-lint.rs create mode 100644 tests/ui/auto-traits/suspicious-negative-impls-lint.stderr diff --git a/tests/ui/auto-traits/suspicious-impls-lint.rs b/tests/ui/auto-traits/suspicious-impls-lint.rs index 86ee2fd67039d..7712e84f4a243 100644 --- a/tests/ui/auto-traits/suspicious-impls-lint.rs +++ b/tests/ui/auto-traits/suspicious-impls-lint.rs @@ -1,4 +1,3 @@ -#![feature(negative_impls)] #![deny(suspicious_auto_trait_impls)] use std::marker::PhantomData; @@ -22,9 +21,6 @@ struct ContainsVec(Vec); unsafe impl Send for ContainsVec {} //~^ ERROR //~| WARNING this will change its meaning -impl !Send for ContainsVec {} -//~^ ERROR -//~| WARNING this will change its meaning struct TwoParams(T, U); unsafe impl Send for TwoParams {} // ok @@ -44,17 +40,11 @@ pub struct WithPhantomDataSend(PhantomData, U); unsafe impl Send for WithPhantomDataSend<*const T, i8> {} //~^ ERROR //~| WARNING this will change its meaning -impl !Send for WithPhantomDataSend<*const T, u8> {} -//~^ ERROR -//~| WARNING this will change its meaning pub struct WithLifetime<'a, T>(&'a (), T); unsafe impl Send for WithLifetime<'static, T> {} // ok unsafe impl Sync for WithLifetime<'static, Vec> {} //~^ ERROR //~| WARNING this will change its meaning -impl !Sync for WithLifetime<'static, Option> {} -//~^ ERROR -//~| WARNING this will change its meaning fn main() {} diff --git a/tests/ui/auto-traits/suspicious-impls-lint.stderr b/tests/ui/auto-traits/suspicious-impls-lint.stderr index d4e7fe636e677..9cd4e79f851eb 100644 --- a/tests/ui/auto-traits/suspicious-impls-lint.stderr +++ b/tests/ui/auto-traits/suspicious-impls-lint.stderr @@ -1,5 +1,5 @@ error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:10:1 + --> $DIR/suspicious-impls-lint.rs:9:1 | LL | unsafe impl Send for MayImplementSendErr<&T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,18 +8,18 @@ LL | unsafe impl Send for MayImplementSendErr<&T> {} = note: for more information, see issue #93367 = note: `&T` is not a generic parameter note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:9:1 + --> $DIR/suspicious-impls-lint.rs:8:1 | LL | struct MayImplementSendErr(T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/suspicious-impls-lint.rs:2:9 + --> $DIR/suspicious-impls-lint.rs:1:9 | LL | #![deny(suspicious_auto_trait_impls)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:22:1 + --> $DIR/suspicious-impls-lint.rs:21:1 | LL | unsafe impl Send for ContainsVec {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,28 +28,13 @@ LL | unsafe impl Send for ContainsVec {} = note: for more information, see issue #93367 = note: `i32` is not a generic parameter note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:21:1 + --> $DIR/suspicious-impls-lint.rs:20:1 | LL | struct ContainsVec(Vec); | ^^^^^^^^^^^^^^^^^^^^^ error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:25:1 - | -LL | impl !Send for ContainsVec {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #93367 - = note: `u32` is not a generic parameter -note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:21:1 - | -LL | struct ContainsVec(Vec); - | ^^^^^^^^^^^^^^^^^^^^^ - -error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:36:1 + --> $DIR/suspicious-impls-lint.rs:32:1 | LL | unsafe impl Send for TwoParamsSame {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -58,13 +43,13 @@ LL | unsafe impl Send for TwoParamsSame {} = note: for more information, see issue #93367 = note: `T` is mentioned multiple times note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:35:1 + --> $DIR/suspicious-impls-lint.rs:31:1 | LL | struct TwoParamsSame(T, U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:44:1 + --> $DIR/suspicious-impls-lint.rs:40:1 | LL | unsafe impl Send for WithPhantomDataSend<*const T, i8> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,28 +58,13 @@ LL | unsafe impl Send for WithPhantomDataSend<*const T, i8> {} = note: for more information, see issue #93367 = note: `*const T` is not a generic parameter note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:43:1 - | -LL | pub struct WithPhantomDataSend(PhantomData, U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:47:1 - | -LL | impl !Send for WithPhantomDataSend<*const T, u8> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #93367 - = note: `*const T` is not a generic parameter -note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:43:1 + --> $DIR/suspicious-impls-lint.rs:39:1 | LL | pub struct WithPhantomDataSend(PhantomData, U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cross-crate traits with a default impl, like `Sync`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:53:1 + --> $DIR/suspicious-impls-lint.rs:46:1 | LL | unsafe impl Sync for WithLifetime<'static, Vec> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -103,25 +73,10 @@ LL | unsafe impl Sync for WithLifetime<'static, Vec> {} = note: for more information, see issue #93367 = note: `Vec` is not a generic parameter note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:51:1 - | -LL | pub struct WithLifetime<'a, T>(&'a (), T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: cross-crate traits with a default impl, like `Sync`, should not be specialized - --> $DIR/suspicious-impls-lint.rs:56:1 - | -LL | impl !Sync for WithLifetime<'static, Option> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #93367 - = note: `Option` is not a generic parameter -note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-impls-lint.rs:51:1 + --> $DIR/suspicious-impls-lint.rs:44:1 | LL | pub struct WithLifetime<'a, T>(&'a (), T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 5 previous errors diff --git a/tests/ui/auto-traits/suspicious-negative-impls-lint.rs b/tests/ui/auto-traits/suspicious-negative-impls-lint.rs new file mode 100644 index 0000000000000..34842e5944b46 --- /dev/null +++ b/tests/ui/auto-traits/suspicious-negative-impls-lint.rs @@ -0,0 +1,21 @@ +#![feature(negative_impls)] +#![deny(suspicious_auto_trait_impls)] + +use std::marker::PhantomData; + +struct ContainsVec(Vec); +impl !Send for ContainsVec {} +//~^ ERROR +//~| WARNING this will change its meaning + +pub struct WithPhantomDataSend(PhantomData, U); +impl !Send for WithPhantomDataSend<*const T, u8> {} +//~^ ERROR +//~| WARNING this will change its meaning + +pub struct WithLifetime<'a, T>(&'a (), T); +impl !Sync for WithLifetime<'static, Option> {} +//~^ ERROR +//~| WARNING this will change its meaning + +fn main() {} diff --git a/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr b/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr new file mode 100644 index 0000000000000..14785b98a17dd --- /dev/null +++ b/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr @@ -0,0 +1,82 @@ +error: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/suspicious-negative-impls-lint.rs:7:1 + | +LL | impl !Send for ContainsVec {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `u32` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-negative-impls-lint.rs:6:1 + | +LL | struct ContainsVec(Vec); + | ^^^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/suspicious-negative-impls-lint.rs:2:9 + | +LL | #![deny(suspicious_auto_trait_impls)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/suspicious-negative-impls-lint.rs:12:1 + | +LL | unsafe impl Send for WithPhantomDataSend<*const T, i8> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `*const T` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-negative-impls-lint.rs:11:1 + | +LL | pub struct WithPhantomDataSend(PhantomData, U); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/suspicious-negative-impls-lint.rs:15:1 + | +LL | impl !Send for WithPhantomDataSend<*const T, u8> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `*const T` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-negative-impls-lint.rs:11:1 + | +LL | pub struct WithPhantomDataSend(PhantomData, U); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Sync`, should not be specialized + --> $DIR/suspicious-negative-impls-lint.rs:21:1 + | +LL | unsafe impl Sync for WithLifetime<'static, Vec> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `Vec` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-negative-impls-lint.rs:19:1 + | +LL | pub struct WithLifetime<'a, T>(&'a (), T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cross-crate traits with a default impl, like `Sync`, should not be specialized + --> $DIR/suspicious-negative-impls-lint.rs:24:1 + | +LL | impl !Sync for WithLifetime<'static, Option> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `Option` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/suspicious-negative-impls-lint.rs:19:1 + | +LL | pub struct WithLifetime<'a, T>(&'a (), T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + From 23ba4ceb9edbd3ab962c91f5852367b4529ad8a7 Mon Sep 17 00:00:00 2001 From: Mu42 Date: Mon, 6 Mar 2023 21:05:35 +0800 Subject: [PATCH 11/12] Bless the remaining ui tests --- ...oherence-conflicting-negative-trait-impl.rs | 2 ++ ...ence-conflicting-negative-trait-impl.stderr | 18 +++++++++++++++++- tests/ui/coherence/coherence-orphan.rs | 5 +++-- tests/ui/coherence/coherence-orphan.stderr | 15 ++++++++++++++- tests/ui/issues/issue-106755.rs | 2 ++ tests/ui/issues/issue-106755.stderr | 18 +++++++++++++++++- 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs index 24b878927530c..76a57936e6985 100644 --- a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs +++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs @@ -13,5 +13,7 @@ impl !Send for TestType {} //~ ERROR found both positive and nega unsafe impl Send for TestType {} //~ ERROR conflicting implementations impl !Send for TestType {} +//~^ WARNING +//~| WARNING this will change its meaning fn main() {} diff --git a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr index 2463f38a92251..020199da99141 100644 --- a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr +++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr @@ -16,7 +16,23 @@ LL | unsafe impl Send for TestType {} LL | unsafe impl Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` -error: aborting due to 2 previous errors +warning: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/coherence-conflicting-negative-trait-impl.rs:15:1 + | +LL | impl !Send for TestType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `i32` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ + = note: `#[warn(suspicious_auto_trait_impls)]` on by default + +error: aborting due to 2 previous errors; 1 warning emitted Some errors have detailed explanations: E0119, E0751. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/coherence/coherence-orphan.rs b/tests/ui/coherence/coherence-orphan.rs index 3beac04c7e829..bed782203af50 100644 --- a/tests/ui/coherence/coherence-orphan.rs +++ b/tests/ui/coherence/coherence-orphan.rs @@ -14,7 +14,8 @@ impl TheTrait for isize { } impl TheTrait for TheType { } -impl !Send for Vec { } -//~^ ERROR E0117 +impl !Send for Vec { } //~ ERROR E0117 +//~^ WARNING +//~| WARNING this will change its meaning fn main() { } diff --git a/tests/ui/coherence/coherence-orphan.stderr b/tests/ui/coherence/coherence-orphan.stderr index 01f166a21f768..9ec1d0dc32aa4 100644 --- a/tests/ui/coherence/coherence-orphan.stderr +++ b/tests/ui/coherence/coherence-orphan.stderr @@ -21,6 +21,19 @@ LL | impl !Send for Vec { } | = note: define and implement a trait or new type instead -error: aborting due to 2 previous errors +warning: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/coherence-orphan.rs:17:1 + | +LL | impl !Send for Vec { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `isize` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + = note: `#[warn(suspicious_auto_trait_impls)]` on by default + +error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0117`. diff --git a/tests/ui/issues/issue-106755.rs b/tests/ui/issues/issue-106755.rs index 46ece725fb7c1..5eabc3bfb1384 100644 --- a/tests/ui/issues/issue-106755.rs +++ b/tests/ui/issues/issue-106755.rs @@ -15,5 +15,7 @@ impl !Send for TestType {} //~ ERROR found both positive and nega unsafe impl Send for TestType {} //~ ERROR conflicting implementations impl !Send for TestType {} +//~^ WARNING +//~| WARNING this will change its meaning fn main() {} diff --git a/tests/ui/issues/issue-106755.stderr b/tests/ui/issues/issue-106755.stderr index 543970340620d..6b3a8427e7738 100644 --- a/tests/ui/issues/issue-106755.stderr +++ b/tests/ui/issues/issue-106755.stderr @@ -16,7 +16,23 @@ LL | unsafe impl Send for TestType {} LL | unsafe impl Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` -error: aborting due to 2 previous errors +warning: cross-crate traits with a default impl, like `Send`, should not be specialized + --> $DIR/issue-106755.rs:17:1 + | +LL | impl !Send for TestType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this will change its meaning in a future release! + = note: for more information, see issue #93367 + = note: `i32` is not a generic parameter +note: try using the same sequence of generic parameters as the struct definition + --> $DIR/issue-106755.rs:9:1 + | +LL | struct TestType(::std::marker::PhantomData); + | ^^^^^^^^^^^^^^^^^^ + = note: `#[warn(suspicious_auto_trait_impls)]` on by default + +error: aborting due to 2 previous errors; 1 warning emitted Some errors have detailed explanations: E0119, E0751. For more information about an error, try `rustc --explain E0119`. From 717f93cec57606e83b20c26bedad1e0cdf5154c2 Mon Sep 17 00:00:00 2001 From: Mu42 Date: Mon, 6 Mar 2023 21:25:43 +0800 Subject: [PATCH 12/12] Bless the suspicious-negative-impls-lint.rs --- .../suspicious-negative-impls-lint.stderr | 36 ++----------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr b/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr index 14785b98a17dd..ee03ea1255757 100644 --- a/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr +++ b/tests/ui/auto-traits/suspicious-negative-impls-lint.stderr @@ -21,21 +21,6 @@ LL | #![deny(suspicious_auto_trait_impls)] error: cross-crate traits with a default impl, like `Send`, should not be specialized --> $DIR/suspicious-negative-impls-lint.rs:12:1 | -LL | unsafe impl Send for WithPhantomDataSend<*const T, i8> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #93367 - = note: `*const T` is not a generic parameter -note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-negative-impls-lint.rs:11:1 - | -LL | pub struct WithPhantomDataSend(PhantomData, U); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: cross-crate traits with a default impl, like `Send`, should not be specialized - --> $DIR/suspicious-negative-impls-lint.rs:15:1 - | LL | impl !Send for WithPhantomDataSend<*const T, u8> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | @@ -49,22 +34,7 @@ LL | pub struct WithPhantomDataSend(PhantomData, U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cross-crate traits with a default impl, like `Sync`, should not be specialized - --> $DIR/suspicious-negative-impls-lint.rs:21:1 - | -LL | unsafe impl Sync for WithLifetime<'static, Vec> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this will change its meaning in a future release! - = note: for more information, see issue #93367 - = note: `Vec` is not a generic parameter -note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-negative-impls-lint.rs:19:1 - | -LL | pub struct WithLifetime<'a, T>(&'a (), T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: cross-crate traits with a default impl, like `Sync`, should not be specialized - --> $DIR/suspicious-negative-impls-lint.rs:24:1 + --> $DIR/suspicious-negative-impls-lint.rs:17:1 | LL | impl !Sync for WithLifetime<'static, Option> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,10 +43,10 @@ LL | impl !Sync for WithLifetime<'static, Option> {} = note: for more information, see issue #93367 = note: `Option` is not a generic parameter note: try using the same sequence of generic parameters as the struct definition - --> $DIR/suspicious-negative-impls-lint.rs:19:1 + --> $DIR/suspicious-negative-impls-lint.rs:16:1 | LL | pub struct WithLifetime<'a, T>(&'a (), T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors