@@ -553,7 +553,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
553
553
this. super_place ( place, context, location) ;
554
554
match proj. elem {
555
555
ProjectionElem :: Deref => {
556
- this. add ( Qualif :: NOT_CONST ) ;
556
+ if context. is_mutating_use ( ) {
557
+ // `not_const` errors out in const contexts
558
+ this. not_const ( )
559
+ } else {
560
+ // just make sure this doesn't get promoted
561
+ this. add ( Qualif :: NOT_CONST ) ;
562
+ }
557
563
let base_ty = proj. base . ty ( this. mir , this. tcx ) . to_ty ( this. tcx ) ;
558
564
match this. mode {
559
565
Mode :: Fn => { } ,
@@ -1178,7 +1184,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
1178
1184
if self . mir . local_kind ( index) == LocalKind :: Var &&
1179
1185
self . const_fn_arg_vars . insert ( index) &&
1180
1186
!self . tcx . features ( ) . const_let {
1181
-
1182
1187
// Direct use of an argument is permitted.
1183
1188
match * rvalue {
1184
1189
Rvalue :: Use ( Operand :: Copy ( Place :: Local ( local) ) ) |
@@ -1189,7 +1194,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
1189
1194
}
1190
1195
_ => { }
1191
1196
}
1192
-
1193
1197
// Avoid a generic error for other uses of arguments.
1194
1198
if self . qualif . contains ( Qualif :: FN_ARGUMENT ) {
1195
1199
let decl = & self . mir . local_decls [ index] ;
@@ -1348,6 +1352,37 @@ impl MirPass for QualifyAndPromoteConstants {
1348
1352
// Do the actual promotion, now that we know what's viable.
1349
1353
promote_consts:: promote_candidates ( mir, tcx, temps, candidates) ;
1350
1354
} else {
1355
+ if !mir. control_flow_destroyed . is_empty ( ) {
1356
+ let mut locals = mir. vars_iter ( ) ;
1357
+ if let Some ( local) = locals. next ( ) {
1358
+ let span = mir. local_decls [ local] . source_info . span ;
1359
+ let mut error = tcx. sess . struct_span_err (
1360
+ span,
1361
+ & format ! (
1362
+ "new features like let bindings are not permitted in {}s \
1363
+ which also use short circuiting operators",
1364
+ mode,
1365
+ ) ,
1366
+ ) ;
1367
+ for ( span, kind) in mir. control_flow_destroyed . iter ( ) {
1368
+ error. span_note (
1369
+ * span,
1370
+ & format ! ( "use of {} here does not actually short circuit due to \
1371
+ the const evaluator presently not being able to do control flow. \
1372
+ See https://github.com/rust-lang/rust/issues/49146 for more \
1373
+ information.", kind) ,
1374
+ ) ;
1375
+ }
1376
+ for local in locals {
1377
+ let span = mir. local_decls [ local] . source_info . span ;
1378
+ error. span_note (
1379
+ span,
1380
+ "more locals defined here" ,
1381
+ ) ;
1382
+ }
1383
+ error. emit ( ) ;
1384
+ }
1385
+ }
1351
1386
let promoted_temps = if mode == Mode :: Const {
1352
1387
// Already computed by `mir_const_qualif`.
1353
1388
const_promoted_temps. unwrap ( )
0 commit comments