When `unload-feature' looks in hooks for functions that it's going to unload, it doesn't seem to look in buffer-local values, other than for the current buffer. Evalling the code in try-foo.el below loads then unloads foo.el. It gets an error void-function foo-message where I hoped unload-feature might have purged that `foo-message' from `after-change-functions'. I suppose looking in all buffers is more work for unload-feature, but would be a good protection against bad things happening later. I expect some of the standard hooks like `after-change-functions' are used buffer-local most of the time. If instead it's an intentional omission (to save work) then the elisp manual and the docstring could note it so that modes or packages using buffer-local hook settings can take steps to undo.