ep: Fix panic when switching to a non-store provider (#49698)

Oleksiy Syvokon created

The `unreachable()` assumption at `queue_prediction_refresh` could be
violated by an async race condition:

1. `request_prediction_internal` spawns an async task
2. The task awaits a prediction request
3. If the prediction returns `None`, it calls `queue_prediction_refresh`
4. Between the time the prediction was initiated (when the provider was
an EP-store provider) and when the async callback runs, the user can
change their edit prediction provider setting to a non-EP-store provider
5. `queue_prediction_refresh` re-reads the settings and hits the
`unreachable!()

Release Notes:

- N/A

Change summary

crates/edit_prediction/src/edit_prediction.rs | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)

Detailed changes

crates/edit_prediction/src/edit_prediction.rs 🔗

@@ -1537,6 +1537,10 @@ impl EditPredictionStore {
         scope: DiagnosticSearchScope,
         cx: &mut Context<Self>,
     ) {
+        if !is_ep_store_provider(all_language_settings(None, cx).edit_predictions.provider) {
+            return;
+        }
+
         let Some(project_state) = self.projects.get_mut(&project.entity_id()) else {
             return;
         };
@@ -1722,7 +1726,10 @@ impl EditPredictionStore {
                 EditPredictionProvider::None
                 | EditPredictionProvider::Copilot
                 | EditPredictionProvider::Supermaven
-                | EditPredictionProvider::Codestral => unreachable!(),
+                | EditPredictionProvider::Codestral => {
+                    log::error!("queue_prediction_refresh called with non-store provider");
+                    return;
+                }
             };
 
         let drop_on_cancel = !needs_acceptance_tracking;