@@ -553,7 +553,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
553553 this. super_place ( place, context, location) ;
554554 match proj. elem {
555555 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+ }
557563 let base_ty = proj. base . ty ( this. mir , this. tcx ) . to_ty ( this. tcx ) ;
558564 match this. mode {
559565 Mode :: Fn => { } ,
@@ -1178,7 +1184,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
11781184 if self . mir . local_kind ( index) == LocalKind :: Var &&
11791185 self . const_fn_arg_vars . insert ( index) &&
11801186 !self . tcx . features ( ) . const_let {
1181-
11821187 // Direct use of an argument is permitted.
11831188 match * rvalue {
11841189 Rvalue :: Use ( Operand :: Copy ( Place :: Local ( local) ) ) |
@@ -1189,7 +1194,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
11891194 }
11901195 _ => { }
11911196 }
1192-
11931197 // Avoid a generic error for other uses of arguments.
11941198 if self . qualif . contains ( Qualif :: FN_ARGUMENT ) {
11951199 let decl = & self . mir . local_decls [ index] ;
@@ -1348,6 +1352,37 @@ impl MirPass for QualifyAndPromoteConstants {
13481352 // Do the actual promotion, now that we know what's viable.
13491353 promote_consts:: promote_candidates ( mir, tcx, temps, candidates) ;
13501354 } 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+ }
13511386 let promoted_temps = if mode == Mode :: Const {
13521387 // Already computed by `mir_const_qualif`.
13531388 const_promoted_temps. unwrap ( )
0 commit comments