Skip to content

Commit 2bcca41

Browse files
committed
Auto merge of #122524 - cuviper:beta-next, r=cuviper
[beta] backports - AST validation: Improve handling of inherent impls nested within functions and anon consts #122004 - Downgrade const eval dangling ptr in final to future incompat lint #122204 r? cuviper
2 parents 339fb69 + 6b0992f commit 2bcca41

17 files changed

+1118
-136
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

+30-27
Original file line numberDiff line numberDiff line change
@@ -925,35 +925,38 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
925925
only_trait: only_trait.then_some(()),
926926
};
927927

928-
self.visibility_not_permitted(
929-
&item.vis,
930-
errors::VisibilityNotPermittedNote::IndividualImplItems,
931-
);
932-
if let &Unsafe::Yes(span) = unsafety {
933-
self.dcx().emit_err(errors::InherentImplCannotUnsafe {
934-
span: self_ty.span,
935-
annotation_span: span,
936-
annotation: "unsafe",
937-
self_ty: self_ty.span,
938-
});
939-
}
940-
if let &ImplPolarity::Negative(span) = polarity {
941-
self.dcx().emit_err(error(span, "negative", false));
942-
}
943-
if let &Defaultness::Default(def_span) = defaultness {
944-
self.dcx().emit_err(error(def_span, "`default`", true));
945-
}
946-
if let &Const::Yes(span) = constness {
947-
self.dcx().emit_err(error(span, "`const`", true));
948-
}
928+
self.with_in_trait_impl(None, |this| {
929+
this.visibility_not_permitted(
930+
&item.vis,
931+
errors::VisibilityNotPermittedNote::IndividualImplItems,
932+
);
933+
if let &Unsafe::Yes(span) = unsafety {
934+
this.dcx().emit_err(errors::InherentImplCannotUnsafe {
935+
span: self_ty.span,
936+
annotation_span: span,
937+
annotation: "unsafe",
938+
self_ty: self_ty.span,
939+
});
940+
}
941+
if let &ImplPolarity::Negative(span) = polarity {
942+
this.dcx().emit_err(error(span, "negative", false));
943+
}
944+
if let &Defaultness::Default(def_span) = defaultness {
945+
this.dcx().emit_err(error(def_span, "`default`", true));
946+
}
947+
if let &Const::Yes(span) = constness {
948+
this.dcx().emit_err(error(span, "`const`", true));
949+
}
949950

950-
self.visit_vis(&item.vis);
951-
self.visit_ident(item.ident);
952-
self.with_tilde_const(Some(DisallowTildeConstContext::Impl(item.span)), |this| {
953-
this.visit_generics(generics)
951+
this.visit_vis(&item.vis);
952+
this.visit_ident(item.ident);
953+
this.with_tilde_const(
954+
Some(DisallowTildeConstContext::Impl(item.span)),
955+
|this| this.visit_generics(generics),
956+
);
957+
this.visit_ty(self_ty);
958+
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
954959
});
955-
self.visit_ty(self_ty);
956-
walk_list!(self, visit_assoc_item, items, AssocCtxt::Impl);
957960
walk_list!(self, visit_attribute, &item.attrs);
958961
return; // Avoid visiting again.
959962
}

compiler/rustc_const_eval/src/errors.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,13 @@ pub(crate) struct DanglingPtrInFinal {
2727
pub kind: InternKind,
2828
}
2929

30-
#[derive(Diagnostic)]
30+
#[derive(LintDiagnostic)]
3131
#[diag(const_eval_mutable_ptr_in_final)]
3232
pub(crate) struct MutablePtrInFinal {
33-
#[primary_span]
33+
// rust-lang/rust#122153: This was marked as `#[primary_span]` under
34+
// `derive(Diagnostic)`. Since we expect we may hard-error in future, we are
35+
// keeping the field (and skipping it under `derive(LintDiagnostic)`).
36+
#[skip_arg]
3437
pub span: Span,
3538
pub kind: InternKind,
3639
}

compiler/rustc_const_eval/src/interpret/intern.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc_errors::ErrorGuaranteed;
1919
use rustc_hir as hir;
2020
use rustc_middle::mir::interpret::{CtfeProvenance, InterpResult};
2121
use rustc_middle::ty::layout::TyAndLayout;
22+
use rustc_session::lint;
2223

2324
use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy};
2425
use crate::const_eval;
@@ -195,10 +196,13 @@ pub fn intern_const_alloc_recursive<
195196
})?;
196197
}
197198
if found_bad_mutable_pointer {
198-
return Err(ecx
199-
.tcx
200-
.dcx()
201-
.emit_err(MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind }));
199+
let err_diag = MutablePtrInFinal { span: ecx.tcx.span, kind: intern_kind };
200+
ecx.tcx.emit_node_span_lint(
201+
lint::builtin::CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
202+
ecx.best_lint_scope(),
203+
err_diag.span,
204+
err_diag,
205+
)
202206
}
203207

204208
Ok(())

compiler/rustc_lint_defs/src/builtin.rs

+46
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ declare_lint_pass! {
2727
CENUM_IMPL_DROP_CAST,
2828
COHERENCE_LEAK_CHECK,
2929
CONFLICTING_REPR_HINTS,
30+
CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
3031
CONST_EVALUATABLE_UNCHECKED,
3132
CONST_ITEM_MUTATION,
3233
CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
@@ -2905,6 +2906,51 @@ declare_lint! {
29052906
@feature_gate = sym::strict_provenance;
29062907
}
29072908

2909+
declare_lint! {
2910+
/// The `const_eval_mutable_ptr_in_final_value` lint detects if a mutable pointer
2911+
/// has leaked into the final value of a const expression.
2912+
///
2913+
/// ### Example
2914+
///
2915+
/// ```rust
2916+
/// pub enum JsValue {
2917+
/// Undefined,
2918+
/// Object(std::cell::Cell<bool>),
2919+
/// }
2920+
///
2921+
/// impl ::std::ops::Drop for JsValue {
2922+
/// fn drop(&mut self) {}
2923+
/// }
2924+
///
2925+
/// const UNDEFINED: &JsValue = &JsValue::Undefined;
2926+
///
2927+
/// fn main() {
2928+
/// }
2929+
/// ```
2930+
///
2931+
/// {{produces}}
2932+
///
2933+
/// ### Explanation
2934+
///
2935+
/// In the 1.77 release, the const evaluation machinery adopted some
2936+
/// stricter rules to reject expressions with values that could
2937+
/// end up holding mutable references to state stored in static memory
2938+
/// (which is inherently immutable).
2939+
///
2940+
/// This is a [future-incompatible] lint to ease the transition to an error.
2941+
/// See [issue #122153] for more details.
2942+
///
2943+
/// [issue #122153]: https://github.com/rust-lang/rust/issues/122153
2944+
/// [future-incompatible]: ../index.md#future-incompatible-lints
2945+
pub CONST_EVAL_MUTABLE_PTR_IN_FINAL_VALUE,
2946+
Warn,
2947+
"detects a mutable pointer that has leaked into final value of a const expression",
2948+
@future_incompatible = FutureIncompatibleInfo {
2949+
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
2950+
reference: "issue #122153 <https://github.com/rust-lang/rust/issues/122153>",
2951+
};
2952+
}
2953+
29082954
declare_lint! {
29092955
/// The `const_evaluatable_unchecked` lint detects a generic constant used
29102956
/// in a type.
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#![feature(core_intrinsics)]
22
#![feature(const_heap)]
33
#![feature(const_mut_refs)]
4+
#![deny(const_eval_mutable_ptr_in_final_value)]
45
use std::intrinsics;
56

67
const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
78
//~^ error: mutable pointer in final value of constant
9+
//~| WARNING this was previously accepted by the compiler
810

911
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
error: encountered mutable pointer in final value of constant
2-
--> $DIR/alloc_intrinsic_untyped.rs:6:1
2+
--> $DIR/alloc_intrinsic_untyped.rs:7:1
33
|
44
LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
55
| ^^^^^^^^^^^^^^^^^^^
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
9+
note: the lint level is defined here
10+
--> $DIR/alloc_intrinsic_untyped.rs:4:9
11+
|
12+
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
614

715
error: aborting due to 1 previous error
816

17+
Future incompatibility report: Future breakage diagnostic:
18+
error: encountered mutable pointer in final value of constant
19+
--> $DIR/alloc_intrinsic_untyped.rs:7:1
20+
|
21+
LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
22+
| ^^^^^^^^^^^^^^^^^^^
23+
|
24+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
25+
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
26+
note: the lint level is defined here
27+
--> $DIR/alloc_intrinsic_untyped.rs:4:9
28+
|
29+
LL | #![deny(const_eval_mutable_ptr_in_final_value)]
30+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// check-pass
2+
use std::cell::Cell;
3+
4+
pub enum JsValue {
5+
Undefined,
6+
Object(Cell<bool>),
7+
}
8+
9+
impl ::std::ops::Drop for JsValue {
10+
fn drop(&mut self) {}
11+
}
12+
13+
const UNDEFINED: &JsValue = &JsValue::Undefined;
14+
//~^ WARN encountered mutable pointer in final value of constant
15+
//~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
16+
17+
fn main() {
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
warning: encountered mutable pointer in final value of constant
2+
--> $DIR/future-incompat-mutable-in-final-value-issue-121610.rs:13:1
3+
|
4+
LL | const UNDEFINED: &JsValue = &JsValue::Undefined;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
8+
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
9+
= note: `#[warn(const_eval_mutable_ptr_in_final_value)]` on by default
10+
11+
warning: 1 warning emitted
12+
13+
Future incompatibility report: Future breakage diagnostic:
14+
warning: encountered mutable pointer in final value of constant
15+
--> $DIR/future-incompat-mutable-in-final-value-issue-121610.rs:13:1
16+
|
17+
LL | const UNDEFINED: &JsValue = &JsValue::Undefined;
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
19+
|
20+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
21+
= note: for more information, see issue #122153 <https://github.com/rust-lang/rust/issues/122153>
22+
= note: `#[warn(const_eval_mutable_ptr_in_final_value)]` on by default
23+

0 commit comments

Comments
 (0)