Auto merge of #137284 - matthiaskrgr:rollup-deuhk46, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #127793 (Added project-specific Zed IDE settings) - #134995 (Stabilize const_slice_flatten) - #136301 (Improve instant docs) - #136347 (Add a bullet point to `std::fs::copy`) - #136794 (Stabilize file_lock) - #137094 (x86_win64 ABI: do not use xmm0 with softfloat ABI) - #137227 (docs(dev): Update the feature-gate instructions) - #137232 (Don't mention `FromResidual` on bad `?`) - #137251 (coverage: Get hole spans from nested items without fully visiting them) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f280acf4c7
21 changed files with 330 additions and 125 deletions
|
@ -346,35 +346,37 @@ fn extract_hole_spans_from_hir<'tcx>(
|
|||
body_span: Span, // Usually `hir_body.value.span`, but not always
|
||||
hir_body: &hir::Body<'tcx>,
|
||||
) -> Vec<Span> {
|
||||
struct HolesVisitor<'hir, F> {
|
||||
tcx: TyCtxt<'hir>,
|
||||
visit_hole_span: F,
|
||||
struct HolesVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body_span: Span,
|
||||
hole_spans: Vec<Span>,
|
||||
}
|
||||
|
||||
impl<'hir, F: FnMut(Span)> Visitor<'hir> for HolesVisitor<'hir, F> {
|
||||
/// - We need `NestedFilter::INTRA = true` so that `visit_item` will be called.
|
||||
/// - Bodies of nested items don't actually get visited, because of the
|
||||
/// `visit_item` override.
|
||||
/// - For nested bodies that are not part of an item, we do want to visit any
|
||||
/// items contained within them.
|
||||
type NestedFilter = nested_filter::All;
|
||||
impl<'tcx> Visitor<'tcx> for HolesVisitor<'tcx> {
|
||||
/// We have special handling for nested items, but we still want to
|
||||
/// traverse into nested bodies of things that are not considered items,
|
||||
/// such as "anon consts" (e.g. array lengths).
|
||||
type NestedFilter = nested_filter::OnlyBodies;
|
||||
|
||||
fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
|
||||
fn maybe_tcx(&mut self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, item: &'hir hir::Item<'hir>) {
|
||||
(self.visit_hole_span)(item.span);
|
||||
/// We override `visit_nested_item` instead of `visit_item` because we
|
||||
/// only need the item's span, not the item itself.
|
||||
fn visit_nested_item(&mut self, id: hir::ItemId) -> Self::Result {
|
||||
let span = self.tcx.def_span(id.owner_id.def_id);
|
||||
self.visit_hole_span(span);
|
||||
// Having visited this item, we don't care about its children,
|
||||
// so don't call `walk_item`.
|
||||
}
|
||||
|
||||
// We override `visit_expr` instead of the more specific expression
|
||||
// visitors, so that we have direct access to the expression span.
|
||||
fn visit_expr(&mut self, expr: &'hir hir::Expr<'hir>) {
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
match expr.kind {
|
||||
hir::ExprKind::Closure(_) | hir::ExprKind::ConstBlock(_) => {
|
||||
(self.visit_hole_span)(expr.span);
|
||||
self.visit_hole_span(expr.span);
|
||||
// Having visited this expression, we don't care about its
|
||||
// children, so don't call `walk_expr`.
|
||||
}
|
||||
|
@ -384,18 +386,17 @@ fn extract_hole_spans_from_hir<'tcx>(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut hole_spans = vec![];
|
||||
let mut visitor = HolesVisitor {
|
||||
tcx,
|
||||
visit_hole_span: |hole_span| {
|
||||
impl HolesVisitor<'_> {
|
||||
fn visit_hole_span(&mut self, hole_span: Span) {
|
||||
// Discard any holes that aren't directly visible within the body span.
|
||||
if body_span.contains(hole_span) && body_span.eq_ctxt(hole_span) {
|
||||
hole_spans.push(hole_span);
|
||||
if self.body_span.contains(hole_span) && self.body_span.eq_ctxt(hole_span) {
|
||||
self.hole_spans.push(hole_span);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let mut visitor = HolesVisitor { tcx, body_span, hole_spans: vec![] };
|
||||
|
||||
visitor.visit_body(hir_body);
|
||||
hole_spans
|
||||
visitor.hole_spans
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use rustc_abi::{BackendRepr, Float, Integer, Primitive, RegKind, Size};
|
||||
|
||||
use crate::callconv::{ArgAbi, FnAbi, Reg};
|
||||
use crate::spec::HasTargetSpec;
|
||||
use crate::spec::{HasTargetSpec, RustcAbi};
|
||||
|
||||
// Win64 ABI: https://docs.microsoft.com/en-us/cpp/build/parameter-passing
|
||||
|
||||
pub(crate) fn compute_abi_info<Ty>(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
|
||||
pub(crate) fn compute_abi_info<Ty>(cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<'_, Ty>) {
|
||||
let fixup = |a: &mut ArgAbi<'_, Ty>, is_ret: bool| {
|
||||
match a.layout.backend_repr {
|
||||
BackendRepr::Uninhabited | BackendRepr::Memory { sized: false } => {}
|
||||
|
@ -24,10 +24,14 @@ pub(crate) fn compute_abi_info<Ty>(_cx: &impl HasTargetSpec, fn_abi: &mut FnAbi<
|
|||
}
|
||||
BackendRepr::Scalar(scalar) => {
|
||||
if is_ret && matches!(scalar.primitive(), Primitive::Int(Integer::I128, _)) {
|
||||
// `i128` is returned in xmm0 by Clang and GCC
|
||||
// FIXME(#134288): This may change for the `-msvc` targets in the future.
|
||||
let reg = Reg { kind: RegKind::Vector, size: Size::from_bits(128) };
|
||||
a.cast_to(reg);
|
||||
if cx.target_spec().rustc_abi == Some(RustcAbi::X86Softfloat) {
|
||||
// Use the native `i128` LLVM type for the softfloat ABI -- in other words, adjust nothing.
|
||||
} else {
|
||||
// `i128` is returned in xmm0 by Clang and GCC
|
||||
// FIXME(#134288): This may change for the `-msvc` targets in the future.
|
||||
let reg = Reg { kind: RegKind::Vector, size: Size::from_bits(128) };
|
||||
a.cast_to(reg);
|
||||
}
|
||||
} else if a.layout.size.bytes() > 8
|
||||
&& !matches!(scalar.primitive(), Primitive::Float(Float::F128))
|
||||
{
|
||||
|
|
|
@ -3289,6 +3289,14 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
let mut parent_trait_pred =
|
||||
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
|
||||
let parent_def_id = parent_trait_pred.def_id();
|
||||
if tcx.is_diagnostic_item(sym::FromResidual, parent_def_id)
|
||||
&& !tcx.features().enabled(sym::try_trait_v2)
|
||||
{
|
||||
// If `#![feature(try_trait_v2)]` is not enabled, then there's no point on
|
||||
// talking about `FromResidual<Result<A, B>>`, as the end user has nothing they
|
||||
// can do about it. As far as they are concerned, `?` is compiler magic.
|
||||
return;
|
||||
}
|
||||
let self_ty_str =
|
||||
tcx.short_string(parent_trait_pred.skip_binder().self_ty(), err.long_ty_path());
|
||||
let trait_name = parent_trait_pred.print_modifiers_and_trait_path().to_string();
|
||||
|
|
|
@ -4796,7 +4796,7 @@ impl<T, const N: usize> [[T; N]] {
|
|||
/// assert!(empty_slice_of_arrays.as_flattened().is_empty());
|
||||
/// ```
|
||||
#[stable(feature = "slice_flatten", since = "1.80.0")]
|
||||
#[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")]
|
||||
#[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn as_flattened(&self) -> &[T] {
|
||||
let len = if T::IS_ZST {
|
||||
self.len().checked_mul(N).expect("slice len overflow")
|
||||
|
@ -4833,7 +4833,7 @@ impl<T, const N: usize> [[T; N]] {
|
|||
/// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
|
||||
/// ```
|
||||
#[stable(feature = "slice_flatten", since = "1.80.0")]
|
||||
#[rustc_const_unstable(feature = "const_slice_flatten", issue = "95629")]
|
||||
#[rustc_const_stable(feature = "const_slice_flatten", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn as_flattened_mut(&mut self) -> &mut [T] {
|
||||
let len = if T::IS_ZST {
|
||||
self.len().checked_mul(N).expect("slice len overflow")
|
||||
|
|
|
@ -664,7 +664,6 @@ impl File {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(file_lock)]
|
||||
/// use std::fs::File;
|
||||
///
|
||||
/// fn main() -> std::io::Result<()> {
|
||||
|
@ -673,7 +672,7 @@ impl File {
|
|||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "file_lock", issue = "130994")]
|
||||
#[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub fn lock(&self) -> io::Result<()> {
|
||||
self.inner.lock()
|
||||
}
|
||||
|
@ -717,7 +716,6 @@ impl File {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(file_lock)]
|
||||
/// use std::fs::File;
|
||||
///
|
||||
/// fn main() -> std::io::Result<()> {
|
||||
|
@ -726,7 +724,7 @@ impl File {
|
|||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "file_lock", issue = "130994")]
|
||||
#[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub fn lock_shared(&self) -> io::Result<()> {
|
||||
self.inner.lock_shared()
|
||||
}
|
||||
|
@ -775,7 +773,6 @@ impl File {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(file_lock)]
|
||||
/// use std::fs::File;
|
||||
///
|
||||
/// fn main() -> std::io::Result<()> {
|
||||
|
@ -784,7 +781,7 @@ impl File {
|
|||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "file_lock", issue = "130994")]
|
||||
#[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub fn try_lock(&self) -> io::Result<bool> {
|
||||
self.inner.try_lock()
|
||||
}
|
||||
|
@ -832,7 +829,6 @@ impl File {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(file_lock)]
|
||||
/// use std::fs::File;
|
||||
///
|
||||
/// fn main() -> std::io::Result<()> {
|
||||
|
@ -841,7 +837,7 @@ impl File {
|
|||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "file_lock", issue = "130994")]
|
||||
#[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub fn try_lock_shared(&self) -> io::Result<bool> {
|
||||
self.inner.try_lock_shared()
|
||||
}
|
||||
|
@ -869,7 +865,6 @@ impl File {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(file_lock)]
|
||||
/// use std::fs::File;
|
||||
///
|
||||
/// fn main() -> std::io::Result<()> {
|
||||
|
@ -879,7 +874,7 @@ impl File {
|
|||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "file_lock", issue = "130994")]
|
||||
#[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub fn unlock(&self) -> io::Result<()> {
|
||||
self.inner.unlock()
|
||||
}
|
||||
|
@ -2531,6 +2526,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
|
|||
/// * `from` does not exist.
|
||||
/// * The current process does not have the permission rights to read
|
||||
/// `from` or write `to`.
|
||||
/// * The parent directory of `to` doesn't exist.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
@ -93,11 +93,17 @@ use crate::sys_common::{FromInner, IntoInner};
|
|||
/// use std::time::{Instant, Duration};
|
||||
///
|
||||
/// let now = Instant::now();
|
||||
/// let max_seconds = u64::MAX / 1_000_000_000;
|
||||
/// let duration = Duration::new(max_seconds, 0);
|
||||
/// let days_per_10_millennia = 365_2425;
|
||||
/// let solar_seconds_per_day = 60 * 60 * 24;
|
||||
/// let millenium_in_solar_seconds = 31_556_952_000;
|
||||
/// assert_eq!(millenium_in_solar_seconds, days_per_10_millennia * solar_seconds_per_day / 10);
|
||||
///
|
||||
/// let duration = Duration::new(millenium_in_solar_seconds, 0);
|
||||
/// println!("{:?}", now + duration);
|
||||
/// ```
|
||||
///
|
||||
/// For cross-platform code, you can comfortably use durations of up to around one hundred years.
|
||||
///
|
||||
/// # Underlying System calls
|
||||
///
|
||||
/// The following system calls are [currently] being used by `now()` to find out
|
||||
|
|
|
@ -523,19 +523,31 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
|
|||
/// Handles editor-specific setup differences
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
enum EditorKind {
|
||||
Vscode,
|
||||
Vim,
|
||||
Emacs,
|
||||
Helix,
|
||||
Vim,
|
||||
VsCode,
|
||||
Zed,
|
||||
}
|
||||
|
||||
impl EditorKind {
|
||||
// Used in `./tests.rs`.
|
||||
#[allow(dead_code)]
|
||||
pub const ALL: &[EditorKind] = &[
|
||||
EditorKind::Emacs,
|
||||
EditorKind::Helix,
|
||||
EditorKind::Vim,
|
||||
EditorKind::VsCode,
|
||||
EditorKind::Zed,
|
||||
];
|
||||
|
||||
fn prompt_user() -> io::Result<Option<EditorKind>> {
|
||||
let prompt_str = "Available editors:
|
||||
1. vscode
|
||||
2. vim
|
||||
3. emacs
|
||||
4. helix
|
||||
1. Emacs
|
||||
2. Helix
|
||||
3. Vim
|
||||
4. VS Code
|
||||
5. Zed
|
||||
|
||||
Select which editor you would like to set up [default: None]: ";
|
||||
|
||||
|
@ -543,28 +555,41 @@ Select which editor you would like to set up [default: None]: ";
|
|||
loop {
|
||||
print!("{}", prompt_str);
|
||||
io::stdout().flush()?;
|
||||
input.clear();
|
||||
io::stdin().read_line(&mut input)?;
|
||||
match input.trim().to_lowercase().as_str() {
|
||||
"1" | "vscode" => return Ok(Some(EditorKind::Vscode)),
|
||||
"2" | "vim" => return Ok(Some(EditorKind::Vim)),
|
||||
"3" | "emacs" => return Ok(Some(EditorKind::Emacs)),
|
||||
"4" | "helix" => return Ok(Some(EditorKind::Helix)),
|
||||
"" => return Ok(None),
|
||||
|
||||
let mut modified_input = input.to_lowercase();
|
||||
modified_input.retain(|ch| !ch.is_whitespace());
|
||||
match modified_input.as_str() {
|
||||
"1" | "emacs" => return Ok(Some(EditorKind::Emacs)),
|
||||
"2" | "helix" => return Ok(Some(EditorKind::Helix)),
|
||||
"3" | "vim" => return Ok(Some(EditorKind::Vim)),
|
||||
"4" | "vscode" => return Ok(Some(EditorKind::VsCode)),
|
||||
"5" | "zed" => return Ok(Some(EditorKind::Zed)),
|
||||
"" | "none" => return Ok(None),
|
||||
_ => {
|
||||
eprintln!("ERROR: unrecognized option '{}'", input.trim());
|
||||
eprintln!("NOTE: press Ctrl+C to exit");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
input.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// A list of historical hashes of each LSP settings file
|
||||
/// New entries should be appended whenever this is updated so we can detect
|
||||
/// outdated vs. user-modified settings files.
|
||||
fn hashes(&self) -> Vec<&str> {
|
||||
fn hashes(&self) -> &'static [&'static str] {
|
||||
match self {
|
||||
EditorKind::Vscode | EditorKind::Vim => vec![
|
||||
EditorKind::Emacs => &[
|
||||
"51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0",
|
||||
"d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45",
|
||||
],
|
||||
EditorKind::Helix => &[
|
||||
"2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233",
|
||||
"6736d61409fbebba0933afd2e4c44ff2f97c1cb36cf0299a7f4a7819b8775040",
|
||||
],
|
||||
EditorKind::Vim | EditorKind::VsCode => &[
|
||||
"ea67e259dedf60d4429b6c349a564ffcd1563cf41c920a856d1f5b16b4701ac8",
|
||||
"56e7bf011c71c5d81e0bf42e84938111847a810eee69d906bba494ea90b51922",
|
||||
"af1b5efe196aed007577899db9dae15d6dbc923d6fa42fa0934e68617ba9bbe0",
|
||||
|
@ -576,12 +601,8 @@ Select which editor you would like to set up [default: None]: ";
|
|||
"4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4",
|
||||
"c394386e6133bbf29ffd32c8af0bb3d4aac354cba9ee051f29612aa9350f8f8d",
|
||||
],
|
||||
EditorKind::Emacs => vec![
|
||||
"51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0",
|
||||
"d29af4d949bbe2371eac928a3c31cf9496b1701aa1c45f11cd6c759865ad5c45",
|
||||
],
|
||||
EditorKind::Helix => {
|
||||
vec!["2d3069b8cf1b977e5d4023965eb6199597755e6c96c185ed5f2854f98b83d233"]
|
||||
EditorKind::Zed => {
|
||||
&["bbce727c269d1bd0c98afef4d612eb4ce27aea3c3a8968c5f10b31affbc40b6c"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -592,29 +613,31 @@ Select which editor you would like to set up [default: None]: ";
|
|||
|
||||
fn settings_short_path(&self) -> PathBuf {
|
||||
self.settings_folder().join(match self {
|
||||
EditorKind::Vscode => "settings.json",
|
||||
EditorKind::Vim => "coc-settings.json",
|
||||
EditorKind::Emacs => ".dir-locals.el",
|
||||
EditorKind::Helix => "languages.toml",
|
||||
EditorKind::Vim => "coc-settings.json",
|
||||
EditorKind::VsCode | EditorKind::Zed => "settings.json",
|
||||
})
|
||||
}
|
||||
|
||||
fn settings_folder(&self) -> PathBuf {
|
||||
match self {
|
||||
EditorKind::Vscode => PathBuf::from(".vscode"),
|
||||
EditorKind::Vim => PathBuf::from(".vim"),
|
||||
EditorKind::Emacs => PathBuf::new(),
|
||||
EditorKind::Helix => PathBuf::from(".helix"),
|
||||
EditorKind::Vim => PathBuf::from(".vim"),
|
||||
EditorKind::VsCode => PathBuf::from(".vscode"),
|
||||
EditorKind::Zed => PathBuf::from(".zed"),
|
||||
}
|
||||
}
|
||||
|
||||
fn settings_template(&self) -> &str {
|
||||
fn settings_template(&self) -> &'static str {
|
||||
match self {
|
||||
EditorKind::Vscode | EditorKind::Vim => {
|
||||
include_str!("../../../../etc/rust_analyzer_settings.json")
|
||||
}
|
||||
EditorKind::Emacs => include_str!("../../../../etc/rust_analyzer_eglot.el"),
|
||||
EditorKind::Helix => include_str!("../../../../etc/rust_analyzer_helix.toml"),
|
||||
EditorKind::Vim | EditorKind::VsCode => {
|
||||
include_str!("../../../../etc/rust_analyzer_settings.json")
|
||||
}
|
||||
EditorKind::Zed => include_str!("../../../../etc/rust_analyzer_zed.json"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,16 @@ use crate::utils::helpers::hex_encode;
|
|||
|
||||
#[test]
|
||||
fn check_matching_settings_hash() {
|
||||
let editor = EditorKind::Vscode;
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(&editor.settings_template());
|
||||
let hash = hex_encode(hasher.finalize().as_slice());
|
||||
assert_eq!(
|
||||
&hash,
|
||||
editor.hashes().last().unwrap(),
|
||||
"Update `EditorKind::hashes()` with the new hash of `src/etc/rust_analyzer_settings.json`"
|
||||
);
|
||||
for editor in EditorKind::ALL {
|
||||
let mut hasher = sha2::Sha256::new();
|
||||
hasher.update(&editor.settings_template());
|
||||
let hash = hex_encode(hasher.finalize().as_slice());
|
||||
assert_eq!(
|
||||
&hash,
|
||||
editor.hashes().last().unwrap(),
|
||||
"Update `EditorKind::hashes()` with the new hash of `{}` for `EditorKind::{:?}`",
|
||||
editor.settings_template(),
|
||||
editor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,6 +154,16 @@ You can run `./x setup editor` and select `helix`, which will prompt you to
|
|||
create `languages.toml` with the recommended configuration for Helix. The
|
||||
recommended settings live at [`src/etc/rust_analyzer_helix.toml`].
|
||||
|
||||
### Zed
|
||||
|
||||
Zed comes with built-in LSP and rust-analyzer support.
|
||||
It can be configured through `.zed/settings.json`, as described
|
||||
[here](https://zed.dev/docs/configuring-languages). Selecting `zed`
|
||||
in `./x setup editor` will prompt you to create a `.zed/settings.json`
|
||||
file which will configure Zed with the recommended configuration. The
|
||||
recommended `rust-analyzer` settings live
|
||||
at [`src/etc/rust_analyzer_zed.json`].
|
||||
|
||||
## Check, check, and check again
|
||||
|
||||
When doing simple refactoring, it can be useful to run `./x check`
|
||||
|
@ -381,4 +391,5 @@ load this completion.
|
|||
[`src/etc/rust_analyzer_settings.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_settings.json
|
||||
[`src/etc/rust_analyzer_eglot.el`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_eglot.el
|
||||
[`src/etc/rust_analyzer_helix.toml`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_helix.toml
|
||||
[`src/etc/rust_analyzer_zed.json`]: https://github.com/rust-lang/rust/blob/master/src/etc/rust_analyzer_zed.json
|
||||
[`src/etc/pre-push.sh`]: https://github.com/rust-lang/rust/blob/master/src/etc/pre-push.sh
|
||||
|
|
|
@ -167,9 +167,7 @@ a new unstable feature:
|
|||
|
||||
1. Prevent usage of the new feature unless the feature gate is set.
|
||||
You can check it in most places in the compiler using the
|
||||
expression `tcx.features().$feature_name` (or
|
||||
`sess.features_untracked().$feature_name` if the
|
||||
tcx is unavailable)
|
||||
expression `tcx.features().$feature_name()`
|
||||
|
||||
If the feature gate is not set, you should either maintain
|
||||
the pre-feature behavior or raise an error, depending on
|
||||
|
|
52
src/etc/rust_analyzer_zed.json
Normal file
52
src/etc/rust_analyzer_zed.json
Normal file
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"lsp": {
|
||||
"rust-analyzer": {
|
||||
"initialization_options": {
|
||||
"cargo": {
|
||||
"buildScripts": {
|
||||
"enable": true,
|
||||
"invocationLocation": "root",
|
||||
"invocationStrategy": "once",
|
||||
"overrideCommand": ["python3", "x.py", "check", "--json-output"]
|
||||
},
|
||||
"extraEnv": {
|
||||
"RUSTC_BOOTSTRAP": "1"
|
||||
},
|
||||
"sysrootSrc": "./library"
|
||||
},
|
||||
"check": {
|
||||
"invocationLocation": "root",
|
||||
"invocationStrategy": "once",
|
||||
"overrideCommand": ["python3", "x.py", "check", "--json-output"]
|
||||
},
|
||||
"linkedProjects": [
|
||||
"Cargo.toml",
|
||||
"library/Cargo.toml",
|
||||
"src/tools/x/Cargo.toml",
|
||||
"src/bootstrap/Cargo.toml",
|
||||
"src/tools/rust-analyzer/Cargo.toml",
|
||||
"compiler/rustc_codegen_cranelift/Cargo.toml",
|
||||
"compiler/rustc_codegen_gcc/Cargo.toml"
|
||||
],
|
||||
"procMacro": {
|
||||
"enable": true,
|
||||
"server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv"
|
||||
},
|
||||
"rustc": {
|
||||
"source": "./Cargo.toml"
|
||||
},
|
||||
"rustfmt": {
|
||||
"overrideCommand": [
|
||||
"${workspaceFolder}/build/host/rustfmt/bin/rustfmt",
|
||||
"--edition=2021"
|
||||
]
|
||||
},
|
||||
"server": {
|
||||
"extraEnv": {
|
||||
"RUSTUP_TOOLCHAIN": "nightly"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
26
tests/assembly/x86_64-windows-i128-abi.rs
Normal file
26
tests/assembly/x86_64-windows-i128-abi.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
//@ assembly-output: emit-asm
|
||||
//@ add-core-stubs
|
||||
//@ revisions: msvc softfloat
|
||||
//@ compile-flags: -Copt-level=3
|
||||
//@[msvc] compile-flags: --target x86_64-pc-windows-msvc
|
||||
//@[msvc] needs-llvm-components: x86
|
||||
//@[softfloat] compile-flags: --target x86_64-unknown-uefi
|
||||
//@[softfloat] needs-llvm-components: x86
|
||||
|
||||
#![feature(no_core)]
|
||||
#![no_core]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
// CHECK-LABEL: ret_i128
|
||||
// Hardfloat targets return via xmm0, softfloat targets via rax and rdx.
|
||||
// msvc: movaps {{.*}}, %xmm0
|
||||
// softfloat: movq (%[[INPUT:.*]]), %rax
|
||||
// softfloat-NEXT: movq 8(%[[INPUT]]), %rdx
|
||||
// CHECK-NEXT: retq
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ret_i128(x: &i128) -> i128 {
|
||||
*x
|
||||
}
|
|
@ -4,13 +4,18 @@
|
|||
//@ compile-flags: -Copt-level=1
|
||||
|
||||
//@ add-core-stubs
|
||||
//@ revisions: MSVC MINGW
|
||||
//@ revisions: MSVC MINGW softfloat
|
||||
//@ [MSVC] needs-llvm-components: x86
|
||||
//@ [MINGW] needs-llvm-components: x86
|
||||
//@ [MSVC] compile-flags: --target x86_64-pc-windows-msvc
|
||||
//@ [MINGW] compile-flags: --target x86_64-pc-windows-gnu
|
||||
// Use `WIN` as a common prefix for MSVC and MINGW but *not* the softfloat test.
|
||||
//@ [MSVC] filecheck-flags: --check-prefix=WIN
|
||||
//@ [MINGW] needs-llvm-components: x86
|
||||
//@ [MINGW] compile-flags: --target x86_64-pc-windows-gnu
|
||||
//@ [MINGW] filecheck-flags: --check-prefix=WIN
|
||||
// The `x86_64-unknown-uefi` target also uses the Windows calling convention,
|
||||
// but does not have SSE registers available.
|
||||
//@ [softfloat] needs-llvm-components: x86
|
||||
//@ [softfloat] compile-flags: --target x86_64-unknown-uefi
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![no_std]
|
||||
|
@ -28,24 +33,26 @@ extern "C" {
|
|||
pub extern "C" fn pass(_arg0: u32, arg1: i128) {
|
||||
// CHECK-LABEL: @pass(
|
||||
// i128 is passed indirectly on Windows. It should load the pointer to the stack and pass
|
||||
// a pointer to that allocation.
|
||||
// WIN-SAME: %_arg0, ptr{{.*}} %arg1)
|
||||
// WIN: [[PASS:%[_0-9]+]] = alloca [16 x i8], align 16
|
||||
// WIN: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
|
||||
// WIN: store i128 [[LOADED]], ptr [[PASS]]
|
||||
// WIN: call void @extern_call
|
||||
// a pointer to that allocation. The softfloat ABI works the same.
|
||||
// CHECK-SAME: %_arg0, ptr{{.*}} %arg1)
|
||||
// CHECK: [[PASS:%[_0-9]+]] = alloca [16 x i8], align 16
|
||||
// CHECK: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
|
||||
// CHECK: store i128 [[LOADED]], ptr [[PASS]]
|
||||
// CHECK: call void @extern_call
|
||||
unsafe { extern_call(arg1) };
|
||||
}
|
||||
|
||||
// Check that we produce the correct return ABI
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ret(_arg0: u32, arg1: i128) -> i128 {
|
||||
// CHECK-LABEL: @ret(
|
||||
// WIN-LABEL: @ret(
|
||||
// i128 is returned in xmm0 on Windows
|
||||
// FIXME(#134288): This may change for the `-msvc` targets in the future.
|
||||
// WIN-SAME: i32{{.*}} %_arg0, ptr{{.*}} %arg1)
|
||||
// WIN: [[LOADED:%[_0-9]+]] = load <16 x i8>, ptr %arg1
|
||||
// WIN-NEXT: ret <16 x i8> [[LOADED]]
|
||||
// The softfloat ABI returns this indirectly.
|
||||
// softfloat-LABEL: i128 @ret(i32{{.*}} %_arg0, ptr{{.*}} %arg1)
|
||||
arg1
|
||||
}
|
||||
|
||||
|
@ -57,6 +64,7 @@ pub extern "C" fn forward(dst: *mut i128) {
|
|||
// WIN: [[RETURNED:%[_0-9]+]] = tail call <16 x i8> @extern_ret()
|
||||
// WIN: store <16 x i8> [[RETURNED]], ptr %dst
|
||||
// WIN: ret void
|
||||
// softfloat: [[RETURNED:%[_0-9]+]] = tail call {{.*}}i128 @extern_ret()
|
||||
unsafe { *dst = extern_ret() };
|
||||
}
|
||||
|
||||
|
@ -70,10 +78,10 @@ struct RetAggregate {
|
|||
pub extern "C" fn ret_aggregate(_arg0: u32, arg1: i128) -> RetAggregate {
|
||||
// CHECK-LABEL: @ret_aggregate(
|
||||
// Aggregates should also be returned indirectly
|
||||
// WIN-SAME: ptr{{.*}}sret([32 x i8]){{.*}}[[RET:%[_0-9]+]], i32{{.*}}%_arg0, ptr{{.*}}%arg1)
|
||||
// WIN: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
|
||||
// WIN: [[GEP:%[_0-9]+]] = getelementptr{{.*}}, ptr [[RET]]
|
||||
// WIN: store i128 [[LOADED]], ptr [[GEP]]
|
||||
// WIN: ret void
|
||||
// CHECK-SAME: ptr{{.*}}sret([32 x i8]){{.*}}[[RET:%[_0-9]+]], i32{{.*}}%_arg0, ptr{{.*}}%arg1)
|
||||
// CHECK: [[LOADED:%[_0-9]+]] = load i128, ptr %arg1
|
||||
// CHECK: [[GEP:%[_0-9]+]] = getelementptr{{.*}}, ptr [[RET]]
|
||||
// CHECK: store i128 [[LOADED]], ptr [[GEP]]
|
||||
// CHECK: ret void
|
||||
RetAggregate { a: 1, b: arg1 }
|
||||
}
|
||||
|
|
|
@ -1,52 +1,57 @@
|
|||
Function name: <holes::main::MyStruct>::_method (unused)
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 00, 25, 09, 00, 1d]
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 00, 2b, 09, 00, 1d]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Zero) at (prev + 37, 9) to (start + 0, 29)
|
||||
- Code(Zero) at (prev + 43, 9) to (start + 0, 29)
|
||||
Highest counter ID seen: (none)
|
||||
|
||||
Function name: holes::main
|
||||
Raw bytes (44): 0x[01, 01, 00, 08, 01, 08, 01, 06, 11, 01, 0f, 05, 00, 12, 01, 04, 05, 00, 12, 01, 07, 05, 00, 12, 01, 06, 05, 00, 12, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 01, 02]
|
||||
Raw bytes (69): 0x[01, 01, 00, 0d, 01, 08, 01, 01, 12, 01, 05, 05, 00, 12, 01, 07, 09, 00, 11, 01, 09, 05, 00, 12, 01, 04, 05, 00, 12, 01, 07, 05, 00, 12, 01, 06, 05, 00, 12, 01, 04, 05, 00, 12, 01, 04, 05, 00, 12, 01, 06, 05, 03, 0f, 01, 0a, 05, 03, 0f, 01, 0a, 05, 0c, 0d, 01, 0f, 0e, 05, 02]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 8
|
||||
- Code(Counter(0)) at (prev + 8, 1) to (start + 6, 17)
|
||||
- Code(Counter(0)) at (prev + 15, 5) to (start + 0, 18)
|
||||
Number of file 0 mappings: 13
|
||||
- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 18)
|
||||
- Code(Counter(0)) at (prev + 5, 5) to (start + 0, 18)
|
||||
- Code(Counter(0)) at (prev + 7, 9) to (start + 0, 17)
|
||||
- Code(Counter(0)) at (prev + 9, 5) to (start + 0, 18)
|
||||
- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18)
|
||||
- Code(Counter(0)) at (prev + 7, 5) to (start + 0, 18)
|
||||
- Code(Counter(0)) at (prev + 6, 5) to (start + 0, 18)
|
||||
- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18)
|
||||
- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 18)
|
||||
- Code(Counter(0)) at (prev + 6, 5) to (start + 3, 15)
|
||||
- Code(Counter(0)) at (prev + 10, 5) to (start + 3, 15)
|
||||
- Code(Counter(0)) at (prev + 10, 5) to (start + 1, 2)
|
||||
- Code(Counter(0)) at (prev + 10, 5) to (start + 12, 13)
|
||||
- Code(Counter(0)) at (prev + 15, 14) to (start + 5, 2)
|
||||
Highest counter ID seen: c0
|
||||
|
||||
Function name: holes::main::_unused_fn (unused)
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 05, 00, 17]
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 00, 1f, 05, 00, 17]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Zero) at (prev + 25, 5) to (start + 0, 23)
|
||||
- Code(Zero) at (prev + 31, 5) to (start + 0, 23)
|
||||
Highest counter ID seen: (none)
|
||||
|
||||
Function name: holes::main::{closure#0} (unused)
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 00, 12, 09, 02, 0a]
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 00, 18, 09, 02, 0a]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Zero) at (prev + 18, 9) to (start + 2, 10)
|
||||
- Code(Zero) at (prev + 24, 9) to (start + 2, 10)
|
||||
Highest counter ID seen: (none)
|
||||
|
||||
Function name: holes::main::{closure#1} (unused)
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 00, 3d, 09, 02, 0a]
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 00, 4b, 09, 02, 0a]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Zero) at (prev + 61, 9) to (start + 2, 10)
|
||||
- Code(Zero) at (prev + 75, 9) to (start + 2, 10)
|
||||
Highest counter ID seen: (none)
|
||||
|
||||
|
|
|
@ -7,10 +7,16 @@
|
|||
LL| |
|
||||
LL| 1|fn main() {
|
||||
LL| 1| black_box(());
|
||||
LL| 1|
|
||||
LL| 1| // Splitting this across multiple lines makes it easier to see where the
|
||||
LL| 1| // coverage mapping regions begin and end.
|
||||
LL| 1| #[rustfmt::skip]
|
||||
LL| |
|
||||
LL| | static MY_STATIC: () = ();
|
||||
LL| |
|
||||
LL| 1| black_box(());
|
||||
LL| |
|
||||
LL| | const MY_CONST: () = ();
|
||||
LL| |
|
||||
LL| | // Splitting this across multiple lines makes it easier to see where the
|
||||
LL| | // coverage mapping regions begin and end.
|
||||
LL| | #[rustfmt::skip]
|
||||
LL| 1| let _closure =
|
||||
LL| | |
|
||||
LL| | _arg: (),
|
||||
|
@ -39,6 +45,14 @@
|
|||
LL| |
|
||||
LL| 1| black_box(());
|
||||
LL| |
|
||||
LL| | trait MyTrait {}
|
||||
LL| |
|
||||
LL| 1| black_box(());
|
||||
LL| |
|
||||
LL| | impl MyTrait for MyStruct {}
|
||||
LL| |
|
||||
LL| 1| black_box(());
|
||||
LL| |
|
||||
LL| | macro_rules! _my_macro {
|
||||
LL| | () => {};
|
||||
LL| | }
|
||||
|
@ -64,5 +78,24 @@
|
|||
LL| | ;
|
||||
LL| |
|
||||
LL| 1| black_box(());
|
||||
LL| 1|
|
||||
LL| 1| // This tests the edge case of a const block nested inside an "anon const",
|
||||
LL| 1| // such as the length of an array literal. Handling this case requires
|
||||
LL| 1| // `nested_filter::OnlyBodies` or equivalent.
|
||||
LL| 1| #[rustfmt::skip]
|
||||
LL| 1| let _const_block_inside_anon_const =
|
||||
LL| 1| [
|
||||
LL| 1| 0
|
||||
LL| 1| ;
|
||||
LL| 1| 7
|
||||
LL| 1| +
|
||||
LL| 1| const
|
||||
LL| | {
|
||||
LL| | 3
|
||||
LL| 1| }
|
||||
LL| 1| ]
|
||||
LL| 1| ;
|
||||
LL| 1|
|
||||
LL| 1| black_box(());
|
||||
LL| 1|}
|
||||
|
||||
|
|
|
@ -8,6 +8,12 @@ use core::hint::black_box;
|
|||
fn main() {
|
||||
black_box(());
|
||||
|
||||
static MY_STATIC: () = ();
|
||||
|
||||
black_box(());
|
||||
|
||||
const MY_CONST: () = ();
|
||||
|
||||
// Splitting this across multiple lines makes it easier to see where the
|
||||
// coverage mapping regions begin and end.
|
||||
#[rustfmt::skip]
|
||||
|
@ -39,6 +45,14 @@ fn main() {
|
|||
|
||||
black_box(());
|
||||
|
||||
trait MyTrait {}
|
||||
|
||||
black_box(());
|
||||
|
||||
impl MyTrait for MyStruct {}
|
||||
|
||||
black_box(());
|
||||
|
||||
macro_rules! _my_macro {
|
||||
() => {};
|
||||
}
|
||||
|
@ -64,4 +78,23 @@ fn main() {
|
|||
;
|
||||
|
||||
black_box(());
|
||||
|
||||
// This tests the edge case of a const block nested inside an "anon const",
|
||||
// such as the length of an array literal. Handling this case requires
|
||||
// `nested_filter::OnlyBodies` or equivalent.
|
||||
#[rustfmt::skip]
|
||||
let _const_block_inside_anon_const =
|
||||
[
|
||||
0
|
||||
;
|
||||
7
|
||||
+
|
||||
const
|
||||
{
|
||||
3
|
||||
}
|
||||
]
|
||||
;
|
||||
|
||||
black_box(());
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#![feature(try_trait_v2)]
|
||||
fn foo() -> Result<String, String> { //~ NOTE expected `String` because of this
|
||||
let test = String::from("one,two");
|
||||
let x = test
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0277]: `?` couldn't convert the error to `String`
|
||||
--> $DIR/question-mark-result-err-mismatch.rs:14:22
|
||||
--> $DIR/question-mark-result-err-mismatch.rs:15:22
|
||||
|
|
||||
LL | fn foo() -> Result<String, String> {
|
||||
| ---------------------- expected `String` because of this
|
||||
|
@ -17,7 +17,7 @@ LL | .map(|()| "")?;
|
|||
= note: required for `Result<String, String>` to implement `FromResidual<Result<Infallible, ()>>`
|
||||
|
||||
error[E0277]: `?` couldn't convert the error to `String`
|
||||
--> $DIR/question-mark-result-err-mismatch.rs:28:25
|
||||
--> $DIR/question-mark-result-err-mismatch.rs:29:25
|
||||
|
|
||||
LL | fn bar() -> Result<(), String> {
|
||||
| ------------------ expected `String` because of this
|
||||
|
@ -40,7 +40,7 @@ LL | .map_err(|_| ())?;
|
|||
= note: required for `Result<(), String>` to implement `FromResidual<Result<Infallible, ()>>`
|
||||
|
||||
error[E0277]: `?` couldn't convert the error to `String`
|
||||
--> $DIR/question-mark-result-err-mismatch.rs:48:11
|
||||
--> $DIR/question-mark-result-err-mismatch.rs:49:11
|
||||
|
|
||||
LL | fn baz() -> Result<String, String> {
|
||||
| ---------------------- expected `String` because of this
|
||||
|
|
|
@ -10,7 +10,6 @@ LL | Err("")?;
|
|||
= help: the trait `From<&str>` is not implemented for `TryFromSliceError`
|
||||
but trait `From<Infallible>` is implemented for it
|
||||
= help: for that trait implementation, expected `Infallible`, found `&str`
|
||||
= note: required for `Result<u32, TryFromSliceError>` to implement `FromResidual<Result<Infallible, &str>>`
|
||||
|
||||
error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
|
||||
--> $DIR/try-block-bad-type.rs:12:9
|
||||
|
|
|
@ -12,7 +12,6 @@ LL | Ok(Err(123_i32)?)
|
|||
= help: the following other types implement trait `From<T>`:
|
||||
`u8` implements `From<Char>`
|
||||
`u8` implements `From<bool>`
|
||||
= note: required for `Result<u64, u8>` to implement `FromResidual<Result<Infallible, i32>>`
|
||||
|
||||
error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
|
||||
--> $DIR/bad-interconversion.rs:9:12
|
||||
|
|
|
@ -19,7 +19,6 @@ LL | Err(5)?;
|
|||
`(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>`
|
||||
`(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>`
|
||||
and 4 others
|
||||
= note: required for `Result<i32, ()>` to implement `FromResidual<Result<Infallible, {integer}>>`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue