@@ -217,6 +217,74 @@ let move_hyp id dest =
217217 end
218218 end
219219
220+ let error_renaming_implicit_dependency ?loc env where ids gr =
221+ CErrors. user_err ?loc @@
222+ fmt " Cannot rename section variable %t@ because it is used implicitly through %t@ in %t."
223+ (fun () -> Id. print (Id.Set. choose ids))
224+ (fun () -> pr_global_env env gr)
225+ (fun () -> match where with
226+ | None -> str " the conclusion"
227+ | Some h -> fmt " hypothesis %t" (fun () -> Id. print h))
228+
229+ let check_renaming ~src ~dst env sigma concl =
230+ let sign = named_context_val env in
231+ (* Check that we do not mess variables *)
232+ let vars = ids_of_named_context_val sign in
233+ let () =
234+ if not (Id.Set. subset src vars) then
235+ let hyp = Id.Set. choose (Id.Set. diff src vars) in
236+ raise (RefinerError (env, sigma, NoSuchHyp hyp))
237+ in
238+ let mods = Id.Set. diff vars src in
239+ let () =
240+ try
241+ let elt = Id.Set. choose (Id.Set. inter dst mods) in
242+ TacticErrors. already_used elt
243+ with Not_found -> ()
244+ in
245+ let secvars =
246+ Id.Set. filter (fun id ->
247+ match NamedDecl. get_status (lookup_named id env) with
248+ | SecVar -> true
249+ | ProofVar -> false )
250+ src
251+ in
252+ let checked = ref GlobRef.Set_env. empty in
253+ let check_constr where c =
254+ let rec aux c =
255+ match EConstr. destRef sigma c with
256+ | VarRef _ , _ ->
257+ (* we only refuse implicit dependencies, because they can't be substituted *)
258+ ()
259+ | gr , _ ->
260+ if GlobRef.Set_env. mem gr ! checked then ()
261+ else begin
262+ let deps = Evarutil. vars_of_global env sigma gr in
263+ let bad = Id.Set. inter deps secvars in
264+ let () =
265+ if not @@ Id.Set. is_empty bad then
266+ error_renaming_implicit_dependency env where bad gr
267+ in
268+ checked := GlobRef.Set_env. add gr ! checked
269+ end
270+ | exception DestKO -> EConstr. iter sigma aux c
271+ in
272+ aux c
273+ in
274+ let () =
275+ if Id.Set. is_empty secvars then
276+ (* not renaming any secvars -> no problem *)
277+ ()
278+ else
279+ let () = check_constr None concl in
280+ let () =
281+ List. iter (fun d -> NamedDecl. iter_constr (check_constr (Some (NamedDecl. get_id d))) d)
282+ (named_context env)
283+ in
284+ ()
285+ in
286+ ()
287+
220288let rename_hyp repl =
221289 let fold accu (src , dst ) = match accu with
222290 | None -> None
@@ -238,30 +306,16 @@ let rename_hyp repl =
238306 Proofview.Goal. enter begin fun gl ->
239307 let concl = Proofview.Goal. concl gl in
240308 let env = Proofview.Goal. env gl in
241- let sign = named_context_val env in
242309 let sigma = Proofview.Goal. sigma gl in
243310 let relevance = Proofview.Goal. relevance gl in
244- (* Check that we do not mess variables *)
245- let vars = ids_of_named_context_val sign in
246- let () =
247- if not (Id.Set. subset src vars) then
248- let hyp = Id.Set. choose (Id.Set. diff src vars) in
249- raise (RefinerError (env, sigma, NoSuchHyp hyp))
250- in
251- let mods = Id.Set. diff vars src in
252- let () =
253- try
254- let elt = Id.Set. choose (Id.Set. inter dst mods) in
255- TacticErrors. already_used elt
256- with Not_found -> ()
257- in
311+ let () = check_renaming ~src ~dst env sigma concl in
258312 (* All is well *)
259313 let make_subst (src , dst ) = (src, mkVar dst) in
260314 let subst = List. map make_subst repl in
261315 let subst c = Vars. replace_vars sigma subst c in
262316 let replace id = try List. assoc_f Id. equal id repl with Not_found -> id in
263317 let map decl = decl |> NamedDecl. map_id replace |> NamedDecl. map_constr subst in
264- let ohyps = named_context_of_val sign in
318+ let ohyps = EConstr. named_context env in
265319 let nhyps = List. map map ohyps in
266320 let nconcl = subst concl in
267321 let nctx = val_of_named_context nhyps in
0 commit comments