Question:
Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to

per_local.insert(local); } } <del> cx.per_local[IsNotPromotable].insert(local); </del> <ins> cx.per_local[IsNotConst].insert(local); </ins> } LocalKind::Var if mode == Mode::Fn => {


Question:
Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to

} LocalKind::Temp if !temps[local].is_promotable() => { <del> cx.per_local[IsNotPromotable].insert(local); </del> <ins> cx.per_local[IsNotConst].insert(local); </ins> } _ => {}


Question:
Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to

} } <del> // Ensure the `IsNotPromotable` qualification is preserved. </del> <ins> // Ensure the `IsNotConst` qualification is preserved. </ins> // NOTE(eddyb) this is actually unnecessary right now, as // we never replace the local's qualif, but we might in // the future, and so it serves to catch changes that unset


Question:
Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to

// be replaced with calling `insert` to re-set the bit). if kind == LocalKind::Temp { if !self.temp_promotion_state[index].is_promotable() { <del> assert!(self.cx.per_local[IsNotPromotable].contains(index)); </del> <ins> assert!(self.cx.per_local[IsNotConst].contains(index)); </ins> } } }


Question:
Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to

<ins> // only-x86_64 #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; unsafe fn pclmul(a: __m128i, b: __m128i) -> __m128i { let imm8 = 3; _mm_clmulepi64_si128(a, b, imm8) //~ ERROR argument 3 is required to be a constant } fn main() {} </ins>


Question:
Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to

<ins> error: argument 3 is required to be a constant --> $DIR/const_arg_local.rs:10:5 | LL |     _mm_clmulepi64_si128(a, b, imm8) |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error </ins>


Question:
Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to

<ins> // only-x86_64 #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; unsafe fn pclmul(a: __m128i, b: __m128i) -> __m128i { _mm_clmulepi64_si128(a, b, *&mut 42) //~ ERROR argument 3 is required to be a constant } fn main() {} </ins>


Question:
Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to

<ins> error: argument 3 is required to be a constant --> $DIR/const_arg_promotable.rs:9:5 | LL |     _mm_clmulepi64_si128(a, b, *&mut 42) |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error </ins>


Question:
Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to

<ins> // only-x86_64 #[cfg(target_arch = "x86")] use std::arch::x86::*; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; unsafe fn pclmul(a: __m128i, b: __m128i, imm8: i32) -> __m128i { _mm_clmulepi64_si128(a, b, imm8) //~ ERROR argument 3 is required to be a constant } fn main() {} </ins>


Question:
Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to

<ins> error: argument 3 is required to be a constant --> $DIR/const_arg_wrapper.rs:9:5 | LL |     _mm_clmulepi64_si128(a, b, imm8) |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error </ins>


Question:
Discovered a compiler panic, thought it might relate to , but was told to post a new issue. In minimizing, it seems the generic types are required to trigger the panic, I was unable to reproduce when inlining t7p or t8n. This code panics on 1.33 - 1.35, but does not panic on 1.32 (): On 1.32: On 1.35 nightly: --Bryan
triage: P-high. Removing nominated tag since there's little to discuss beyond its P-highness. (The fact its unassigned will be discussed regardless of nomination state.)
Bisection points to i.e. as the culprit. The backtrace in that commit looks very similar to the one reported here, and the parent commit () gives the same compiler error.
I spent some time looking at this a few weeks ago but did not manage to find anything conclusive. At this point I'm going to be taking a break for a few months, so I am unassigning myself from this issue.
triage: assigning self.
triage: downgrading to P-medium; this does not warrant revisiting every week.
I was able to minify it a bit further:
Triage: It's no longer ICE with the latest nightly.

<ins> // check-pass trait Mirror { type Other; } #[derive(Debug)] struct Even(usize); struct Odd; impl Mirror for Even { type Other = Odd; } impl Mirror for Odd { type Other = Even; } trait Dyn<T: Mirror>: AsRef<<T as Mirror>::Other> {} impl Dyn<Odd> for Even {} impl AsRef<Even> for Even { fn as_ref(&self) -> &Even { self } } fn code<T: Mirror>(d: &dyn Dyn<T>) -> &T::Other { d.as_ref() } fn main() { println!("{:?}", code(&Even(22))); } </ins>


Question:
Discovered a compiler panic, thought it might relate to , but was told to post a new issue. In minimizing, it seems the generic types are required to trigger the panic, I was unable to reproduce when inlining t7p or t8n. This code panics on 1.33 - 1.35, but does not panic on 1.32 (): On 1.32: On 1.35 nightly: --Bryan
triage: P-high. Removing nominated tag since there's little to discuss beyond its P-highness. (The fact its unassigned will be discussed regardless of nomination state.)
Bisection points to i.e. as the culprit. The backtrace in that commit looks very similar to the one reported here, and the parent commit () gives the same compiler error.
I spent some time looking at this a few weeks ago but did not manage to find anything conclusive. At this point I'm going to be taking a break for a few months, so I am unassigning myself from this issue.
triage: assigning self.
triage: downgrading to P-medium; this does not warrant revisiting every week.
I was able to minify it a bit further:
Triage: It's no longer ICE with the latest nightly.

<ins> fn t7p<A, B, C>(f: impl Fn(B) -> C, g: impl Fn(A) -> B) -> impl Fn(A) -> C { move |a: A| -> C { f(g(a)) } } fn t8n<A, B, C>(f: impl Fn(A) -> B, g: impl Fn(A) -> C) -> impl Fn(A) -> (B, C) where A: Copy, { move |a: A| -> (B, C) { let b = a; let fa = f(a); let ga = g(b); (fa, ga) } } fn main() { let f = |(_, _)| {}; let g = |(a, _)| a; let t7 = |env| |a| |b| t7p(f, g)(((env, a), b)); let t8 = t8n(t7, t7p(f, g)); //~^ ERROR: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)> } </ins>


Question:
Discovered a compiler panic, thought it might relate to , but was told to post a new issue. In minimizing, it seems the generic types are required to trigger the panic, I was unable to reproduce when inlining t7p or t8n. This code panics on 1.33 - 1.35, but does not panic on 1.32 (): On 1.32: On 1.35 nightly: --Bryan
triage: P-high. Removing nominated tag since there's little to discuss beyond its P-highness. (The fact its unassigned will be discussed regardless of nomination state.)
Bisection points to i.e. as the culprit. The backtrace in that commit looks very similar to the one reported here, and the parent commit () gives the same compiler error.
I spent some time looking at this a few weeks ago but did not manage to find anything conclusive. At this point I'm going to be taking a break for a few months, so I am unassigning myself from this issue.
triage: assigning self.
triage: downgrading to P-medium; this does not warrant revisiting every week.
I was able to minify it a bit further:
Triage: It's no longer ICE with the latest nightly.

<ins> error[E0277]: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>` --> $DIR/issue-59494.rs:21:22 | LL | fn t8n<A, B, C>(f: impl Fn(A) -> B, g: impl Fn(A) -> C) -> impl Fn(A) -> (B, C) |                                             ---------- required by this bound in `t8n` ... LL |     let t8 = t8n(t7, t7p(f, g)); |                      ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>` | = help: the trait `Fn<(_,)>` is not implemented for `impl Fn<(((_, _), _),)>` error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. </ins>


Question:
Discovered a compiler panic, thought it might relate to , but was told to post a new issue. In minimizing, it seems the generic types are required to trigger the panic, I was unable to reproduce when inlining t7p or t8n. This code panics on 1.33 - 1.35, but does not panic on 1.32 (): On 1.32: On 1.35 nightly: --Bryan
triage: P-high. Removing nominated tag since there's little to discuss beyond its P-highness. (The fact its unassigned will be discussed regardless of nomination state.)
Bisection points to i.e. as the culprit. The backtrace in that commit looks very similar to the one reported here, and the parent commit () gives the same compiler error.
I spent some time looking at this a few weeks ago but did not manage to find anything conclusive. At this point I'm going to be taking a break for a few months, so I am unassigning myself from this issue.
triage: assigning self.
triage: downgrading to P-medium; this does not warrant revisiting every week.
I was able to minify it a bit further:
Triage: It's no longer ICE with the latest nightly.

<ins> // check-pass pub trait Trait1 { type C; } struct T1; impl Trait1 for T1 { type C = usize; } pub trait Callback<T: Trait1>: FnMut(<T as Trait1>::C) {} impl<T: Trait1, F: FnMut(<T as Trait1>::C)> Callback<T> for F {} pub struct State<T: Trait1> { callback: Option<Box<dyn Callback<T>>>, } impl<T: Trait1> State<T> { fn new() -> Self { Self { callback: None } } fn test_cb(&mut self, d: <T as Trait1>::C) { (self.callback.as_mut().unwrap())(d) } } fn main() { let mut s = State::<T1>::new(); s.test_cb(1); } </ins>


Question:
Discovered a compiler panic, thought it might relate to , but was told to post a new issue. In minimizing, it seems the generic types are required to trigger the panic, I was unable to reproduce when inlining t7p or t8n. This code panics on 1.33 - 1.35, but does not panic on 1.32 (): On 1.32: On 1.35 nightly: --Bryan
triage: P-high. Removing nominated tag since there's little to discuss beyond its P-highness. (The fact its unassigned will be discussed regardless of nomination state.)
Bisection points to i.e. as the culprit. The backtrace in that commit looks very similar to the one reported here, and the parent commit () gives the same compiler error.
I spent some time looking at this a few weeks ago but did not manage to find anything conclusive. At this point I'm going to be taking a break for a few months, so I am unassigning myself from this issue.
triage: assigning self.
triage: downgrading to P-medium; this does not warrant revisiting every week.
I was able to minify it a bit further:
Triage: It's no longer ICE with the latest nightly.

<ins> // check-pass fn any<T>() -> T { loop {} } trait Foo { type V; } trait Callback<T: Foo>: Fn(&T, &T::V) {} impl<T: Foo, F: Fn(&T, &T::V)> Callback<T> for F {} struct Bar<T: Foo> { callback: Box<dyn Callback<T>>, } impl<T: Foo> Bar<T> { fn event(&self) { (self.callback)(any(), any()); } } struct A; struct B; impl Foo for A { type V = B; } fn main() { let foo = Bar::<A> { callback: Box::new(|_: &A, _: &B| ()) }; foo.event(); } </ins>


Question:
() Output: Version: 1.34.0 1.35.0 2019-04-15 nightly () Expected: Original report:
26.0 is the first version that accepts this. 1.25.0 rejects it with:
(not really a regression since more code now compiles)
Adding T-compiler since is a built-in.
Opened —it should fix the issue.
triage: P-medium. I'm going to assume we don't need any future-compat machinery for a bug of this nature, unless the crater run on PR indicates that there are occurrences of this mis-use of in the wild.

<del> use errors::DiagnosticBuilder; </del> <ins> use errors::{Applicability, DiagnosticBuilder}; </ins> use syntax::ast::{self, *}; use syntax::source_map::Spanned; use syntax::ext::base::*; use syntax::ext::build::AstBuilder; use syntax::parse::token; <ins> use syntax::parse::parser::Parser; </ins> use syntax::print::pprust; use syntax::ptr::P; use syntax::symbol::Symbol;


Question:
() Output: Version: 1.34.0 1.35.0 2019-04-15 nightly () Expected: Original report:
26.0 is the first version that accepts this. 1.25.0 rejects it with:
(not really a regression since more code now compiles)
Adding T-compiler since is a built-in.
Opened —it should fix the issue.
triage: P-medium. I'm going to assume we don't need any future-compat machinery for a bug of this nature, unless the crater run on PR indicates that there are occurrences of this mis-use of in the wild.

return Err(err); } <del> Ok(Assert { cond_expr: parser.parse_expr()?, custom_message: if parser.eat(&token::Comma) { let ts = parser.parse_tokens(); if !ts.is_empty() { Some(ts) } else { None } } else { None }, }) </del> <ins> let cond_expr = parser.parse_expr()?; // Some crates use the `assert!` macro in the following form (note extra semicolon): // // assert!( //     my_function(); // ); // // Warn about semicolon and suggest removing it. Eventually, this should be turned into an // error. if parser.token == token::Semi { let mut err = cx.struct_span_warn(sp, "macro requires an expression as an argument"); err.span_suggestion( parser.span, "try removing semicolon", String::new(), Applicability::MaybeIncorrect ); err.note("this is going to be an error in the future"); err.emit(); parser.bump(); } // Some crates use the `assert!` macro in the following form (note missing comma before // message): // // assert!(true "error message"); // // Parse this as an actual message, and suggest inserting a comma. Eventually, this should be // turned into an error. let custom_message = if let token::Literal(token::Lit::Str_(_), _) = parser.token { let mut err = cx.struct_span_warn(parser.span, "unexpected string literal"); let comma_span = cx.source_map().next_point(parser.prev_span); err.span_suggestion_short( comma_span, "try adding a comma", ", ".to_string(), Applicability::MaybeIncorrect ); err.note("this is going to be an error in the future"); err.emit(); parse_custom_message(&mut parser) } else if parser.eat(&token::Comma) { parse_custom_message(&mut parser) } else { None }; if parser.token != token::Eof { parser.expect_one_of(&[], &[])?; unreachable!(); } Ok(Assert { cond_expr, custom_message }) } fn parse_custom_message<'a>(parser: &mut Parser<'a>) -> Option<TokenStream> { let ts = parser.parse_tokens(); if !ts.is_empty() { Some(ts) } else { None } </ins> }


Question:
() Output: Version: 1.34.0 1.35.0 2019-04-15 nightly () Expected: Original report:
26.0 is the first version that accepts this. 1.25.0 rejects it with:
(not really a regression since more code now compiles)
Adding T-compiler since is a built-in.
Opened —it should fix the issue.
triage: P-medium. I'm going to assume we don't need any future-compat machinery for a bug of this nature, unless the crater run on PR indicates that there are occurrences of this mis-use of in the wild.

<ins> // Ensure assert macro does not ignore trailing garbage. // // See https://github.com/rust-lang/rust/issues/60024 for details. fn main() { assert!(true some extra junk, "whatever"); //~^ ERROR expected one of assert!(true some extra junk); //~^ ERROR expected one of assert!(true, "whatever" blah); //~^ ERROR no rules expected assert!(true "whatever" blah); //~^ WARN unexpected string literal //~^^ ERROR no rules expected assert!(true;); //~^ WARN macro requires an expression assert!(false || true "error message"); //~^ WARN unexpected string literal } </ins>


Question:
() Output: Version: 1.34.0 1.35.0 2019-04-15 nightly () Expected: Original report:
26.0 is the first version that accepts this. 1.25.0 rejects it with:
(not really a regression since more code now compiles)
Adding T-compiler since is a built-in.
Opened —it should fix the issue.
triage: P-medium. I'm going to assume we don't need any future-compat machinery for a bug of this nature, unless the crater run on PR indicates that there are occurrences of this mis-use of in the wild.

<ins> error: expected one of `,`, `.`, `?`, or an operator, found `some` --> $DIR/assert-trailing-junk.rs:6:18 | LL |     assert!(true some extra junk, "whatever"); |                  ^^^^ expected one of `,`, `.`, `?`, or an operator here error: expected one of `,`, `.`, `?`, or an operator, found `some` --> $DIR/assert-trailing-junk.rs:9:18 | LL |     assert!(true some extra junk); |                  ^^^^ expected one of `,`, `.`, `?`, or an operator here error: no rules expected the token `blah` --> $DIR/assert-trailing-junk.rs:12:30 | LL |     assert!(true, "whatever" blah); |                             -^^^^ no rules expected this token in macro call |                             | |                             help: missing comma here warning: unexpected string literal --> $DIR/assert-trailing-junk.rs:15:18 | LL |     assert!(true "whatever" blah); |                 -^^^^^^^^^^ |                 | |                 help: try adding a comma | = note: this is going to be an error in the future error: no rules expected the token `blah` --> $DIR/assert-trailing-junk.rs:15:29 | LL |     assert!(true "whatever" blah); |                            -^^^^ no rules expected this token in macro call |                            | |                            help: missing comma here warning: macro requires an expression as an argument --> $DIR/assert-trailing-junk.rs:19:5 | LL |     assert!(true;); |     ^^^^^^^^^^^^-^^ |                 | |                 help: try removing semicolon | = note: this is going to be an error in the future warning: unexpected string literal --> $DIR/assert-trailing-junk.rs:22:27 | LL |     assert!(false || true "error message"); |                          -^^^^^^^^^^^^^^^ |                          | |                          help: try adding a comma | = note: this is going to be an error in the future error: aborting due to 4 previous errors </ins>


Question:
With the following code: comes the following error: However, this function compiles correctly without the keyword.
cc
You can trigger this without async/await using : cc
Some more reduction in genericity and clearing up a few things: The problem is that is not know in impl trait items. It's also not related to the return position, but refers to any impl trait in the function. Outside of impl trait can be resolved without a problem, so it must be something related to the way impl trait reuses the generics of its parent.
It seems to be a missing normalization, most likely.
I have a local fix for reduction above, but is making this rather difficult as it makes output not work properly.
This also happens for definitions: My fix only seems to turn this into a cycle error for some reason. EDIT: Nevermind I just broke existential types in general lol
Marking as blocking, although I think there's minimal future compat risk. If push came to shove I personally would be ok with removing this from the blocking list. But then it looks like already fixed it =)
I think the problem is on this line of code: in particular, we "instantiate" the predicates -- meaning, substitute in the values for their type parameters -- but we never normalize them. We should be able to invoke the methods. Note that in this code we do have an available, as well, in . I think we should be able to invoke: this returns an  value, which contains obligations that must be pushed into .
Hmm, that code is only invoked if is true, which I think wouldn't be the case here since there are no region bounds at all (right?). I also noticed that does not exist in this context ( is an ), and there's no nearby either. However, another place where is called without normalizing the result is here, further down in the same file: there does exist (as does ). Quick testing shows that normalizing there fixes this issue as well, and as a bonus also fixes the issue with without ICEs!
good catch -- actually I think the lines you found are the ones I meant to direct you to in the first place. I see you have some other problems on the PR, looking now.

let predicates_of = tcx.predicates_of(def_id); debug!("instantiate_opaque_types: predicates={:#?}", predicates_of,); let bounds = predicates_of.instantiate(tcx, substs); <ins> let param_env = tcx.param_env(def_id); let InferOk { value: bounds, obligations } = infcx.partially_normalize_associated_types_in(span, self.body_id, param_env, &bounds); self.obligations.extend(obligations); </ins> debug!("instantiate_opaque_types: bounds={:?}", bounds); let required_region_bounds = tcx.required_region_bounds(ty, bounds.predicates.clone());


Question:
With the following code: comes the following error: However, this function compiles correctly without the keyword.
cc
You can trigger this without async/await using : cc
Some more reduction in genericity and clearing up a few things: The problem is that is not know in impl trait items. It's also not related to the return position, but refers to any impl trait in the function. Outside of impl trait can be resolved without a problem, so it must be something related to the way impl trait reuses the generics of its parent.
It seems to be a missing normalization, most likely.
I have a local fix for reduction above, but is making this rather difficult as it makes output not work properly.
This also happens for definitions: My fix only seems to turn this into a cycle error for some reason. EDIT: Nevermind I just broke existential types in general lol
Marking as blocking, although I think there's minimal future compat risk. If push came to shove I personally would be ok with removing this from the blocking list. But then it looks like already fixed it =)
I think the problem is on this line of code: in particular, we "instantiate" the predicates -- meaning, substitute in the values for their type parameters -- but we never normalize them. We should be able to invoke the methods. Note that in this code we do have an available, as well, in . I think we should be able to invoke: this returns an  value, which contains obligations that must be pushed into .
Hmm, that code is only invoked if is true, which I think wouldn't be the case here since there are no region bounds at all (right?). I also noticed that does not exist in this context ( is an ), and there's no nearby either. However, another place where is called without normalizing the result is here, further down in the same file: there does exist (as does ). Quick testing shows that normalizing there fixes this issue as well, and as a bonus also fixes the issue with without ICEs!
good catch -- actually I think the lines you found are the ones I meant to direct you to in the first place. I see you have some other problems on the PR, looking now.

&declared_ret_ty, decl.output.span(), ); <ins> debug!("check_fn: declared_ret_ty: {}, revealed_ret_ty: {}", declared_ret_ty, revealed_ret_ty); </ins> fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(revealed_ret_ty))); fn_sig = fcx.tcx.mk_fn_sig( fn_sig.inputs().iter().cloned(),


Question:
With the following code: comes the following error: However, this function compiles correctly without the keyword.
cc
You can trigger this without async/await using : cc
Some more reduction in genericity and clearing up a few things: The problem is that is not know in impl trait items. It's also not related to the return position, but refers to any impl trait in the function. Outside of impl trait can be resolved without a problem, so it must be something related to the way impl trait reuses the generics of its parent.
It seems to be a missing normalization, most likely.
I have a local fix for reduction above, but is making this rather difficult as it makes output not work properly.
This also happens for definitions: My fix only seems to turn this into a cycle error for some reason. EDIT: Nevermind I just broke existential types in general lol
Marking as blocking, although I think there's minimal future compat risk. If push came to shove I personally would be ok with removing this from the blocking list. But then it looks like already fixed it =)
I think the problem is on this line of code: in particular, we "instantiate" the predicates -- meaning, substitute in the values for their type parameters -- but we never normalize them. We should be able to invoke the methods. Note that in this code we do have an available, as well, in . I think we should be able to invoke: this returns an  value, which contains obligations that must be pushed into .
Hmm, that code is only invoked if is true, which I think wouldn't be the case here since there are no region bounds at all (right?). I also noticed that does not exist in this context ( is an ), and there's no nearby either. However, another place where is called without normalizing the result is here, further down in the same file: there does exist (as does ). Quick testing shows that normalizing there fixes this issue as well, and as a bonus also fixes the issue with without ICEs!
good catch -- actually I think the lines you found are the ones I meant to direct you to in the first place. I see you have some other problems on the PR, looking now.

<ins> // check-pass // edition:2018 #![feature(async_await)] // See issue 60414 trait Trait { type Assoc; } async fn foo<T: Trait<Assoc=()>>() -> T::Assoc { () } fn main() {} </ins>


Question:
With the following code: comes the following error: However, this function compiles correctly without the keyword.
cc
You can trigger this without async/await using : cc
Some more reduction in genericity and clearing up a few things: The problem is that is not know in impl trait items. It's also not related to the return position, but refers to any impl trait in the function. Outside of impl trait can be resolved without a problem, so it must be something related to the way impl trait reuses the generics of its parent.
It seems to be a missing normalization, most likely.
I have a local fix for reduction above, but is making this rather difficult as it makes output not work properly.
This also happens for definitions: My fix only seems to turn this into a cycle error for some reason. EDIT: Nevermind I just broke existential types in general lol
Marking as blocking, although I think there's minimal future compat risk. If push came to shove I personally would be ok with removing this from the blocking list. But then it looks like already fixed it =)
I think the problem is on this line of code: in particular, we "instantiate" the predicates -- meaning, substitute in the values for their type parameters -- but we never normalize them. We should be able to invoke the methods. Note that in this code we do have an available, as well, in . I think we should be able to invoke: this returns an  value, which contains obligations that must be pushed into .
Hmm, that code is only invoked if is true, which I think wouldn't be the case here since there are no region bounds at all (right?). I also noticed that does not exist in this context ( is an ), and there's no nearby either. However, another place where is called without normalizing the result is here, further down in the same file: there does exist (as does ). Quick testing shows that normalizing there fixes this issue as well, and as a bonus also fixes the issue with without ICEs!
good catch -- actually I think the lines you found are the ones I meant to direct you to in the first place. I see you have some other problems on the PR, looking now.

<ins> // compile-fail // edition:2018 #![feature(async_await)] #![feature(existential_type)] #![feature(impl_trait_in_bindings)] //~^ WARNING the feature `impl_trait_in_bindings` is incomplete // See issue 60414 ///////////////////////////////////////////// // Reduction to `impl Trait` struct Foo<T>(T); trait FooLike { type Output; } impl<T> FooLike for Foo<T> { type Output = T; } mod impl_trait { use super::*; trait Trait { type Assoc; } /// `T::Assoc` can't be normalized any further here. fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> { //~^ ERROR: type mismatch Foo(()) } } ///////////////////////////////////////////// // Same with lifetimes in the trait mod lifetimes { use super::*; trait Trait<'a> { type Assoc; } /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further. fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> { //~^ ERROR: type mismatch Foo(()) } } fn main() {} </ins>


Question:
With the following code: comes the following error: However, this function compiles correctly without the keyword.
cc
You can trigger this without async/await using : cc
Some more reduction in genericity and clearing up a few things: The problem is that is not know in impl trait items. It's also not related to the return position, but refers to any impl trait in the function. Outside of impl trait can be resolved without a problem, so it must be something related to the way impl trait reuses the generics of its parent.
It seems to be a missing normalization, most likely.
I have a local fix for reduction above, but is making this rather difficult as it makes output not work properly.
This also happens for definitions: My fix only seems to turn this into a cycle error for some reason. EDIT: Nevermind I just broke existential types in general lol
Marking as blocking, although I think there's minimal future compat risk. If push came to shove I personally would be ok with removing this from the blocking list. But then it looks like already fixed it =)
I think the problem is on this line of code: in particular, we "instantiate" the predicates -- meaning, substitute in the values for their type parameters -- but we never normalize them. We should be able to invoke the methods. Note that in this code we do have an available, as well, in . I think we should be able to invoke: this returns an  value, which contains obligations that must be pushed into .
Hmm, that code is only invoked if is true, which I think wouldn't be the case here since there are no region bounds at all (right?). I also noticed that does not exist in this context ( is an ), and there's no nearby either. However, another place where is called without normalizing the result is here, further down in the same file: there does exist (as does ). Quick testing shows that normalizing there fixes this issue as well, and as a bonus also fixes the issue with without ICEs!
good catch -- actually I think the lines you found are the ones I meant to direct you to in the first place. I see you have some other problems on the PR, looking now.

<ins> warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash --> $DIR/bound-normalization-fail.rs:6:12 | LL | #![feature(impl_trait_in_bindings)] |            ^^^^^^^^^^^^^^^^^^^^^^ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` --> $DIR/bound-normalization-fail.rs:30:32 | LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> { |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type | = note: expected type `()` found type `<T as impl_trait::Trait>::Assoc` = note: the return type of a function must have a statically known size error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` --> $DIR/bound-normalization-fail.rs:47:41 | LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> { |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type | = note: expected type `()` found type `<T as lifetimes::Trait<'static>>::Assoc` = note: the return type of a function must have a statically known size error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0271`. </ins>


Question:
With the following code: comes the following error: However, this function compiles correctly without the keyword.
cc
You can trigger this without async/await using : cc
Some more reduction in genericity and clearing up a few things: The problem is that is not know in impl trait items. It's also not related to the return position, but refers to any impl trait in the function. Outside of impl trait can be resolved without a problem, so it must be something related to the way impl trait reuses the generics of its parent.
It seems to be a missing normalization, most likely.
I have a local fix for reduction above, but is making this rather difficult as it makes output not work properly.
This also happens for definitions: My fix only seems to turn this into a cycle error for some reason. EDIT: Nevermind I just broke existential types in general lol
Marking as blocking, although I think there's minimal future compat risk. If push came to shove I personally would be ok with removing this from the blocking list. But then it looks like already fixed it =)
I think the problem is on this line of code: in particular, we "instantiate" the predicates -- meaning, substitute in the values for their type parameters -- but we never normalize them. We should be able to invoke the methods. Note that in this code we do have an available, as well, in . I think we should be able to invoke: this returns an  value, which contains obligations that must be pushed into .
Hmm, that code is only invoked if is true, which I think wouldn't be the case here since there are no region bounds at all (right?). I also noticed that does not exist in this context ( is an ), and there's no nearby either. However, another place where is called without normalizing the result is here, further down in the same file: there does exist (as does ). Quick testing shows that normalizing there fixes this issue as well, and as a bonus also fixes the issue with without ICEs!
good catch -- actually I think the lines you found are the ones I meant to direct you to in the first place. I see you have some other problems on the PR, looking now.

<ins> // check-pass // edition:2018 #![feature(async_await)] #![feature(existential_type)] #![feature(impl_trait_in_bindings)] //~^ WARNING the feature `impl_trait_in_bindings` is incomplete // See issue 60414 ///////////////////////////////////////////// // Reduction to `impl Trait` struct Foo<T>(T); trait FooLike { type Output; } impl<T> FooLike for Foo<T> { type Output = T; } mod impl_trait { use super::*; trait Trait { type Assoc; } /// `T::Assoc` should be normalized to `()` here. fn foo_pass<T: Trait<Assoc=()>>() -> impl FooLike<Output=T::Assoc> { Foo(()) } } ///////////////////////////////////////////// // Same with lifetimes in the trait mod lifetimes { use super::*; trait Trait<'a> { type Assoc; } /// Like above. /// /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here fn foo2_pass<'a, T: Trait<'a, Assoc=()> + 'a>( ) -> impl FooLike<Output=<T as Trait<'a>>::Assoc> + 'a { Foo(()) } /// Normalization to type containing bound region. /// /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here fn foo2_pass2<'a, T: Trait<'a, Assoc=&'a ()> + 'a>( ) -> impl FooLike<Output=<T as Trait<'a>>::Assoc> + 'a { Foo(&()) } } ///////////////////////////////////////////// // Reduction using `impl Trait` in bindings mod impl_trait_in_bindings { struct Foo; trait FooLike { type Output; } impl FooLike for Foo { type Output = u32; } trait Trait { type Assoc; } fn foo<T: Trait<Assoc=u32>>() { let _: impl FooLike<Output=T::Assoc> = Foo; } } ///////////////////////////////////////////// // The same applied to `existential type`s mod existential_types { trait Implemented { type Assoc; } impl<T> Implemented for T { type Assoc = u8; } trait Trait { type Out; } impl Trait for () { type Out = u8; } existential type Ex: Trait<Out = <() as Implemented>::Assoc>; fn define() -> Ex { () } } fn main() {} </ins>


Question:
With the following code: comes the following error: However, this function compiles correctly without the keyword.
cc
You can trigger this without async/await using : cc
Some more reduction in genericity and clearing up a few things: The problem is that is not know in impl trait items. It's also not related to the return position, but refers to any impl trait in the function. Outside of impl trait can be resolved without a problem, so it must be something related to the way impl trait reuses the generics of its parent.
It seems to be a missing normalization, most likely.
I have a local fix for reduction above, but is making this rather difficult as it makes output not work properly.
This also happens for definitions: My fix only seems to turn this into a cycle error for some reason. EDIT: Nevermind I just broke existential types in general lol
Marking as blocking, although I think there's minimal future compat risk. If push came to shove I personally would be ok with removing this from the blocking list. But then it looks like already fixed it =)
I think the problem is on this line of code: in particular, we "instantiate" the predicates -- meaning, substitute in the values for their type parameters -- but we never normalize them. We should be able to invoke the methods. Note that in this code we do have an available, as well, in . I think we should be able to invoke: this returns an  value, which contains obligations that must be pushed into .
Hmm, that code is only invoked if is true, which I think wouldn't be the case here since there are no region bounds at all (right?). I also noticed that does not exist in this context ( is an ), and there's no nearby either. However, another place where is called without normalizing the result is here, further down in the same file: there does exist (as does ). Quick testing shows that normalizing there fixes this issue as well, and as a bonus also fixes the issue with without ICEs!
good catch -- actually I think the lines you found are the ones I meant to direct you to in the first place. I see you have some other problems on the PR, looking now.

<ins> warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash --> $DIR/bound-normalization-pass.rs:6:12 | LL | #![feature(impl_trait_in_bindings)] |            ^^^^^^^^^^^^^^^^^^^^^^ </ins>


Question:
I was using nightly rust extensively for its async/await and specialization feature. After a recent update (nightly-2019-05-02), a new ICE introduced with following logs: After a quick search it seems like is the only in direct cause (stack frame 10). ~I cannot share the code or produce a minimal case because the code base is rather big.~
I've the minimal case for reproducing. Hope that would help!
Thanks! Looks like even this line is enough to trigger the ICE:
: rustc complains you should have variable mut although it is already mut.
That's and should be fixed in the next nightly
cc it looks like the desugaring may have broken in argument-position?
Oops, sorry. I'll take a look.
Denominating since already has a fix
Thanks guys! This is a super fast fix!

visit::walk_generics(this, generics); // Walk the generated arguments for the `async fn`. <del> for a in arguments { </del> <ins> for (i, a) in arguments.iter().enumerate() { </ins> use visit::Visitor; if let Some(arg) = &a.arg { this.visit_ty(&arg.ty); <ins> } else { this.visit_ty(&decl.inputs[i].ty); </ins> } }


Question:
I was using nightly rust extensively for its async/await and specialization feature. After a recent update (nightly-2019-05-02), a new ICE introduced with following logs: After a quick search it seems like is the only in direct cause (stack frame 10). ~I cannot share the code or produce a minimal case because the code base is rather big.~
I've the minimal case for reproducing. Hope that would help!
Thanks! Looks like even this line is enough to trigger the ICE:
: rustc complains you should have variable mut although it is already mut.
That's and should be fixed in the next nightly
cc it looks like the desugaring may have broken in argument-position?
Oops, sorry. I'll take a look.
Denominating since already has a fix
Thanks guys! This is a super fast fix!

<ins> // compile-pass // edition:2018 #![feature(async_await)] // This is a regression test to ensure that simple bindings (where replacement arguments aren't // created during async fn lowering) that have their DefId used during HIR lowering (such as impl // trait) are visited during def collection and thus have a DefId. async fn foo(ws: impl Iterator<Item = ()>) {} fn main() {} </ins>


Question:
Following code sample causes a compiler panic. should be .
Also happens on nightly. Likely due to const generics changes (cc
Minimal reproduction:
Another case:

if !fail { return None; } <del> bug!("unexpected const parent path def {:?}", x); </del> <ins> tcx.sess.delay_span_bug( DUMMY_SP, &format!( "unexpected const parent path def {:?}", x ), ); tcx.types.err </ins> } } }


Question:
Following code sample causes a compiler panic. should be .
Also happens on nightly. Likely due to const generics changes (cc
Minimal reproduction:
Another case:

if !fail { return None; } <del> bug!("unexpected const parent path {:?}", x); </del> <ins> tcx.sess.delay_span_bug( DUMMY_SP, &format!( "unexpected const parent path {:?}", x ), ); tcx.types.err </ins> } } }


Question:
Following code sample causes a compiler panic. should be .
Also happens on nightly. Likely due to const generics changes (cc
Minimal reproduction:
Another case:

if !fail { return None; } <del> bug!("unexpected const parent in type_of_def_id(): {:?}", x); </del> <ins> tcx.sess.delay_span_bug( DUMMY_SP, &format!( "unexpected const parent in type_of_def_id(): {:?}", x ), ); tcx.types.err </ins> } } }


Question:
Following code sample causes a compiler panic. should be .
Also happens on nightly. Likely due to const generics changes (cc
Minimal reproduction:
Another case:

<ins> #![feature(const_generics)] //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash // We should probably be able to infer the types here. However, this test is checking that we don't // get an ICE in this case. It may be modified later to not be an error. struct Foo<const NUM_BYTES: usize>(pub [u8; NUM_BYTES]); fn main() { let _ = Foo::<3>([1, 2, 3]); //~ ERROR type annotations needed } </ins>


Question:
Following code sample causes a compiler panic. should be .
Also happens on nightly. Likely due to const generics changes (cc
Minimal reproduction:
Another case:

<ins> warning: the feature `const_generics` is incomplete and may cause the compiler to crash --> $DIR/cannot-infer-type-for-const-param.rs:1:12 | LL | #![feature(const_generics)] |            ^^^^^^^^^^^^^^ error[E0282]: type annotations needed --> $DIR/cannot-infer-type-for-const-param.rs:10:19 | LL |     let _ = Foo::<3>([1, 2, 3]); |                   ^ cannot infer type for `{integer}` error: aborting due to previous error For more information about this error, try `rustc --explain E0282`. </ins>


Question:
Following code sample causes a compiler panic. should be .
Also happens on nightly. Likely due to const generics changes (cc
Minimal reproduction:
Another case:

<ins> use std::convert::TryInto; struct S; fn main() { let _: u32 = 5i32.try_into::<32>().unwrap(); //~ ERROR wrong number of const arguments S.f::<0>(); //~ ERROR no method named `f` S::<0>; //~ ERROR  wrong number of const arguments } </ins>


Question:
Following code sample causes a compiler panic. should be .
Also happens on nightly. Likely due to const generics changes (cc
Minimal reproduction:
Another case:

<ins> error[E0107]: wrong number of const arguments: expected 0, found 1 --> $DIR/invalid-const-arg-for-type-param.rs:6:34 | LL |     let _: u32 = 5i32.try_into::<32>().unwrap(); |                                  ^^ unexpected const argument error[E0599]: no method named `f` found for type `S` in the current scope --> $DIR/invalid-const-arg-for-type-param.rs:7:7 | LL | struct S; | --------- method `f` not found for this ... LL |     S.f::<0>(); |       ^ error[E0107]: wrong number of const arguments: expected 0, found 1 --> $DIR/invalid-const-arg-for-type-param.rs:8:9 | LL |     S::<0>; |         ^ unexpected const argument error: aborting due to 3 previous errors Some errors have detailed explanations: E0107, E0599. For more information about an error, try `rustc --explain E0107`. </ins>


Question:
shows that the impl of is not idempotent. That is, if fails, the is left in an "un-droppable" state, and trying to re-drop the vector invokes undefined behavior - that is, the vector must be leaked. It might be possible to make it idempotent without adding significant overhead [0], but I don't know whether we should do this. I think we should be clearer about whether the impl of a type is idempotent or not, since making the wrong assumption can lead to UB, so I believe we should document this somewhere. We could document this for the type, but maybe this can also be something that can be documented at the top of the // crates for all types (e.g. impls of standard types are not idempotent). [0] Maybe setting the vector field to zero before dropping the slice elements and having the impl of set the capacity to zero before exiting is enough to avoid trying to re-drop the elements or trying to deallocate the memory (which is always freed on the first drop attempt).
cc
"It's not idempotent" should be the safe default assumption, and I know of no case so far where we've documented that a drop glue is idempotent. We might want to mention the general principle in suitable places (e.g., nomicon, UCG) but I don't think we should repeat "as usual, double-dropping this type causes UB" again on all specific types. We should only document the exceptions, if any. (I am also quite unsure whether going through the effort of guaranteeing that certain types' drop glue is idempotent is a good use of time, as it seems extremely niche and I don't know any use cases for that. But that just means I personally won't invest time in that discussion.)
I think this is not an issue wit . Rather, any unsafe code needs to be careful about panic safety, especially if it is also generic. FWIW I’ve always assumed that double drop could be as much a memory safety issue as use-after-free. (“One and a half” drop even more so.) I don’t think idempotency should be expected for any type, but that sounds like a decision for more than
Fully agreed. The best you can hope for, IMO, is that a type will make an effort to drop as much as possible even when there's a panic during dropping. actually does that by using the slice drop glue, which, if dropping one element panics, will keep dropping the other elements. This seems more useful than allowing idempotent dropping (it minimizes leakage even without any being involved), and it makes idempotent dropping unnecessary (if you catch a panic, the involved types already did everything they can to drop as much as possible, so there's no point in calling drop again). I think it makes more sense to improve panic-resiliance of our drop impls than to make them idempotent. For example, AFAIK drops two 's; if dropping the first panics, the second one will be leaked. This could be improved. One interesting question I see here is the interaction with . Does deallocate the backing store if dropping one of the elements panicked? If yes, is that a violation of the drop guarantee (assuming we extended with pinning projections -- )?
Today double-drops are not a form of undefined behavior. They could, however, lead to undefined behavior depending on the types involved and how is implemented for those types. As part of the UCGs one could try to make double-drops UB per se. That would mean that unsafe code needs to make sure that double-drops don't happen, period. That might be a breaking change. If we don't do that, then we have some types for which double-drops are ok, and some types for which they are not, and the only way to tell is either by reading the documentation, or inspecting the type's source code. I'd rather not recommend people to rely on what the source code does. It suffices that one crate starts relying on some impl being "accidentally idempotent" in libstd today, for us to not be able to evolve that impl in the future without breaking code. A "Unless stated otherwise, impls of standard library types are not guaranteed to be idempotent, and if they are, we reserve the right to change that without maintaining backwards compatibility" note somewhere might be enough to prevent that. I expect that to happen in an idempotent impl for as well. Right now, the issue is that all elements that can be dropped are dropped, the backing allocation of the Vec is deallocated, but the len of the Vec is not set to zero, so a double drop will try to double drop the elements again (and then the drop impl of RawVec will be invoked, whose capacity has not been set to zero, which will try to double-free memory). Yes. When drop panics, the destructors of the fields are invoked. For Vec this means that the contained RawVec is dropped, which deallocates the backing storage of the Vec without setting the capacity of the Vec to zero. AFAICT, no. If you have a the only thing that will be deallocated without running destructors when that is dropped is the storage of the . Since the destructor of the does not run, the destructor of the does not run, and the backing allocation of the gets leaked, which is fine (some other thread could still write to it).
https://rust- (both the proposal that is now implemented an the description of the status quo before that) is relevant to the efforts that the language makes to not let double- happen in safe Rust. This guarantee has existed for years, since before 1.0, so writers of unsafe code rely on it. Although calling twice is not inherently UB in the Rust language, many unsafe libraries are written with the assumption that it never happens. Therefore, writers of generic unsafe code should assume that double drop of a value of a type parameter can cause UB. Calling twice with the Unix system allocator causes a double , which is UB. But is only an example.
Drop is not the only operation that has such issues; pretty much any function you call can be UB or not under certain circumstances depending on implementation details. One example is e.g. relying on not to reallocate -- if we did a before, is that guaranteed? What if we did and then ? And so on. If we really consider such details to be stable just because they are observable by "this program was not UB but now it is", we'd have to bake an abstract model of all of these data structures into our operational semantics, just to make some more code UB. I think that is a bad approach. UB is for enabling compiler optimizations. It is not for catching clients that exploit unstable details of the current implementation of some library. Conflating these two problems makes the definition of UB much, much more complicated, I think that's a mistake. Just because some interaction with is not UB currently, doesn't mean we are not allowed to ever change it to be UB. There is no implicit stabilization of the full set of UB-free interactions. I agree catching such "overfit" clients is an important problem, but let's keep that library-level discussion separate from the language-level discussion of what is and is not UB. I don't understand why you'd even want to call again, if we already agree that the first should do the maximal amount of dropping that it can. You are basically saying "make 's drop idempotent by making the second a NOP". I don't see the point. Seems like you want to write generic code that drops stuff again if the first drop panicked. But what would be a situation where that is ever a good idea? From all I can see, the only place where this can help is if the second drops stuff that the first "missed" because of the panic. I am saying, if that is the problem, then fix to not "miss" stuff. This misses the point, because . The interesting case is a . Then we could pin the , and from our get a , and insert that into the list. Now we are in a situation where if the 's backing store gets deallocated without dropping the , we have a safety violation. But it seems to me if can guarantee that it itself does not panic, then we are okay: if an earlier element in the list panics while dropping (maybe it's a heterogeneous list through an or trait objects), we know we still get dropped properly.
How can you drop the while s into the vector are still live ? The documentation of guarantees these details, e.g., see , so AFAICT Rust unsafe code can rely on these details, and breaking that code would be an API breaking change.
I was talking about the implicit drop that happens when the vector goes out of scope. I am aware. When libraries decide to document such details, clients may of course rely on them. has no such section even though many similar questions apply; thus, clients may not rely on the same properties for even if they happen to be true currently. This matches the situation for idempotent drop: clients may rely on this if and only if the library decides to document this as a guarantee. I don't think we should change our language spec to detect clients relying on implementation details, and similarly, I don't think we should change our language spec to detect clients that rely on some being idempotent even though that is not documented (e.g., double-drop of an empty that had called on it).
The problem is that safe Rust can be called from Rust, and it isn't clear to me from that RFC whether writers of code can rely on other code not performing a double-drop. It isn't clear either whether code can assume that double-dropping something is ok.
Are you saying that this is analogous to whether users should be able to rely on double-drops invoking / not invoking UB? These data-structure properties feel quite obvious to me, but I have no idea how users can today learn that, at least when using the libstd types, they should always assume that is not idempotent unless a type guarantees otherwise. AFAICT they can just try it for some type, and if it works, deduce that it is ok. Then they publish their crate, and some time later we break their code. Saying that "we did not guarantee that it worked anywhere" does not change the fact that the code now is broken, and we are not warning them about this either. So even if we might be right in that technically we are allowed to break that code, it might turn out that in practice, now we cannot, and that user has somehow managed to, by accident, specify that double-drops for some type must be ok. We'd have a stronger case if we explicitly call this out in the docs, warn when users do this (or panic or similar), etc.
Both seem equally obvious to me. We also don't document that you cannot to a vector after dropping it. leaves the data structure is a "deinitialized" state in which no further operation can be performed on it. I don't understand why you or anyone else might think that dropping would be special in the sense of being the only operation that you may call on such a "deinitialized" data structure. I mean, nobody thinks that you can an already free'd piece of the heap either, right? Surely we don't have to exhaustively list everything we do not guarantee. That could get exhausting indeed... I'm all for being more explicit, and in that sense I am okay with noting this explicitly somewhere. But in no way does that mean that other undocumented assumptions can randomly be conjured. (This is how the discussion at hand feels to me: coming up with a random assumption and then arguing that just because nothing says that you can not assume this, hence you can. I understand you do not consider it random, but I see nothing distinguishing this from any other not-documented-not-to-hold assumption that people might come up with.)
further operation can be performed on it. AFAICT a second attempt to drop a value only makes sense if the first one failed (which is what the issue cited in the top comment does). You seem to be arguing that a drop that fails (panics) actually deinitializes the value and therefore trying to re-drop isn’t a logical operation to perform. If this is the case, to me this imply that a drop that fails actually succeeds, such that drops are infallible, which makes me wonder why do we allow drop to panic at all?
I mostly agree with especially wrt. to turning "unstated non-guarantees" through random assumptions into guarantees. However, I think if there are reasonable assumptions that could be made that we don't want to guarantee, it's a practical idea to disabuse users of those assumptions.
Note however that themselves demonstrated that currently double-drops (of Vecs) don't work -- elements get double-dropped on the second drop. That means if a hypothetical users actually tries to determine this behavior experimentally, they'd quickly find double frees and similar issues if they are at all diligent.
that holds as long as users try it with types for which this is the case. maybe you can explain to me how this assumption feels random to you (and maybe the others). Rust allows fallible drop, that is, drop can fail. I don't understand how from this it follows that, because drop failed, one cannot attempt to drop the value again. The only idea I have about how this could be the case is if drop is infallible, that is, even if drop fails, the value is dropped, but then I don't understand why we allow drops to fail in the first place. AFAICT, drop failed, therefore the value was not dropped, therefore I can try to drop it again, and that is not a double-drop because the value wasn't dropped in the first place. It is just a second attempt to drop a value, and this issue is about whether attempting to drop should be idempotent until drop succeeds (once the value is dropped, you don't longer own it, so attempting to drop further is a use-after-move kind of UB AFAICT).
My impression is that it's been considered bad form in general to panic in a implementation, if only because it causes an abort if the drop occurred during unwinding. It's allowed just because the alternative (always aborting when a impl panics) is worse.
...however, this could certainly be documented better. Currently the has an oddly worded note: I think it's trying to explain that double panic = abort, but as worded it doesn't really make sense. It should probably explain that more clearly, and also explicitly state that panicking in is discouraged.
It should also cover the case in which the double panic does not happen, and suggest what users should assume if the details of a particular drop implementation are not guaranteed. For example, that a dropped value for which drop fails must, in general, be leaked, because it is, in general, left in an unspecified partially-dropped state which is neither "initialized" nor "deinitialized" and which does not, in general, support an attempt to re-drop the value or any other operation. How bad would it be to make drop impls ?
Well, at least I am arguing that that might be the case. You have no way to tell. Would you expect it to be legal to to a vector after panicked? I guess not. Same for calling again. "panic" doesn't mean "I failed in a clean way and nothing happened", it means "something went wrong half-way through this operation and any part of it might or might not have happened".
Why not? If the value was not dropped, then I'd expect that to work just like pushing into an empty vector would.
For , on , the memory is deallocated, but the length and capacity of the vector are not set to . Are you saying that it is ok to leave safe abstractions over unsafe code in such an invalid state when a happens?
"panic during drop" is very different from "not dropped". This is true for any operation. I don't understand why you would assume that an operation that panicked had no effect and thus can be considered as having not happened. You keep just changing my words "drop panicked" into "not dropped". Please don't. :) I think it is okay to leave safe abstrcations in an invalid state when completes (whether that is return or unwind), because we can rely on this being the last operation. This is actually an advantage of Rust over C++, we don't need run-time tracking for this as we have proper static move tracking. would be the only operation where the "return" and "unwind" ways of completing would have widely different guarantees. I see no grounds for assuming it is special.
Where are you getting the impression that I assume that? How could you make have no effect? AFAICT you would need to revert the of the already dropped elements of the vector which is not possible. How can we rely on this? The example I show using corrupts memory at run-time, and is neither rejected statically, nor at run-time (e.g. via a proper run-time error).
You keep saying "not dropped" for "drop panicked", making it sound as if a drop-that-panicked was the same thing as if drop had never been called. I am sorry if I misunderstood you here, but I also don't know any other way to interpret your words. The Rust compiler ensures that is called exactly once. It inserts boolean variables to track this at run-time if necessary. Calling manually from safe code is impossible (even though its signature looks like it should be possible). Sure, unsafe code can circumvent this. Needless to say, unsafe code can circumvent any compiler-enforced restriction. But "drop is called exactly once" has been deeply entrenched in the guarantees and considerations around dropping in Rust as far back as I can remember. There is plenty of unsafe code in libstd that relies on this. This is as close to a guarantee as we get without formal proofs. The docs for say "using the pointed-to value after calling dropinplace can cause undefined behavior". It doesn't have an exception for when this operation panicked.
I am repeating myself here, but just to be clear: I am all for improving the docs. But I find it implausible to assume that doing double-drops could ever be legal (in generic code). There is plenty of evidence for code relying on no double drops happening, there is plenty of mechanism to make sure this doesn't happen in safe code, says so in the docs. I don't even know of a in libstd that would be safe to call twice (probably there are some). As a random example, is also not idempotent and might release a lock not even held by the current thread if it gets called a second time. The run-time tracking of the "move" state that the compiler does would literally be useless if drop was idempotent! Heck, before we had proper move tracking we even had a compiler-implemented mechanism to make drop idempotent (overwriting memory with some bit pattern, I forgot the details) and we got rid of it because of its unnecessary run-time cost. It feels to me like you are altering the deal here, and the deal has been set and clear for many years. We should discuss how to improve the docs because clearly it is still possible to assume that drop might be idempotent , but there is no point discussing the deal itself. Unfortunately, I do not understand at all where you got the idea from that drop might be idempotent, so I don't know where the docs could be improved to fix this. This issue has nothing to do with , it is more general. Where would you expect such things to be said? In ? We basically already say that there but maybe the case where drop panics could be called out more explicitly. Or maybe the Nomicon should have a chapter on dropping?
By "not dropped" I precisely mean "a value was not dropped". A drop-that-panics is a drop that fails, which is not the same as if drop was never called (how could it panic if it was never called?). I assumed a couple of things. First, that a drop that fails does not successfully drop a value, and since the value has not been dropped, code is allowed to try to drop it again. Again, this does not mean that I thought that a failed call to would have no effect here. It can have an effect, but that effect is not "the value is dropped" if the call fails - the effect is just "trying to drop the value failed", which is different from "drop was never called". Nothing nowhere taught me otherwise. For me, it just feel obvious that a value that has not been dropped (which is what AFAICT happens if calling for it fails), can be dropped just like any other value (unless these values are special somehow). Second, I assumed that correct safe abstractions over unsafe code made sure this works. My own abstractions do this, e.g., is left in a valid but unspecified state if fails (len = capacity = 0, ptr = null, just like ). This means that, after for fails, you can call or the value without invoking undefined behavior. Last weekend, I one of the test to last week, and this test ran slower. The reason was that does not put itself into a valid state after fails, and this results in UB in the example shown, while was putting itself into a valid state in a sub-optimal way (enough to be noticeable, and easy to fix). I then asked on Discord why was that, and whether the Drop impl for Vec has a bug, or whether Drop impls never have to account for that, and the discussion was that for is not idempotent, but whether this is by design or a bug was not clear, so I filled this bug.
It seems, in other words, that you assumed the drop glue is exception safe in a fairly strong way (even when it fails, it upholds the safety invariants necessary for dropping). Of course, as you might guess from my phrasing, that seems like a pretty big and unwarranted assumption to me. We don't generally expect any Rust code to be very exception safe (that's why we have marker traits like ). Some basic exception safety is required from unsafe code to ensure that safe code mustn't be able to cause UB just by catching a panic, but no more. Yet to run the drop glue again after the drop glue fails, you have to dip into unsafe code, so that principle doesn't apply.
The whole safe API is exception safe in such a strong way (e.g. ). AFAICT, the only part of the API for which this does not hold is the of for , so I suppose the assumption might have come from there.
The entire safe API, yes, by necessity (and only as exception safe as required to maintain memory safety -- e.g., it will happily leak memory). Though there don't seem to be any unsafe APIs (or methods at least) that have to worry about panics, so I guess it's true that distinction might not be apparent just from looking at Vec.
From the point-of-view of safe code, it does not matter whether is exception safe, because it can only be called once. From the POV of unsafe code, I knew that double-drops cannot happen, but what I did not know is that what also cannot happen is getting called twice. I thought, of course that can happen, if code calls , and that panics, and then is called again, that will call twice, but is not a double-drop, because the first time the value failed to drop. When mentions that the issue is not double-drops, but calling more than once, that's news to me.
I would like to close this issue. We have open to document the exact guarantees around drop and panicking, and it seems like that would be the place for this; I agree with others on this thread that I don't really see how one could assume that initiating drop twice in any way (whether it be due to unwinding or otherwise) is safe. Specifically, any method which conceptually has a signature of or so, if it panics, shouldn't be called again assuming that you still have a T; that seems like it should be fairly easy to understand, unless I'm missing something, as the T is almost guaranteed to have dropped already (so it would be odd to assume that you can drop it again, as that calls something on that T -- you've lost ownership already). This sentence is confusing to me -- double-drops cannot happen sounds equivalent to Drop::drop getting called twice; Drop::drop is the drop operation? Specifically, I think the confusion lies here: " I thought, of course that can happen, if unsafe code calls dropinplace, and that panics, and then Drop::drop is called again, that will call Drop::drop twice, but is not a double-drop, because the first time the value failed to drop" -- this is a double drop. When dropinplace panics, it cannot assumed to have done nothing, so calling drop again means that you're violating the safety contract of dropinplace. This is why or equivalents are commonly needed when calling dropinplace, as you need to be sure that the value you're dropping in place is not dropped again (during unwinding or otherwise), otherwise your unsafe code is incorrect. Presuming there's not further discussion here I will aim to close this issue in a week or so.
In the context of this discussion, the question that needs to be properly answered somewhere in the reference is: If a call to fails, was the value dropped? If the answer is "no", then calling again isn't a "double-drop" because the value has not been dropped. Looking at the comments here there is a certain amount of consensus that a call that fails "succeeds" in dropping the value, which is why even if fails, calling it again on a value drops the value twice and that's a double drop, which is UB. That's what should be documented somewhere in the reference. Which part of the reference issue summarizes / super-seeds this discussion ? If there isn't any, could you post a summary of this discussion there before closing this, so that documenting this still gets tracked somewhere?

/// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`] /// in a `drop` implementation will likely abort. /// <ins> /// Note that even if this panics, the value is considered to be dropped; /// you must not cause `drop` to be called again. This is normally automatically /// handled by the compiler, but when using unsafe code, can sometimes occur /// unintentionally, particularly when using [`std::ptr::drop_in_place`]. /// </ins> /// [E0040]: ../../error-index.html#E0040 /// [`panic!`]: ../macro.panic.html /// [`std::mem::drop`]: ../../std/mem/fn.drop.html <ins> /// [`std::ptr::drop_in_place`]: ../../std/ptr/fn.drop_in_place.html </ins> #[stable(feature = "rust1", since = "1.0.0")] fn drop(&mut self); }


Question:
When I used the character in comment, combined with some (invalid) code preceding it, the compiler panicked. I tried this code: I expected to see this happen: rustc compiles this code. Instead, this happened: rustc panicked with the following output : Backtrace:
Regressed in 1.34.0. Used to be:
cc
Miminized: Probably some span handcrafting?
Probably some span handcrafting? +1
I was idly curious, so I took a brief look at this. The diagnostic that triggers this was introduced in , but I don't think it is responsible for the error (it's just stepping through characters looking for a closing brace). There is some strange math in  (introduced in ). It oscillates between zero-length and 1+ length spans as it is stepping over characters. When it hits a multi-byte character, it returns an invalid span. Example: Starting with a span of (0,1), using would result in (1,1), then (1,2), then (2,2), then (2,4). That last one slices into the middle of the multi-byte character (because of , where width is 3), causing a panic. I'm not familiar enough with this stuff to say how it should behave. It seems like is being used for two different purposes (getting the next zero-length span, and getting the "next" character), and it's not clear to me what the behavior should be since it is used in a variety of places. I don't think it can be changed to always return zero-length spans, and it can't be changed to always return non-zero length spans. Perhaps there should be two different functions?
triage: P-medium, removing nomination; the ICE to me appears to include enough information for a user to identify the offending character and work-around the problem (namely by getting rid of the character). I do agree with that there should probably be two distinct functions corresponding to the two distinct purposes that they identified for the current callers of .
More test cases have been brought up in
I guess this is the same bug, but the examples I've seen here concern non-ASCII characters in comments. I'm getting a similar rustc panic from an erroneous code without comments: Compilation attempt:
Please file a new issue and reference this one.
I think it's fixed, try .
confirmed fixed by .

/// extract function takes three arguments: a string slice containing the source, an index in /// the slice for the beginning of the span and an index in the slice for the end of the span. fn span_to_source<F>(&self, sp: Span, extract_source: F) -> Result<String, SpanSnippetError> <del> where F: Fn(&str, usize, usize) -> String </del> <ins> where F: Fn(&str, usize, usize) -> Result<String, SpanSnippetError> </ins> { if sp.lo() > sp.hi() { return Err(SpanSnippetError::IllFormedSpan(sp));


Question:
When I used the character in comment, combined with some (invalid) code preceding it, the compiler panicked. I tried this code: I expected to see this happen: rustc compiles this code. Instead, this happened: rustc panicked with the following output : Backtrace:
Regressed in 1.34.0. Used to be:
cc
Miminized: Probably some span handcrafting?
Probably some span handcrafting? +1
I was idly curious, so I took a brief look at this. The diagnostic that triggers this was introduced in , but I don't think it is responsible for the error (it's just stepping through characters looking for a closing brace). There is some strange math in  (introduced in ). It oscillates between zero-length and 1+ length spans as it is stepping over characters. When it hits a multi-byte character, it returns an invalid span. Example: Starting with a span of (0,1), using would result in (1,1), then (1,2), then (2,2), then (2,4). That last one slices into the middle of the multi-byte character (because of , where width is 3), causing a panic. I'm not familiar enough with this stuff to say how it should behave. It seems like is being used for two different purposes (getting the next zero-length span, and getting the "next" character), and it's not clear to me what the behavior should be since it is used in a variety of places. I don't think it can be changed to always return zero-length spans, and it can't be changed to always return non-zero length spans. Perhaps there should be two different functions?
triage: P-medium, removing nomination; the ICE to me appears to include enough information for a user to identify the offending character and work-around the problem (namely by getting rid of the character). I do agree with that there should probably be two distinct functions corresponding to the two distinct purposes that they identified for the current callers of .
More test cases have been brought up in
I guess this is the same bug, but the examples I've seen here concern non-ASCII characters in comments. I'm getting a similar rustc panic from an erroneous code without comments: Compilation attempt:
Please file a new issue and reference this one.
I think it's fixed, try .
confirmed fixed by .

} if let Some(ref src) = local_begin.sf.src { <del> return Ok(extract_source(src, start_index, end_index)); </del> <ins> return extract_source(src, start_index, end_index); </ins> } else if let Some(src) = local_begin.sf.external_src.borrow().get_source() { <del> return Ok(extract_source(src, start_index, end_index)); </del> <ins> return extract_source(src, start_index, end_index); </ins> } else { return Err(SpanSnippetError::SourceNotAvailable { filename: local_begin.sf.name.clone()


Question:
When I used the character in comment, combined with some (invalid) code preceding it, the compiler panicked. I tried this code: I expected to see this happen: rustc compiles this code. Instead, this happened: rustc panicked with the following output : Backtrace:
Regressed in 1.34.0. Used to be:
cc
Miminized: Probably some span handcrafting?
Probably some span handcrafting? +1
I was idly curious, so I took a brief look at this. The diagnostic that triggers this was introduced in , but I don't think it is responsible for the error (it's just stepping through characters looking for a closing brace). There is some strange math in  (introduced in ). It oscillates between zero-length and 1+ length spans as it is stepping over characters. When it hits a multi-byte character, it returns an invalid span. Example: Starting with a span of (0,1), using would result in (1,1), then (1,2), then (2,2), then (2,4). That last one slices into the middle of the multi-byte character (because of , where width is 3), causing a panic. I'm not familiar enough with this stuff to say how it should behave. It seems like is being used for two different purposes (getting the next zero-length span, and getting the "next" character), and it's not clear to me what the behavior should be since it is used in a variety of places. I don't think it can be changed to always return zero-length spans, and it can't be changed to always return non-zero length spans. Perhaps there should be two different functions?
triage: P-medium, removing nomination; the ICE to me appears to include enough information for a user to identify the offending character and work-around the problem (namely by getting rid of the character). I do agree with that there should probably be two distinct functions corresponding to the two distinct purposes that they identified for the current callers of .
More test cases have been brought up in
I guess this is the same bug, but the examples I've seen here concern non-ASCII characters in comments. I'm getting a similar rustc panic from an erroneous code without comments: Compilation attempt:
Please file a new issue and reference this one.
I think it's fixed, try .
confirmed fixed by .

/// Returns the source snippet as `String` corresponding to the given `Span` pub fn span_to_snippet(&self, sp: Span) -> Result<String, SpanSnippetError> { <del> self.span_to_source(sp, |src, start_index, end_index| src[start_index..end_index] .to_string()) </del> <ins> self.span_to_source(sp, |src, start_index, end_index| src.get(start_index..end_index) .map(|s| s.to_string()) .ok_or_else(|| SpanSnippetError::IllFormedSpan(sp))) </ins> } pub fn span_to_margin(&self, sp: Span) -> Option<usize> {


Question:
When I used the character in comment, combined with some (invalid) code preceding it, the compiler panicked. I tried this code: I expected to see this happen: rustc compiles this code. Instead, this happened: rustc panicked with the following output : Backtrace:
Regressed in 1.34.0. Used to be:
cc
Miminized: Probably some span handcrafting?
Probably some span handcrafting? +1
I was idly curious, so I took a brief look at this. The diagnostic that triggers this was introduced in , but I don't think it is responsible for the error (it's just stepping through characters looking for a closing brace). There is some strange math in  (introduced in ). It oscillates between zero-length and 1+ length spans as it is stepping over characters. When it hits a multi-byte character, it returns an invalid span. Example: Starting with a span of (0,1), using would result in (1,1), then (1,2), then (2,2), then (2,4). That last one slices into the middle of the multi-byte character (because of , where width is 3), causing a panic. I'm not familiar enough with this stuff to say how it should behave. It seems like is being used for two different purposes (getting the next zero-length span, and getting the "next" character), and it's not clear to me what the behavior should be since it is used in a variety of places. I don't think it can be changed to always return zero-length spans, and it can't be changed to always return non-zero length spans. Perhaps there should be two different functions?
triage: P-medium, removing nomination; the ICE to me appears to include enough information for a user to identify the offending character and work-around the problem (namely by getting rid of the character). I do agree with that there should probably be two distinct functions corresponding to the two distinct purposes that they identified for the current callers of .
More test cases have been brought up in
I guess this is the same bug, but the examples I've seen here concern non-ASCII characters in comments. I'm getting a similar rustc panic from an erroneous code without comments: Compilation attempt:
Please file a new issue and reference this one.
I think it's fixed, try .
confirmed fixed by .

/// Returns the source snippet as `String` before the given `Span` pub fn span_to_prev_source(&self, sp: Span) -> Result<String, SpanSnippetError> { <del> self.span_to_source(sp, |src, start_index, _| src[..start_index].to_string()) </del> <ins> self.span_to_source(sp, |src, start_index, _| src.get(..start_index) .map(|s| s.to_string()) .ok_or_else(|| SpanSnippetError::IllFormedSpan(sp))) </ins> } /// Extend the given `Span` to just after the previous occurrence of `c`. Return the same span


Question:
When I used the character in comment, combined with some (invalid) code preceding it, the compiler panicked. I tried this code: I expected to see this happen: rustc compiles this code. Instead, this happened: rustc panicked with the following output : Backtrace:
Regressed in 1.34.0. Used to be:
cc
Miminized: Probably some span handcrafting?
Probably some span handcrafting? +1
I was idly curious, so I took a brief look at this. The diagnostic that triggers this was introduced in , but I don't think it is responsible for the error (it's just stepping through characters looking for a closing brace). There is some strange math in  (introduced in ). It oscillates between zero-length and 1+ length spans as it is stepping over characters. When it hits a multi-byte character, it returns an invalid span. Example: Starting with a span of (0,1), using would result in (1,1), then (1,2), then (2,2), then (2,4). That last one slices into the middle of the multi-byte character (because of , where width is 3), causing a panic. I'm not familiar enough with this stuff to say how it should behave. It seems like is being used for two different purposes (getting the next zero-length span, and getting the "next" character), and it's not clear to me what the behavior should be since it is used in a variety of places. I don't think it can be changed to always return zero-length spans, and it can't be changed to always return non-zero length spans. Perhaps there should be two different functions?
triage: P-medium, removing nomination; the ICE to me appears to include enough information for a user to identify the offending character and work-around the problem (namely by getting rid of the character). I do agree with that there should probably be two distinct functions corresponding to the two distinct purposes that they identified for the current callers of .
More test cases have been brought up in
I guess this is the same bug, but the examples I've seen here concern non-ASCII characters in comments. I'm getting a similar rustc panic from an erroneous code without comments: Compilation attempt:
Please file a new issue and reference this one.
I think it's fixed, try .
confirmed fixed by .

<ins> struct X {} fn main() { vec![X]; //… //~^ ERROR expected value, found struct `X` } </ins>