jiebi/CodeConvo huggingface dataset:
Code change:
This takes ~2 seconds to type check (according to ): Doubling (respectively, halving) the number of invocations multiplies (resp. divides) the time by 4. It applies to arithmetic in s/s too which is, I imagine, where this will occur most often in practice (it's how I found it). Observations: for , , and , annotating either side (e.g. ) or both sides makes it take only 0.03s and behave linearly (AFAICT) for and : annotating the LHS () reduces the time to ~1.5s, annotating the RHS () reduces it to ~1.1s but both are still quadratic, annotating both takes it to 0.04s and linear it seems to only be dependent on the number of operations in a single function/item, separating the 4 big chunks above across 4 functions reduces the time to ~0.5s. there's no significant difference between using the macro or writing the operations inline (I only use to allow easier experimentation) cc
This must be what's making my old macro-abusing inflate implementation take almost 300 seconds in typeck. It almost sounds like type-checking a function is quadratic over the number of inference variables. Having ran callgrind on the sample and also half of it, I'm seeing the following trace: An unrefined conclusion is that either shouldn't call or should be constant-time.
Is this the same issue as ?
I'm not too familiar with fulfill and infer, but couldn't track the latest snapshot it processed and look at the new information there?
We have exactly for this reason. It doesn't work for some reason tho.
This is the same issue as This is a different issue from (I think I will fix that one separately).

Related discussion:
text: use dep_graph::DepGraph; use middle::infer::InferCtxt; <del> use middle::ty::{self, Ty, TypeFoldable}; </del> <ins> use middle::ty::{self, Ty, TypeFoldable, ToPolyTraitRef}; </ins> use rustc_data_structures::obligation_forest::{Backtrace, ObligationForest, Error}; use std::iter; use syntax::ast;
Code change:
This takes ~2 seconds to type check (according to ): Doubling (respectively, halving) the number of invocations multiplies (resp. divides) the time by 4. It applies to arithmetic in s/s too which is, I imagine, where this will occur most often in practice (it's how I found it). Observations: for , , and , annotating either side (e.g. ) or both sides makes it take only 0.03s and behave linearly (AFAICT) for and : annotating the LHS () reduces the time to ~1.5s, annotating the RHS () reduces it to ~1.1s but both are still quadratic, annotating both takes it to 0.04s and linear it seems to only be dependent on the number of operations in a single function/item, separating the 4 big chunks above across 4 functions reduces the time to ~0.5s. there's no significant difference between using the macro or writing the operations inline (I only use to allow easier experimentation) cc
This must be what's making my old macro-abusing inflate implementation take almost 300 seconds in typeck. It almost sounds like type-checking a function is quadratic over the number of inference variables. Having ran callgrind on the sample and also half of it, I'm seeing the following trace: An unrefined conclusion is that either shouldn't call or should be constant-time.
Is this the same issue as ?
I'm not too familiar with fulfill and infer, but couldn't track the latest snapshot it processed and look at the new information there?
We have exactly for this reason. It doesn't work for some reason tho.
This is the same issue as This is a different issue from (I think I will fix that one separately).

Related discussion:
text: } } <ins> /// Return the set of type variables contained in a trait ref fn trait_ref_type_vars<'a, 'tcx>(selcx: &mut SelectionContext<'a, 'tcx>, t: ty::PolyTraitRef<'tcx>) -> Vec<Ty<'tcx>> { t.skip_binder() // ok b/c this check doesn't care about regions .input_types() .iter() .map(|t| selcx.infcx().resolve_type_vars_if_possible(t)) .filter(|t| t.has_infer_types()) .flat_map(|t| t.walk()) .filter(|t| match t.sty { ty::TyInfer(_) => true, _ => false }) .collect() } </ins> /// Processes a predicate obligation and returns either: /// - `Ok(Some(v))` if the predicate is true, presuming that `v` are also true /// - `Ok(None)` if we don't have enough info to be sure
Code change:
This takes ~2 seconds to type check (according to ): Doubling (respectively, halving) the number of invocations multiplies (resp. divides) the time by 4. It applies to arithmetic in s/s too which is, I imagine, where this will occur most often in practice (it's how I found it). Observations: for , , and , annotating either side (e.g. ) or both sides makes it take only 0.03s and behave linearly (AFAICT) for and : annotating the LHS () reduces the time to ~1.5s, annotating the RHS () reduces it to ~1.1s but both are still quadratic, annotating both takes it to 0.04s and linear it seems to only be dependent on the number of operations in a single function/item, separating the 4 big chunks above across 4 functions reduces the time to ~0.5s. there's no significant difference between using the macro or writing the operations inline (I only use to allow easier experimentation) cc
This must be what's making my old macro-abusing inflate implementation take almost 300 seconds in typeck. It almost sounds like type-checking a function is quadratic over the number of inference variables. Having ran callgrind on the sample and also half of it, I'm seeing the following trace: An unrefined conclusion is that either shouldn't call or should be constant-time.
Is this the same issue as ?
I'm not too familiar with fulfill and infer, but couldn't track the latest snapshot it processed and look at the new information there?
We have exactly for this reason. It doesn't work for some reason tho.
This is the same issue as This is a different issue from (I think I will fix that one separately).

Related discussion:
text: // doing more work yet if !pending_obligation.stalled_on.is_empty() { if pending_obligation.stalled_on.iter().all(|&ty| { <del> let resolved_ty = selcx.infcx().resolve_type_vars_if_possible(&ty); </del> <ins> let resolved_ty = selcx.infcx().shallow_resolve(&ty); </ins> resolved_ty == ty // nothing changed here }) { debug!("process_predicate: pending obligation {:?} still stalled on {:?}",
Code change:
This takes ~2 seconds to type check (according to ): Doubling (respectively, halving) the number of invocations multiplies (resp. divides) the time by 4. It applies to arithmetic in s/s too which is, I imagine, where this will occur most often in practice (it's how I found it). Observations: for , , and , annotating either side (e.g. ) or both sides makes it take only 0.03s and behave linearly (AFAICT) for and : annotating the LHS () reduces the time to ~1.5s, annotating the RHS () reduces it to ~1.1s but both are still quadratic, annotating both takes it to 0.04s and linear it seems to only be dependent on the number of operations in a single function/item, separating the 4 big chunks above across 4 functions reduces the time to ~0.5s. there's no significant difference between using the macro or writing the operations inline (I only use to allow easier experimentation) cc
This must be what's making my old macro-abusing inflate implementation take almost 300 seconds in typeck. It almost sounds like type-checking a function is quadratic over the number of inference variables. Having ran callgrind on the sample and also half of it, I'm seeing the following trace: An unrefined conclusion is that either shouldn't call or should be constant-time.
Is this the same issue as ?
I'm not too familiar with fulfill and infer, but couldn't track the latest snapshot it processed and look at the new information there?
We have exactly for this reason. It doesn't work for some reason tho.
This is the same issue as This is a different issue from (I think I will fix that one separately).

Related discussion:
text: // of its type, and those types are resolved at // the same time. pending_obligation.stalled_on = <del> data.skip_binder() // ok b/c this check doesn't care about regions .input_types() .iter() .map(|t| selcx.infcx().resolve_type_vars_if_possible(t)) .filter(|t| t.has_infer_types()) .flat_map(|t| t.walk()) .filter(|t| match t.sty { ty::TyInfer(_) => true, _ => false }) .collect(); </del> <ins> trait_ref_type_vars(selcx, data.to_poly_trait_ref()); </ins> debug!("process_predicate: pending obligation {:?} now stalled on {:?}", selcx.infcx().resolve_type_vars_if_possible(obligation),
Code change:
This takes ~2 seconds to type check (according to ): Doubling (respectively, halving) the number of invocations multiplies (resp. divides) the time by 4. It applies to arithmetic in s/s too which is, I imagine, where this will occur most often in practice (it's how I found it). Observations: for , , and , annotating either side (e.g. ) or both sides makes it take only 0.03s and behave linearly (AFAICT) for and : annotating the LHS () reduces the time to ~1.5s, annotating the RHS () reduces it to ~1.1s but both are still quadratic, annotating both takes it to 0.04s and linear it seems to only be dependent on the number of operations in a single function/item, separating the 4 big chunks above across 4 functions reduces the time to ~0.5s. there's no significant difference between using the macro or writing the operations inline (I only use to allow easier experimentation) cc
This must be what's making my old macro-abusing inflate implementation take almost 300 seconds in typeck. It almost sounds like type-checking a function is quadratic over the number of inference variables. Having ran callgrind on the sample and also half of it, I'm seeing the following trace: An unrefined conclusion is that either shouldn't call or should be constant-time.
Is this the same issue as ?
I'm not too familiar with fulfill and infer, but couldn't track the latest snapshot it processed and look at the new information there?
We have exactly for this reason. It doesn't work for some reason tho.
This is the same issue as This is a different issue from (I think I will fix that one separately).

Related discussion:
text: ty::Predicate::Projection(ref data) => { let project_obligation = obligation.with(data.clone()); match project::poly_project_and_unify_type(selcx, &project_obligation) { <ins> Ok(None) => { pending_obligation.stalled_on = trait_ref_type_vars(selcx, data.to_poly_trait_ref()); Ok(None) } </ins> Ok(v) => Ok(v), Err(e) => Err(CodeProjectionError(e)) }
Code change:
This takes ~2 seconds to type check (according to ): Doubling (respectively, halving) the number of invocations multiplies (resp. divides) the time by 4. It applies to arithmetic in s/s too which is, I imagine, where this will occur most often in practice (it's how I found it). Observations: for , , and , annotating either side (e.g. ) or both sides makes it take only 0.03s and behave linearly (AFAICT) for and : annotating the LHS () reduces the time to ~1.5s, annotating the RHS () reduces it to ~1.1s but both are still quadratic, annotating both takes it to 0.04s and linear it seems to only be dependent on the number of operations in a single function/item, separating the 4 big chunks above across 4 functions reduces the time to ~0.5s. there's no significant difference between using the macro or writing the operations inline (I only use to allow easier experimentation) cc
This must be what's making my old macro-abusing inflate implementation take almost 300 seconds in typeck. It almost sounds like type-checking a function is quadratic over the number of inference variables. Having ran callgrind on the sample and also half of it, I'm seeing the following trace: An unrefined conclusion is that either shouldn't call or should be constant-time.
Is this the same issue as ?
I'm not too familiar with fulfill and infer, but couldn't track the latest snapshot it processed and look at the new information there?
We have exactly for this reason. It doesn't work for some reason tho.
This is the same issue as This is a different issue from (I think I will fix that one separately).

Related discussion:
text: } ty::Predicate::WellFormed(ty) => { <del> Ok(ty::wf::obligations(selcx.infcx(), obligation.cause.body_id, ty, obligation.cause.span)) </del> <ins> match ty::wf::obligations(selcx.infcx(), obligation.cause.body_id, ty, obligation.cause.span) { None => { pending_obligation.stalled_on = vec![ty]; Ok(None) } s => Ok(s) } </ins> } } }
Code change:
This takes ~2 seconds to type check (according to ): Doubling (respectively, halving) the number of invocations multiplies (resp. divides) the time by 4. It applies to arithmetic in s/s too which is, I imagine, where this will occur most often in practice (it's how I found it). Observations: for , , and , annotating either side (e.g. ) or both sides makes it take only 0.03s and behave linearly (AFAICT) for and : annotating the LHS () reduces the time to ~1.5s, annotating the RHS () reduces it to ~1.1s but both are still quadratic, annotating both takes it to 0.04s and linear it seems to only be dependent on the number of operations in a single function/item, separating the 4 big chunks above across 4 functions reduces the time to ~0.5s. there's no significant difference between using the macro or writing the operations inline (I only use to allow easier experimentation) cc
This must be what's making my old macro-abusing inflate implementation take almost 300 seconds in typeck. It almost sounds like type-checking a function is quadratic over the number of inference variables. Having ran callgrind on the sample and also half of it, I'm seeing the following trace: An unrefined conclusion is that either shouldn't call or should be constant-time.
Is this the same issue as ?
I'm not too familiar with fulfill and infer, but couldn't track the latest snapshot it processed and look at the new information there?
We have exactly for this reason. It doesn't work for some reason tho.
This is the same issue as This is a different issue from (I think I will fix that one separately).

Related discussion:
text: impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> { fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx> { <del> self.map_bound_ref(|trait_pred| trait_pred.trait_ref.clone()) </del> <ins> self.map_bound_ref(|trait_pred| trait_pred.trait_ref) </ins> } }
Code change:
This takes ~2 seconds to type check (according to ): Doubling (respectively, halving) the number of invocations multiplies (resp. divides) the time by 4. It applies to arithmetic in s/s too which is, I imagine, where this will occur most often in practice (it's how I found it). Observations: for , , and , annotating either side (e.g. ) or both sides makes it take only 0.03s and behave linearly (AFAICT) for and : annotating the LHS () reduces the time to ~1.5s, annotating the RHS () reduces it to ~1.1s but both are still quadratic, annotating both takes it to 0.04s and linear it seems to only be dependent on the number of operations in a single function/item, separating the 4 big chunks above across 4 functions reduces the time to ~0.5s. there's no significant difference between using the macro or writing the operations inline (I only use to allow easier experimentation) cc
This must be what's making my old macro-abusing inflate implementation take almost 300 seconds in typeck. It almost sounds like type-checking a function is quadratic over the number of inference variables. Having ran callgrind on the sample and also half of it, I'm seeing the following trace: An unrefined conclusion is that either shouldn't call or should be constant-time.
Is this the same issue as ?
I'm not too familiar with fulfill and infer, but couldn't track the latest snapshot it processed and look at the new information there?
We have exactly for this reason. It doesn't work for some reason tho.
This is the same issue as This is a different issue from (I think I will fix that one separately).

Related discussion:
text: // This is because here `self` has a `Binder` and so does our // return value, so we are preserving the number of binding // levels. <del> ty::Binder(self.0.projection_ty.trait_ref.clone()) </del> <ins> ty::Binder(self.0.projection_ty.trait_ref) </ins> } }
Code change:
All of the following I'm going to describe happens only when expanding doc comments in a macro, using meta fragments, in other contexts it works fine, so it indeed is a thing! A sample of doc comments expansion in a macro can be found at so I'll skip samples and go direct to the point. If I use a escape sequence of usual strings it seems to expand it right there on rustdoc. I have found the issue by trying to do something like the following: When I run I get this panic: When using the outside a code block it does not happen, but if I try a hexadecimal literal outside the code block instead it still panics. I get Interesting but let's try something that is not a null character to see what happens: Ha! I get a in my html output!

Related discussion:
text: tts: vec![TtToken(sp, token::Ident(token::str_to_ident("doc"), token::Plain)), TtToken(sp, token::Eq), <del> TtToken(sp, token::Literal(token::Str_(name), None))], </del> <ins> TtToken(sp, token::Literal(token::StrRaw(name, 0), None))], </ins> close_span: sp, })) }
Code change:
All of the following I'm going to describe happens only when expanding doc comments in a macro, using meta fragments, in other contexts it works fine, so it indeed is a thing! A sample of doc comments expansion in a macro can be found at so I'll skip samples and go direct to the point. If I use a escape sequence of usual strings it seems to expand it right there on rustdoc. I have found the issue by trying to do something like the following: When I run I get this panic: When using the outside a code block it does not happen, but if I try a hexadecimal literal outside the code block instead it still panics. I get Interesting but let's try something that is not a null character to see what happens: Ha! I get a in my html output!

Related discussion:
text: <ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // When expanding a macro, documentation attributes (including documentation comments) must be // passed "as is" without being parsed. Otherwise, some text will be incorrectly interpreted as // escape sequences, leading to an ICE. // // Related issues: #25929, #25943 macro_rules! homura { (#[$x:meta]) => () } homura! { /// madoka x41 } fn main() { } </ins>
Code change:
This does generate code that calls in the vtable, but is not particularly useful. cc
Still a problem?
It's still true, but I'm not especially worried about it.
Isn't it a bug that you can declare such a trait at all? There's no way to implement it, right?
This code is now rejected with:

Related discussion:
text: <ins> // ignore-tidy-linelength // regression test for #26376 trait Foo { fn foo(&self) -> [u8]; } fn foo(f: Option<&dyn Foo>) { if let Some(f) = f { let _ = f.foo(); //~^ ERROR cannot move a value of type [u8]: the size of [u8] cannot be statically determined } } fn main() { foo(None) } </ins>
Code change:
This does generate code that calls in the vtable, but is not particularly useful. cc
Still a problem?
It's still true, but I'm not especially worried about it.
Isn't it a bug that you can declare such a trait at all? There's no way to implement it, right?
This code is now rejected with:

Related discussion:
text: <ins> error[E0161]: cannot move a value of type [u8]: the size of [u8] cannot be statically determined --> $DIR/return-unsized-from-trait-method.rs:11:17 | LL |         let _ = f.foo(); |                 ^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0161`. </ins>
Code change:
Much of the implementation work for rust-lang/rfcs has been done, but there remain some corner cases to fix: [ ] Casts between raw pointers to different traits are accepted but should not be (e.g. ) [ ] Double-check other cases, ensure adequate tests exist
triage: P-high -- I'm giving this high priority since accepting casts that we ought not to is a backwards compatibility risk, though it is mitigated by the fact that afaik the illegal casts yield an ICE (but I haven't done exhaustive testing)
The newly-illegal casts shouldn't be ICE-s (I mean, on nightly). Casts on stable are just randomly ICE-ey.

Related discussion:
text: //! //! where `&.T` and `*T` are references of either mutability, //! and where unsize_kind(`T`) is the kind of the unsize info <del> //! in `T` - a vtable or a length (or `()` if `T: Sized`). </del> <ins> //! in `T` - the vtable for a trait definition (e.g. `fmt::Display` or //! `Iterator`, not `Iterator<Item=u8>`) or a length (or `()` if `T: Sized`). //! //! Note that lengths are not adjusted when casting raw slices - //! `T: *const [u16] as *const [u8]` creates a slice that only includes //! half of the original memory. </ins> //! //! Casting is not transitive, that is, even if `e as U1 as U2` is a valid //! expression, `e as U2` is not necessarily so (in fact it will only be valid if
Code change:
Much of the implementation work for rust-lang/rfcs has been done, but there remain some corner cases to fix: [ ] Casts between raw pointers to different traits are accepted but should not be (e.g. ) [ ] Double-check other cases, ensure adequate tests exist
triage: P-high -- I'm giving this high priority since accepting casts that we ought not to is a backwards compatibility risk, though it is mitigated by the fact that afaik the illegal casts yield an ICE (but I haven't done exhaustive testing)
The newly-illegal casts shouldn't be ICE-s (I mean, on nightly). Casts on stable are just randomly ICE-ey.

Related discussion:
text: /// fat pointers if their unsize-infos have the same kind. #[derive(Copy, Clone, PartialEq, Eq)] enum UnsizeKind<'tcx> { <del> Vtable, </del> <ins> Vtable(ast::DefId), </ins> Length, /// The unsize info of this projection OfProjection(&'tcx ty::ProjectionTy<'tcx>),
Code change:
Much of the implementation work for rust-lang/rfcs has been done, but there remain some corner cases to fix: [ ] Casts between raw pointers to different traits are accepted but should not be (e.g. ) [ ] Double-check other cases, ensure adequate tests exist
triage: P-high -- I'm giving this high priority since accepting casts that we ought not to is a backwards compatibility risk, though it is mitigated by the fact that afaik the illegal casts yield an ICE (but I haven't done exhaustive testing)
The newly-illegal casts shouldn't be ICE-s (I mean, on nightly). Casts on stable are just randomly ICE-ey.

Related discussion:
text: -> Option<UnsizeKind<'tcx>> { match t.sty { ty::TySlice(_) | ty::TyStr => Some(UnsizeKind::Length), <del> ty::TyTrait(_) => Some(UnsizeKind::Vtable), </del> <ins> ty::TyTrait(ref tty) => Some(UnsizeKind::Vtable(tty.principal_def_id())), </ins> ty::TyStruct(did, substs) => { match ty::struct_fields(fcx.tcx(), did, substs).pop() { None => None,
Code change:
Much of the implementation work for rust-lang/rfcs has been done, but there remain some corner cases to fix: [ ] Casts between raw pointers to different traits are accepted but should not be (e.g. ) [ ] Double-check other cases, ensure adequate tests exist
triage: P-high -- I'm giving this high priority since accepting casts that we ought not to is a backwards compatibility risk, though it is mitigated by the fact that afaik the illegal casts yield an ICE (but I haven't done exhaustive testing)
The newly-illegal casts shouldn't be ICE-s (I mean, on nightly). Casts on stable are just randomly ICE-ey.

Related discussion:
text: trait Foo { fn foo(&self) {} } impl<T> Foo for T {} <ins> trait Bar { fn foo(&self) {} } impl<T> Bar for T {} </ins> enum E { A, B }