Vscode-rust: Including a build.rs breaks plugin functionality

Created on 27 Nov 2017  路  14Comments  路  Source: rust-lang/vscode-rust

When my project includes a build.rs referenced in the Cargo.toml the error output and Problems panel of this plugin no longer works.

Information

VSCode version: Version 1.18.1
Plugin version: 0.3.2
OS: Arch Linux

Steps to reproduce

  • Create a new project with cargo new --bin my_test
  • Open VSCode in that directory
  • Add some code that will cause a problem (this works):
fn main() {
  let a = 5;
  a = 12;
}
  • Now add a build = "build.rs" to the Cargo.toml file which contains some code (my example)
  • Now the Problems panel no longer updates. New problems will also not be highlighted

Not sure if I'm doing something wrong here but I think this is a bug 馃槖

bug rls

Most helpful comment

When build.rs has a syntax error, the whole Cargo.toml is highlighted with no useful message.
Also it does not format build.rs even if it compiles.

All 14 comments

I guess I can confirm your issue. Same versions, Arch and Ubuntu 17.10. I first assumed I was hit by #188. There is nothing on the error console and no suspicious output in the rls debug file, I presume, like in my case?

Using default RLS will not work with build script, as this is something that requires more info about inter-package dependencies. This should work with "rust.workspace_mode": true and "rust.unstable_features": true, however.
@spacekookie could you try turning those on and see if it helps?

@Xanewok : It doesn't work for me using these options. I'm using:

{
    "rust.workspace_mode": true,
    "rust-client.logToFile": true,
    "rust.unstable_features": true,
    "rust-client.channel": "nightly-2017-11-15-x86_64-unknown-linux-gnu"
}

@oleid Damn, beat me to it 馃槈
@Xanewok It doesn't work for me either

Here is the settings I'm using

{
    "rust.workspace_mode": true,
    "rust.unstable_features": true,

    // ... unrelated stuff ...
}

@spacekookie It was quite close. Fortunately, this is not a competition :)

I forgot to mention: I don't see any errors in rls's log file, but something like:

{"message":"unused import: `c_int`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"sync/prog/gpgpu/stochastic_particles/compute_kernel/lib.rs","byte_start":53,"byte_end":58,"line_start":4,"line_end":4,"column_start":12,"column_end":17,"is_primary":true,"text":[{"text":"use libc::{c_int};","highlight_start":12,"highlight_end":17}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[{"message":"#[warn(unused_imports)] on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":null}
{"message":"unused import: `ndarray::prelude::*;`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"sync/prog/gpgpu/stochastic_particles/compute_kernel/lib.rs","byte_start":65,"byte_end":85,"line_start":5,"line_end":5,"column_start":5,"column_end":25,"is_primary":true,"text":[{"text":"use ndarray::prelude::*;","highlight_start":5,"highlight_end":25}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[{"message":"#[warn(unused_imports)] on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":null}
{"message":"missing field `positions` in initializer of `root::SimulationState`","code":{"code":"E0063","explanation":"\nThis error indicates that during an attempt to build a struct or struct-like\nenum variant, one of the fields was not provided. Erroneous code example:\n\n```compile_fail,E0063\nstruct Foo {\n    x: i32,\n    y: i32,\n}\n\nfn main() {\n    let x = Foo { x: 0 }; // error: missing field: `y`\n}\n```\n\nEach field should be specified exactly once. Example:\n\n```\nstruct Foo {\n    x: i32,\n    y: i32,\n}\n\nfn main() {\n    let x = Foo { x: 0, y: 0 }; // ok!\n}\n```\n"},"level":"error","spans":[{"file_name":"sync/prog/gpgpu/stochastic_particles/compute_kernel/lib.rs","byte_start":745,"byte_end":766,"line_start":36,"line_end":36,"column_start":21,"column_end":42,"is_primary":true,"text":[{"text":"    let mut state = root::SimulationState {","highlight_start":21,"highlight_end":42}],"label":"missing `positions`","suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}
{"message":"mismatched types","code":{"code":"E0308","explanation":"\nThis error occurs when the compiler was unable to infer the concrete type of a\nvariable. It can occur for several cases, the most common of which is a\nmismatch in the expected type that the compiler inferred for a variable's\ninitializing expression, and the actual type explicitly assigned to the\nvariable.\n\nFor example:\n\n```compile_fail,E0308\nlet x: i32 = \"I am not a number!\";\n//     ~~~   ~~~~~~~~~~~~~~~~~~~~\n//      |             |\n//      |    initializing expression;\n//      |    compiler infers type `&str`\n//      |\n//    type `i32` assigned to variable `x`\n```\n"},"level":"error","spans":[{"file_name":"sync/prog/gpgpu/stochastic_particles/compute_kernel/lib.rs","byte_start":811,"byte_end":819,"line_start":39,"line_end":39,"column_start":23,"column_end":31,"is_primary":true,"text":[{"text":"        root::RunDemo(settings, state) == 0","highlight_start":23,"highlight_end":31}],"label":"expected *-ptr, found struct `root::SimulationSettingsBase`","suggested_replacement":null,"expansion":null}],"children":[{"message":"expected type `*const root::SimulationSettingsBase`\n   found type `root::SimulationSettingsBase`","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":null}
{"message":"mismatched types","code":{"code":"E0308","explanation":"\nThis error occurs when the compiler was unable to infer the concrete type of a\nvariable. It can occur for several cases, the most common of which is a\nmismatch in the expected type that the compiler inferred for a variable's\ninitializing expression, and the actual type explicitly assigned to the\nvariable.\n\nFor example:\n\n```compile_fail,E0308\nlet x: i32 = \"I am not a number!\";\n//     ~~~   ~~~~~~~~~~~~~~~~~~~~\n//      |             |\n//      |    initializing expression;\n//      |    compiler infers type `&str`\n//      |\n//    type `i32` assigned to variable `x`\n```\n"},"level":"error","spans":[{"file_name":"sync/prog/gpgpu/stochastic_particles/compute_kernel/lib.rs","byte_start":821,"byte_end":826,"line_start":39,"line_end":39,"column_start":33,"column_end":38,"is_primary":true,"text":[{"text":"        root::RunDemo(settings, state) == 0","highlight_start":33,"highlight_end":38}],"label":"expected *-ptr, found struct `root::SimulationState`","suggested_replacement":null,"expansion":null}],"children":[{"message":"expected type `*mut root::SimulationState`\n   found type `root::SimulationState`","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":null}
{"message":"aborting due to 3 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":null}

Which looks okay to me. For the record: I'm building a c++ based library using cmake in the build.rs file and wrap it using bindgen.

well yeah, it definitely should show these 2 warnings and 3 errors. I'll take a look, but in the meantime, could you reload the vscode with the workspace_mode on and see what are the logs then? Preferably rerunning vscode with RUST_LOG=rls=trace env var set.

@Xanewok : Here you are:

DEBUG:rls::server: Language Server starting up. Version: 0.123.0-nightly (015073b 2017-11-10)
TRACE:rls::server::io: reading: 1267 bytes
TRACE:rls::server: Read message `{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":11313,"rootPath":"/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles","rootUri":"file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles","capabilities":{"workspace":{"didChangeConfiguration":{"dynamicRegistration":true},"didChangeWatchedFiles":{"dynamicRegistration":true},"symbol":{"dynamicRegistration":true},"executeCommand":{"dynamicRegistration":true}},"textDocument":{"synchronization":{"dynamicRegistration":true,"willSave":true,"willSaveWaitUntil":true,"didSave":true},"completion":{"dynamicRegistration":true,"completionItem":{"snippetSupport":true}},"hover":{"dynamicRegistration":true},"signatureHelp":{"dynamicRegistration":true},"definition":{"dynamicRegistration":true},"references":{"dynamicRegistration":true},"documentHighlight":{"dynamicRegistration":true},"documentSymbol":{"dynamicRegistration":true},"codeAction":{"dynamicRegistration":true},"codeLens":{"dynamicRegistration":true},"formatting":{"dynamicRegistration":true},"rangeFormatting":{"dynamicRegistration":true},"onTypeFormatting":{"dynamicRegistration":true},"rename":{"dynamicRegistration":true},"documentLink":{"dynamicRegistration":true}}},"initializationOptions":{"omitInitBuild":true},"trace":"off"}}`
TRACE:rls::server: Parsed message `RawMessage { method: "initialize", id: Some(Num(0)), params: Object({"capabilities": Object({"textDocument": Object({"codeAction": Object({"dynamicRegistration": Bool(true)}), "codeLens": Object({"dynamicRegistration": Bool(true)}), "completion": Object({"completionItem": Object({"snippetSupport": Bool(true)}), "dynamicRegistration": Bool(true)}), "definition": Object({"dynamicRegistration": Bool(true)}), "documentHighlight": Object({"dynamicRegistration": Bool(true)}), "documentLink": Object({"dynamicRegistration": Bool(true)}), "documentSymbol": Object({"dynamicRegistration": Bool(true)}), "formatting": Object({"dynamicRegistration": Bool(true)}), "hover": Object({"dynamicRegistration": Bool(true)}), "onTypeFormatting": Object({"dynamicRegistration": Bool(true)}), "rangeFormatting": Object({"dynamicRegistration": Bool(true)}), "references": Object({"dynamicRegistration": Bool(true)}), "rename": Object({"dynamicRegistration": Bool(true)}), "signatureHelp": Object({"dynamicRegistration": Bool(true)}), "synchronization": Object({"didSave": Bool(true), "dynamicRegistration": Bool(true), "willSave": Bool(true), "willSaveWaitUntil": Bool(true)})}), "workspace": Object({"didChangeConfiguration": Object({"dynamicRegistration": Bool(true)}), "didChangeWatchedFiles": Object({"dynamicRegistration": Bool(true)}), "executeCommand": Object({"dynamicRegistration": Bool(true)}), "symbol": Object({"dynamicRegistration": Bool(true)})})}), "initializationOptions": Object({"omitInitBuild": Bool(true)}), "processId": Number(PosInt(11313)), "rootPath": String("/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles"), "rootUri": String("file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles"), "trace": String("off")}) }`
TRACE:rls::server: Handling `initialize`
TRACE:rls::server: init: InitializationOptions { omit_init_build: true }
TRACE:rls::server::io: response: "Content-Length: 500\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":0,\"result\":{\"capabilities\":{\"textDocumentSync\":2,\"hoverProvider\":true,\"completionProvider\":{\"resolveProvider\":true,\"triggerCharacters\":[\".\",\":\"]},\"definitionProvider\":true,\"referencesProvider\":true,\"documentHighlightProvider\":true,\"documentSymbolProvider\":true,\"workspaceSymbolProvider\":true,\"codeActionProvider\":true,\"documentFormattingProvider\":true,\"documentRangeFormattingProvider\":false,\"renameProvider\":true,\"executeCommandProvider\":{\"commands\":[\"rls.applySuggestion\"]}}}}"
TRACE:rls::config: root manifest_path: "/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/Cargo.toml"
TRACE:rls::config: infer_config_defaults: Auto-detected `stochastic_particles` package
TRACE:rls::config: infer_config_defaults: build_lib: false, build_bin: Some("stochastic_particles")
TRACE:rls::server::io: reading: 52 bytes
TRACE:rls::server: Read message `{"jsonrpc":"2.0","method":"initialized","params":{}}`
TRACE:rls::server: Parsed message `RawMessage { method: "initialized", id: None, params: Object({}) }`
TRACE:rls::server: Handling `initialized`
TRACE:rls::server::io: response: "Content-Length: 368\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"client/registerCapability\",\"params\":{\"registrations\":[{\"id\":\"rls-watch\",\"method\":\"workspace/didChangeWatchedFiles\",\"registerOptions\":{\"watchers\":[{\"globPattern\":\"/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/Cargo{.toml,.lock}\"},{\"globPattern\":\"/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/target\",\"kind\":4}]}}]}}"
TRACE:rls::server::io: reading: 472 bytes
TRACE:rls::server: Read message `{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{"rust":{"sysroot":null,"target":null,"rustflags":null,"clear_env_rust_log":true,"build_lib":null,"build_bin":null,"cfg_test":false,"unstable_features":true,"wait_to_build":500,"show_warnings":true,"goto_def_racer_fallback":false,"use_crate_blacklist":true,"build_on_save":false,"workspace_mode":true,"analyze_package":null,"features":[],"all_features":false,"no_default_features":false}}}}`
TRACE:rls::server: Parsed message `RawMessage { method: "workspace/didChangeConfiguration", id: None, params: Object({"settings": Object({"rust": Object({"all_features": Bool(false), "analyze_package": Null, "build_bin": Null, "build_lib": Null, "build_on_save": Bool(false), "cfg_test": Bool(false), "clear_env_rust_log": Bool(true), "features": Array([]), "goto_def_racer_fallback": Bool(false), "no_default_features": Bool(false), "rustflags": Null, "show_warnings": Bool(true), "sysroot": Null, "target": Null, "unstable_features": Bool(true), "use_crate_blacklist": Bool(true), "wait_to_build": Number(PosInt(500)), "workspace_mode": Bool(true)})})}) }`
TRACE:rls::server: Handling `workspace/didChangeConfiguration`
TRACE:rls::actions::notifications: config change: Object({"rust": Object({"all_features": Bool(false), "analyze_package": Null, "build_bin": Null, "build_lib": Null, "build_on_save": Bool(false), "cfg_test": Bool(false), "clear_env_rust_log": Bool(true), "features": Array([]), "goto_def_racer_fallback": Bool(false), "no_default_features": Bool(false), "rustflags": Null, "show_warnings": Bool(true), "sysroot": Null, "target": Null, "unstable_features": Bool(true), "use_crate_blacklist": Bool(true), "wait_to_build": Number(PosInt(500)), "workspace_mode": Bool(true)})})
TRACE:rls::actions::notifications: Updated config: Config { sysroot: None, target: None, rustflags: None, build_lib: Inferred(false), build_bin: Inferred(None), cfg_test: false, unstable_features: true, wait_to_build: 500, show_warnings: true, goto_def_racer_fallback: false, workspace_mode: true, analyze_package: None, clear_env_rust_log: true, build_on_save: false, use_crate_blacklist: true, target_dir: None, features: [], all_features: false, no_default_features: false }
TRACE:rls::server::io: response: "Content-Length: 66\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"rustDocument/beginBuild\",\"params\":null}"
TRACE:rls::build: request_build Cargo
TRACE:rls::server::io: response: "Content-Length: 183\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"client/registerCapability\",\"params\":{\"registrations\":[{\"id\":\"rls-range-formatting\",\"method\":\"textDocument/rangeFormatting\",\"registerOptions\":null}]}}"
TRACE:rls::server::io: reading: 6472 bytes
TRACE:rls::server: Read message `{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/src/main.rs","languageId":"rust","version":1,"text":"#![cfg_attr(not(feature = \"gtk_3_10\"), allow(unused_variables, unused_mut))]\n\nextern crate gtk;\nextern crate cairo;\nextern crate ocl;\nextern crate rand;\nextern crate compute_kernel;\n\nuse ocl::{util, ProQue, Buffer, MemFlags};\nuse ocl::prm::Float4;\n\nuse std::rc::Rc;\nuse std::cmp;\nuse std::sync::{Mutex, Arc};\nuse gtk::traits::*;\nuse gtk::Inhibit;\nuse cairo::{Context, RectangleInt};\nuse std::{thread, time, f64};\nuse std::io::prelude::*;\nuse std::fs::File;\n\nuse rand::Rng;\nuse rand::distributions::{IndependentSample, Range, Exp};\n\nuse compute_kernel::run_computation;\n\nstruct RenderingAPITestWindow {\n    window: gtk::Window,\n    drawing_area: gtk::DrawingArea,\n    state: Arc>,\n}\n\nstruct RenderingState {\n    width: i32,\n    height: i32,\n    points: Vec\n}\n\n#[derive(Debug,Copy,Clone,Default)]\nstruct SimulationContext\n{\n\tdt : f32,\n\tbox_min : Float4,\n\tbox_max : Float4\n}\n\nimpl PartialEq for SimulationContext {\n    fn eq(&self, other: &SimulationContext) -> bool {\n        self.dt == other.dt &&\n        self.box_min == other.box_min &&\n        self.box_max == other.box_max\n    }\n}\n\nunsafe impl ocl::OclPrm for SimulationContext{}\n\n\nimpl RenderingAPITestWindow {\n    fn new(width: i32, height: i32) -> Rc {\n        let window = gtk::Window::new(gtk::WindowType::Toplevel);\n        let drawing_area = gtk::DrawingArea::new();\n        drawing_area.set_size_request(width, height);\n        window.set_title(\"Cairo API test\");\n        window.add(&drawing_area);\n\n        let instance = Rc::new(RenderingAPITestWindow {\n            window: window,\n            drawing_area: drawing_area,\n            state: Arc::new(Mutex::new(RenderingState{\n                width: width,\n                height: height,\n                points: vec!()\n            })),\n        });\n\n        {\n            let instance2 = instance.clone();\n            instance.drawing_area.connect_draw(move |widget, cairo_context| {\n                instance2.state.lock().unwrap().on_draw(cairo_context);\n                instance2.drawing_area.queue_draw();\n                Inhibit(true)\n            });\n        }\n        {\n            let instance2 = instance.clone();\n            instance.drawing_area.connect_size_allocate(move |widget, rect| {\n                instance2.state.lock().unwrap().on_size_allocate(rect);\n            });\n        }\n        instance.window.show_all();\n        instance\n    }\n\n    fn exit_on_close(&self) {\n        self.window.connect_delete_event(|_, _| {\n            gtk::main_quit();\n            Inhibit(true)\n        });\n    }\n}\n\nimpl RenderingState {\n\tfn draw_box(&self, cairo_ctx: &Context) {\n\t\tcairo_ctx.set_line_width(5e-3);\n    \tcairo_ctx.translate(0.0,0.0);\n    \tcairo_ctx.rectangle(0.,0.,1.,1.);\n    \tcairo_ctx.stroke();\n    }\n\n\tfn draw_discs(&self, cairo_ctx: &Context) {\n\t    cairo_ctx.set_source_rgb(0.1, 0.1, 0.1);\n\t    for pt in self.points.iter() {\n\t    \tlet x = pt[0] as f64;\n\t    \tlet y = pt[1] as f64;\n\t    \tcairo_ctx.arc(x, y, 5e-3, 0.0, 2.0 * f64::consts::PI);\n\t    \tcairo_ctx.fill();\n\t    }\n    }\n\n    fn on_draw(&self, cairo_ctx: &Context) {\n        let text = format!(\"--- The current state of simulation --- {} points\", self.points.len());\n        cairo_ctx.save();\n        //cairo_ctx.move_to(50.0, (self.height as f64) * 0.5);\n        //cairo_ctx.set_font_size(18.0);\n        //cairo_ctx.show_text(text.as_str());\n        let SCALE = cmp::min(self.width, self.height) as f64;\n        cairo_ctx.translate(0.5*(self.width as f64 - SCALE), 0.5 *(self.height as f64 - SCALE));\n\n        cairo_ctx.scale(SCALE, SCALE);\n        self.draw_box(cairo_ctx);\n        self.draw_discs(cairo_ctx);\n\n        cairo_ctx.restore();\n    }\n\n\n    fn on_size_allocate(&mut self, rect: >k::Rectangle) {\n        self.width = rect.width as i32;\n        self.height = rect.height as i32;\n    }\n}\nfn MakeInitialPositionAndVelocity(N_ELEMENTS: usize) -> (Vec, Vec)\n{\n\t// TODO: distribute velocity according to temperature\n\tlet mut pos = vec![Float4::new(1f32,1f32,1f32,0f32); N_ELEMENTS];\n\tlet mut vel = vec![Float4::new(1f32,1f32,0f32,0f32); N_ELEMENTS];\n\n   \tlet between = Range::new(0f32, 1f32);\n   \tlet exp = Exp::new(1.0f64);\n\n\tlet mut rng = rand::thread_rng();\n\tfor i in 0..N_ELEMENTS {\n\t\tpos[i] = Float4::new(\n\t\t\tbetween.ind_sample(&mut rng),\n\t\t\tbetween.ind_sample(&mut rng),\n\t\t\tbetween.ind_sample(&mut rng),\n\t\t\tbetween.ind_sample(&mut rng)\n\t\t);\n\t\tvel[i] = Float4::new(\n\t\t\texp.ind_sample(&mut rng) as f32,\n\t\t\texp.ind_sample(&mut rng) as f32,\n\t\t\texp.ind_sample(&mut rng) as f32,\n\t\t\texp.ind_sample(&mut rng) as f32\n\t\t);\n\t}\n\n\t(pos, vel)\n}\n\nfn opencl_worker(state: Arc>)\n{\n    // Number of results to print out:\n    const RESULTS_TO_PRINT: usize = 20;\n\n\tconst N_ELEMENTS: usize = 10000;\n\n\tlet SIM_SETTINGS: SimulationContext = SimulationContext{\n\t\t\tdt : 1e-4,\n\t\t\tbox_min : Float4::new(0f32,0f32,0f32,0f32),\n\t\t\tbox_max : Float4::new(1f32,1f32,1f32,1f32)\n\t};\n\n    // Create an empty vec and buffer (the quick way) for results. Note that\n    // there is no need to initialize the buffer as we did above because we\n    // will be writing to the entire buffer first thing, overwriting any junk\n    // data that may be there.\n\n    loop {\n        run_computation();\n        \n        //state.lock().and_then(|mut s| {\n        //\ts.points.truncate(0);\n        //\ts.points.extend_from_slice(pos_result.as_slice());\n        //    Ok(())\n        //});\n    }\n}\n\nfn main() {\n    gtk::init().unwrap_or_else(|_| panic!(\"Failed to initialize GTK.\"));\n    println!(\"Major: {}, Minor: {}\", gtk::get_major_version(), gtk::get_minor_version());\n\n    let window = RenderingAPITestWindow::new(800, 500);\n    window.exit_on_close();\n\n    let shared_state = window.state.clone();\n\n    match thread::Builder::new()\n    \t\t.name(\"child1\".to_string())\n    \t\t.spawn(move || {opencl_worker(shared_state) })\n    {\n    \tOk(_) => gtk::main(),\n    \t_ => println!(\"Forking OpenCL thread failed!\"),\n    }\n}\n"}}}`
TRACE:rls::server: Parsed message `RawMessage { method: "textDocument/didOpen", id: None, params: Object({"textDocument": Object({"languageId": String("rust"), "text": String("#![cfg_attr(not(feature = \"gtk_3_10\"), allow(unused_variables, unused_mut))]\n\nextern crate gtk;\nextern crate cairo;\nextern crate ocl;\nextern crate rand;\nextern crate compute_kernel;\n\nuse ocl::{util, ProQue, Buffer, MemFlags};\nuse ocl::prm::Float4;\n\nuse std::rc::Rc;\nuse std::cmp;\nuse std::sync::{Mutex, Arc};\nuse gtk::traits::*;\nuse gtk::Inhibit;\nuse cairo::{Context, RectangleInt};\nuse std::{thread, time, f64};\nuse std::io::prelude::*;\nuse std::fs::File;\n\nuse rand::Rng;\nuse rand::distributions::{IndependentSample, Range, Exp};\n\nuse compute_kernel::run_computation;\n\nstruct RenderingAPITestWindow {\n    window: gtk::Window,\n    drawing_area: gtk::DrawingArea,\n    state: Arc>,\n}\n\nstruct RenderingState {\n    width: i32,\n    height: i32,\n    points: Vec\n}\n\n#[derive(Debug,Copy,Clone,Default)]\nstruct SimulationContext\n{\n\tdt : f32,\n\tbox_min : Float4,\n\tbox_max : Float4\n}\n\nimpl PartialEq for SimulationContext {\n    fn eq(&self, other: &SimulationContext) -> bool {\n        self.dt == other.dt &&\n        self.box_min == other.box_min &&\n        self.box_max == other.box_max\n    }\n}\n\nunsafe impl ocl::OclPrm for SimulationContext{}\n\n\nimpl RenderingAPITestWindow {\n    fn new(width: i32, height: i32) -> Rc {\n        let window = gtk::Window::new(gtk::WindowType::Toplevel);\n        let drawing_area = gtk::DrawingArea::new();\n        drawing_area.set_size_request(width, height);\n        window.set_title(\"Cairo API test\");\n        window.add(&drawing_area);\n\n        let instance = Rc::new(RenderingAPITestWindow {\n            window: window,\n            drawing_area: drawing_area,\n            state: Arc::new(Mutex::new(RenderingState{\n                width: width,\n                height: height,\n                points: vec!()\n            })),\n        });\n\n        {\n            let instance2 = instance.clone();\n            instance.drawing_area.connect_draw(move |widget, cairo_context| {\n                instance2.state.lock().unwrap().on_draw(cairo_context);\n                instance2.drawing_area.queue_draw();\n                Inhibit(true)\n            });\n        }\n        {\n            let instance2 = instance.clone();\n            instance.drawing_area.connect_size_allocate(move |widget, rect| {\n                instance2.state.lock().unwrap().on_size_allocate(rect);\n            });\n        }\n        instance.window.show_all();\n        instance\n    }\n\n    fn exit_on_close(&self) {\n        self.window.connect_delete_event(|_, _| {\n            gtk::main_quit();\n            Inhibit(true)\n        });\n    }\n}\n\nimpl RenderingState {\n\tfn draw_box(&self, cairo_ctx: &Context) {\n\t\tcairo_ctx.set_line_width(5e-3);\n    \tcairo_ctx.translate(0.0,0.0);\n    \tcairo_ctx.rectangle(0.,0.,1.,1.);\n    \tcairo_ctx.stroke();\n    }\n\n\tfn draw_discs(&self, cairo_ctx: &Context) {\n\t    cairo_ctx.set_source_rgb(0.1, 0.1, 0.1);\n\t    for pt in self.points.iter() {\n\t    \tlet x = pt[0] as f64;\n\t    \tlet y = pt[1] as f64;\n\t    \tcairo_ctx.arc(x, y, 5e-3, 0.0, 2.0 * f64::consts::PI);\n\t    \tcairo_ctx.fill();\n\t    }\n    }\n\n    fn on_draw(&self, cairo_ctx: &Context) {\n        let text = format!(\"--- The current state of simulation --- {} points\", self.points.len());\n        cairo_ctx.save();\n        //cairo_ctx.move_to(50.0, (self.height as f64) * 0.5);\n        //cairo_ctx.set_font_size(18.0);\n        //cairo_ctx.show_text(text.as_str());\n        let SCALE = cmp::min(self.width, self.height) as f64;\n        cairo_ctx.translate(0.5*(self.width as f64 - SCALE), 0.5 *(self.height as f64 - SCALE));\n\n        cairo_ctx.scale(SCALE, SCALE);\n        self.draw_box(cairo_ctx);\n        self.draw_discs(cairo_ctx);\n\n        cairo_ctx.restore();\n    }\n\n\n    fn on_size_allocate(&mut self, rect: >k::Rectangle) {\n        self.width = rect.width as i32;\n        self.height = rect.height as i32;\n    }\n}\nfn MakeInitialPositionAndVelocity(N_ELEMENTS: usize) -> (Vec, Vec)\n{\n\t// TODO: distribute velocity according to temperature\n\tlet mut pos = vec![Float4::new(1f32,1f32,1f32,0f32); N_ELEMENTS];\n\tlet mut vel = vec![Float4::new(1f32,1f32,0f32,0f32); N_ELEMENTS];\n\n   \tlet between = Range::new(0f32, 1f32);\n   \tlet exp = Exp::new(1.0f64);\n\n\tlet mut rng = rand::thread_rng();\n\tfor i in 0..N_ELEMENTS {\n\t\tpos[i] = Float4::new(\n\t\t\tbetween.ind_sample(&mut rng),\n\t\t\tbetween.ind_sample(&mut rng),\n\t\t\tbetween.ind_sample(&mut rng),\n\t\t\tbetween.ind_sample(&mut rng)\n\t\t);\n\t\tvel[i] = Float4::new(\n\t\t\texp.ind_sample(&mut rng) as f32,\n\t\t\texp.ind_sample(&mut rng) as f32,\n\t\t\texp.ind_sample(&mut rng) as f32,\n\t\t\texp.ind_sample(&mut rng) as f32\n\t\t);\n\t}\n\n\t(pos, vel)\n}\n\nfn opencl_worker(state: Arc>)\n{\n    // Number of results to print out:\n    const RESULTS_TO_PRINT: usize = 20;\n\n\tconst N_ELEMENTS: usize = 10000;\n\n\tlet SIM_SETTINGS: SimulationContext = SimulationContext{\n\t\t\tdt : 1e-4,\n\t\t\tbox_min : Float4::new(0f32,0f32,0f32,0f32),\n\t\t\tbox_max : Float4::new(1f32,1f32,1f32,1f32)\n\t};\n\n    // Create an empty vec and buffer (the quick way) for results. Note that\n    // there is no need to initialize the buffer as we did above because we\n    // will be writing to the entire buffer first thing, overwriting any junk\n    // data that may be there.\n\n    loop {\n        run_computation();\n        \n        //state.lock().and_then(|mut s| {\n        //\ts.points.truncate(0);\n        //\ts.points.extend_from_slice(pos_result.as_slice());\n        //    Ok(())\n        //});\n    }\n}\n\nfn main() {\n    gtk::init().unwrap_or_else(|_| panic!(\"Failed to initialize GTK.\"));\n    println!(\"Major: {}, Minor: {}\", gtk::get_major_version(), gtk::get_minor_version());\n\n    let window = RenderingAPITestWindow::new(800, 500);\n    window.exit_on_close();\n\n    let shared_state = window.state.clone();\n\n    match thread::Builder::new()\n    \t\t.name(\"child1\".to_string())\n    \t\t.spawn(move || {opencl_worker(shared_state) })\n    {\n    \tOk(_) => gtk::main(),\n    \t_ => println!(\"Forking OpenCL thread failed!\"),\n    }\n}\n"), "uri": String("file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/src/main.rs"), "version": Number(PosInt(1))})}) }`
TRACE:rls::server: Handling `textDocument/didOpen`
TRACE:rls::actions::notifications: on_open: "file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/src/main.rs"
TRACE:rls::build: run_build, "/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles" Cargo
TRACE:rls::build: running build
TRACE:rls::build::cargo: root manifest_path: "/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/Cargo.toml"
TRACE:rls::build::cargo: Cargo compilation options:
CargoOptions { package: [], target: None, lib: false, bin: [], bins: false, all: true, exclude: [], all_features: false, no_default_features: false, features: [] }
TRACE:rls::config: root manifest_path: "/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/Cargo.toml"
TRACE:rls::server::io: reading: 38 bytes
TRACE:rls::server: Read message `{"jsonrpc":"2.0","id":1,"result":null}`
TRACE:rls::server::io: reading: 38 bytes
TRACE:rls::server: Read message `{"jsonrpc":"2.0","id":2,"result":null}`
TRACE:rls::server::io: reading: 275 bytes
TRACE:rls::server: Read message `{"jsonrpc":"2.0","id":1,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/src/main.rs"},"range":{"start":{"line":6,"character":28},"end":{"line":6,"character":28}},"context":{"diagnostics":[]}}}`
TRACE:rls::server: Parsed message `RawMessage { method: "textDocument/codeAction", id: Some(Num(1)), params: Object({"context": Object({"diagnostics": Array([])}), "range": Object({"end": Object({"character": Number(PosInt(28)), "line": Number(PosInt(6))}), "start": Object({"character": Number(PosInt(28)), "line": Number(PosInt(6))})}), "textDocument": Object({"uri": String("file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/src/main.rs")})}) }`
TRACE:rls::server: Handling `textDocument/codeAction`
TRACE:rls::actions::requests: code_action CodeActionParams { text_document: TextDocumentIdentifier { uri: "file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/src/main.rs" }, range: Range { start: Position { line: 6, character: 28 }, end: Position { line: 6, character: 28 } }, context: CodeActionContext { diagnostics: [] } }
TRACE:rls::server::io: response: "Content-Length: 36\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":[]}"
TRACE:rls::build::cargo: exec: compute_kernel
TRACE:rls::build::cargo: rustc not intercepted - compute_kernel
{"message":"unused import: `c_int`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"sync/PrivateProg/gpgpu/stochastic_particles/compute_kernel/lib.rs","byte_start":53,"byte_end":58,"line_start":4,"line_end":4,"column_start":12,"column_end":17,"is_primary":true,"text":[{"text":"use libc::{c_int};","highlight_start":12,"highlight_end":17}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[{"message":"#[warn(unused_imports)] on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":null}
{"message":"unused import: `ndarray::prelude::*;`","code":{"code":"unused_imports","explanation":null},"level":"warning","spans":[{"file_name":"sync/PrivateProg/gpgpu/stochastic_particles/compute_kernel/lib.rs","byte_start":65,"byte_end":85,"line_start":5,"line_end":5,"column_start":5,"column_end":25,"is_primary":true,"text":[{"text":"use ndarray::prelude::*;","highlight_start":5,"highlight_end":25}],"label":null,"suggested_replacement":null,"expansion":null}],"children":[{"message":"#[warn(unused_imports)] on by default","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":null}
{"message":"missing field `positions` in initializer of `root::SimulationState`","code":{"code":"E0063","explanation":"\nThis error indicates that during an attempt to build a struct or struct-like\nenum variant, one of the fields was not provided. Erroneous code example:\n\n```compile_fail,E0063\nstruct Foo {\n    x: i32,\n    y: i32,\n}\n\nfn main() {\n    let x = Foo { x: 0 }; // error: missing field: `y`\n}\n```\n\nEach field should be specified exactly once. Example:\n\n```\nstruct Foo {\n    x: i32,\n    y: i32,\n}\n\nfn main() {\n    let x = Foo { x: 0, y: 0 }; // ok!\n}\n```\n"},"level":"error","spans":[{"file_name":"sync/PrivateProg/gpgpu/stochastic_particles/compute_kernel/lib.rs","byte_start":745,"byte_end":766,"line_start":36,"line_end":36,"column_start":21,"column_end":42,"is_primary":true,"text":[{"text":"    let mut state = root::SimulationState {","highlight_start":21,"highlight_end":42}],"label":"missing `positions`","suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}
{"message":"this function takes 2 parameters but 0 parameters were supplied","code":{"code":"E0061","explanation":"\nThe number of arguments passed to a function must match the number of arguments\nspecified in the function signature.\n\nFor example, a function like:\n\n```\nfn f(a: u16, b: &str) {}\n```\n\nMust always be called with exactly two arguments, e.g. `f(2, \"test\")`.\n\nNote that Rust does not have a notion of optional function arguments or\nvariadic functions (except for its C-FFI).\n"},"level":"error","spans":[{"file_name":"/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/target/rls/debug/build/compute_kernel-1cd9ab9c1a8748ec/out/bindings.rs","byte_start":15228,"byte_end":15368,"line_start":5,"line_end":5,"column_start":2,"column_end":142,"is_primary":false,"text":[{"text":" pub fn RunDemo ( settings : * const root :: SimulationSettings , state : * mut root :: SimulationState , ) -> :: std :: os :: raw :: c_int ; ","highlight_start":2,"highlight_end":142}],"label":"defined here","suggested_replacement":null,"expansion":null},{"file_name":"sync/PrivateProg/gpgpu/stochastic_particles/compute_kernel/lib.rs","byte_start":798,"byte_end":813,"line_start":40,"line_end":40,"column_start":9,"column_end":24,"is_primary":true,"text":[{"text":"        root::RunDemo() == 0","highlight_start":9,"highlight_end":24}],"label":"expected 2 parameters","suggested_replacement":null,"expansion":null}],"children":[],"rendered":null}
{"message":"aborting due to 2 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":null}
INFO:rls::build::cargo: cargo failed
cause: Could not compile `compute_kernel`.
stdout: 
TRACE:rls::server::io: response: "Content-Length: 72\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"rustDocument/diagnosticsBegin\",\"params\":null}"
TRACE:rls::actions::post_build: build - Error
TRACE:rls::server::io: response: "Content-Length: 70\r\n\r\n{\"jsonrpc\":\"2.0\",\"method\":\"rustDocument/diagnosticsEnd\",\"params\":null}"
TRACE:rls::server::io: reading: 161 bytes
TRACE:rls::server: Read message `{"jsonrpc":"2.0","method":"textDocument/didClose","params":{"textDocument":{"uri":"file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/src/main.rs"}}}`
TRACE:rls::server: Parsed message `RawMessage { method: "textDocument/didClose", id: None, params: Object({"textDocument": Object({"uri": String("file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/src/main.rs")})}) }`
TRACE:rls::server: Handling `textDocument/didClose`
DEBUG:rls::server: Method not found: textDocument/didClose

compute_kernel is the c++ library, which is built and wrapped with the build.rs file.

This is my main Cargo.toml:

[package]
name = "stochastic_particles"
version = "0.1.0"

[dependencies]
ocl = "0.13"
rand = "0.3"
compute_kernel = { path = "compute_kernel", version = "*" }

[dependencies.gtk]
version = "0.1"
features = ["v3_10"]

[dependencies.cairo-rs]
version = "0.1"

@oleid since we're having this remote co-debugging session already :smile: would you mind trying to get the library to compiling state, then reload the vscode with the workspace mode on? It may be possible that the first run is crucial for the mode to work later and I'd like to verify that hypothesis here

Indeed, if the project compiles successfully, I get warnings in the editor.

@oleid even after you subsequently modify build.rs or other files, after the initial successful compilation?

Nope, adding an error, the editor doesn't highlight the newly introduced problem. I added something like

let a = 3;
a = 4;

And the last few lines of the log file are:

TRACE:rls::actions: start: 8, end: 9
TRACE:rls::actions::requests: hover: Span { file: "/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/compute_kernel/lib.rs", range: Range { row_start: Row(24, PhantomData), row_end: Row(24, PhantomData), col_start: Column(8, PhantomData), col_end: Column(9, PhantomData) } }
TRACE:rls::server::io: response: "Content-Length: 63\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":33,\"result\":{\"contents\":[],\"range\":null}}"
TRACE:rls::server::io: reading: 213 bytes
TRACE:rls::server: Read message `{"jsonrpc":"2.0","id":34,"method":"textDocument/hover","params":{"textDocument":{"uri":"file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/compute_kernel/lib.rs"},"position":{"line":24,"character":9}}}`
TRACE:rls::server: Parsed message `RawMessage { method: "textDocument/hover", id: Some(Num(34)), params: Object({"position": Object({"character": Number(PosInt(9)), "line": Number(PosInt(24))}), "textDocument": Object({"uri": String("file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/compute_kernel/lib.rs")})}) }`
TRACE:rls::server: Handling `textDocument/hover`
TRACE:rls::actions: convert_pos_to_span: "/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/compute_kernel/lib.rs" Position { line: 24, character: 9 }
TRACE:rls::actions: line: `    a = 4;
`
TRACE:rls::actions: start: 8, end: 9
TRACE:rls::actions::requests: hover: Span { file: "/home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/compute_kernel/lib.rs", range: Range { row_start: Row(24, PhantomData), row_end: Row(24, PhantomData), col_start: Column(8, PhantomData), col_end: Column(9, PhantomData) } }
TRACE:rls::server::io: response: "Content-Length: 63\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":34,\"result\":{\"contents\":[],\"range\":null}}"
TRACE:rls::server::io: reading: 161 bytes
TRACE:rls::server: Read message `{"jsonrpc":"2.0","method":"textDocument/didClose","params":{"textDocument":{"uri":"file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/src/main.rs"}}}`
TRACE:rls::server: Parsed message `RawMessage { method: "textDocument/didClose", id: None, params: Object({"textDocument": Object({"uri": String("file:///home/oleid/sync/PrivateProg/gpgpu/stochastic_particles/src/main.rs")})}) }`
TRACE:rls::server: Handling `textDocument/didClose`
DEBUG:rls::server: Method not found: textDocument/didClose

EDIT:
Just checked: Some other project, which doesn't compile successfully and doesn't include a build.rs file has proper error highlighting.

same issue here. with build.rs, it properly reports issues and errors when first load. after make any changes, the rls status icon spins forever. the workspace_mode and unstable_features make no difference.

Workspace mode has been turned on as the default for quite some time now and this should Just Work^tm. Do you still have any issues with that?

When build.rs has a syntax error, the whole Cargo.toml is highlighted with no useful message.
Also it does not format build.rs even if it compiles.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mcclure picture mcclure  路  4Comments

simobiggs picture simobiggs  路  4Comments

byteshiva picture byteshiva  路  4Comments

iBeizsley picture iBeizsley  路  3Comments

japert picture japert  路  4Comments