Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 95f437b

Browse files
committedOct 27, 2019
Auto merge of #65869 - Centril:rollup-bzlo74f, r=Centril
Rollup of 6 pull requests Successful merges: - #65566 (Use heuristics to suggest assignment) - #65738 (Coherence should allow fundamental types to impl traits when they are local) - #65777 (Don't ICE for completely unexpandable `impl Trait` types) - #65834 (Remove lint callback from driver) - #65839 (Clean up `check_consts` now that new promotion pass is implemented) - #65855 (Add long error explaination for E0666) Failed merges: r? @ghost
2 parents 0f677c6 + b5b4f9b commit 95f437b

29 files changed

+520
-459
lines changed
 

‎src/librustc/traits/coherence.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -378,15 +378,21 @@ fn orphan_check_trait_ref<'tcx>(
378378
// Let Ti be the first such type.
379379
// - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti)
380380
//
381-
fn uncover_fundamental_ty(ty: Ty<'_>) -> Vec<Ty<'_>> {
382-
if fundamental_ty(ty) {
383-
ty.walk_shallow().flat_map(|ty| uncover_fundamental_ty(ty)).collect()
381+
fn uncover_fundamental_ty<'a>(
382+
tcx: TyCtxt<'_>,
383+
ty: Ty<'a>,
384+
in_crate: InCrate,
385+
) -> Vec<Ty<'a>> {
386+
if fundamental_ty(ty) && !ty_is_local(tcx, ty, in_crate) {
387+
ty.walk_shallow().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)).collect()
384388
} else {
385389
vec![ty]
386390
}
387391
}
388392

389-
for input_ty in trait_ref.input_types().flat_map(uncover_fundamental_ty) {
393+
for input_ty in
394+
trait_ref.input_types().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
395+
{
390396
debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty);
391397
if ty_is_local(tcx, input_ty, in_crate) {
392398
debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty);

‎src/librustc_driver/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,6 @@ pub fn abort_on_err<T>(result: Result<T, ErrorReported>, sess: &Session) -> T {
106106
pub trait Callbacks {
107107
/// Called before creating the compiler instance
108108
fn config(&mut self, _config: &mut interface::Config) {}
109-
/// Called early during compilation to allow other drivers to easily register lints.
110-
fn extra_lints(&mut self, _ls: &mut lint::LintStore) {}
111109
/// Called after parsing. Return value instructs the compiler whether to
112110
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
113111
fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation {

‎src/librustc_mir/transform/check_consts/mod.rs

+79-30
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,27 @@
44
//! has interior mutability or needs to be dropped, as well as the visitor that emits errors when
55
//! it finds operations that are invalid in a certain context.
66
7-
use rustc::hir::def_id::DefId;
7+
use rustc::hir::{self, def_id::DefId};
88
use rustc::mir;
99
use rustc::ty::{self, TyCtxt};
1010

11+
use std::fmt;
12+
1113
pub use self::qualifs::Qualif;
1214

1315
pub mod ops;
1416
pub mod qualifs;
1517
mod resolver;
1618
pub mod validation;
1719

18-
/// Information about the item currently being validated, as well as a reference to the global
20+
/// Information about the item currently being const-checked, as well as a reference to the global
1921
/// context.
2022
pub struct Item<'mir, 'tcx> {
21-
body: &'mir mir::Body<'tcx>,
22-
tcx: TyCtxt<'tcx>,
23-
def_id: DefId,
24-
param_env: ty::ParamEnv<'tcx>,
25-
mode: validation::Mode,
26-
for_promotion: bool,
23+
pub body: &'mir mir::Body<'tcx>,
24+
pub tcx: TyCtxt<'tcx>,
25+
pub def_id: DefId,
26+
pub param_env: ty::ParamEnv<'tcx>,
27+
pub const_kind: Option<ConstKind>,
2728
}
2829

2930
impl Item<'mir, 'tcx> {
@@ -33,43 +34,91 @@ impl Item<'mir, 'tcx> {
3334
body: &'mir mir::Body<'tcx>,
3435
) -> Self {
3536
let param_env = tcx.param_env(def_id);
36-
let mode = validation::Mode::for_item(tcx, def_id)
37-
.expect("const validation must only be run inside a const context");
37+
let const_kind = ConstKind::for_item(tcx, def_id);
3838

3939
Item {
4040
body,
4141
tcx,
4242
def_id,
4343
param_env,
44-
mode,
45-
for_promotion: false,
44+
const_kind,
4645
}
4746
}
4847

49-
// HACK(eddyb) this is to get around the panic for a runtime fn from `Item::new`.
50-
// Also, it allows promoting `&mut []`.
51-
pub fn for_promotion(
52-
tcx: TyCtxt<'tcx>,
53-
def_id: DefId,
54-
body: &'mir mir::Body<'tcx>,
55-
) -> Self {
56-
let param_env = tcx.param_env(def_id);
57-
let mode = validation::Mode::for_item(tcx, def_id)
58-
.unwrap_or(validation::Mode::ConstFn);
48+
/// Returns the kind of const context this `Item` represents (`const`, `static`, etc.).
49+
///
50+
/// Panics if this `Item` is not const.
51+
pub fn const_kind(&self) -> ConstKind {
52+
self.const_kind.expect("`const_kind` must not be called on a non-const fn")
53+
}
54+
}
5955

60-
Item {
61-
body,
62-
tcx,
63-
def_id,
64-
param_env,
65-
mode,
66-
for_promotion: true,
56+
/// The kinds of items which require compile-time evaluation.
57+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
58+
pub enum ConstKind {
59+
/// A `static` item.
60+
Static,
61+
/// A `static mut` item.
62+
StaticMut,
63+
/// A `const fn` item.
64+
ConstFn,
65+
/// A `const` item or an anonymous constant (e.g. in array lengths).
66+
Const,
67+
}
68+
69+
impl ConstKind {
70+
/// Returns the validation mode for the item with the given `DefId`, or `None` if this item
71+
/// does not require validation (e.g. a non-const `fn`).
72+
pub fn for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Self> {
73+
use hir::BodyOwnerKind as HirKind;
74+
75+
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
76+
77+
let mode = match tcx.hir().body_owner_kind(hir_id) {
78+
HirKind::Closure => return None,
79+
80+
HirKind::Fn if tcx.is_const_fn(def_id) => ConstKind::ConstFn,
81+
HirKind::Fn => return None,
82+
83+
HirKind::Const => ConstKind::Const,
84+
85+
HirKind::Static(hir::MutImmutable) => ConstKind::Static,
86+
HirKind::Static(hir::MutMutable) => ConstKind::StaticMut,
87+
};
88+
89+
Some(mode)
90+
}
91+
92+
pub fn is_static(self) -> bool {
93+
match self {
94+
ConstKind::Static | ConstKind::StaticMut => true,
95+
ConstKind::ConstFn | ConstKind::Const => false,
96+
}
97+
}
98+
99+
/// Returns `true` if the value returned by this item must be `Sync`.
100+
///
101+
/// This returns false for `StaticMut` since all accesses to one are `unsafe` anyway.
102+
pub fn requires_sync(self) -> bool {
103+
match self {
104+
ConstKind::Static => true,
105+
ConstKind::ConstFn | ConstKind::Const | ConstKind::StaticMut => false,
67106
}
68107
}
69108
}
70109

110+
impl fmt::Display for ConstKind {
111+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112+
match *self {
113+
ConstKind::Const => write!(f, "constant"),
114+
ConstKind::Static | ConstKind::StaticMut => write!(f, "static"),
115+
ConstKind::ConstFn => write!(f, "constant function"),
116+
}
117+
}
118+
}
71119

72-
fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
120+
/// Returns `true` if this `DefId` points to one of the official `panic` lang items.
121+
pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
73122
Some(def_id) == tcx.lang_items().panic_fn() ||
74123
Some(def_id) == tcx.lang_items().begin_panic_fn()
75124
}

‎src/librustc_mir/transform/check_consts/ops.rs

+16-17
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ use syntax::feature_gate::{emit_feature_err, GateIssue};
88
use syntax::symbol::sym;
99
use syntax_pos::{Span, Symbol};
1010

11-
use super::Item;
12-
use super::validation::Mode;
11+
use super::{ConstKind, Item};
1312

1413
/// An operation that is not *always* allowed in a const context.
1514
pub trait NonConstOp: std::fmt::Debug {
@@ -36,7 +35,7 @@ pub trait NonConstOp: std::fmt::Debug {
3635
span,
3736
E0019,
3837
"{} contains unimplemented expression type",
39-
item.mode
38+
item.const_kind()
4039
);
4140
if item.tcx.sess.teach(&err.get_code().unwrap()) {
4241
err.note("A function call isn't allowed in the const's initialization expression \
@@ -76,7 +75,7 @@ impl NonConstOp for FnCallNonConst {
7675
E0015,
7776
"calls in {}s are limited to constant functions, \
7877
tuple structs and tuple variants",
79-
item.mode,
78+
item.const_kind(),
8079
);
8180
err.emit();
8281
}
@@ -121,8 +120,8 @@ impl NonConstOp for HeapAllocation {
121120

122121
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
123122
let mut err = struct_span_err!(item.tcx.sess, span, E0010,
124-
"allocations are not allowed in {}s", item.mode);
125-
err.span_label(span, format!("allocation not allowed in {}s", item.mode));
123+
"allocations are not allowed in {}s", item.const_kind());
124+
err.span_label(span, format!("allocation not allowed in {}s", item.const_kind()));
126125
if item.tcx.sess.teach(&err.get_code().unwrap()) {
127126
err.note(
128127
"The value of statics and constants must be known at compile time, \
@@ -146,7 +145,7 @@ impl NonConstOp for LiveDrop {
146145
struct_span_err!(item.tcx.sess, span, E0493,
147146
"destructors cannot be evaluated at compile-time")
148147
.span_label(span, format!("{}s cannot evaluate destructors",
149-
item.mode))
148+
item.const_kind()))
150149
.emit();
151150
}
152151
}
@@ -163,9 +162,9 @@ impl NonConstOp for MutBorrow {
163162
if let BorrowKind::Mut { .. } = kind {
164163
let mut err = struct_span_err!(item.tcx.sess, span, E0017,
165164
"references in {}s may only refer \
166-
to immutable values", item.mode);
165+
to immutable values", item.const_kind());
167166
err.span_label(span, format!("{}s require immutable values",
168-
item.mode));
167+
item.const_kind()));
169168
if item.tcx.sess.teach(&err.get_code().unwrap()) {
170169
err.note("References in statics and constants may only refer \
171170
to immutable values.\n\n\
@@ -202,7 +201,7 @@ impl NonConstOp for Panic {
202201
sym::const_panic,
203202
span,
204203
GateIssue::Language,
205-
&format!("panicking in {}s is unstable", item.mode),
204+
&format!("panicking in {}s is unstable", item.const_kind()),
206205
);
207206
}
208207
}
@@ -220,7 +219,7 @@ impl NonConstOp for RawPtrComparison {
220219
sym::const_compare_raw_pointers,
221220
span,
222221
GateIssue::Language,
223-
&format!("comparing raw pointers inside {}", item.mode),
222+
&format!("comparing raw pointers inside {}", item.const_kind()),
224223
);
225224
}
226225
}
@@ -238,7 +237,7 @@ impl NonConstOp for RawPtrDeref {
238237
span, GateIssue::Language,
239238
&format!(
240239
"dereferencing raw pointers in {}s is unstable",
241-
item.mode,
240+
item.const_kind(),
242241
),
243242
);
244243
}
@@ -257,7 +256,7 @@ impl NonConstOp for RawPtrToIntCast {
257256
span, GateIssue::Language,
258257
&format!(
259258
"casting pointers to integers in {}s is unstable",
260-
item.mode,
259+
item.const_kind(),
261260
),
262261
);
263262
}
@@ -268,13 +267,13 @@ impl NonConstOp for RawPtrToIntCast {
268267
pub struct StaticAccess;
269268
impl NonConstOp for StaticAccess {
270269
fn is_allowed_in_item(&self, item: &Item<'_, '_>) -> bool {
271-
item.mode.is_static()
270+
item.const_kind().is_static()
272271
}
273272

274273
fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
275274
let mut err = struct_span_err!(item.tcx.sess, span, E0013,
276275
"{}s cannot refer to statics, use \
277-
a constant instead", item.mode);
276+
a constant instead", item.const_kind());
278277
if item.tcx.sess.teach(&err.get_code().unwrap()) {
279278
err.note(
280279
"Static and const variables can refer to other const variables. \
@@ -313,7 +312,7 @@ impl NonConstOp for Transmute {
313312
&item.tcx.sess.parse_sess, sym::const_transmute,
314313
span, GateIssue::Language,
315314
&format!("The use of std::mem::transmute() \
316-
is gated in {}s", item.mode));
315+
is gated in {}s", item.const_kind()));
317316
}
318317
}
319318

@@ -322,7 +321,7 @@ pub struct UnionAccess;
322321
impl NonConstOp for UnionAccess {
323322
fn is_allowed_in_item(&self, item: &Item<'_, '_>) -> bool {
324323
// Union accesses are stable in all contexts except `const fn`.
325-
item.mode != Mode::ConstFn || Self::feature_gate(item.tcx).unwrap()
324+
item.const_kind() != ConstKind::ConstFn || Self::feature_gate(item.tcx).unwrap()
326325
}
327326

328327
fn feature_gate(tcx: TyCtxt<'_>) -> Option<bool> {

‎src/librustc_mir/transform/check_consts/qualifs.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use rustc::mir::interpret::ConstValue;
55
use rustc::ty::{self, Ty};
66
use syntax_pos::DUMMY_SP;
77

8-
use super::Item as ConstCx;
9-
use super::validation::Mode;
8+
use super::{ConstKind, Item as ConstCx};
109

1110
#[derive(Clone, Copy)]
1211
pub struct QualifSet(u8);
@@ -236,13 +235,17 @@ impl Qualif for HasMutInterior {
236235
// mutably without consequences.
237236
match ty.kind {
238237
// Inside a `static mut`, &mut [...] is also allowed.
239-
ty::Array(..) | ty::Slice(_) if cx.mode == Mode::StaticMut => {},
240-
241-
// FIXME(eddyb) the `cx.for_promotion` condition
242-
// seems unnecessary, given that this is merely a ZST.
243-
ty::Array(_, len)
244-
if len.try_eval_usize(cx.tcx, cx.param_env) == Some(0)
245-
&& cx.for_promotion => {},
238+
| ty::Array(..)
239+
| ty::Slice(_)
240+
if cx.const_kind == Some(ConstKind::StaticMut)
241+
=> {},
242+
243+
// FIXME(eddyb): We only return false for `&mut []` outside a const
244+
// context which seems unnecessary given that this is merely a ZST.
245+
| ty::Array(_, len)
246+
if len.try_eval_usize(cx.tcx, cx.param_env) == Some(0)
247+
&& cx.const_kind == None
248+
=> {},
246249

247250
_ => return true,
248251
}

0 commit comments

Comments
 (0)
Please sign in to comment.