mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-01 01:23:26 +00:00
Auto merge of #108821 - matthiaskrgr:rollup-cmkbgpr, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #107801 (const_eval: `implies_by` in `rustc_const_unstable`) - #108750 (Fix `ObligationCtxt::sub`) - #108780 (Add regression tests for issue 70919) - #108786 (Check for free regions in MIR validation) - #108790 (Do not ICE when interpreting a cast between non-monomorphic types) - #108803 (Do not ICE when failing to normalize in ConstProp.) - #108807 (Emit the suspicious_auto_trait_impls for negative impls as well) - #108812 (Add regression test for #98444) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
81be7b86d3
@ -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::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<Symbol> {
|
||||
/// 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<Symbol>)> {
|
||||
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
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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).
|
||||
|
@ -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;
|
||||
|
@ -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()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -416,8 +416,6 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
|
||||
|
||||
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)
|
||||
}
|
||||
|
@ -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
|
||||
});
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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)]
|
||||
|
||||
|
21
tests/ui/auto-traits/suspicious-negative-impls-lint.rs
Normal file
21
tests/ui/auto-traits/suspicious-negative-impls-lint.rs
Normal file
@ -0,0 +1,21 @@
|
||||
#![feature(negative_impls)]
|
||||
#![deny(suspicious_auto_trait_impls)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
struct ContainsVec<T>(Vec<T>);
|
||||
impl !Send for ContainsVec<u32> {}
|
||||
//~^ ERROR
|
||||
//~| WARNING this will change its meaning
|
||||
|
||||
pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
|
||||
impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
|
||||
//~^ ERROR
|
||||
//~| WARNING this will change its meaning
|
||||
|
||||
pub struct WithLifetime<'a, T>(&'a (), T);
|
||||
impl<T> !Sync for WithLifetime<'static, Option<T>> {}
|
||||
//~^ ERROR
|
||||
//~| WARNING this will change its meaning
|
||||
|
||||
fn main() {}
|
52
tests/ui/auto-traits/suspicious-negative-impls-lint.stderr
Normal file
52
tests/ui/auto-traits/suspicious-negative-impls-lint.stderr
Normal file
@ -0,0 +1,52 @@
|
||||
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<u32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this will change its meaning in a future release!
|
||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/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<T>(Vec<T>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
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 | impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this will change its meaning in a future release!
|
||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/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<T, U>(PhantomData<T>, U);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: cross-crate traits with a default impl, like `Sync`, should not be specialized
|
||||
--> $DIR/suspicious-negative-impls-lint.rs:17:1
|
||||
|
|
||||
LL | impl<T> !Sync for WithLifetime<'static, Option<T>> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this will change its meaning in a future release!
|
||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
|
||||
= note: `Option<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:16:1
|
||||
|
|
||||
LL | pub struct WithLifetime<'a, T>(&'a (), T);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
24
tests/ui/borrowck/drop-in-loop.rs
Normal file
24
tests/ui/borrowck/drop-in-loop.rs
Normal file
@ -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() {
|
||||
}
|
14
tests/ui/borrowck/drop-in-loop.stderr
Normal file
14
tests/ui/borrowck/drop-in-loop.stderr
Normal file
@ -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`.
|
25
tests/ui/borrowck/issue-70919-drop-in-loop.rs
Normal file
25
tests/ui/borrowck/issue-70919-drop-in-loop.rs
Normal file
@ -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() {
|
||||
}
|
@ -13,5 +13,7 @@ impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and nega
|
||||
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
|
||||
|
||||
impl !Send for TestType<i32> {}
|
||||
//~^ WARNING
|
||||
//~| WARNING this will change its meaning
|
||||
|
||||
fn main() {}
|
||||
|
@ -16,7 +16,23 @@ LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
LL | unsafe impl<T: 'static> Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<i32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this will change its meaning in a future release!
|
||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/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<T>(::std::marker::PhantomData<T>);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
= 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`.
|
||||
|
@ -14,7 +14,8 @@ impl TheTrait<TheType> for isize { }
|
||||
|
||||
impl TheTrait<isize> for TheType { }
|
||||
|
||||
impl !Send for Vec<isize> { }
|
||||
//~^ ERROR E0117
|
||||
impl !Send for Vec<isize> { } //~ ERROR E0117
|
||||
//~^ WARNING
|
||||
//~| WARNING this will change its meaning
|
||||
|
||||
fn main() { }
|
||||
|
@ -21,6 +21,19 @@ LL | impl !Send for Vec<isize> { }
|
||||
|
|
||||
= 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<isize> { }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this will change its meaning in a future release!
|
||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/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`.
|
||||
|
@ -15,5 +15,7 @@ impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and nega
|
||||
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
|
||||
|
||||
impl !Send for TestType<i32> {}
|
||||
//~^ WARNING
|
||||
//~| WARNING this will change its meaning
|
||||
|
||||
fn main() {}
|
||||
|
@ -16,7 +16,23 @@ LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
|
||||
LL | unsafe impl<T: 'static> Send for TestType<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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<i32> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this will change its meaning in a future release!
|
||||
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/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<T>(::std::marker::PhantomData<T>);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
= 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`.
|
||||
|
7
tests/ui/lint/unconditional_panic_98444.rs
Normal file
7
tests/ui/lint/unconditional_panic_98444.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// build-fail
|
||||
|
||||
fn main() {
|
||||
let xs: [i32; 5] = [1, 2, 3, 4, 5];
|
||||
let _ = &xs;
|
||||
let _ = xs[7]; //~ ERROR: this operation will panic at runtime [unconditional_panic]
|
||||
}
|
10
tests/ui/lint/unconditional_panic_98444.stderr
Normal file
10
tests/ui/lint/unconditional_panic_98444.stderr
Normal file
@ -0,0 +1,10 @@
|
||||
error: this operation will panic at runtime
|
||||
--> $DIR/unconditional_panic_98444.rs:6:13
|
||||
|
|
||||
LL | let _ = xs[7];
|
||||
| ^^^^^ index out of bounds: the length is 5 but the index is 7
|
||||
|
|
||||
= note: `#[deny(unconditional_panic)]` on by default
|
||||
|
||||
error: aborting due to previous error
|
||||
|
15
tests/ui/mir/unsize-trait.rs
Normal file
15
tests/ui/mir/unsize-trait.rs
Normal file
@ -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<B>(buffer: &mut [B; 2])
|
||||
where B: std::marker::Unsize<[u8]>,
|
||||
{
|
||||
let buffer: &[u8] = &buffer[0];
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(&mut [[0], [5]]);
|
||||
}
|
@ -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() {}
|
@ -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();
|
@ -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
|
||||
|
@ -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();
|
@ -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
|
||||
|
@ -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();
|
@ -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
|
||||
|
@ -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();
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user