Skip to content

Commit 48bbf49

Browse files
committed
const generics work!
1 parent b615b98 commit 48bbf49

File tree

17 files changed

+301
-141
lines changed

17 files changed

+301
-141
lines changed

src/librustc_metadata/rmeta/decoder/cstore_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
112112
})
113113
}
114114
optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
115-
promoted_mir => { cdata.get_promoted_mir(tcx, def_id.index) }
115+
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
116116
mir_const_qualif => { cdata.mir_const_qualif(def_id.index) }
117117
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
118118
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }

src/librustc_middle/arena.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,20 @@ macro_rules! arena_types {
3131
rustc_middle::mir::Body<$tcx>
3232
>
3333
>;
34+
[] promoted:
35+
rustc_index::vec::IndexVec<
36+
rustc_middle::mir::Promoted,
37+
rustc_middle::mir::Body<$tcx>
38+
>,
39+
rustc_index::vec::IndexVec<
40+
rustc_middle::mir::Promoted,
41+
rustc_middle::mir::Body<'_x>
42+
>;
3443
[decode] tables: rustc_middle::ty::TypeckTables<$tcx>, rustc_middle::ty::TypeckTables<'_x>;
3544
[decode] borrowck_result:
3645
rustc_middle::mir::BorrowCheckResult<$tcx>,
3746
rustc_middle::mir::BorrowCheckResult<'_x>;
47+
[] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult, rustc_middle::mir::UnsafetyCheckResult;
3848
[] const_allocs: rustc_middle::mir::interpret::Allocation, rustc_middle::mir::interpret::Allocation;
3949
// Required for the incremental on-disk cache
4050
[few, decode] mir_keys: rustc_hir::def_id::DefIdSet, rustc_hir::def_id::DefIdSet;

src/librustc_middle/query/mod.rs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -208,19 +208,27 @@ rustc_queries! {
208208
desc { |tcx| "const checking `{}`", tcx.def_path_str(key) }
209209
cache_on_disk_if { key.is_local() }
210210
}
211+
query mir_const_qualif_const_arg(
212+
key: ty::WithOptParam<LocalDefId>
213+
) -> mir::ConstQualifs {
214+
desc {
215+
|tcx| "const checking the potential const argument `{}`",
216+
tcx.def_path_str(key.did.to_def_id())
217+
}
218+
}
211219

212220
/// Fetch the MIR for a given `DefId` right after it's built - this includes
213221
/// unreachable code.
214-
query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> {
215-
desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.to_def_id()) }
222+
query mir_built(key: ty::WithOptParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> {
223+
desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
216224
}
217225

218226
/// Fetch the MIR for a given `DefId` up till the point where it is
219227
/// ready for const qualification.
220228
///
221229
/// See the README for the `mir` module for details.
222-
query mir_const(key: DefId) -> &'tcx Steal<mir::Body<'tcx>> {
223-
desc { |tcx| "processing MIR for `{}`", tcx.def_path_str(key) }
230+
query mir_const(key: ty::WithOptParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> {
231+
desc { |tcx| "processing MIR for `{}`", tcx.def_path_str(key.did.to_def_id()) }
224232
no_hash
225233
}
226234

@@ -231,13 +239,16 @@ rustc_queries! {
231239
desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.did.to_def_id()) }
232240
}
233241

234-
query mir_validated(key: LocalDefId) ->
242+
query mir_validated(key: ty::WithOptParam<LocalDefId>) ->
235243
(
236244
&'tcx Steal<mir::Body<'tcx>>,
237245
&'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>
238246
) {
239247
no_hash
240-
desc { |tcx| "processing `{}`", tcx.def_path_str(key.to_def_id()) }
248+
desc {
249+
|tcx| "processing the potential const argument `{}`",
250+
tcx.def_path_str(key.did.to_def_id())
251+
}
241252
}
242253

243254
/// MIR after our optimization passes have run. This is MIR that is ready
@@ -261,11 +272,18 @@ rustc_queries! {
261272
cache_on_disk_if { key.is_local() }
262273
}
263274

264-
query promoted_mir(key: DefId) -> IndexVec<mir::Promoted, mir::Body<'tcx>> {
275+
query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> {
265276
desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) }
266-
storage(ArenaCacheSelector<'tcx>)
267277
cache_on_disk_if { key.is_local() }
268278
}
279+
query promoted_mir_of_const_arg(
280+
key: ty::WithOptParam<LocalDefId>
281+
) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> {
282+
desc {
283+
|tcx| "optimizing promoted MIR for the potential const argument `{}`",
284+
tcx.def_path_str(key.did.to_def_id()),
285+
}
286+
}
269287
}
270288

271289
TypeChecking {
@@ -473,11 +491,13 @@ rustc_queries! {
473491
}
474492

475493
TypeChecking {
476-
/// The result of unsafety-checking this `DefId`.
477-
query unsafety_check_result(key: LocalDefId) -> mir::UnsafetyCheckResult {
494+
/// The result of unsafety-checking this `LocalDefId`.
495+
query unsafety_check_result(key: LocalDefId) -> &'tcx mir::UnsafetyCheckResult {
478496
desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) }
479497
cache_on_disk_if { true }
480-
storage(ArenaCacheSelector<'tcx>)
498+
}
499+
query unsafety_check_result_const_arg(key: ty::WithOptParam<LocalDefId>) -> &'tcx mir::UnsafetyCheckResult {
500+
desc { |tcx| "unsafety-checking the potential const arg `{}`", tcx.def_path_str(key.did.to_def_id()) }
481501
}
482502

483503
/// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error.
@@ -601,13 +621,18 @@ rustc_queries! {
601621
/// Borrow-checks the function body. If this is a closure, returns
602622
/// additional requirements that the closure's creator must verify.
603623
query mir_borrowck(key: LocalDefId) -> &'tcx mir::BorrowCheckResult<'tcx> {
604-
storage(ArenaCacheSelector<'tcx>)
605624
desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.to_def_id()) }
606625
cache_on_disk_if(tcx, opt_result) {
607626
tcx.is_closure(key.to_def_id())
608627
|| opt_result.map_or(false, |r| !r.concrete_opaque_types.is_empty())
609628
}
610629
}
630+
query mir_borrowck_const_arg(key: ty::WithOptParam<LocalDefId>) -> &'tcx mir::BorrowCheckResult<'tcx> {
631+
desc {
632+
|tcx| "borrow-checking the potential const argument`{}`",
633+
tcx.def_path_str(key.did.to_def_id())
634+
}
635+
}
611636
}
612637

613638
TypeChecking {

src/librustc_middle/ty/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,13 +1600,21 @@ impl WithOptParam<DefId> {
16001600
self.did.as_local().map(|did| WithOptParam { did, param_did: self.param_did })
16011601
}
16021602

1603+
pub fn expect_local(self) -> WithOptParam<LocalDefId> {
1604+
self.as_local().unwrap()
1605+
}
1606+
16031607
pub fn is_local(self) -> bool {
16041608
self.did.is_local()
16051609
}
16061610

16071611
pub fn ty_def_id(self) -> DefId {
16081612
self.param_did.unwrap_or(self.did)
16091613
}
1614+
1615+
pub fn init_me_bby(tcx: TyCtxt<'_>, did: DefId) -> WithOptParam<DefId> {
1616+
WithOptParam { did, param_did: did.as_local().and_then(|did| tcx.opt_const_param_of(did)) }
1617+
}
16101618
}
16111619

16121620
/// When type checking, we use the `ParamEnv` to track

src/librustc_middle/ty/relate.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -578,12 +578,12 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
578578

579579
// FIXME(const_generics): this is wrong, as it is a projection
580580
(
581-
ty::ConstKind::Unevaluated(a_def_id, a_substs, a_promoted),
582-
ty::ConstKind::Unevaluated(b_def_id, b_substs, b_promoted),
583-
) if a_def_id == b_def_id && a_promoted == b_promoted => {
581+
ty::ConstKind::Unevaluated(a_def, a_substs, a_promoted),
582+
ty::ConstKind::Unevaluated(b_def, b_substs, b_promoted),
583+
) if a_def == b_def && a_promoted == b_promoted => {
584584
let substs =
585585
relation.relate_with_variance(ty::Variance::Invariant, a_substs, b_substs)?;
586-
Ok(ty::ConstKind::Unevaluated(a_def_id, substs, a_promoted))
586+
Ok(ty::ConstKind::Unevaluated(a_def, substs, a_promoted))
587587
}
588588
_ => Err(TypeError::ConstMismatch(expected_found(relation, a, b))),
589589
};

src/librustc_mir/borrow_check/mod.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind
1717
use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
1818
use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
1919
use rustc_middle::ty::query::Providers;
20-
use rustc_middle::ty::{self, RegionVid, TyCtxt};
20+
use rustc_middle::ty::{self, InstanceDef, RegionVid, TyCtxt};
2121
use rustc_session::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT, UNUSED_MUT};
2222
use rustc_span::{Span, Symbol, DUMMY_SP};
2323

@@ -87,17 +87,32 @@ crate struct Upvar {
8787
const DEREF_PROJECTION: &[PlaceElem<'_>; 1] = &[ProjectionElem::Deref];
8888

8989
pub fn provide(providers: &mut Providers) {
90-
*providers = Providers { mir_borrowck, ..*providers };
90+
*providers = Providers {
91+
mir_borrowck: |tcx, did| mir_borrowck(tcx, ty::WithOptParam::dummy(did)),
92+
mir_borrowck_const_arg: |tcx, def| {
93+
if def.param_did.is_none() { tcx.mir_borrowck(def.did) } else { mir_borrowck(tcx, def) }
94+
},
95+
..*providers
96+
};
9197
}
9298

93-
fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx BorrowCheckResult<'tcx> {
94-
let (input_body, promoted) = tcx.mir_validated(def_id);
95-
debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id.to_def_id()));
99+
fn mir_borrowck<'tcx>(
100+
tcx: TyCtxt<'tcx>,
101+
def: ty::WithOptParam<LocalDefId>,
102+
) -> &'tcx BorrowCheckResult<'tcx> {
103+
if def.param_did.is_none() {
104+
if let param_did @ Some(_) = tcx.opt_const_param_of(def.did) {
105+
return tcx.mir_borrowck_const_arg(ty::WithOptParam { param_did, ..def });
106+
}
107+
}
108+
109+
let (input_body, promoted) = tcx.mir_validated(def);
110+
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
96111

97112
let opt_closure_req = tcx.infer_ctxt().enter(|infcx| {
98113
let input_body: &Body<'_> = &input_body.borrow();
99114
let promoted: &IndexVec<_, _> = &promoted.borrow();
100-
do_mir_borrowck(&infcx, input_body, promoted, def_id)
115+
do_mir_borrowck(&infcx, input_body, promoted, def)
101116
});
102117
debug!("mir_borrowck done");
103118

@@ -108,13 +123,13 @@ fn do_mir_borrowck<'a, 'tcx>(
108123
infcx: &InferCtxt<'a, 'tcx>,
109124
input_body: &Body<'tcx>,
110125
input_promoted: &IndexVec<Promoted, Body<'tcx>>,
111-
def_id: LocalDefId,
126+
def: ty::WithOptParam<LocalDefId>,
112127
) -> BorrowCheckResult<'tcx> {
113-
debug!("do_mir_borrowck(def_id = {:?})", def_id);
128+
debug!("do_mir_borrowck(def = {:?})", def);
114129

115130
let tcx = infcx.tcx;
116-
let param_env = tcx.param_env(def_id);
117-
let id = tcx.hir().as_local_hir_id(def_id);
131+
let param_env = tcx.param_env(def.did);
132+
let id = tcx.hir().as_local_hir_id(def.did);
118133

119134
let mut local_names = IndexVec::from_elem(None, &input_body.local_decls);
120135
for var_debug_info in &input_body.var_debug_info {
@@ -135,13 +150,13 @@ fn do_mir_borrowck<'a, 'tcx>(
135150
}
136151

137152
// Gather the upvars of a closure, if any.
138-
let tables = tcx.typeck_tables_of(def_id);
153+
let tables = tcx.typeck_tables_of_const_arg(def);
139154
if let Some(ErrorReported) = tables.tainted_by_errors {
140155
infcx.set_tainted_by_errors();
141156
}
142157
let upvars: Vec<_> = tables
143158
.closure_captures
144-
.get(&def_id.to_def_id())
159+
.get(&def.did.to_def_id())
145160
.into_iter()
146161
.flat_map(|v| v.values())
147162
.map(|upvar_id| {
@@ -171,8 +186,7 @@ fn do_mir_borrowck<'a, 'tcx>(
171186
// will have a lifetime tied to the inference context.
172187
let mut body = input_body.clone();
173188
let mut promoted = input_promoted.clone();
174-
let free_regions =
175-
nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body, &mut promoted);
189+
let free_regions = nll::replace_regions_in_mir(infcx, def, param_env, &mut body, &mut promoted);
176190
let body = &body; // no further changes
177191

178192
let location_table = &LocationTable::new(&body);
@@ -190,7 +204,7 @@ fn do_mir_borrowck<'a, 'tcx>(
190204
let mdpe = MoveDataParamEnv { move_data, param_env };
191205

192206
let mut flow_inits = MaybeInitializedPlaces::new(tcx, &body, &mdpe)
193-
.into_engine(tcx, &body, def_id.to_def_id())
207+
.into_engine(tcx, &body, def.did.to_def_id())
194208
.iterate_to_fixpoint()
195209
.into_results_cursor(&body);
196210

@@ -207,7 +221,7 @@ fn do_mir_borrowck<'a, 'tcx>(
207221
nll_errors,
208222
} = nll::compute_regions(
209223
infcx,
210-
def_id,
224+
def.did,
211225
free_regions,
212226
body,
213227
&promoted,
@@ -223,7 +237,7 @@ fn do_mir_borrowck<'a, 'tcx>(
223237
// write unit-tests, as well as helping with debugging.
224238
nll::dump_mir_results(
225239
infcx,
226-
MirSource::item(def_id.to_def_id()),
240+
MirSource { instance: InstanceDef::Item(def.to_global()), promoted: None },
227241
&body,
228242
&regioncx,
229243
&opt_closure_req,
@@ -234,7 +248,7 @@ fn do_mir_borrowck<'a, 'tcx>(
234248
nll::dump_annotation(
235249
infcx,
236250
&body,
237-
def_id.to_def_id(),
251+
def.did.to_def_id(),
238252
&regioncx,
239253
&opt_closure_req,
240254
&opaque_type_values,
@@ -249,13 +263,13 @@ fn do_mir_borrowck<'a, 'tcx>(
249263
let regioncx = Rc::new(regioncx);
250264

251265
let flow_borrows = Borrows::new(tcx, &body, regioncx.clone(), &borrow_set)
252-
.into_engine(tcx, &body, def_id.to_def_id())
266+
.into_engine(tcx, &body, def.did.to_def_id())
253267
.iterate_to_fixpoint();
254268
let flow_uninits = MaybeUninitializedPlaces::new(tcx, &body, &mdpe)
255-
.into_engine(tcx, &body, def_id.to_def_id())
269+
.into_engine(tcx, &body, def.did.to_def_id())
256270
.iterate_to_fixpoint();
257271
let flow_ever_inits = EverInitializedPlaces::new(tcx, &body, &mdpe)
258-
.into_engine(tcx, &body, def_id.to_def_id())
272+
.into_engine(tcx, &body, def.did.to_def_id())
259273
.iterate_to_fixpoint();
260274

261275
let movable_generator = match tcx.hir().get(id) {
@@ -274,7 +288,7 @@ fn do_mir_borrowck<'a, 'tcx>(
274288
let mut promoted_mbcx = MirBorrowckCtxt {
275289
infcx,
276290
body: promoted_body,
277-
mir_def_id: def_id,
291+
mir_def_id: def.did,
278292
move_data: &move_data,
279293
location_table: &LocationTable::new(promoted_body),
280294
movable_generator,
@@ -307,7 +321,7 @@ fn do_mir_borrowck<'a, 'tcx>(
307321
let mut mbcx = MirBorrowckCtxt {
308322
infcx,
309323
body,
310-
mir_def_id: def_id,
324+
mir_def_id: def.did,
311325
move_data: &mdpe.move_data,
312326
location_table,
313327
movable_generator,

src/librustc_mir/borrow_check/nll.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::mir::{
99
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
1010
Promoted,
1111
};
12-
use rustc_middle::ty::{self, RegionKind, RegionVid};
12+
use rustc_middle::ty::{self, InstanceDef, RegionKind, RegionVid};
1313
use rustc_span::symbol::sym;
1414
use std::env;
1515
use std::fmt::Debug;
@@ -59,20 +59,20 @@ crate struct NllOutput<'tcx> {
5959
/// `compute_regions`.
6060
pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
6161
infcx: &InferCtxt<'cx, 'tcx>,
62-
def_id: LocalDefId,
62+
def: ty::WithOptParam<LocalDefId>,
6363
param_env: ty::ParamEnv<'tcx>,
6464
body: &mut Body<'tcx>,
6565
promoted: &mut IndexVec<Promoted, Body<'tcx>>,
6666
) -> UniversalRegions<'tcx> {
67-
debug!("replace_regions_in_mir(def_id={:?})", def_id);
67+
debug!("replace_regions_in_mir(def={:?})", def);
6868

6969
// Compute named region information. This also renumbers the inputs/outputs.
70-
let universal_regions = UniversalRegions::new(infcx, def_id, param_env);
70+
let universal_regions = UniversalRegions::new(infcx, def, param_env);
7171

7272
// Replace all remaining regions with fresh inference variables.
7373
renumber::renumber_mir(infcx, body, promoted);
7474

75-
let source = MirSource::item(def_id.to_def_id());
75+
let source = MirSource { instance: InstanceDef::Item(def.to_global()), promoted: None };
7676
mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, body, |_, _| Ok(()));
7777

7878
universal_regions

0 commit comments

Comments
 (0)