profile
viewpoint
Aleksey Kladov matklad @ferrous-systems Berlin https://matklad.github.io/ rosalind.info, Stepik.org, IntelliJ Rust, rust-analyzer. Stuck writing parsers.

intellij-rust/intellij-rust 3227

Rust plugin for the IntelliJ Platform

fitzgen/id-arena 54

A simple, id-based arena

ferrous-systems/cargo-review-deps 45

A tool for auditing Cargo dependencies during updates

async-rs/a-chat 36

A simple chat implemented on top of async-std

cuviper/autocfg 27

Automatic cfg for Rust compiler features

eugenyk/hpcourse 15

Repository to store student's practical works on high performance computing course

CAD97/sorbus 8

An experimental reimplementation of rowan, focused on size efficiency

lambda-llama/icfpc2016 2

λ-llama code for ICFP contest 2016

create barnchmatklad/juliaraytracer

branch : master

created branch time in 2 days

created repositorymatklad/juliaraytracer

created time in 2 days

push eventmatklad/config

Aleksey Kladov

commit sha d56bdbc2f61df27219089ef600c928161bdf7a3a

.

view details

push time in 2 days

push eventrust-analyzer/rust-analyzer.github.io

Deployment Bot (from Travis CI)

commit sha e67e7f6a574519c490925957062d6628182c276d

Deploy rust-analyzer/rust-analyzer.github.io to github.com/rust-analyzer/rust-analyzer.github.io.git:master

view details

push time in 3 days

push eventrust-analyzer/rust-analyzer.github.io

Aleksey Kladov

commit sha 4430b115b62e0fdb6a7cf9879e08825af1d08e65

Backfill post authors

view details

push time in 3 days

Pull request review commentrust-analyzer/rust-analyzer

Spawn a flycheck instance per workspace

 pub(crate) struct GlobalState {     req_queue: ReqQueue,     pub(crate) task_pool: Handle<TaskPool<Task>, Receiver<Task>>,     pub(crate) loader: Handle<Box<dyn vfs::loader::Handle>, Receiver<vfs::loader::Message>>,-    pub(crate) flycheck: Option<FlycheckHandle>,+    pub(crate) flycheck: Vec<FlycheckHandle>,

I wonder at what level of abstraction this Vec belongs. I think long term it's better to move these process-herding into FlycheckHandle, so that the logic for "which flycheck to restrat" could be centralized there, but the current soln is fine.

An interesting theoretical argument for pushing the Vec down:

With the current setup, we have sequential shutdown behavior. If we have n flychecks, we kill & wait for them sequentially. The ideal behavior would be to first kill all of the processes, and then wait for them in parallel.

jonas-schievink

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentrust-analyzer/rust-analyzer

Make name resolution resolve proc macros instead of relying purely on the build system

 impl ItemScope {     pub(crate) fn collect_legacy_macros(&self) -> FxHashMap<Name, MacroDefId> {         self.legacy_macros.clone()     }++    /// Marks everything that is not a procedural macro as private to `this_module`.+    pub(crate) fn censor_non_proc_macros(&mut self, this_module: ModuleId) {+        for vis in self+            .types+            .values_mut()+            .chain(self.values.values_mut())+            .map(|(_, v)| v)+            .chain(self.unnamed_trait_imports.values_mut())+        {+            *vis = Visibility::Module(this_module);+        }

Such huge chains sometimes read better with .for_each rather than a for loop.

I once was in the "never .for_each" camp, but I since moved to the "mostly for" one.

jonas-schievink

comment created time in 3 days

Pull request review commentrust-analyzer/rust-analyzer

Make name resolution resolve proc macros instead of relying purely on the build system

 impl DefCollector<'_> {         }         self.unresolved_imports = unresolved_imports; -        // Record proc-macros-        self.collect_proc_macro();+        // FIXME: This condition should instead check if this is a `proc-macro` type crate.+        if self.exports_proc_macros {+            // A crate exporting procedural macros is not allowed to export anything else.+            //+            // Additionally, while the proc macro entry points must be `pub`, they are not publicly+            // exported in type/value namespace. This function reduces the visibility of all items+            // in the crate root that aren't proc macros.+            let root = self.def_map.root;+            let root = &mut self.def_map.modules[root];+            root.scope.censor_non_proc_macros(ModuleId {+                krate: self.def_map.krate,+                local_id: self.def_map.root,+            });+        }     } -    fn collect_proc_macro(&mut self) {-        let proc_macros = std::mem::take(&mut self.proc_macros);-        for (name, expander) in proc_macros {-            let krate = self.def_map.krate;--            let macro_id = MacroDefId {+    fn resolve_proc_macro(&mut self, name: &Name) {+        self.exports_proc_macros = true;+        let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) {+            Some((_, expander)) => MacroDefId {

I feel like we should put a comment about source-level resolving vs .so-level resolving somewhere, and this function seems to be a good place for that!

While reading that I also got confused about whether proc_macros field refers to proc-macros this crate is defining, or to the proc-macros this crate can use. I think it is the former, while I would expect the latter.

jonas-schievink

comment created time in 3 days

PullRequestReviewEvent
PullRequestReviewEvent

pull request commentrust-analyzer/rust-analyzer

Bring back the enhanced enter key

Yeah, this is tricky... I would prefer not to override this by default, even if an override is a no-op. But I don't see a way to do

if config.do_override { install_override() }

which we ideally want here. I guess, in practice, maybe we want to cave in and use the simple regex handler here?

jonas-schievink

comment created time in 3 days

pull request commentrust-analyzer/rust-analyzer

Dont unnecessarily unnest imports

Alright, here is another try, instead of fully splitting the functions up I split up their logic according to an enum, as both functions require a lot of similar functionality. This should properly do the trick if I'm not mistaken.

Yeah, that's the right thing to do: private impl is parametrized by enum/boolean, public API is two separately named functions. This is a special case of a general phenomenon when user and implementer would prefer different APIs.

which is a style I personally like, hence I added it given it was so simple

LGTM! I guess we should just see if folks complain about this. I personally stick to use crate::full::path syntax even when use self::path would work :-)

bors r+

Veykril

comment created time in 3 days

pull request commentrust-analyzer/rust-analyzer

Update chalk to 0.28.0

bors r+

Thanks!

vandenheuvel

comment created time in 3 days

Pull request review commentrust-analyzer/rust-analyzer

Update chalk to 0.28.0

 pub(crate) fn trait_datum_query( }  fn well_known_trait_from_lang_attr(name: &str) -> Option<WellKnownTrait> {+    use chalk_solve::rust_ir::WellKnownTrait::*;+     Some(match name {-        "sized" => WellKnownTrait::Sized,-        "copy" => WellKnownTrait::Copy,-        "clone" => WellKnownTrait::Clone,-        "drop" => WellKnownTrait::Drop,-        "fn_once" => WellKnownTrait::FnOnce,-        "fn_mut" => WellKnownTrait::FnMut,-        "fn" => WellKnownTrait::Fn,-        "unsize" => WellKnownTrait::Unsize,+        "sized" => Sized,+        "copy" => Copy,+        "clone" => Clone,+        "drop" => Drop,+        "fn_once" => FnOnce,+        "fn_mut" => FnMut,+        "fn" => Fn,+        "unsize" => Unsize,+        "coerce_unsized" => CoerceUnsized,         _ => return None,     }) } -fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {+const fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {+    use chalk_solve::rust_ir::WellKnownTrait::*;

Yup, we also have "avoid local enum imports" in the style guide: https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/dev/style.md#import-style

vandenheuvel

comment created time in 3 days

PullRequestReviewEvent

push eventrust-analyzer/metrics

Bot

commit sha 2e64b726ad8179582ad69f58f78fe7a703f2e5cb

📈

view details

push time in 3 days

push eventrust-analyzer/metrics

Bot

commit sha 12a1dc7721b595eb27f0c169c8c4a19709e31986

📈

view details

push time in 3 days

pull request commentrust-analyzer/rust-analyzer

Add ok postfix completion

Hm, I am somewhat ambivalent on this one, as I am not sure this is common enough to warrant an extra completion item.

I guess it's best to check how useful it is in practice rather than theorize!

bors r+

Thanks!

mullr

comment created time in 3 days

pull request commentrust-analyzer/rust-analyzer

Dont unnecessarily unnest imports

Yeah, this is tricky... Here's the case that @flodiebold was talking about in #6071 which will fail under this PR:

diff --git a/crates/assists/src/handlers/add_missing_impl_members.rs b/crates/assists/src/handlers/add_missing_impl_members.rs
index 8df1d786b..1ac5fefd6 100644
--- a/crates/assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/assists/src/handlers/add_missing_impl_members.rs
@@ -414,6 +414,41 @@ impl foo::Foo for S {
         );
     }
 
+    #[test]
+    fn test_qualify_path_2() {
+        check_assist(
+            add_missing_impl_members,
+            r#"
+mod foo {
+    pub mod bar {
+        pub struct Bar;
+        pub trait Foo { fn foo(&self, bar: Bar); }
+    }
+}
+
+use foo::bar;
+
+struct S;
+impl bar::Foo for S { <|> }"#,
+            r#"
+mod foo {
+    pub mod bar {
+        pub struct Bar;
+        pub trait Foo { fn foo(&self, bar: Bar); }
+    }
+}
+
+use foo::bar;
+
+struct S;
+impl bar::Foo for S {
+    fn foo(&self, bar: bar::Bar) {
+        ${0:todo!()}
+    }
+}"#,
+        );
+    }
+
     #[test]
     fn test_qualify_path_generic() {
         check_assist(

I guess maybe we should have two versions of find_path

  • find_path_for_use which returns a path which you can just use (for things like path-qualifing when inserting missing memebers)
  • find_path_for_use (naming is horrible) which returns a path you can insert as a use-statement.

Alternatively, maybe the original idea of fixing the import insertion to work with short paths is worhtwhile? Although I am encouranged by the size of the diff here.

Veykril

comment created time in 3 days

push eventmatklad/config

Aleksey Kladov

commit sha 7a0a2d06ef008fec23c267eee5c8cc2a9f693a3e

Julia for scripting

view details

push time in 3 days

delete branch matklad/rust

delete branch : droporder

delete time in 3 days

create barnchmatklad/rust

branch : droporder

created branch time in 3 days

delete branch matklad/rust

delete branch : droporder

delete time in 3 days

push eventmatklad/dlx

Aleksey Kladov

commit sha 5873f4407e848063a488e0cf7f755ff872b20567

.

view details

push time in 3 days

issue commentrust-analyzer/rust-analyzer

Don't needlessly unnnest imports

I don't understand your suggestion yet though, what would the index be?

So, find_path will return both the full path, as well as path prefix.

This seems like a consideration specific to auto-import to me.

I am not entirely sure, for two reasons:

  • First, it seems like auto-import would need to re-derive some info? When we are looking for File, we get std::fs::File path first, and then shorten it in find_import. Auto-import would then need to effectively lengthen it to std::fs::File back
  • There are case like
use std::fs; // module
use lol::fs; // a macro or a const

Auto-import would need to decide which fs to append to... Although the latter problem might be there even with the my suggested setup?

matklad

comment created time in 3 days

issue commentrust-analyzer/rust-analyzer

Don't needlessly unnnest imports

Hm, yeah, that is also true... Should it return a pair of path and an index?

matklad

comment created time in 3 days

create barnchmatklad/dlx

branch : master

created branch time in 4 days

created repositorymatklad/dlx

created time in 4 days

push eventrust-analyzer/metrics

Bot

commit sha 25481ea5dccd6f3c88691d380ef62132fcf4512d

📈

view details

push time in 4 days

pull request commentrust-analyzer/rust-analyzer

Bump smol_str from 0.1.16 to 0.1.17

bors r+

Thanks!

woshilapin

comment created time in 4 days

push eventrust-analyzer/metrics

Bot

commit sha 5b455b69bb8abc5802f23663e6534aec134d101d

📈

view details

push time in 4 days

push eventrust-analyzer/metrics

Bot

commit sha ddc8e68b66a6464706fa397016f843cd7a748dba

📈

view details

push time in 4 days

push eventrust-analyzer/metrics

Bot

commit sha 8e653c97c2c7ce61d2f3cff42e27e9261f447f4f

📈

view details

push time in 4 days

pull request commentrust-analyzer/rust-analyzer

VS Code + WSL: describe binary location

bors r+

qnighy

comment created time in 4 days

pull request commentrust-analyzer/rust-analyzer

Add dbgr postfix completion

bors r+

lnicola

comment created time in 4 days

pull request commentrust-analyzer/rust-analyzer

Allow to use a Github Auth token for fetching releases

bors r+

Thanks!

Matthias247

comment created time in 4 days

Pull request review commentrust-analyzer/rust-analyzer

Bump smol_str from 0.1.16 to 0.1.17

 impl<'a> TreeSink for TtTreeSink<'a> {                     // Mark the range if needed                     let (text, id) = match leaf {                         tt::Leaf::Ident(ident) => (ident.text.clone(), ident.id),-                        tt::Leaf::Punct(punct) => {-                            (SmolStr::new_inline_from_ascii(1, &[punct.char as u8]), punct.id)-                        }+                        tt::Leaf::Punct(punct) => (+                            std::iter::FromIterator::from_iter(std::iter::once(punct.char)),

Let's do something more direct here

assert(punct.char.is_ascii());
let text = str::from_utf8(slice::from_ref(&(punct.char as u8))).unwrap();
woshilapin

comment created time in 4 days

PullRequestReviewEvent

Pull request review commentrust-lang/rust

UI to unit test for those using Cell/RefCell/UnsafeCell

 fn box_clone_from_ptr_stability() {         assert_eq!(copy.as_ptr() as usize, copy_raw);     } }++#[test]+fn box_deref_lval() {+    use std::cell::Cell;

Let's move this to the top, and use import from core.

poliorcetics

comment created time in 4 days

Pull request review commentrust-lang/rust

UI to unit test for those using Cell/RefCell/UnsafeCell

 fn test_is_sorted() {     assert!(!["c", "bb", "aaa"].is_sorted());     assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len())); }++#[test]+fn test_slice_run_destructors() {+    use core::cell::Cell;

mov import to the top

poliorcetics

comment created time in 4 days

Pull request review commentrust-lang/rust

UI to unit test for those using Cell/RefCell/UnsafeCell

-use std::fmt;+#![deny(warnings)]+#![allow(unused_must_use)]++use std::cell::RefCell;+use std::fmt::{self, Write};  #[test] fn test_format() {     let s = fmt::format(format_args!("Hello, {}!", "world"));     assert_eq!(s, "Hello, world!"); }++struct A;+struct B;+struct C;+struct D;++impl fmt::LowerHex for A {+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {+        f.write_str("aloha")+    }+}+impl fmt::UpperHex for B {+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {+        f.write_str("adios")+    }+}+impl fmt::Display for C {+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {+        f.pad_integral(true, "☃", "123")+    }+}+impl fmt::Binary for D {+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {+        f.write_str("aa")?;+        f.write_char('☃')?;+        f.write_str("bb")+    }+}++macro_rules! t {+    ($a:expr, $b:expr) => {+        assert_eq!($a, $b)+    };+}++#[test]+fn test_format_macro_interface() {+    // Various edge cases without formats+    t!(format!(""), "");+    t!(format!("hello"), "hello");+    t!(format!("hello {{"), "hello {");++    // default formatters should work+    t!(format!("{}", 1.0f32), "1");+    t!(format!("{}", 1.0f64), "1");+    t!(format!("{}", "a"), "a");+    t!(format!("{}", "a".to_string()), "a");+    t!(format!("{}", false), "false");+    t!(format!("{}", 'a'), "a");++    // At least exercise all the formats+    t!(format!("{}", true), "true");+    t!(format!("{}", '☃'), "☃");+    t!(format!("{}", 10), "10");+    t!(format!("{}", 10_usize), "10");+    t!(format!("{:?}", '☃'), "'☃'");+    t!(format!("{:?}", 10), "10");+    t!(format!("{:?}", 10_usize), "10");+    t!(format!("{:?}", "true"), "\"true\"");+    t!(format!("{:?}", "foo\nbar"), "\"foo\\nbar\"");+    t!(+        format!("{:?}", "foo\n\"bar\"\r\n\'baz\'\t\\qux\\"),+        r#""foo\n\"bar\"\r\n\'baz\'\t\\qux\\""#+    );+    t!(format!("{:?}", "foo\0bar\x01baz\u{7f}q\u{75}x"), r#""foo\u{0}bar\u{1}baz\u{7f}qux""#);+    t!(format!("{:o}", 10_usize), "12");+    t!(format!("{:x}", 10_usize), "a");+    t!(format!("{:X}", 10_usize), "A");+    t!(format!("{}", "foo"), "foo");+    t!(format!("{}", "foo".to_string()), "foo");+    if cfg!(target_pointer_width = "32") {+        t!(format!("{:#p}", 0x1234 as *const isize), "0x00001234");+        t!(format!("{:#p}", 0x1234 as *mut isize), "0x00001234");+    } else {+        t!(format!("{:#p}", 0x1234 as *const isize), "0x0000000000001234");+        t!(format!("{:#p}", 0x1234 as *mut isize), "0x0000000000001234");+    }+    t!(format!("{:p}", 0x1234 as *const isize), "0x1234");+    t!(format!("{:p}", 0x1234 as *mut isize), "0x1234");+    t!(format!("{:x}", A), "aloha");+    t!(format!("{:X}", B), "adios");+    t!(format!("foo {} ☃☃☃☃☃☃", "bar"), "foo bar ☃☃☃☃☃☃");+    t!(format!("{1} {0}", 0, 1), "1 0");+    t!(format!("{foo} {bar}", foo = 0, bar = 1), "0 1");+    t!(format!("{foo} {1} {bar} {0}", 0, 1, foo = 2, bar = 3), "2 1 3 0");+    t!(format!("{} {0}", "a"), "a a");+    t!(format!("{_foo}", _foo = 6usize), "6");+    t!(format!("{foo_bar}", foo_bar = 1), "1");+    t!(format!("{}", 5 + 5), "10");+    t!(format!("{:#4}", C), "☃123");+    t!(format!("{:b}", D), "aa☃bb");++    let a: &dyn fmt::Debug = &1;+    t!(format!("{:?}", a), "1");++    // Formatting strings and their arguments+    t!(format!("{}", "a"), "a");+    t!(format!("{:4}", "a"), "a   ");+    t!(format!("{:4}", "☃"), "☃   ");+    t!(format!("{:>4}", "a"), "   a");+    t!(format!("{:<4}", "a"), "a   ");+    t!(format!("{:^5}", "a"), "  a  ");+    t!(format!("{:^5}", "aa"), " aa  ");+    t!(format!("{:^4}", "a"), " a  ");+    t!(format!("{:^4}", "aa"), " aa ");+    t!(format!("{:.4}", "a"), "a");+    t!(format!("{:4.4}", "a"), "a   ");+    t!(format!("{:4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");+    t!(format!("{:<4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");+    t!(format!("{:>4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");+    t!(format!("{:^4.4}", "aaaaaaaaaaaaaaaaaa"), "aaaa");+    t!(format!("{:>10.4}", "aaaaaaaaaaaaaaaaaa"), "      aaaa");+    t!(format!("{:2.4}", "aaaaa"), "aaaa");+    t!(format!("{:2.4}", "aaaa"), "aaaa");+    t!(format!("{:2.4}", "aaa"), "aaa");+    t!(format!("{:2.4}", "aa"), "aa");+    t!(format!("{:2.4}", "a"), "a ");+    t!(format!("{:0>2}", "a"), "0a");+    t!(format!("{:.*}", 4, "aaaaaaaaaaaaaaaaaa"), "aaaa");+    t!(format!("{:.1$}", "aaaaaaaaaaaaaaaaaa", 4), "aaaa");+    t!(format!("{:.a$}", "aaaaaaaaaaaaaaaaaa", a = 4), "aaaa");+    t!(format!("{:._a$}", "aaaaaaaaaaaaaaaaaa", _a = 4), "aaaa");+    t!(format!("{:1$}", "a", 4), "a   ");+    t!(format!("{1:0$}", 4, "a"), "a   ");+    t!(format!("{:a$}", "a", a = 4), "a   ");+    t!(format!("{:-#}", "a"), "a");+    t!(format!("{:+#}", "a"), "a");+    t!(format!("{:/^10.8}", "1234567890"), "/12345678/");++    // Some float stuff+    t!(format!("{:}", 1.0f32), "1");+    t!(format!("{:}", 1.0f64), "1");+    t!(format!("{:.3}", 1.0f64), "1.000");+    t!(format!("{:10.3}", 1.0f64), "     1.000");+    t!(format!("{:+10.3}", 1.0f64), "    +1.000");+    t!(format!("{:+10.3}", -1.0f64), "    -1.000");++    t!(format!("{:e}", 1.2345e6f32), "1.2345e6");+    t!(format!("{:e}", 1.2345e6f64), "1.2345e6");+    t!(format!("{:E}", 1.2345e6f64), "1.2345E6");+    t!(format!("{:.3e}", 1.2345e6f64), "1.234e6");+    t!(format!("{:10.3e}", 1.2345e6f64), "   1.234e6");+    t!(format!("{:+10.3e}", 1.2345e6f64), "  +1.234e6");+    t!(format!("{:+10.3e}", -1.2345e6f64), "  -1.234e6");++    // Float edge cases+    t!(format!("{}", -0.0), "0");+    t!(format!("{:?}", -0.0), "-0.0");+    t!(format!("{:?}", 0.0), "0.0");++    // sign aware zero padding+    t!(format!("{:<3}", 1), "1  ");+    t!(format!("{:>3}", 1), "  1");+    t!(format!("{:^3}", 1), " 1 ");+    t!(format!("{:03}", 1), "001");+    t!(format!("{:<03}", 1), "001");+    t!(format!("{:>03}", 1), "001");+    t!(format!("{:^03}", 1), "001");+    t!(format!("{:+03}", 1), "+01");+    t!(format!("{:<+03}", 1), "+01");+    t!(format!("{:>+03}", 1), "+01");+    t!(format!("{:^+03}", 1), "+01");+    t!(format!("{:#05x}", 1), "0x001");+    t!(format!("{:<#05x}", 1), "0x001");+    t!(format!("{:>#05x}", 1), "0x001");+    t!(format!("{:^#05x}", 1), "0x001");+    t!(format!("{:05}", 1.2), "001.2");+    t!(format!("{:<05}", 1.2), "001.2");+    t!(format!("{:>05}", 1.2), "001.2");+    t!(format!("{:^05}", 1.2), "001.2");+    t!(format!("{:05}", -1.2), "-01.2");+    t!(format!("{:<05}", -1.2), "-01.2");+    t!(format!("{:>05}", -1.2), "-01.2");+    t!(format!("{:^05}", -1.2), "-01.2");+    t!(format!("{:+05}", 1.2), "+01.2");+    t!(format!("{:<+05}", 1.2), "+01.2");+    t!(format!("{:>+05}", 1.2), "+01.2");+    t!(format!("{:^+05}", 1.2), "+01.2");++    // Ergonomic format_args!+    t!(format!("{0:x} {0:X}", 15), "f F");+    t!(format!("{0:x} {0:X} {}", 15), "f F 15");+    t!(format!("{:x}{0:X}{a:x}{:X}{1:x}{a:X}", 13, 14, a = 15), "dDfEeF");+    t!(format!("{a:x} {a:X}", a = 15), "f F");++    // And its edge cases+    t!(+        format!(+            "{a:.0$} {b:.0$} {0:.0$}\n{a:.c$} {b:.c$} {c:.c$}",+            4,+            a = "abcdefg",+            b = "hijklmn",+            c = 3+        ),+        "abcd hijk 4\nabc hij 3"+    );+    t!(format!("{a:.*} {0} {:.*}", 4, 3, "efgh", a = "abcdef"), "abcd 4 efg");+    t!(format!("{:.a$} {a} {a:#x}", "aaaaaa", a = 2), "aa 2 0x2");++    // Test that pointers don't get truncated.+    {+        let val = usize::MAX;+        let exp = format!("{:#x}", val);+        t!(format!("{:p}", val as *const isize), exp);+    }++    // Escaping+    t!(format!("{{"), "{");+    t!(format!("}}"), "}");++    // make sure that format! doesn't move out of local variables+    let a = Box::new(3);+    format!("{}", a);+    format!("{}", a);++    // make sure that format! doesn't cause spurious unused-unsafe warnings when+    // it's inside of an outer unsafe block+    unsafe {+        let a: isize = ::std::mem::transmute(3_usize);+        format!("{}", a);+    }++    // test that trailing commas are acceptable+    format!("{}", "test",);+    format!("{foo}", foo = "test",);+}++// Basic test to make sure that we can invoke the `write!` macro with an+// fmt::Write instance.+#[test]+fn test_write() {+    let mut buf = String::new();+    write!(&mut buf, "{}", 3);+    {+        let w = &mut buf;+        write!(w, "{foo}", foo = 4);+        write!(w, "{}", "hello");+        writeln!(w, "{}", "line");+        writeln!(w, "{foo}", foo = "bar");+        w.write_char('☃');+        w.write_str("str");+    }++    t!(buf, "34helloline\nbar\n☃str");+}++// Just make sure that the macros are defined, there's not really a lot that we+// can do with them just yet (to test the output)+#[test]+fn test_print() {+    print!("hi");+    print!("{:?}", vec![0u8]);+    println!("hello");+    println!("this is a {}", "test");+    println!("{foo}", foo = "bar");+}++// Just make sure that the macros are defined, there's not really a lot that we+// can do with them just yet (to test the output)+#[test]+fn test_format_args() {+    let mut buf = String::new();+    {+        let w = &mut buf;+        write!(w, "{}", format_args!("{}", 1));+        write!(w, "{}", format_args!("test"));+        write!(w, "{}", format_args!("{test}", test = 3));+    }+    let s = buf;+    t!(s, "1test3");++    let s = fmt::format(format_args!("hello {}", "world"));+    t!(s, "hello world");+    let s = format!("{}: {}", "args were", format_args!("hello {}", "world"));+    t!(s, "args were: hello world");+}++#[test]+fn test_order() {+    // Make sure format!() arguments are always evaluated in a left-to-right+    // ordering+    fn foo() -> isize {+        static mut FOO: isize = 0;+        unsafe {+            FOO += 1;+            FOO+        }+    }+    assert_eq!(+        format!("{} {} {a} {b} {} {c}", foo(), foo(), foo(), a = foo(), b = foo(), c = foo()),+        "1 2 4 5 3 6".to_string()+    );+}++#[test]+fn test_once() {+    // Make sure each argument are evaluated only once even though it may be+    // formatted multiple times+    fn foo() -> isize {+        static mut FOO: isize = 0;+        unsafe {+            FOO += 1;+            FOO+        }+    }+    assert_eq!(format!("{0} {0} {0} {a} {a} {a}", foo(), a = foo()), "1 1 1 2 2 2".to_string());+}++#[test]+fn test_refcell() {+    let refcell = RefCell::new(5);+    assert_eq!(format!("{:?}", refcell), "RefCell { value: 5 }");+    let borrow = refcell.borrow_mut();+    assert_eq!(format!("{:?}", refcell), "RefCell { value: <borrowed> }");+    drop(borrow);+    assert_eq!(format!("{:?}", refcell), "RefCell { value: 5 }");+}

Let's update this note as well:

https://github.com/rust-lang/rust/blob/3a4da87f58099f08620a9a3e812abd77301cafb2/library/core/src/fmt/mod.rs#L2241-L2242

poliorcetics

comment created time in 4 days

Pull request review commentrust-lang/rust

UI to unit test for those using Cell/RefCell/UnsafeCell

 fn option_const() {     const IS_NONE: bool = OPTION.is_none();     assert!(!IS_NONE); }++#[test]+fn test_unwrap_drop() {+    use std::cell::Cell;

This should use core, and be at the top of the file with other imports.

poliorcetics

comment created time in 4 days

Pull request review commentrust-lang/rust

UI to unit test for those using Cell/RefCell/UnsafeCell

 mod nonzero; mod num; mod ops; mod option;+mod panic_safe;

Let's rather move this to library/std/panic/tests.rs

poliorcetics

comment created time in 4 days

Pull request review commentrust-lang/rust

UI to unit test for those using Cell/RefCell/UnsafeCell

-// run-pass--#![allow(non_camel_case_types)]-use std::cell::Cell;--struct dtor<'a> {-    x: &'a Cell<isize>,-}--impl<'a> Drop for dtor<'a> {-    fn drop(&mut self) {-        self.x.set(self.x.get() - 1);-    }-}--fn unwrap<T>(o: Option<T>) -> T {-    match o {-      Some(v) => v,-      None => panic!()-    }-}--pub fn main() {-    let x = &Cell::new(1);--    {-        let b = Some(dtor { x:x });-        let _c = unwrap(b);-    }--    assert_eq!(x.get(), 0);-}

This test feels like it intends to stresses auto-generated drop impl, rather than any specific impl details of standard library, so I think it's OK to keep as an UI test. The best way to check if this intends to check compiler or stdlib is to look at the PR which introduced the test: https://github.com/rust-lang/rust/commit/e47d2f60607142eaf68a0c560f5c3d37fd1da13d#diff-518b4158ed084dab26591f1ec09dffef. In this case, this is a change to the compiler.

But keeping this as a #[test] sounds fine by me as well!

poliorcetics

comment created time in 4 days

Pull request review commentrust-lang/rust

UI to unit test for those using Cell/RefCell/UnsafeCell

-use std::fmt;+#![deny(warnings)]+#![allow(unused_must_use)]

let's fix the warnings instead

poliorcetics

comment created time in 4 days

PullRequestReviewEvent
PullRequestReviewEvent

push eventrust-analyzer/metrics

Bot

commit sha fe39bd700d9419dc38137e2b87043df76f6ef744

📈

view details

push time in 4 days

issue commentrust-analyzer/rust-analyzer

Github releases is blocked in many corporations

Thanks, booked a slot for tomorrow!

gilescope

comment created time in 4 days

pull request commentrust-analyzer/rust-analyzer

Add references to fn args during completion

LGTM!

bors r+

adamrk

comment created time in 4 days

issue commentrust-lang/rust

str::split_once is underpowered

It's interesting that basically all string APIs are underpowered in this way? Both find and split don't return the matched pattern.

HeroicKatora

comment created time in 4 days

delete branch matklad/rust

delete branch : spacing

delete time in 4 days

issue commentsalsa-rs/salsa

First-class lists

@Gonkalbell today, queries return Clones because salsa uses interior mutability internally. We mutate the HashMaps which ultimatelly store the values, so we can't return references into values.

One can imagine a smarter scheme a-la OnceCell, where we can safely reutrn an & reference after initialization. I don't think there's any structured discussion about this yet, besides vague ideas that this might be interesting to try out.

Alxandr

comment created time in 4 days

issue commentrust-analyzer/rust-analyzer

VSCode setting to specify path to Cargo.toml

@azzamsa tbh, I don't know how to pass settings to lang servers via lsp mode. I guess it should be documented somewhere here: https://emacs-lsp.github.io/lsp-mode/.

A PR to rust-analyzer's manual clarifying this would help!

oxalica

comment created time in 4 days

pull request commentsalsa-rs/salsa

update on_demand_inputs invalidation

LGTM! I think it's also fine to link to that writeup from the book. Could you add a link in this PR?

ChristopherBiscardi

comment created time in 4 days

Pull request review commentrust-lang/rust

Unstably allow assume intrinsic in const contexts

+// check-pass++// Check that `const_assume` feature allow `assume` intrinsic+// to be used in const contexts.++#![feature(core_intrinsics, const_assume)]++extern crate core;++use core::intrinsics::assume;++pub const unsafe fn foo(x: usize, y: usize) -> usize {+    assume(y != 0);+    x / y+}

Yeah, I think this should be a unit-test.

lzutao

comment created time in 4 days

PullRequestReviewEvent

push eventsalsa-rs/salsa

Andrew Hickman

commit sha b275d36adff3fd754553f24de84e878d5aa4697b

Allow using a borrowed key in `DerivedQueryStorageOps::invalidate`

view details

push time in 4 days

pull request commentsalsa-rs/salsa

Allow using a borrowed key in `DerivedQueryStorageOps::invalidate`

Ah, right, this is a public API. I think we should have this then, thanks!

andrewhickman

comment created time in 4 days

pull request commentrust-lang/rust

Move Wrapping<T> ui tests into library

r=me with this comment addressed

@bors delegate=workingjubilee

workingjubilee

comment created time in 4 days

pull request commentsalsa-rs/salsa

Allow using a borrowed key in `DerivedQueryStorageOps::invalidate`

What is the motivation for this change? plumbing is a semi-internal module, users shouldn't generally interact with its types. And, internally, I think we'll never be able to gain from the advanced flexibility here, as always use type parameters here.

andrewhickman

comment created time in 4 days

issue commentrust-analyzer/rust-analyzer

Auto-import without nested imports

@Veykril filed https://github.com/rust-analyzer/rust-analyzer/issues/6071. I think the problem here is not that auto-import inserts fs::File in the wrong place, but that we tell it to insert fs::File (as opposed to std::fs::File).

jminer

comment created time in 4 days

issue openedrust-analyzer/rust-analyzer

Don't needlessly unnnest imports

If we auto-import File in this code

use std::{fs::{self}};

fn main()  {
    let _: File = todo!();
}

we get

use std::{fs::{self}};
use fs::File;

Instead, we should get use std::{fs::{self, File}};

I think the bug is in this function:

https://github.com/rust-analyzer/rust-analyzer/blob/4ddb8124b01a04adcc7d42444f7ca8d377bb60ae/crates/hir_def/src/find_path.rs#L19-L23

It returns (but this needs to be double checked) fs::File for the above example, rather than std::fs::File

created time in 4 days

issue closedsalsa-rs/salsa

`clippy::type_repetition_in_bounds` clippy warning inside `#[query_group]`

When using the #[salsa::invoke(...)] attribute inside a #[query_group], clippy complains about type repetition inside the function's bounds.

This is the code in question:

#[salsa::query_group(IrDatabaseStorage)]
pub trait IrDatabase: hir::HirDatabase {
    /// Get the LLVM context that should be used for all generation steps.
    #[salsa::input]
    fn context(&self) -> Arc<Context>;

    /// Gets the optimization level for generation.
    #[salsa::input]
    fn optimization_lvl(&self) -> OptimizationLevel;

    /// Returns the target for code generation.
    #[salsa::input]
    fn target(&self) -> Target;

    /// Given a type, return the corresponding IR type.
    #[salsa::invoke(crate::ir::ty::ir_query)]
    fn type_ir(&self, ty: hir::Ty) -> AnyTypeEnum;

    /// Given a `hir::FileId` generate code for the module.
    #[salsa::invoke(crate::ir::module::ir_query)]
    fn module_ir(&self, file: hir::FileId) -> Arc<ModuleIR>;

    /// Given a type, return the runtime `TypeInfo` that can be used to reflect the type.
    #[salsa::invoke(crate::code_gen::symbols::type_info_query)]
    fn type_info(&self, ty: hir::Ty) -> TypeInfo;
}

and these are the consequent warnings in clippy:

warning: this type has already been used as a bound predicate
  --> crates\mun_codegen\src\db.rs:26:8
   |
26 |     fn type_ir(&self, ty: hir::Ty) -> AnyTypeEnum;
   |        ^^^^^^^
   |
   = note: `#[warn(clippy::type_repetition_in_bounds)]` on by default
   = help: consider combining the bounds: `type_ir: IrDatabase + salsa::plumbing::HasQueryGroup<IrDatabaseStorage>`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

warning: this type has already been used as a bound predicate
  --> crates\mun_codegen\src\db.rs:26:8
   |
26 |     fn type_ir(&self, ty: hir::Ty) -> AnyTypeEnum;
   |        ^^^^^^^
   |
   = help: consider combining the bounds: `type_ir: salsa::plumbing::HasQueryGroup<IrDatabaseStorage> + salsa::Database`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

warning: this type has already been used as a bound predicate
  --> crates\mun_codegen\src\db.rs:30:8
   |
30 |     fn module_ir(&self, file: hir::FileId) -> Arc<ModuleIR>;
   |        ^^^^^^^^^
   |
   = help: consider combining the bounds: `module_ir: IrDatabase + salsa::plumbing::HasQueryGroup<IrDatabaseStorage>`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

warning: this type has already been used as a bound predicate
  --> crates\mun_codegen\src\db.rs:30:8
   |
30 |     fn module_ir(&self, file: hir::FileId) -> Arc<ModuleIR>;
   |        ^^^^^^^^^
   |
   = help: consider combining the bounds: `module_ir: salsa::plumbing::HasQueryGroup<IrDatabaseStorage> + salsa::Database`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

warning: this type has already been used as a bound predicate
  --> crates\mun_codegen\src\db.rs:34:8
   |
34 |     fn type_info(&self, ty: hir::Ty) -> TypeInfo;
   |        ^^^^^^^^^
   |
   = help: consider combining the bounds: `type_info: IrDatabase + salsa::plumbing::HasQueryGroup<IrDatabaseStorage>`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

warning: this type has already been used as a bound predicate
  --> crates\mun_codegen\src\db.rs:34:8
   |
34 |     fn type_info(&self, ty: hir::Ty) -> TypeInfo;
   |        ^^^^^^^^^
   |
   = help: consider combining the bounds: `type_info: salsa::plumbing::HasQueryGroup<IrDatabaseStorage> + salsa::Database`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

Used version:

salsa="0.12"

closed time in 4 days

Wodann

issue commentsalsa-rs/salsa

`clippy::type_repetition_in_bounds` clippy warning inside `#[query_group]`

Thanks for those links @rail-rain! I think we should then close this!

Wodann

comment created time in 4 days

issue commentrust-analyzer/rust-analyzer

Auto-import without nested imports

So I guess the idea here is to not add new imports starting from paths already imported.

Yeah, I think we have a similar issue even with nested imports

jminer

comment created time in 4 days

issue commentrust-analyzer/rust-analyzer

Support local imports (use statements in blocks)

Yeah, the #5922 is still how I think we should proceed here. Basically, we first should refactor existing code to be more modular, and than we should add support for local modules.

PRs welcome, but be warned that this is a large task. I'd estimate it as 1-2 weeks full-time for someone who is already familiar with the relevant infra.

At the same time, I wouldn't worry to much about "core design" here. I think both of these are true:

  • the whole DefCollector thing needs to be rewritten
  • this won't affect code outside of the name resolution, as the interface is isolated enough.

Also, +1 to this comment regarding the language :-)

suhr

comment created time in 4 days

issue commentrust-analyzer/rust-analyzer

Auto-import without nested imports

@phaazon could you provide a minimal self-containd example for fs issue, with behavior you get with last, and behavior you want? This is a fresh feature, there may be bugs!

jminer

comment created time in 4 days

issue commentrust-analyzer/rust-analyzer

add options and documentation for diagnostics

@iagox86 no, at the moment there's no way to disable that specific diagnostic. It is a desirable feature, but it is not yet implemented (although the ground work was put in place since the issue was originally opened). The fix should go around here. Note that we already check for config.disabled.contains for most diagnostics except the two hints above.

Note also that this is not a "warning", but a "hint" -- semantically, this is not something you need to fix, and we flag it as such at the protocol level. So, there might also be couple of fixes on the client side:

  • these should be rendered significantly less conspicuous than warnings
  • the client could have "show hints" setting to suppress display of all hints.
BurntSushi

comment created time in 4 days

CommitCommentEvent

Pull request review commentrust-analyzer/rust-analyzer

Add a command to open docs for the symbol under the cursor

 pub struct Function {     pub visibility: RawVisibilityId,     pub generic_params: GenericParamsId,     pub has_self_param: bool,+    pub has_body: bool,

I think this is probably OK, but we should consider refatoring the body query to just return an Option instead.

zacps

comment created time in 4 days

Pull request review commentrust-analyzer/rust-analyzer

Add a command to open docs for the symbol under the cursor

 fn rewrite_url_link(db: &RootDatabase, def: ModuleDef, target: &str) -> Option<S         .map(|url| url.into_string()) } -// Rewrites a markdown document, resolving links using `callback` and additionally striping prefixes/suffixes on link titles.+/// Retrieve a link to documentation for the given symbol.+pub fn external_docs(db: &RootDatabase, position: &FilePosition) -> Option<DocumentationLink> {
pub(crate) fn external_docs(db: &RootDatabase, position: &FilePosition) -> Option<DocumentationLink> {
zacps

comment created time in 4 days

Pull request review commentrust-analyzer/rust-analyzer

Add a command to open docs for the symbol under the cursor

 impl Function {     pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {         hir_ty::diagnostics::validate_body(db, self.id.into(), sink)     }++    /// Whether this function declaration has a definition.+    ///+    /// This is false in the case of required (not provided) trait methods.+    pub fn has_body(self, db: &dyn HirDatabase) -> bool {+        db.function_data(self.id).has_body+    }++    /// If this function is a method, the trait or type where it is declared.+    pub fn method_owner(self, db: &dyn HirDatabase) -> Option<MethodOwner> {+        match self.as_assoc_item(db).map(|assoc| assoc.container(db)) {+            Some(AssocItemContainer::Trait(t)) => Some(t.into()),+            Some(AssocItemContainer::ImplDef(imp)) => {+                let resolver = ModuleId::from(imp.module(db)).resolver(db.upcast());+                let ctx = TyLoweringContext::new(db, &resolver);+                let adt = Ty::from_hir(+                    &ctx,+                    &imp.target_trait(db).unwrap_or_else(|| imp.target_type(db)),+                )+                .as_adt()+                .map(|t| t.0)+                .unwrap();+                Some(Adt::from(adt).into())+            }+            None => None,+        }+    } } +#[derive(Debug)]+pub enum MethodOwner {+    Trait(Trait),+    Adt(Adt),

This should be an ImplDef, as inherent impls not necessary refer to adts. And, with this change, I think this becomes equivalent to AssocItemContainer?

zacps

comment created time in 4 days

Pull request review commentrust-analyzer/rust-analyzer

Add a command to open docs for the symbol under the cursor

 impl Function {     pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {         hir_ty::diagnostics::validate_body(db, self.id.into(), sink)     }++    /// Whether this function declaration has a definition.+    ///+    /// This is false in the case of required (not provided) trait methods.+    pub fn has_body(self, db: &dyn HirDatabase) -> bool {+        db.function_data(self.id).has_body+    }++    /// If this function is a method, the trait or type where it is declared.+    pub fn method_owner(self, db: &dyn HirDatabase) -> Option<MethodOwner> {

I think this is more or less equivalent to self.as_assoc_item()?.container

zacps

comment created time in 4 days

PullRequestReviewEvent
PullRequestReviewEvent

issue commentmatklad/matklad.github.io

media

image

matklad

comment created time in 4 days

push eventrust-analyzer/metrics

Bot

commit sha 74ffd8e6aeb5a9c27cbe9de94323101435ef53a0

📈

view details

push time in 4 days

push eventferrous-systems/teaching-material

matklad

commit sha cc97f9e21bfb93a569965e6377490b765a84390b

Automated deployment: Tue Sep 22 10:50:39 UTC 2020 4ffe71f202497fd24b12034216241785c1001092

view details

push time in 6 days

push eventferrous-systems/teaching-material

Aleksey Kladov

commit sha 4ffe71f202497fd24b12034216241785c1001092

Fix list syntax

view details

push time in 6 days

push eventferrous-systems/teaching-material

skade

commit sha 191af891f657b60258d884f27b5344710fd3dafc

Automated deployment: Tue Sep 22 08:46:54 UTC 2020 7b224b7c78b232268638031205e977bf7b7d83d9

view details

push time in 6 days

push eventferrous-systems/teaching-material

skade

commit sha 03e8734a914adea334572fc2cd9e592f2865f919

Automated deployment: Tue Sep 22 08:44:28 UTC 2020 c895a0f8136f3769572e2c5db9275c39a472fb2e

view details

push time in 6 days

push eventferrous-systems/teaching-material

skade

commit sha 4b2cf6890421f116c1136b4d34bb1a78f1a5afb7

Automated deployment: Tue Sep 22 07:55:24 UTC 2020 d2ce15a43a5ccf962d7dbb56106bb769d6c89eaa

view details

push time in 6 days

push eventferrous-systems/teaching-material

skade

commit sha 7f2d00795b09aa14ea154d040fcf9d023fb832b8

Automated deployment: Tue Sep 22 07:39:21 UTC 2020 bef5172150d78c3267e081f1ee003d225809b7ee

view details

push time in 6 days

issue commentrust-analyzer/smol_str

error[E0658]: `while` is not allowed in a `const fn`

Note that you can always pin smol_str to a specific version in some Cargo.lock.

galich

comment created time in 7 days

issue commentrust-analyzer/smol_str

error[E0658]: `while` is not allowed in a `const fn`

Yep, the MSRV is latest stable. I've pushed commit that clarifies that.

https://github.com/bodil/smartstring is an interesting alternative crate in this space, which might offer more stable MSRV guarantees.

galich

comment created time in 7 days

issue closedrust-analyzer/smol_str

error[E0658]: `while` is not allowed in a `const fn`

While running cargo install cargo-audit --force with Rust 1.44 we are getting following error in smol_str:

error[E0658]: `while` is not allowed in a `const fn`
  --> C:\Users\serg\.cargo\registry\src\github.com-1ecc6299db9ec823\smol_str-0.1.17\src\lib.rs:58:9
   |
58 | /         while i < text.len() {
59 | |             buf[i] = text.as_bytes()[i];
60 | |             i += 1
61 | |         }
   | |_________^
   |
   = note: see issue #52000 <https://github.com/rust-lang/rust/issues/52000> for more information

Is there a minimum supported version for smol_str? We really love cargo audit and we can't go Rust 1.45+ due to performance issues.

closed time in 7 days

galich

push eventrust-analyzer/smol_str

Aleksey Kladov

commit sha de2c360ccb21ba91dedad1207ff994a7635cca5b

Document MSRV

view details

push time in 7 days

pull request commentrust-lang/rust

Add format_to! macro

@crlf0710 this is still waiting on review:

  • I want to get a :+1: from T-libs that this is a good idea before I invest more time into writing tests
  • I don't know exactly why the build fails (some interraction between prelude & unstable macros perhaps), so I'd want to either have guidance on this one, or a :+1: from T-libs to justify digging into this myself
matklad

comment created time in 7 days

push eventferrous-systems/teaching-material

skade

commit sha ddd31f91e55b10fb964f6d50a2de0e8027ab40d5

Automated deployment: Mon Sep 21 13:24:16 UTC 2020 c348e461c57bc72ab001dd7f27d202a1c4e6ba27

view details

push time in 7 days

pull request commentrust-lang/rust

Don't recommend ManuallyDrop to customize drop order

Yeah, that would be helpful, included an example!

matklad

comment created time in 7 days

push eventrust-analyzer/metrics

Bot

commit sha 010d57275d0e14894ee04501a6c3cd9b217d74f5

📈

view details

push time in 7 days

MemberEvent

pull request commentrust-analyzer/rust-analyzer

Code Docs

bors r+

matklad

comment created time in 7 days

push eventmatklad/rust-analyzer

Aleksey Kladov

commit sha fcc3c49013c681d7f7cc98a59fe140e076837813

Apply suggestions from code review Co-authored-by: Laurențiu Nicola <lnicola@users.noreply.github.com>

view details

push time in 7 days

more