diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index b0ab50dd773..f9f2a14dbd2 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -715,7 +715,17 @@ impl Cursor<'_> { self.bump(); self.bump(); self.eat_while(is_id_continue); - return RawLifetime; + match self.first() { + '\'' => { + // Check if after skipping literal contents we've met a closing + // single quote (which means that user attempted to create a + // string with single quotes). + self.bump(); + let kind = Char { terminated: true }; + return Literal { kind, suffix_start: self.pos_within_token() }; + } + _ => return RawLifetime, + } } // Either a lifetime or a character literal with diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fba1d1025ca..ea5b6ff1959 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -12,26 +12,26 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{Diag, EmissionGuarantee}; use rustc_hir as hir; -use rustc_hir::LangItem; use rustc_hir::def_id::DefId; -use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; -use rustc_infer::infer::DefineOpaqueTypes; +use rustc_hir::LangItem; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::relate::TypeRelation; +use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; +use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::TraitObligation; use rustc_middle::bug; -use rustc_middle::dep_graph::{DepNodeIndex, dep_kinds}; +use rustc_middle::dep_graph::{dep_kinds, DepNodeIndex}; use rustc_middle::mir::interpret::ErrorHandled; pub use rustc_middle::traits::select::*; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::TypeErrorToStringExt; -use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; +use rustc_middle::ty::print::{with_no_trimmed_paths, PrintTraitRefExt as _}; use rustc_middle::ty::{ self, GenericArgsRef, PolyProjectionPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, Upcast, }; -use rustc_span::Symbol; use rustc_span::symbol::sym; +use rustc_span::Symbol; use tracing::{debug, instrument, trace}; use self::EvaluationResult::*; @@ -40,9 +40,9 @@ use super::coherence::{self, Conflict}; use super::project::ProjectionTermObligation; use super::util::closure_trait_ref_and_return_type; use super::{ - ImplDerivedCause, Normalized, Obligation, ObligationCause, ObligationCauseCode, Overflow, - PolyTraitObligation, PredicateObligation, Selection, SelectionError, SelectionResult, - TraitQueryMode, const_evaluatable, project, util, wf, + const_evaluatable, project, util, wf, ImplDerivedCause, Normalized, Obligation, + ObligationCause, ObligationCauseCode, Overflow, PolyTraitObligation, PredicateObligation, + Selection, SelectionError, SelectionResult, TraitQueryMode, }; use crate::error_reporting::InferCtxtErrorExt; use crate::infer::{InferCtxt, InferOk, TypeFreshener}; @@ -1306,7 +1306,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } let tcx = self.tcx(); - if self.can_use_global_caches(param_env) { + if self.can_use_global_caches(param_env, trait_pred) { if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) { return Some(res); } @@ -1335,7 +1335,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } - if self.can_use_global_caches(param_env) && !trait_pred.has_infer() { + if self.can_use_global_caches(param_env, trait_pred) && !trait_pred.has_infer() { debug!(?trait_pred, ?result, "insert_evaluation_cache global"); // This may overwrite the cache with the same value // FIXME: Due to #50507 this overwrites the different values @@ -1479,7 +1479,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } /// Returns `true` if the global caches can be used. - fn can_use_global_caches(&self, param_env: ty::ParamEnv<'tcx>) -> bool { + fn can_use_global_caches( + &self, + param_env: ty::ParamEnv<'tcx>, + pred: ty::PolyTraitPredicate<'tcx>, + ) -> bool { // If there are any inference variables in the `ParamEnv`, then we // always use a cache local to this particular scope. Otherwise, we // switch to a global cache. @@ -1500,7 +1504,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Avoid using the global cache when we're defining opaque types // as their hidden type may impact the result of candidate selection. - if !self.infcx.defining_opaque_types().is_empty() { + // + // HACK: This is still theoretically unsound. Goals can indirectly rely + // on opaques in the defining scope, and it's easier to do so with TAIT. + // However, if we disqualify *all* goals from being cached, perf suffers. + // This is likely fixed by better caching in general in the new solver. + // See: . + if !self.infcx.defining_opaque_types().is_empty() && pred.has_opaque_types() { return false; } @@ -1523,7 +1533,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tcx = self.tcx(); let pred = cache_fresh_trait_pred.skip_binder(); - if self.can_use_global_caches(param_env) { + if self.can_use_global_caches(param_env, cache_fresh_trait_pred) { if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) { return Some(res); } @@ -1580,7 +1590,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } - if self.can_use_global_caches(param_env) { + if self.can_use_global_caches(param_env, cache_fresh_trait_pred) { if let Err(Overflow(OverflowError::Canonical)) = candidate { // Don't cache overflow globally; we only produce this in certain modes. } else if !pred.has_infer() && !candidate.has_infer() { @@ -1787,7 +1797,11 @@ enum DropVictim { impl DropVictim { fn drop_if(should_drop: bool) -> DropVictim { - if should_drop { DropVictim::Yes } else { DropVictim::No } + if should_drop { + DropVictim::Yes + } else { + DropVictim::No + } } } @@ -1891,7 +1905,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> { (ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(victim_cand)) => { // Prefer these to a global where-clause bound // (see issue #50825). - if is_global(*victim_cand) { DropVictim::Yes } else { DropVictim::No } + if is_global(*victim_cand) { + DropVictim::Yes + } else { + DropVictim::No + } } ( ImplCandidate(_) @@ -2450,9 +2468,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } else { // If this is an ill-formed auto/built-in trait, then synthesize // new error args for the missing generics. - let err_args = ty::GenericArgs::extend_with_error(tcx, trait_def_id, &[ - normalized_ty.into(), - ]); + let err_args = ty::GenericArgs::extend_with_error( + tcx, + trait_def_id, + &[normalized_ty.into()], + ); ty::TraitRef::new_from_args(tcx, trait_def_id, err_args) }; @@ -3154,7 +3174,11 @@ impl<'o, 'tcx> TraitObligationStackList<'o, 'tcx> { } fn depth(&self) -> usize { - if let Some(head) = self.head { head.depth } else { 0 } + if let Some(head) = self.head { + head.depth + } else { + 0 + } } } diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 8f49f623afa..876abb6d915 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -46,7 +46,7 @@ envs: RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.12 MACOSX_STD_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_14.3.1.app + SELECT_XCODE: /Applications/Xcode_15.2.app NO_LLVM_ASSERTIONS: 1 NO_DEBUG_ASSERTIONS: 1 NO_OVERFLOW_CHECKS: 1 @@ -282,7 +282,7 @@ auto: RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set rust.lto=thin --set rust.codegen-units=1 RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_14.3.1.app + SELECT_XCODE: /Applications/Xcode_15.2.app NO_LLVM_ASSERTIONS: 1 NO_DEBUG_ASSERTIONS: 1 NO_OVERFLOW_CHECKS: 1 @@ -298,7 +298,7 @@ auto: RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc --set target.aarch64-apple-ios-macabi.sanitizers=false --set target.x86_64-apple-ios-macabi.sanitizers=false RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.12 - SELECT_XCODE: /Applications/Xcode_14.3.1.app + SELECT_XCODE: /Applications/Xcode_15.2.app NO_LLVM_ASSERTIONS: 1 NO_DEBUG_ASSERTIONS: 1 NO_OVERFLOW_CHECKS: 1 @@ -327,7 +327,7 @@ auto: --set llvm.ninja=false --set rust.lto=thin RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - SELECT_XCODE: /Applications/Xcode_14.3.1.app + SELECT_XCODE: /Applications/Xcode_15.4.app USE_XCODE_CLANG: 1 MACOSX_DEPLOYMENT_TARGET: 11.0 MACOSX_STD_DEPLOYMENT_TARGET: 11.0 @@ -347,7 +347,7 @@ auto: --enable-profiler --set rust.jemalloc RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 - SELECT_XCODE: /Applications/Xcode_14.3.1.app + SELECT_XCODE: /Applications/Xcode_15.4.app USE_XCODE_CLANG: 1 MACOSX_DEPLOYMENT_TARGET: 11.0 MACOSX_STD_DEPLOYMENT_TARGET: 11.0 diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index eed64d024c0..526a32e194a 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2098,6 +2098,7 @@ class DocSearch { const sortResults = async(results, isType, preferredCrate) => { const userQuery = parsedQuery.userQuery; const casedUserQuery = parsedQuery.original; + const isMixedCase = casedUserQuery !== userQuery; const result_list = []; for (const result of results.values()) { result.item = this.searchIndex[result.id]; @@ -2109,10 +2110,12 @@ class DocSearch { let a, b; // sort by exact case-sensitive match - a = (aaa.item.name !== casedUserQuery); - b = (bbb.item.name !== casedUserQuery); - if (a !== b) { - return a - b; + if (isMixedCase) { + a = (aaa.item.name !== casedUserQuery); + b = (bbb.item.name !== casedUserQuery); + if (a !== b) { + return a - b; + } } // sort by exact match with regard to the last word (mismatch goes later) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 9773d8dbce0..691ea6f5677 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -1068,7 +1068,7 @@ pub(crate) fn handle_completion_resolve( else { return Ok(original_completion); }; - let resolved_completions = to_proto::completion_items( + let mut resolved_completions = to_proto::completion_items( &snap.config, &forced_resolve_completions_config.fields_to_resolve, &line_index, @@ -1077,15 +1077,13 @@ pub(crate) fn handle_completion_resolve( resolve_data.trigger_character, resolved_completions, ); - let Some(mut resolved_completion) = resolved_completions.into_iter().find(|completion| { - completion.label == original_completion.label - && completion.kind == original_completion.kind - && completion.deprecated == original_completion.deprecated - && completion.preselect == original_completion.preselect - && completion.sort_text == original_completion.sort_text - }) else { - return Ok(original_completion); - }; + + let mut resolved_completion = + if resolved_completions.get(resolve_data.completion_item_index).is_some() { + resolved_completions.swap_remove(resolve_data.completion_item_index) + } else { + return Ok(original_completion); + }; if !resolve_data.imports.is_empty() { let additional_edits = snap diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs index 8039f0644ee..6ddfe118d5e 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/ext.rs @@ -826,6 +826,7 @@ pub struct CompletionResolveData { pub imports: Vec, pub version: Option, pub trigger_character: Option, + pub completion_item_index: usize, } #[derive(Debug, Serialize, Deserialize)] diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 375b7428c2d..cdc6fb17fd4 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -391,18 +391,36 @@ fn completion_item( } else { Vec::new() }; - if something_to_resolve || !imports.is_empty() { - let data = lsp_ext::CompletionResolveData { + let (ref_resolve_data, resolve_data) = if something_to_resolve || !imports.is_empty() { + let mut item_index = acc.len(); + let ref_resolve_data = if ref_match.is_some() { + let ref_resolve_data = lsp_ext::CompletionResolveData { + position: tdpp.clone(), + imports: Vec::new(), + version, + trigger_character: completion_trigger_character, + completion_item_index: item_index, + }; + item_index += 1; + Some(to_value(ref_resolve_data).unwrap()) + } else { + None + }; + let resolve_data = lsp_ext::CompletionResolveData { position: tdpp.clone(), imports, version, trigger_character: completion_trigger_character, + completion_item_index: item_index, }; - lsp_item.data = Some(to_value(data).unwrap()); - } + (ref_resolve_data, Some(to_value(resolve_data).unwrap())) + } else { + (None, None) + }; if let Some((label, indel, relevance)) = ref_match { - let mut lsp_item_with_ref = lsp_types::CompletionItem { label, ..lsp_item.clone() }; + let mut lsp_item_with_ref = + lsp_types::CompletionItem { label, data: ref_resolve_data, ..lsp_item.clone() }; lsp_item_with_ref .additional_text_edits .get_or_insert_with(Default::default) @@ -411,6 +429,7 @@ fn completion_item( acc.push(lsp_item_with_ref); }; + lsp_item.data = resolve_data; acc.push(lsp_item); fn set_score( diff --git a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md index 7764f7843a0..b7c536e0279 100644 --- a/src/tools/rust-analyzer/docs/dev/lsp-extensions.md +++ b/src/tools/rust-analyzer/docs/dev/lsp-extensions.md @@ -1,5 +1,5 @@ $DIR/immediately-followed-by-lt.rs:11:4 + | +LL | w!('r#long'id); + | ^^^^^^^^ + | +help: if you meant to write a string literal, use double quotes + | +LL | w!("r#long"id); + | ~ ~ + +error: aborting due to 1 previous error +