@@ -28,6 +28,7 @@ use util;
2828
2929pub struct UnsafetyChecker < ' a , ' tcx : ' a > {
3030 mir : & ' a Mir < ' tcx > ,
31+ min_const_fn : bool ,
3132 source_scope_local_data : & ' a IndexVec < SourceScope , SourceScopeLocalData > ,
3233 violations : Vec < UnsafetyViolation > ,
3334 source_info : SourceInfo ,
@@ -38,12 +39,16 @@ pub struct UnsafetyChecker<'a, 'tcx: 'a> {
3839}
3940
4041impl < ' a , ' gcx , ' tcx > UnsafetyChecker < ' a , ' tcx > {
41- fn new ( mir : & ' a Mir < ' tcx > ,
42- source_scope_local_data : & ' a IndexVec < SourceScope , SourceScopeLocalData > ,
43- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
44- param_env : ty:: ParamEnv < ' tcx > ) -> Self {
42+ fn new (
43+ min_const_fn : bool ,
44+ mir : & ' a Mir < ' tcx > ,
45+ source_scope_local_data : & ' a IndexVec < SourceScope , SourceScopeLocalData > ,
46+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
47+ param_env : ty:: ParamEnv < ' tcx > ,
48+ ) -> Self {
4549 Self {
4650 mir,
51+ min_const_fn,
4752 source_scope_local_data,
4853 violations : vec ! [ ] ,
4954 source_info : SourceInfo {
@@ -269,14 +274,22 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
269274 fn register_violations ( & mut self ,
270275 violations : & [ UnsafetyViolation ] ,
271276 unsafe_blocks : & [ ( ast:: NodeId , bool ) ] ) {
277+ if self . min_const_fn {
278+ for violation in violations {
279+ let mut violation = violation. clone ( ) ;
280+ violation. kind = UnsafetyViolationKind :: MinConstFn ;
281+ if !self . violations . contains ( & violation) {
282+ self . violations . push ( violation)
283+ }
284+ }
285+ }
272286 let within_unsafe = match self . source_scope_local_data [ self . source_info . scope ] . safety {
273287 Safety :: Safe => {
274288 for violation in violations {
275289 if !self . violations . contains ( violation) {
276290 self . violations . push ( violation. clone ( ) )
277291 }
278292 }
279-
280293 false
281294 }
282295 Safety :: BuiltinUnsafe | Safety :: FnUnsafe => true ,
@@ -369,6 +382,7 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
369382
370383 let param_env = tcx. param_env ( def_id) ;
371384 let mut checker = UnsafetyChecker :: new (
385+ tcx. is_const_fn ( def_id) && tcx. is_min_const_fn ( def_id) ,
372386 mir, source_scope_local_data, tcx, param_env) ;
373387 checker. visit_mir ( mir) ;
374388
@@ -478,6 +492,15 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
478492 . note ( & details. as_str ( ) [ ..] )
479493 . emit ( ) ;
480494 }
495+ UnsafetyViolationKind :: MinConstFn => {
496+ tcx. sess . struct_span_err (
497+ source_info. span ,
498+ & format ! ( "{} is unsafe and unsafe operations \
499+ are not allowed in const fn", description) )
500+ . span_label ( source_info. span , & description. as_str ( ) [ ..] )
501+ . note ( & details. as_str ( ) [ ..] )
502+ . emit ( ) ;
503+ }
481504 UnsafetyViolationKind :: ExternStatic ( lint_node_id) => {
482505 tcx. lint_node_note ( SAFE_EXTERN_STATICS ,
483506 lint_node_id,
0 commit comments