Skip to content

Commit

Permalink
Auto merge of rust-lang#108821 - matthiaskrgr:rollup-cmkbgpr, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#107801 (const_eval: `implies_by` in `rustc_const_unstable`)
 - rust-lang#108750 (Fix `ObligationCtxt::sub`)
 - rust-lang#108780 (Add regression tests for issue 70919)
 - rust-lang#108786 (Check for free regions in MIR validation)
 - rust-lang#108790 (Do not ICE when interpreting a cast between non-monomorphic types)
 - rust-lang#108803 (Do not ICE when failing to normalize in ConstProp.)
 - rust-lang#108807 (Emit the suspicious_auto_trait_impls for negative impls as well)
 - rust-lang#108812 (Add regression test for rust-lang#98444)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 6, 2023
2 parents f63ccaf + 567cab9 commit 81be7b8
Show file tree
Hide file tree
Showing 33 changed files with 443 additions and 46 deletions.
13 changes: 10 additions & 3 deletions compiler/rustc_const_eval/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
use rustc_attr as attr;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
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
}
Expand Down
35 changes: 22 additions & 13 deletions compiler/rustc_const_eval/src/interpret/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {:?} -> {:?}",
Expand Down Expand Up @@ -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
)
}
}
}
}
11 changes: 2 additions & 9 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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).
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
);
}
}
}
}
}

Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}

Expand All @@ -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)
}
9 changes: 9 additions & 0 deletions compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
});
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down
8 changes: 7 additions & 1 deletion tests/ui/associated-types/issue-67684.rs
Original file line number Diff line number Diff line change
@@ -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)]

Expand Down
21 changes: 21 additions & 0 deletions tests/ui/auto-traits/suspicious-negative-impls-lint.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 52 additions & 0 deletions tests/ui/auto-traits/suspicious-negative-impls-lint.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 24 additions & 0 deletions tests/ui/borrowck/drop-in-loop.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 14 additions & 0 deletions tests/ui/borrowck/drop-in-loop.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 25 additions & 0 deletions tests/ui/borrowck/issue-70919-drop-in-loop.rs
Original file line number Diff line number Diff line change
@@ -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() {
}
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
Loading

0 comments on commit 81be7b8

Please sign in to comment.