Skip to content

ICE: borrowck/check_loans: assertion failed: self.bccx.region_scope_tree.scopes_intersect(...) #64453

Closed
@flippedoffbit

Description

@flippedoffbit

err :

D:\work\rust\web_api_rust>cargo build
   Compiling web_api_rust v0.1.0 (D:\work\rust\web_api_rust)
warning: unused variable: `x`
  --> src\response_builder.rs:13:20
   |
13 | pub fn file_server(x:&str) {
   |                    ^ help: consider prefixing with an underscore: `_x`
   |
   = note: #[warn(unused_variables)] on by default

thread 'rustc' panicked at 'assertion failed: self.bccx.region_scope_tree.scopes_intersect(old_loan.kill_scope,      
                                             new_loan.kill_scope)', src\librustc_borrowck\borrowck\check_loans.rs:493:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports    

note: rustc 1.37.0 (eae3437df 2019-08-13) running on x86_64-pc-windows-msvc

note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin

note: some of the compiler flags provided by cargo are hidden

error: Could not compile `web_api_rust`.

code i was compiling :

main.rs

use std::env;
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::fs::File;

mod request_proc;
mod thread_pool;
mod response_builder;
mod misc;
fn main() {
    //Getting thread pool size from environment variable (to be set by user)
    //using 2 threads per route as default in case variable is not set
    //this can be hardcoded or read from a file , hence optional
    let pool_size: usize = match env::var("THREAD_POOL_SIZE_FOR_EACH_ROUTE") {
        // value of 'THREAD_POOL_SIZE_FOR_EACH_ROUTE' is returned as string that needs to
        // be parsed into usize ,in case of errors we are using default values
        Ok(var) => match var.parse() {
            Ok(val) => val,
            Err(_err) => {
                println!("> Parse Error :{}'THREAD_POOL_SIZE_FOR_EACH_ROUTE' can only have unsigned integer Value",_err);
                println!("> using default value for THREAD_POOL_SIZE_FOR_EACH_ROUTE");
                2
            }
        },
        Err(_s) => 2,
    };

    //Getting listening port  from environment variable (to be set by user)
    //using 0.0.0.0:7878 as defaut port in case variable is not set
    //this can be hardcoded or read from a file , hence optional
    let port = match env::var("RUST_SERVER_PORT") {
        Ok(var) => var,
        Err(_s) => {
            println!(
                "> failed at reading :{} 'RUST_SERVER_PORT' using default",
                _s
            );
            "0.0.0.0:7878".to_string()
        }
    };

    //spitting basic chatter to notify user that application is running and reporting settings being used
    // again totally optional but helpful
    println!("> edit 'RUST_SERVER_PORT' environment variable to change server listening port");
    println!(
        "> edit 'THREAD_POOL_SIZE_FOR_EACH_ROUTE' environment variable to change thread pool size"
    );
    println!(
        "> Using {} as thread pool size for each route \n> using {} as port",
        pool_size, port
    );

    // binding a listner on our designated port for listening for Tcp requests
    // binding to a port might fail in case if we are bining to port that needs
    // elivated privelleges to access or port is busy(being used by another application)
    // or port/Ip are unavailable or wrong , its a good idea to report details to user
    let listner = match TcpListener::bind(&port) {
        Ok(val) => val,
        Err(err) => panic!("> Binding failure : {}", err),
    };

    //declaring string pattern for all routes
    let home_route = "/".to_string();
    let route_2 = "/r2".to_string();
    let route_3 = "/r3".to_string();
    //making thread pool for each route
    let home_pool = thread_pool::ThreadPool::new(pool_size);
    let route2pool = thread_pool::ThreadPool::new(pool_size);
    let route3pool = thread_pool::ThreadPool::new(pool_size);
    //buffer to store request
    let mut req_buffer = [0; 512];
    let test_file = fopen("x.html".to_string());
    // listening to incoming requests in an infinite loop
    // listner.incoming() waits until a request comes in
    // and returns a 'std::result::Result<std::net::TcpStream, std::io::Error>' whenever a request drops
    // which should be unwrapped/matched to get 'std::net::TcpStream' which contains our Tcp request
    // and acts a portal to send back the response for incoming Tcp request
    // assume 'std::net::TcpStream' as a special envelope that is used to recieve Tcp request
    // and send Tcp respose
    for stream in listner.incoming() {
        // getting actual Tcp::stream from Result type given by listener
        let mut stream = match stream {
            Ok(val) => val,
            Err(_err) => {
                println!("> Failed at Unwrapping Stream :{}", _err);
                continue;
            }
        };

        // stream does not returns Tcp request directly , instead it writes it into
        // empty byte array we provid
        match stream.read(&mut req_buffer) {
            Ok(_val) => {}
            Err(err) => println!("> Failed at reading Request into buffer :{}", err),
        };

        // parsing request (which is stored in req_buffer) from [u8] to more readable and usable data structure
        let request =
            request_proc::parse_request(&mut String::from_utf8_lossy(&req_buffer).to_string())
                .unwrap();
        // using match as case-switch to send requests to be executed in different thread-pools
        match request {
            // compairing refrance to path inside request to routes and
            // accordingly execute appropriate functions in designated thread pools
            ref path if path.path == home_route => home_pool.execute(|| home(stream, request,&test_file)),
            ref path if path.path == route_2 => route2pool.execute(|| route1(stream)),
            ref path if path.path == route_3 => route3pool.execute(|| route2(stream)),

            // _ handles all the cases that cannot be handled in our defined paths
            // since we dont have what user is asking for so according to internet standard
            // we will return Error 404
            // we will send response by stream.write(b"some response") method in stream
            // response is always written as &[u8] (refrance to byte array)
            // stream.write returns an Result<usize> that should be checked as there is a real
            // possibility of respose writing failure
            // if everything goes well it returns number bytes sent as response (which is useless in most cases)
            _ => err(stream),
        }
    }
}

fn home(mut stream: TcpStream, request: request_proc::Request,fdata:&String) {
    println!("{}", request.to_string());
    match stream.write(format!("HTTP/1.1 200 OK \nContent-Type: text/html \r\n\r\n  {} ",fdata).as_bytes()){
        Err(err) => println!("> write error : {}", err),
        Ok(_val) => {}
    }
}

fn route1(mut stream: TcpStream) {
    match stream
        .write("HTTP/1.1 200 OK \nContent-Type: text/html \r\n\r\n hello from route 1".as_bytes())
    {
        Err(err) => println!("> write error : {}", err),
        Ok(_val) => {}
    }
}

fn route2(mut stream: TcpStream) {
    match stream
        .write("HTTP/1.1 200 OK \nContent-Type: text/html \r\n\r\n hello from route 2".as_bytes())
    {
        Err(err) => println!("> write error : {}", err),
        Ok(_val) => {}
    }
}

fn err(mut stream: TcpStream) {
    let res = "Error 404 , not found".as_bytes().to_vec();
    let reponse = response_builder::response_builder_text(response_builder::Text::Html,&res);
    match stream.write(reponse.as_bytes()) {
        Err(err) => println!("> write error : {}", err),
        Ok(_val) => {}
    }
}
// set env var for speed optimization during release build <RUSTFLAGS="-C target-cpu=native">

#[inline(always)] 
fn fopen(fname :String) -> String{
    //let mut buffer :Vec<u8>= Vec::with_capacity(5000);
    let mut buffer : String = String::new();
    let nname = &fname[1..];
    let k = File::open(nname);
    
    match k {
    Err(_e) => { buffer = format!("{}",_e).to_string()}//"ERROR 404 NOT FOUND".to_string().into_bytes(); },
    Ok(mut fread) => {                   
        match fread.read_to_string(&mut buffer) {
            Err(_err) =>{ buffer = "UNABLE TO READ FILE".to_string() } 
            Ok(_n) => {
                println!("read {} bytes of data ", _n)
            }
        }
    }
}

    buffer
}

rest code lives at https://github.com/acnologia000/rust_web_api_example

Metadata

Metadata

Assignees

Labels

A-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions