-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ICE in rustc_borrowck/src/region_infer #114907
Comments
@sjeohp The code snippet is incomplete: is there a repository available that we could try, to reproduce the error? If not, could you at least add the full |
use tungstenite::handshake::server::{Response, ErrorResponse};
fn accept_connection(stream: TcpStream, config: rustls::server::ServerConfig) -> Result<Socket> {
let mut conn = rustls::server::ServerConnection::new(std::sync::Arc::new(config.clone()))?;
let tlsstream = rustls::StreamOwned::new(conn, stream.try_clone()?);
if let Ok(ws) = match tungstenite::accept_hdr_with_config(tlsstream, |req, res| -> std::result::Result<Response, ErrorResponse> {
let callback = |req, res| -> std::result::Result<tungstenite::handshake::server::Response, tungstenite::handshake::server::ErrorResponse> {
dbg!(&req);
dbg!(&res);
Ok(res)
};
if let Ok(ws) = match tungstenite::accept_hdr_with_config(tlsstream, callback, None) {
Err(HandshakeError::Interrupted(midhandshake)) => {
info!(
"Handshake interrupted with peer {} - waiting to try again.",
peer_addr
);
Ok(Socket::Interrupted(midhandshake))
}
Err(e) => {
error!("Error accepting secure websocket connection: {e}");
Err(e)?
}
Ok(ws) => Ok(Socket::SecureWebSocket(ws)),
}
}
} |
@sjeohp This is still incomplete and doesn't parse. Do you have a repository where the issue can be reproduced? |
No repo. You can make it parse pretty easily. I am not a rustc expert but I believe the issue was with the callback. |
Here's a small (but not minimal yet) working repro: use std::io::{self, Read, Write};
struct S;
impl Read for S {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
todo!()
}
}
impl Write for S {
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
todo!()
}
fn flush(&mut self) -> io::Result<()> {
todo!()
}
}
fn main() {
let s = S;
tungstenite::accept_hdr(s, |_, _| {
let callback = |_, _| {
todo!()
};
tungstenite::accept_hdr(s, callback);
todo!()
});
} and with that we can finally bisect, to
I'll minimize |
use std::{
error, fmt,
io::{self, Cursor, Read, Write},
marker::PhantomData,
result,
};
struct S;
impl Read for S {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
todo!()
}
}
impl Write for S {
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
todo!()
}
fn flush(&mut self) -> io::Result<()> {
todo!()
}
}
pub type Result<T, E = Error> = result::Result<T, E>;
pub enum Error {}
struct Request;
struct Response;
pub trait Callback {}
impl<F> Callback for F where F: FnOnce(&Request, Response) -> Result<Response> {}
pub enum HandshakeError<Role: HandshakeRole> {
Interrupted(MidHandshake<Role>),
}
impl<Role: HandshakeRole> fmt::Debug for HandshakeError<Role> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
todo!()
}
}
impl<Role: HandshakeRole> fmt::Display for HandshakeError<Role> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
todo!()
}
}
impl<Role: HandshakeRole> error::Error for HandshakeError<Role> {}
pub trait HandshakeRole {
type InternalStream: Read + Write;
}
pub struct ServerHandshake<S, C> {
_marker: PhantomData<(S, C)>,
}
impl<S: Read + Write, C: Callback> HandshakeRole for ServerHandshake<S, C> {
type InternalStream = S;
}
pub struct MidHandshake<Role: HandshakeRole> {
machine: HandshakeMachine<Role::InternalStream>,
}
impl<Role: HandshakeRole> MidHandshake<Role> {
pub fn handshake(mut self) -> Result<(), HandshakeError<Role>> {
todo!()
}
}
pub struct HandshakeMachine<Stream> {
stream: Stream,
state: io::Cursor<Vec<u8>>,
}
fn accept<C: Callback>(callback: C) -> Result<(), HandshakeError<ServerHandshake<S, C>>> {
todo!()
}
fn main() {
accept(|_, _| {
let callback = |_, _| todo!();
accept(callback);
todo!()
});
} |
Probably not yet an MCVE and could be further simplified, but getting close. use std::marker::PhantomData;
trait Callback {}
impl<F> Callback for F where F: FnOnce(&()) {} // arg needs to be a ref
trait HandshakeRole {
type InternalStream;
}
struct ServerHandshake<C> {
_marker: PhantomData<C>,
}
impl<C: Callback> HandshakeRole for ServerHandshake<C> {
type InternalStream = ();
}
struct HandshakeError<Role: HandshakeRole> {
_machine: HandshakeMachine<Role::InternalStream>,
}
struct HandshakeMachine<S> {
_stream: S,
_state: TypeWithDrop, // needs a Drop impl
}
struct TypeWithDrop;
impl Drop for TypeWithDrop {
fn drop(&mut self) {
}
}
fn accept<C: Callback>(_callback: C) -> HandshakeError<ServerHandshake<C>> {
todo!()
}
fn main() {
let callback = |_| {};
accept(callback);
} |
trait Role<C> {
type I;
}
struct H;
impl<C: Fn(&())> Role<C> for H {
type I = ();
}
struct Machine<C, R: Role<C>> {
_i: R::I,
}
impl<C, R: Role<C>> Drop for Machine<C, R> {
fn drop(&mut self) {}
}
fn accept<C: Fn(&()), R: Role<C>>(_callback: C) -> Machine<C, R> {
todo!()
}
fn main() {
let callback = |_| {};
accept::<_, H>(callback);
} |
1.62 error -> 1.63 error + ice |
WG-prioritization assigning priority (Zulip discussion). @rustbot label -I-prioritize +P-medium -E-needs-mcve |
Code
Does not happen with this callback:
Meta
rustc --version --verbose
:Error output
The text was updated successfully, but these errors were encountered: