Skip to content

Commit 81be7b8

Browse files
committed
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
2 parents f63ccaf + 567cab9 commit 81be7b8

33 files changed

+443
-46
lines changed

compiler/rustc_const_eval/src/const_eval/fn_queries.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
1+
use rustc_attr as attr;
12
use rustc_hir as hir;
23
use rustc_hir::def::DefKind;
34
use rustc_hir::def_id::{DefId, LocalDefId};
45
use rustc_middle::ty::query::Providers;
56
use rustc_middle::ty::TyCtxt;
67
use rustc_span::symbol::Symbol;
78

8-
/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
9-
pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
9+
/// Whether the `def_id` is an unstable const fn and what feature gate(s) are necessary to enable
10+
/// it.
11+
pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<(Symbol, Option<Symbol>)> {
1012
if tcx.is_const_fn_raw(def_id) {
1113
let const_stab = tcx.lookup_const_stability(def_id)?;
12-
if const_stab.is_const_unstable() { Some(const_stab.feature) } else { None }
14+
match const_stab.level {
15+
attr::StabilityLevel::Unstable { implied_by, .. } => {
16+
Some((const_stab.feature, implied_by))
17+
}
18+
attr::StabilityLevel::Stable { .. } => None,
19+
}
1320
} else {
1421
None
1522
}

compiler/rustc_const_eval/src/interpret/cast.rs

+22-13
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
6767
}
6868

6969
Pointer(PointerCast::ReifyFnPointer) => {
70+
// All reifications must be monomorphic, bail out otherwise.
71+
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
72+
7073
// The src operand does not matter, just its type
7174
match *src.layout.ty.kind() {
7275
ty::FnDef(def_id, substs) => {
73-
// All reifications must be monomorphic, bail out otherwise.
74-
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
75-
7676
let instance = ty::Instance::resolve_for_fn_ptr(
7777
*self.tcx,
7878
self.param_env,
@@ -100,12 +100,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
100100
}
101101

102102
Pointer(PointerCast::ClosureFnPointer(_)) => {
103+
// All reifications must be monomorphic, bail out otherwise.
104+
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
105+
103106
// The src operand does not matter, just its type
104107
match *src.layout.ty.kind() {
105108
ty::Closure(def_id, substs) => {
106-
// All reifications must be monomorphic, bail out otherwise.
107-
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
108-
109109
let instance = ty::Instance::resolve_closure(
110110
*self.tcx,
111111
def_id,
@@ -359,8 +359,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
359359
let val = Immediate::new_dyn_trait(ptr, vtable, &*self.tcx);
360360
self.write_immediate(val, dest)
361361
}
362-
363362
_ => {
363+
// Do not ICE if we are not monomorphic enough.
364+
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
365+
ensure_monomorphic_enough(*self.tcx, cast_ty)?;
366+
364367
span_bug!(
365368
self.cur_span(),
366369
"invalid pointer unsizing {:?} -> {:?}",
@@ -404,12 +407,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
404407
}
405408
Ok(())
406409
}
407-
_ => span_bug!(
408-
self.cur_span(),
409-
"unsize_into: invalid conversion: {:?} -> {:?}",
410-
src.layout,
411-
dest.layout
412-
),
410+
_ => {
411+
// Do not ICE if we are not monomorphic enough.
412+
ensure_monomorphic_enough(*self.tcx, src.layout.ty)?;
413+
ensure_monomorphic_enough(*self.tcx, cast_ty.ty)?;
414+
415+
span_bug!(
416+
self.cur_span(),
417+
"unsize_into: invalid conversion: {:?} -> {:?}",
418+
src.layout,
419+
dest.layout
420+
)
421+
}
413422
}
414423
}
415424
}

compiler/rustc_const_eval/src/interpret/eval_context.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use either::{Either, Left, Right};
77
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
88
use rustc_index::vec::IndexVec;
99
use rustc_middle::mir;
10-
use rustc_middle::mir::interpret::{ErrorHandled, InterpError, InvalidProgramInfo};
10+
use rustc_middle::mir::interpret::{ErrorHandled, InterpError};
1111
use rustc_middle::ty::layout::{
1212
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers,
1313
TyAndLayout,
@@ -508,14 +508,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
508508
frame
509509
.instance
510510
.try_subst_mir_and_normalize_erasing_regions(*self.tcx, self.param_env, value)
511-
.map_err(|e| {
512-
self.tcx.sess.delay_span_bug(
513-
self.cur_span(),
514-
format!("failed to normalize {}", e.get_type_for_failure()).as_str(),
515-
);
516-
517-
InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric)
518-
})
511+
.map_err(|_| err_inval!(TooGeneric))
519512
}
520513

521514
/// The `substs` are assumed to already be in our interpreter "universe" (param_env).

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -926,15 +926,24 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
926926

927927
// If the `const fn` we are trying to call is not const-stable, ensure that we have
928928
// the proper feature gate enabled.
929-
if let Some(gate) = is_unstable_const_fn(tcx, callee) {
929+
if let Some((gate, implied_by)) = is_unstable_const_fn(tcx, callee) {
930930
trace!(?gate, "calling unstable const fn");
931931
if self.span.allows_unstable(gate) {
932932
return;
933933
}
934+
if let Some(implied_by_gate) = implied_by && self.span.allows_unstable(implied_by_gate) {
935+
return;
936+
}
934937

935938
// Calling an unstable function *always* requires that the corresponding gate
936-
// be enabled, even if the function has `#[rustc_allow_const_fn_unstable(the_gate)]`.
937-
if !tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate) {
939+
// (or implied gate) be enabled, even if the function has
940+
// `#[rustc_allow_const_fn_unstable(the_gate)]`.
941+
let gate_declared = |gate| {
942+
tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate)
943+
};
944+
let feature_gate_declared = gate_declared(gate);
945+
let implied_gate_declared = implied_by.map(gate_declared).unwrap_or(false);
946+
if !feature_gate_declared && !implied_gate_declared {
938947
self.check_op(ops::FnCallUnstable(callee, Some(gate)));
939948
return;
940949
}
@@ -947,7 +956,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
947956
}
948957

949958
// Otherwise, we are something const-stable calling a const-unstable fn.
950-
951959
if super::rustc_allow_const_fn_unstable(tcx, caller, gate) {
952960
trace!("rustc_allow_const_fn_unstable gate active");
953961
return;

compiler/rustc_const_eval/src/transform/validate.rs

+11
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ impl<'tcx> MirPass<'tcx> for Validator {
7272
};
7373
checker.visit_body(body);
7474
checker.check_cleanup_control_flow();
75+
76+
if let MirPhase::Runtime(_) = body.phase {
77+
if let ty::InstanceDef::Item(_) = body.source.instance {
78+
if body.has_free_regions() {
79+
checker.fail(
80+
Location::START,
81+
format!("Free regions in optimized {} MIR", body.phase.name()),
82+
);
83+
}
84+
}
85+
}
7586
}
7687
}
7788

compiler/rustc_hir_analysis/src/coherence/orphan.rs

-4
Original file line numberDiff line numberDiff line change
@@ -478,10 +478,6 @@ fn lint_auto_trait_impl<'tcx>(
478478
trait_ref: ty::TraitRef<'tcx>,
479479
impl_def_id: LocalDefId,
480480
) {
481-
if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive {
482-
return;
483-
}
484-
485481
assert_eq!(trait_ref.substs.len(), 1);
486482
let self_ty = trait_ref.self_ty();
487483
let (self_type_did, substs) = match self_ty.kind() {

compiler/rustc_mir_transform/src/lib.rs

-6
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,6 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -
416416

417417
pm::run_passes(tcx, &mut body, &[&ctfe_limit::CtfeLimit], None);
418418

419-
debug_assert!(!body.has_free_regions(), "Free regions in MIR for CTFE");
420-
421419
body
422420
}
423421

@@ -626,8 +624,6 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
626624
debug!("body: {:#?}", body);
627625
run_optimization_passes(tcx, &mut body);
628626

629-
debug_assert!(!body.has_free_regions(), "Free regions in optimized MIR");
630-
631627
body
632628
}
633629

@@ -651,7 +647,5 @@ fn promoted_mir(
651647
run_analysis_to_runtime_passes(tcx, body);
652648
}
653649

654-
debug_assert!(!promoted.has_free_regions(), "Free regions in promoted MIR");
655-
656650
tcx.arena.alloc(promoted)
657651
}

compiler/rustc_passes/src/stability.rs

+9
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,15 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
265265
self.index.implications.insert(implied_by, feature);
266266
}
267267

268+
if let Some(ConstStability {
269+
level: Unstable { implied_by: Some(implied_by), .. },
270+
feature,
271+
..
272+
}) = const_stab
273+
{
274+
self.index.implications.insert(implied_by, feature);
275+
}
276+
268277
self.index.stab_map.insert(def_id, stab);
269278
stab
270279
});

compiler/rustc_trait_selection/src/traits/engine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
158158
self.infcx
159159
.at(cause, param_env)
160160
.define_opaque_types(true)
161-
.sup(expected, actual)
161+
.sub(expected, actual)
162162
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
163163
}
164164

tests/ui/associated-types/issue-67684.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
// check-pass
1+
// revisions: check build
2+
// [check]check-pass
3+
//
4+
// This second configuration aims to verify that we do not ICE in ConstProp because of
5+
// normalization failure.
6+
// [build]build-pass
7+
// [build]compile-flags: -Zmir-opt-level=3 --emit=mir
28

39
#![allow(dead_code)]
410

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![feature(negative_impls)]
2+
#![deny(suspicious_auto_trait_impls)]
3+
4+
use std::marker::PhantomData;
5+
6+
struct ContainsVec<T>(Vec<T>);
7+
impl !Send for ContainsVec<u32> {}
8+
//~^ ERROR
9+
//~| WARNING this will change its meaning
10+
11+
pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
12+
impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
13+
//~^ ERROR
14+
//~| WARNING this will change its meaning
15+
16+
pub struct WithLifetime<'a, T>(&'a (), T);
17+
impl<T> !Sync for WithLifetime<'static, Option<T>> {}
18+
//~^ ERROR
19+
//~| WARNING this will change its meaning
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
error: cross-crate traits with a default impl, like `Send`, should not be specialized
2+
--> $DIR/suspicious-negative-impls-lint.rs:7:1
3+
|
4+
LL | impl !Send for ContainsVec<u32> {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= warning: this will change its meaning in a future release!
8+
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
9+
= note: `u32` is not a generic parameter
10+
note: try using the same sequence of generic parameters as the struct definition
11+
--> $DIR/suspicious-negative-impls-lint.rs:6:1
12+
|
13+
LL | struct ContainsVec<T>(Vec<T>);
14+
| ^^^^^^^^^^^^^^^^^^^^^
15+
note: the lint level is defined here
16+
--> $DIR/suspicious-negative-impls-lint.rs:2:9
17+
|
18+
LL | #![deny(suspicious_auto_trait_impls)]
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
20+
21+
error: cross-crate traits with a default impl, like `Send`, should not be specialized
22+
--> $DIR/suspicious-negative-impls-lint.rs:12:1
23+
|
24+
LL | impl<T> !Send for WithPhantomDataSend<*const T, u8> {}
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26+
|
27+
= warning: this will change its meaning in a future release!
28+
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
29+
= note: `*const T` is not a generic parameter
30+
note: try using the same sequence of generic parameters as the struct definition
31+
--> $DIR/suspicious-negative-impls-lint.rs:11:1
32+
|
33+
LL | pub struct WithPhantomDataSend<T, U>(PhantomData<T>, U);
34+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
35+
36+
error: cross-crate traits with a default impl, like `Sync`, should not be specialized
37+
--> $DIR/suspicious-negative-impls-lint.rs:17:1
38+
|
39+
LL | impl<T> !Sync for WithLifetime<'static, Option<T>> {}
40+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
41+
|
42+
= warning: this will change its meaning in a future release!
43+
= note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367>
44+
= note: `Option<T>` is not a generic parameter
45+
note: try using the same sequence of generic parameters as the struct definition
46+
--> $DIR/suspicious-negative-impls-lint.rs:16:1
47+
|
48+
LL | pub struct WithLifetime<'a, T>(&'a (), T);
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50+
51+
error: aborting due to 3 previous errors
52+

tests/ui/borrowck/drop-in-loop.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// A version of `issue-70919-drop-in-loop`, but without
2+
// the necessary `drop` call.
3+
//
4+
// This should fail to compile, since the `Drop` impl
5+
// for `WrapperWithDrop` could observe the changed
6+
// `base` value.
7+
8+
struct WrapperWithDrop<'a>(&'a mut bool);
9+
impl<'a> Drop for WrapperWithDrop<'a> {
10+
fn drop(&mut self) {
11+
}
12+
}
13+
14+
fn drop_in_loop() {
15+
let mut base = true;
16+
let mut wrapper = WrapperWithDrop(&mut base);
17+
loop {
18+
base = false; //~ ERROR: cannot assign to `base`
19+
wrapper = WrapperWithDrop(&mut base);
20+
}
21+
}
22+
23+
fn main() {
24+
}

tests/ui/borrowck/drop-in-loop.stderr

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0506]: cannot assign to `base` because it is borrowed
2+
--> $DIR/drop-in-loop.rs:18:9
3+
|
4+
LL | let mut wrapper = WrapperWithDrop(&mut base);
5+
| --------- `base` is borrowed here
6+
LL | loop {
7+
LL | base = false;
8+
| ^^^^^^^^^^^^ `base` is assigned to here but it was already borrowed
9+
LL | wrapper = WrapperWithDrop(&mut base);
10+
| ------- borrow might be used here, when `wrapper` is dropped and runs the `Drop` code for type `WrapperWithDrop`
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0506`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Regression test for issue #70919
2+
// Tests that we don't emit a spurious "borrow might be used" error
3+
// when we have an explicit `drop` in a loop
4+
5+
// check-pass
6+
7+
struct WrapperWithDrop<'a>(&'a mut bool);
8+
impl<'a> Drop for WrapperWithDrop<'a> {
9+
fn drop(&mut self) {
10+
}
11+
}
12+
13+
fn drop_in_loop() {
14+
let mut base = true;
15+
let mut wrapper = WrapperWithDrop(&mut base);
16+
loop {
17+
drop(wrapper);
18+
19+
base = false;
20+
wrapper = WrapperWithDrop(&mut base);
21+
}
22+
}
23+
24+
fn main() {
25+
}

tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs

+2
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and nega
1313
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
1414

1515
impl !Send for TestType<i32> {}
16+
//~^ WARNING
17+
//~| WARNING this will change its meaning
1618

1719
fn main() {}

0 commit comments

Comments
 (0)