profile
viewpoint
Bastian Kauschke lcnr Germany NaCl (he/him)

lcnr/crow 90

A simple pixel perfect 2D rendering engine

lcnr/akari 35

A showcase game for the crow rendering engine

distransient/gmtk2019 5

"Only One"

lcnr/computer 2

A simple computer made from scratch

lcnr/binary 1

Efficient type based integers

lcnr/amethyst 0

Data-oriented and data-driven game engine written in Rust

lcnr/arewegameyet 0

The repository for arewegameyet.rs

lcnr/awesome-rust-mentors 0

A list of rust lang mentors tagged by topics of interest

pull request commentrust-lang/rust

Add `has_default` to `GenericParamDefKind::Const`

Hmm, I am not sure how easy it is to start here and think that's it's probably better to start by actually parsing const N: Type = expr, so we can test these changes.

Do we want to implement this as part of const_generics or do we want a new feature gate for this?

Also, while I will review this, I won't merge it myself, so r? @varkor

JulianKnodt

comment created time in 23 minutes

issue commentrust-lang/rust

Const generics unconstrained generics

Considering that anon consts are mostly just projections, wouldn't this be similar to

#![feature(const_generics)]

struct Collatz<T>(T);

trait Foo {
    type Assoc;
}

impl<T: Foo> Collatz<T::Assoc> {}

fn main() {}

which doesn't really make a lot of sense (we have to guarantee that the projection maps each value of T to a unique type).

While Some(N) is injective, finding an intuitive subset of expressions for which this is the case is hard and imo not actually desirable rn.

Not quite sure what's the best error message though :thinking:

probably something like

error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
 --> src/main.rs:5:13
  |
5 | impl <const N: usize> Collatz<{Some(N)}> {
  |             ^ unconstrained const parameter
note: const parameters can be constrained by using them in a trivial expression
DutchGhost

comment created time in 30 minutes

issue closedrust-lang/rust

ICE with const generics with dependent const parameters

#![feature(const_generics)]

fn foo<const N: usize, const A: [u8; N]>() {}

fn bar() {
    foo::<1, {[1]}>();
}

results in an ICE:

error: internal compiler error: src/librustc/ty/subst.rs:597: const parameter `N/#0` (Const { ty: usize, val: Param(N/#0) }/0) out of range when substituting substs=[]

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:584:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:47
   3: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:36
   4: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:200
   5: std::panicking::default_hook
             at src/libstd/panicking.rs:214
   6: rustc::util::common::panic_hook
   7: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:481
   8: std::panicking::begin_panic
   9: rustc_errors::Handler::span_bug
  10: rustc::util::bug::opt_span_bug_fmt::{{closure}}
  11: rustc::ty::context::tls::with_opt::{{closure}}
  12: rustc::ty::context::tls::with_context_opt
  13: rustc::ty::context::tls::with_opt
  14: rustc::util::bug::opt_span_bug_fmt
  15: rustc::util::bug::span_bug_fmt
  16: <rustc::ty::subst::SubstFolder as rustc::ty::fold::TypeFolder>::fold_const
  17: rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable for &rustc::ty::TyS>::super_fold_with
  18: <rustc::ty::subst::SubstFolder as rustc::ty::fold::TypeFolder>::fold_ty
  19: rustc::traits::codegen::<impl rustc::ty::context::TyCtxt>::subst_and_normalize_erasing_regions
  20: rustc::ty::instance::Instance::resolve
  21: <rustc::traits::project::AssocTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_const
  22: <smallvec::SmallVec<A> as core::iter::traits::collect::FromIterator<<A as smallvec::Array>::Item>>::from_iter
  23: rustc::ty::fold::TypeFoldable::fold_with
  24: rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable for &rustc::ty::TyS>::super_fold_with
  25: <rustc::traits::project::AssocTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_ty
  26: rustc::traits::project::normalize
  27: rustc_typeck::check::FnCtxt::instantiate_value_path
  28: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  29: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::check_call
  30: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  31: rustc_typeck::check::FnCtxt::check_stmt
  32: rustc_typeck::check::FnCtxt::check_block_with_expected
  33: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  34: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_return_expr
  35: rustc_typeck::check::check_fn
  36: rustc::ty::context::GlobalCtxt::enter_local
  37: rustc_typeck::check::typeck_tables_of
  38: rustc::ty::query::__query_compute::typeck_tables_of
  39: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::typeck_tables_of>::compute
  40: rustc::dep_graph::graph::DepGraph::with_task_impl
  41: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  42: rustc::ty::<impl rustc::ty::context::TyCtxt>::par_body_owners
  43: rustc_typeck::check::typeck_item_bodies
  44: rustc::ty::query::__query_compute::typeck_item_bodies
  45: rustc::dep_graph::graph::DepGraph::with_task_impl
  46: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  47: rustc::util::common::time
  48: rustc_typeck::check_crate
  49: rustc_interface::passes::analysis
  50: rustc::ty::query::__query_compute::analysis
  51: rustc::dep_graph::graph::DepGraph::with_task_impl
  52: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  53: rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}
  54: rustc_interface::passes::create_global_ctxt::{{closure}}
  55: rustc_interface::interface::run_compiler_in_existing_thread_pool
  56: std::thread::local::LocalKey<T>::with
  57: scoped_tls::ScopedKey<T>::set
  58: syntax::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
query stack during panic:
#0 [typeck_tables_of] processing `bar`
#1 [typeck_item_bodies] type-checking all item bodies
#2 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to previous error


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

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

note: rustc 1.38.0-nightly (4b65a86eb 2019-07-15) running on x86_64-unknown-linux-gnu

closed time in 42 minutes

Centril

Pull request review commentrust-lang/rust

Add `has_default` to `GenericParamDefKind::Const`

 impl<'tcx> TyCtxt<'tcx> {         let adt_def = self.adt_def(wrapper_def_id);         let substs =             InternalSubsts::for_item(self, wrapper_def_id, |param, substs| match param.kind {-                GenericParamDefKind::Lifetime | GenericParamDefKind::Const => bug!(),+                GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => bug!(),

I think you have to deal with Const here

JulianKnodt

comment created time in an hour

Pull request review commentrust-lang/rust

Add `has_default` to `GenericParamDefKind::Const`

 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {             .rev()             .filter_map(|param| match param.kind {                 ty::GenericParamDefKind::Lifetime => None,-                ty::GenericParamDefKind::Type { has_default, .. } => {++                ty::GenericParamDefKind::Type { has_default, .. } |+                // FIXME(const_generics:defaults)

isn't that fixme outdated now?

JulianKnodt

comment created time in an hour

pull request commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

@bors r+ rollup=iffy

affects all tests in src/test/ui/const-generics.

JulianKnodt

comment created time in an hour

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

+// Checks that `impl Trait<{anon_const}>` evaluates successfully.
// Checks that `impl Trait<{anon_const}> for Type` evaluates successfully.

impl Trait has a slightly different meaning :sweat_smile:

JulianKnodt

comment created time in 10 hours

pull request commentrust-lang/rust

polymorphize: constrain unevaluated const handling

@bors r+ rollup

davidtwco

comment created time in 18 hours

pull request commentrust-lang/rust

Use existing `infcx` when emitting trait impl diagnostic

@bors r+ rollup

Aaron1011

comment created time in 18 hours

Pull request review commentrust-lang/rust

Use existing `infcx` when emitting trait impl diagnostic

+error[E0106]: missing lifetime specifier+  --> $DIR/issue-74918-missing-lifetime.rs:9:31+   |+LL |     type Item = IteratorChunk<T, S>;+   |                               ^ expected named lifetime parameter+   |+help: consider introducing a named lifetime parameter+   |+LL |     type Item<'a> = IteratorChunk<<'a>T, S>;

do we already have an issue for this error message?

Aaron1011

comment created time in 18 hours

Pull request review commentrust-lang/rust

polymorphize: constrain unevaluated const handling

+// build-pass+// compile-flags: -Zpolymorphize=on -Zmir-opt-level=3++fn caller<T, U>() -> &'static usize {+    callee::<U>()+}++fn callee<T>() -> &'static usize {+    &std::mem::size_of::<T>()+}++fn main() {+    assert_eq!(caller::<(), ()>(), &7);

:sweat_smile: can you change this to run-pass and &0?

r=me afterwards

davidtwco

comment created time in 18 hours

pull request commentrust-lang/rust

polymorphisation: re-enable

@craterbot abort

davidtwco

comment created time in 19 hours

pull request commentrust-lang/rust

Minimize the cost of write_fmt without arguments

@bors try @rust-timer queue

lzutao

comment created time in 20 hours

PR opened rust-lang/rust

unused_delims: trim expr

improves rustfix output.

+26 -24

0 comment

5 changed files

pr created time in 20 hours

create barnchlcnr/rust

branch : unused-delims-trim

created branch time in 20 hours

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

 #![feature(const_generics)]-//~^ WARN the feature `const_generics` is incomplete+#![allow(incomplete_features)]

is there a reason you are not testing min_const_generics here?

JulianKnodt

comment created time in 21 hours

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

 // check-pass

Is there a reason why we aren't actually calling these functions here?

It would be nice to change main to

fn main() {
    takes_closure_of_array_3(returns_closure_of_array_3());
    takes_closure_of_array_3_apit(returns_closure_of_array_3());
}
JulianKnodt

comment created time in 21 hours

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

-#![feature(const_generics)]-//~^ WARN the feature `const_generics` is incomplete+// Assert that cannot use const generics as ptrs and cannot deref them.
// Checks that pointers must not be used as the type of const params.

or sth

JulianKnodt

comment created time in 21 hours

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

 // run-pass+// revisions: full+// FIXME Omitted min revision for now due to ICE.
// FIXME(#75323): Omitted min revision for now due to ICE.
JulianKnodt

comment created time in 21 hours

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

-#![feature(const_generics)]-//~^ WARN the feature `const_generics` is incomplete+// Check that different const types are different.+// revisions: full min++#![cfg_attr(full, feature(const_generics))]+#![cfg_attr(full, allow(incomplete_features))]+#![cfg_attr(min, feature(min_const_generics))]  struct Const<const V: [usize; 1]> {}+//[min]~^ using `[usize; 1]` as const generic parameters is forbidden  fn main() {     let mut x = Const::<{ [3] }> {};     x = Const::<{ [4] }> {};-    //~^ ERROR mismatched types-+    //[full]~^ ERROR mismatched types

can you add a copy of that test using V: usize instead of V: [usize: 1]?

JulianKnodt

comment created time in 21 hours

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

+// Check that const args in functions can be used.

imo this is fairly redundant

JulianKnodt

comment created time in 21 hours

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

+// Check `const fn` with const param is alright
// Checks that `const fn` with const params can be used.

or sth like that

JulianKnodt

comment created time in 21 hours

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

-#![feature(const_generics)]-//~^ WARN the feature `const_generics` is incomplete+// Tests that array sizes that depend on const-params does not yet work.

that's not quite true. This test pretty much checks that array lengths used in structs are checked using ConstEvaluatable.

struct Foo<const N: usize>([u32; N]); already works

JulianKnodt

comment created time in 21 hours

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

+// Checks whether conditions in traits can be evaluated.

This doesn't seem right to me :thinking: This only checks that impl Trait<{anon_const}> evaluates successfully.

JulianKnodt

comment created time in 21 hours

pull request commentrust-lang/rust

polymorphisation: re-enable

We will have to start a new crater run considering the recent changes: @craterbot abort

davidtwco

comment created time in 21 hours

Pull request review commentrust-lang/rust

polymorphize: constrain unevaluated const handling

 impl<'a, 'tcx> TypeVisitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> {                 self.unused_parameters.clear(param.index);                 false             }-            ty::ConstKind::Unevaluated(_, _, Some(p)) => {+            ty::ConstKind::Unevaluated(def, _, Some(p))+                // Avoid considering `T` unused when constants are of the form:+                //   `<Self as Foo<T>>::foo::promoted[p]`+                if !self.tcx.generics_of(def.did).has_self =>+            {                 // If there is a promoted, don't look at the substs - since it will always contain                 // the generic parameters, instead, traverse the promoted MIR.-                let promoted = self.tcx.promoted_mir(self.def_id);+                let promoted = self.tcx.promoted_mir(def.did);                 self.visit_body(&promoted[p]);

https://rust.godbolt.org/z/s8rd99

davidtwco

comment created time in a day

Pull request review commentrust-lang/rust

polymorphize: constrain unevaluated const handling

 impl<'a, 'tcx> TypeVisitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> {                 self.unused_parameters.clear(param.index);                 false             }-            ty::ConstKind::Unevaluated(_, _, Some(p)) => {+            ty::ConstKind::Unevaluated(def, _, Some(p))+                // Avoid considering `T` unused when constants are of the form:+                //   `<Self as Foo<T>>::foo::promoted[p]`+                if !self.tcx.generics_of(def.did).has_self =>+            {                 // If there is a promoted, don't look at the substs - since it will always contain                 // the generic parameters, instead, traverse the promoted MIR.-                let promoted = self.tcx.promoted_mir(self.def_id);+                let promoted = self.tcx.promoted_mir(def.did);                 self.visit_body(&promoted[p]);

unless we're in the MIR inliner, apparently - which shouldn't be a problem for us

not unless we're in the MIR inliner, unless we use the mir inliner. The following breaks:

// compile-flags: -Zpolymorphize=on -Zmir-opt-level=3
#![feature(rustc_attrs)]

fn caller<T, U>() -> &'static usize {
    callee::<U>()
}

fn callee<T>() -> &'static usize {
    &std::mem::size_of::<T>()
}

fn main() {
    assert_eq!(caller::<(), ()>(), &7);
}

thread 'rustc' panicked at 'index out of bounds: the len is 0 but the index is 0', src/librustc_mir/monomorphize/polymorphize.rs:276:34

davidtwco

comment created time in a day

Pull request review commentrust-lang/rust

polymorphize: constrain unevaluated const handling

 impl<'a, 'tcx> TypeVisitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> {                 self.unused_parameters.clear(param.index);                 false             }-            ty::ConstKind::Unevaluated(_, _, Some(p)) => {+            ty::ConstKind::Unevaluated(def, _, Some(p))+                // Avoid considering `T` unused when constants are of the form:+                //   `<Self as Foo<T>>::foo::promoted[p]`+                if !self.tcx.generics_of(def.did).has_self =>+            {                 // If there is a promoted, don't look at the substs - since it will always contain                 // the generic parameters, instead, traverse the promoted MIR.-                let promoted = self.tcx.promoted_mir(self.def_id);+                let promoted = self.tcx.promoted_mir(def.did);                 self.visit_body(&promoted[p]);

What happens here if the def.did != self.def_id. Aren't we then treating the ty::Param of the promoted mir as params of self.def_id?

Should we just constrain this to if !self.tcx.generics_of(def.did).has_self && self.def_id == def.did for now or am I misunderstanding something here?

davidtwco

comment created time in a day

Pull request review commentrust-lang/rust

Detect JS-style `===` and `!==` and recover

 impl<'a> Parser<'a> {                     return Ok(expr);                 }             }++            if (op.node == AssocOp::Equal || op.node == AssocOp::NotEqual)+                && self.token.kind == token::Eq

My main concern is that the error message will mention === which isn't what's actually written, but that really isn't important enough to spend a lot of time on :laughing: so feel free to go ahead and merge this even if you don't want to fix this

estebank

comment created time in a day

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

-#![feature(const_generics)]-#![allow(incomplete_features)]+// Checks errors when there is an abstract data type.

I feel like this line doesn't help much/is slightly incorrect rn.

This test checks that type_of does not break for const args on unknown types.

Also, adt means "algebraic data type", not "abstract dt" :sparkles:

JulianKnodt

comment created time in 2 days

Pull request review commentrust-lang/rust

Add a bunch of const-generic revisions for `min_const_generics`

-#![feature(const_generics)]-//~^ WARN the feature `const_generics` is incomplete+// Test if emits error if cannot properly infer constant.
// Test that we emit an error if we cannot properly infer a constant.

words

JulianKnodt

comment created time in 2 days

Pull request review commentrust-lang/rust

Detect JS-style `===` and `!==` and recover

 impl<'a> Parser<'a> {                     return Ok(expr);                 }             }++            if (op.node == AssocOp::Equal || op.node == AssocOp::NotEqual)+                && self.token.kind == token::Eq

how does this deal with a == = B?

estebank

comment created time in 2 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

 pub type GenericBounds = Vec<GenericBound>; pub enum ParamKindOrd {     Lifetime,     Type,-    // unordered is only true if sess.has_features().const_generics-    // is active. Specifically, if it's only `min_const_generics`, it will still require ordered-    // types.+    // `unordered` is only `true` if `sess.has_features().const_generics`+    // is active. Specifically, if it's only `min_const_generics`, it will still require+    // ordering `const`s after `type`s.     Const { unordered: bool }, } -impl PartialOrd for ParamKindOrd {-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {+impl Ord for ParamKindOrd {+    fn cmp(&self, other: &Self) -> Ordering {         use ParamKindOrd::*;-        let ord = match self {-            &Lifetime if other == &Lifetime => Ordering::Equal,-            &Lifetime => Ordering::Less,--            &Type if other == &Lifetime => Ordering::Greater,-            &Type if other == &Type || other == &Const { unordered: true } => Ordering::Equal,-            &Type => Ordering::Less,--            &Const { .. } if other == &Lifetime => Ordering::Greater,--            &Const { unordered: false } if other == &Type => Ordering::Greater,+        match (self, other) {+            (&Lifetime, &Lifetime) => Ordering::Equal,+            (&Lifetime, _) => Ordering::Less,+            (_, &Lifetime) => Ordering::Greater,+            (&Type | &Const { unordered: true }, &Type | &Const { unordered: true }) => {+                Ordering::Equal+            }+            (&Type, &Const { unordered: false }) => Ordering::Less,+            (&Const { unordered: false }, &Type) => Ordering::Greater,

nit: you can remove the & here due to match ergonomics.

If you don't want to rely on that, you can also match on (*self, *other) :thinking:

I think in general that this match is slightly too complex for what it wants to do, maybe something like

let to_int = |v| match v {
    Lifetime => 0,
    Type | Const { unordered: true } => 1,
    Const { unordered: false } => 2,
};

to_int(self).cmp(to_int(other))
JulianKnodt

comment created time in 2 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

+//[const_gens] run-pass // Verifies that having generic parameters after constants is not permitted without the // `const_generics` feature.+// revisions: none const_gens++#![cfg_attr(const_gens, feature(const_generics))]+#![cfg_attr(const_gens, allow(incomplete_features))]

Can you add a revision for min_const_generics here?

JulianKnodt

comment created time in 2 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

 pub type GenericBounds = Vec<GenericBound>; pub enum ParamKindOrd {     Lifetime,     Type,-    // unordered is only true if sess.has_features().const_generics-    // is active. Specifically, if it's only `min_const_generics`, it will still require ordered-    // types.+    // `unordered` is only `true` if `sess.has_features().const_generics`+    // is active. Specifically, if it's only `min_const_generics`, it will still require+    // ordering `const`s after `type`s.
    // ordering consts after types.

const and type aren't variables here :laughing:

JulianKnodt

comment created time in 2 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

 pub type GenericBounds = Vec<GenericBound>; pub enum ParamKindOrd {     Lifetime,     Type,-    // unordered is only true if sess.has_features().const_generics-    // is active. Specifically, if it's only `min_const_generics`, it will still require ordered-    // types.+    // `unordered` is only `true` if `sess.has_features().const_generics`+    // is active. Specifically, if it's only `min_const_generics`, it will still require+    // ordering `const`s after `type`s.     Const { unordered: bool }, } -impl PartialOrd for ParamKindOrd {-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {+impl Ord for ParamKindOrd {+    fn cmp(&self, other: &Self) -> Ordering {         use ParamKindOrd::*;-        let ord = match self {-            &Lifetime if other == &Lifetime => Ordering::Equal,-            &Lifetime => Ordering::Less,--            &Type if other == &Lifetime => Ordering::Greater,-            &Type if other == &Type || other == &Const { unordered: true } => Ordering::Equal,-            &Type => Ordering::Less,--            &Const { .. } if other == &Lifetime => Ordering::Greater,--            &Const { unordered: false } if other == &Type => Ordering::Greater,+        match (self, other) {+            (&Lifetime, &Lifetime) => Ordering::Equal,+            (&Lifetime, _) => Ordering::Less,+            (_, &Lifetime) => Ordering::Greater,+            (&Type | &Const { unordered: true }, &Type | &Const { unordered: true }) => {+                Ordering::Equal+            }+            (&Type, &Const { unordered: false }) => Ordering::Less,+            (&Const { unordered: false }, &Type) => Ordering::Greater, -            &Const { .. } => Ordering::Equal,-        };-        Some(ord)+            (&Const { .. }, &Const { .. }) => Ordering::Equal,+        }     } }-impl Ord for ParamKindOrd {-    fn cmp(&self, other: &Self) -> Ordering {-        self.partial_cmp(other).unwrap()+impl PartialOrd for ParamKindOrd {+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {+        Some(self.cmp(&other))
        Some(self.cmp(other))

afaict the ref is unnecessary here

JulianKnodt

comment created time in 2 days

delete branch rust-lang/rust

delete branch : min_const_generics-version

delete time in 2 days

pull request commentrust-lang/rust

Note when a a move/borrow error is caused by a deref coercion

hmm, I don't see any obvious problems here, but am not really familiar enough with what's touched here,

maybe r? @estebank

Aaron1011

comment created time in 2 days

Pull request review commentrust-lang/rust

Note when a a move/borrow error is caused by a deref coercion

 pub(super) enum UseSpans { }  #[derive(Copy, Clone, PartialEq, Eq, Debug)]-pub(super) enum FnSelfUseKind {+pub(super) enum FnSelfUseKind<'tcx> {     /// A normal method call of the form `receiver.foo(a, b, c)`-    Normal { self_arg: Ident, implicit_into_iter: bool },+    Normal {+        self_arg: Ident,+        implicit_into_iter: bool,+    },     /// A call to `FnOnce::call_once`, desugared from `my_closure(a, b, c)`     FnOnceCall,     /// A call to an operator trait, desuraged from operator syntax (e.g. `a << b`)-    Operator { self_arg: Ident },+    Operator {+        self_arg: Ident,+    },+    DerefCoercion {+        deref_target: Span,+        deref_ty: Ty<'tcx>,
        deref_origin_ty: Ty<'tcx>,

or something like this, it wasn't instantly clear to me if this is T or T::Deref

Aaron1011

comment created time in 2 days

pull request commentrust-lang/rust

polymorphisation: re-enable

can quickly fix this myself :sweat_smile:

davidtwco

comment created time in 2 days

pull request commentrust-lang/rust

polymorphisation: re-enable

looks like we can get cycle errors with associated consts

davidtwco

comment created time in 2 days

pull request commentrust-lang/rust

polymorphisation: re-enable

yeah, we can then also reuse this PR for perf :sparkles:

davidtwco

comment created time in 2 days

pull request commentrust-lang/rust

polymorphisation: re-enable

Should we rebase this and requeue the crater run, considering the recent changes?

davidtwco

comment created time in 2 days

pull request commentrust-lang/rust

Add `array` lang item and `[T; N]::map(f: FnMut(T) -> S)`

@LukasKalbertodt seeing that you are interested in this method, can I assign the rest to you?

As I am not a libs team member I don't think I should merge this myself :thinking:

r? @LukasKalbertodt feel free to reassign though

JulianKnodt

comment created time in 3 days

Pull request review commentrust-lang/rust

Implement the `min_const_generics` feature gate

 declare_features! (     /// Alloc calling `transmute` in const fn     (active, const_fn_transmute, "1.46.0", Some(53605), None), +    /// The smallest useful subset of `const_generics`.+    (active, min_const_generics, "1.46.0", Some(74878), None),

thx, opened #75290

lcnr

comment created time in 3 days

PR opened rust-lang/rust

fix `min_const_generics` version

https://github.com/rust-lang/rust/pull/74877#discussion_r467451813

This should be 1.47.0

+1 -1

0 comment

1 changed file

pr created time in 3 days

create barnchrust-lang/rust

branch : min_const_generics-version

created branch time in 3 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

+// run-pass

afaik the name is somewhat misleading here?

I think we probably should move this out of defaults, considering that it doesn't use defaults

JulianKnodt

comment created time in 3 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

+// run-pass+// Verifies that having generic parameters after constants is permitted.++#![feature(const_generics)]+#![allow(incomplete_features)]++struct A<const N: usize, T=u32>(T);

Imo it's probably better to unify this test with src/test/ui/const-generics/defaults/needs-feature.rs and use revisions here.

JulianKnodt

comment created time in 3 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

 pub type GenericBounds = Vec<GenericBound>; /// Specifies the enforced ordering for generic parameters. In the future, /// if we wanted to relax this order, we could override `PartialEq` and /// `PartialOrd`, to allow the kinds to be unordered.-#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]+#[derive(PartialEq, Eq, Hash, Clone, Copy)] pub enum ParamKindOrd {     Lifetime,     Type,-    Const,+    // unordered is only true if sess.has_features().const_generics+    // is active. Specifically, if it's only `min_const_generics`, it will still require ordered+    // types.+    Const { unordered: bool },+}++impl PartialOrd for ParamKindOrd {+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {+        use ParamKindOrd::*;+        let ord = match self {+            &Lifetime if other == &Lifetime => Ordering::Equal,+            &Lifetime => Ordering::Less,++            &Type if other == &Lifetime => Ordering::Greater,+            &Type if other == &Type || other == &Const { unordered: true } => Ordering::Equal,+            &Type => Ordering::Less,++            &Const { .. } if other == &Lifetime => Ordering::Greater,++            &Const { unordered: false } if other == &Type => Ordering::Greater,++            &Const { .. } => Ordering::Equal,+        };+        Some(ord)+    }+}+impl Ord for ParamKindOrd {+    fn cmp(&self, other: &Self) -> Ordering {+        self.partial_cmp(other).unwrap()

wouldn't it make more sense to implement Ord and use Some(self.cmp(other)) in PartialOrd?

JulianKnodt

comment created time in 3 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

+// run-pass+// Checks a complicated usage of unordered params++#![feature(const_generics)]+#![allow(incomplete_features)]+#![allow(dead_code)]++struct FixedOutput<'a, const N: usize, T=u32> {+  out: &'a [T; N],+}++trait FixedOutputter {+  fn out(&self) -> FixedOutput<'_, 10>;+}

I don't think FixedOutput is used in the rest of the example...

It might make sense to move it into a different test, maybe simple-defaults.rs or sth :thinking:

JulianKnodt

comment created time in 3 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

 pub type GenericBounds = Vec<GenericBound>; /// Specifies the enforced ordering for generic parameters. In the future, /// if we wanted to relax this order, we could override `PartialEq` and /// `PartialOrd`, to allow the kinds to be unordered.-#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]+#[derive(PartialEq, Eq, Hash, Clone, Copy)] pub enum ParamKindOrd {     Lifetime,     Type,-    Const,+    // unordered is only true if sess.has_features().const_generics+    // is active. Specifically, if it's only `min_const_generics`, it will still require ordered+    // types.+    Const { unordered: bool },+}++impl PartialOrd for ParamKindOrd {+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {+        use ParamKindOrd::*;+        let ord = match self {

You can use match (self, other) here which is cleaner in my opinion.

Using feature(or_patterns) we can also write the following here:

(
    ParamKindOrd::Type | ParamKindOrd::Const { unordered: true },
    ParamKindOrd::Type | ParamKindOrd::Const { unordered: true }
) => true
JulianKnodt

comment created time in 3 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

 pub type GenericBounds = Vec<GenericBound>; /// Specifies the enforced ordering for generic parameters. In the future, /// if we wanted to relax this order, we could override `PartialEq` and /// `PartialOrd`, to allow the kinds to be unordered.-#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]+#[derive(PartialEq, Eq, Hash, Clone, Copy)] pub enum ParamKindOrd {     Lifetime,     Type,-    Const,+    // unordered is only true if sess.has_features().const_generics+    // is active. Specifically, if it's only `min_const_generics`, it will still require ordered+    // types.
    // `unordered` is only `true` if `sess.has_features().const_generics`
    // is active. Specifically, if it's only `min_const_generics`, it will still require ordered
    // types.

nit: also what are "ordered types" here

JulianKnodt

comment created time in 3 days

issue openedrust-lang/rust

Use revisions to test `min_const_generics`

cc #74878

#74877 implemented feature(min_const_generics) which is split off from feature(const_generics).

As these two features have some meaningful differences it is desirable to run try and run all const generics tests with both features.

An example for how this can be done is in https://github.com/rust-lang/rust/blob/f9c2177ddc605f9c75ca1a3e6ddb33835b8a178d/src/test/ui/const-generics/issues/issue-56445.rs#L1-L13

If you want to work on this feel free to ask for help here or on zulip.

created time in 3 days

delete branch lcnr/rust

delete branch : min_const_generics

delete time in 3 days

pull request commentrust-lang/rust

Implement the `min_const_generics` feature gate

network failure

@bors retry

lcnr

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

+// build-pass+// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0++fn foo(f: impl Fn()) {+    // Mutate a upvar from `x` so that it implements `FnMut`.
    // Mutate an upvar from `x` so that it implements `FnMut`.
davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    struct PolymorphizationFolder<'tcx> {+        tcx: TyCtxt<'tcx>,+    };++    impl ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> {+        fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {+            self.tcx+        }++        fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {+            debug!("fold_ty: ty={:?}", ty);+            match ty.kind {+                ty::Closure(def_id, substs) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_closure(def_id, polymorphized_substs)+                }+                ty::Generator(def_id, substs, movability) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_generator(def_id, polymorphized_substs, movability)+                }+                _ => ty.super_fold_with(self),

This probably also has the mangling issue :thinking: not really sure about how mangling works for FnDef though

davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    struct PolymorphizationFolder<'tcx> {+        tcx: TyCtxt<'tcx>,+    };++    impl ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> {+        fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {+            self.tcx+        }++        fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {+            debug!("fold_ty: ty={:?}", ty);+            match ty.kind {+                ty::Closure(def_id, substs) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_closure(def_id, polymorphized_substs)+                }+                ty::Generator(def_id, substs, movability) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_generator(def_id, polymorphized_substs, movability)+                }+                _ => ty.super_fold_with(self),

this should allow us to optimize the following I think

fn unused<T>() -> u64 {
    42
}

fn test<T>() {
    std::iter::repeat(unused::<T>).take(10);
}

pub fn main() {
    test::<String>();
    test::<Vec<String>>();
}
davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    struct PolymorphizationFolder<'tcx> {+        tcx: TyCtxt<'tcx>,+    };++    impl ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> {+        fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {+            self.tcx+        }++        fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {+            debug!("fold_ty: ty={:?}", ty);+            match ty.kind {+                ty::Closure(def_id, substs) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_closure(def_id, polymorphized_substs)

nit: it's slightly more performant to check substs != polymorphized_substs here to prevent unnecessary hashmap lookups, similar to https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.reuse_or_mk_region

davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    struct PolymorphizationFolder<'tcx> {+        tcx: TyCtxt<'tcx>,+    };++    impl ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> {+        fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {+            self.tcx+        }++        fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {+            debug!("fold_ty: ty={:?}", ty);+            match ty.kind {+                ty::Closure(def_id, substs) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_closure(def_id, polymorphized_substs)+                }+                ty::Generator(def_id, substs, movability) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_generator(def_id, polymorphized_substs, movability)+                }+                _ => ty.super_fold_with(self),

This is not that related to this PR itself, but why aren't we doing the same for FnDef here?

davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

polymorphize: visit promoted MIR

 impl<'a, 'tcx> TypeVisitor<'tcx> for UsedGenericParametersVisitor<'a, 'tcx> {                 self.unused_parameters.clear(param.index);                 false             }+            ty::ConstKind::Unevaluated(_, _, Some(p)) => {

We actually have the same problem for other unevaluated constants:

#![feature(lazy_normalization_consts)]

fn test<T>() {
    let x = [0; 3 + 4];
}

pub fn caller() {
    test::<String>();
    test::<Vec<String>>();
}

But afaict that doesn't concern stable rn, not completely sure if we can end up with cycle errors here, but I think we should be fine and able to use unused_generic_params here (or we just have to restrict this to DefKind::AnonConst for now)

davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

+// build-pass+// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0++fn foo(f: impl Fn()) {+    let x = |_: ()| ();++    // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to+    // `x` that will differ for each instantiation despite polymorphisation of the varying+    // argument.+    let y = || x(());

Can y consider f unused if it uses x which considers it used?

davidtwco

comment created time in 4 days

pull request commentrust-lang/rust

Add missing backtick

@bors r+ rollup

giraffate

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    if unused.is_empty() {+        // Exit early if every parameter was used.+        return substs;+    }++    // If this is a closure or generator then we need to handle the case where another closure+    // from the function is captured as an upvar and hasn't been polymorphized. In this case,+    // the unpolymorphized upvar closure would result in a polymorphized closure producing+    // multiple mono items (and eventually symbol clashes).+    let upvars_ty = if tcx.is_closure(def_id) {+        Some(substs.as_closure().tupled_upvars_ty())+    } else if tcx.type_of(def_id).is_generator() {+        Some(substs.as_generator().tupled_upvars_ty())+    } else {+        None+    };+    let has_upvars = upvars_ty.map(|ty| ty.tuple_fields().count() > 0).unwrap_or(false);+    debug!("polymorphize: upvars_ty={:?} has_upvars={:?}", upvars_ty, has_upvars);++    struct PolymorphizationFolder<'tcx> {+        tcx: TyCtxt<'tcx>,+    };++    impl ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> {+        fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {+            self.tcx+        }++        fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {+            debug!("fold_ty: ty={:?}", ty);+            match ty.kind {+                ty::Closure(def_id, substs) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_closure(def_id, polymorphized_substs)+                }+                ty::Generator(def_id, substs, movability) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_generator(def_id, polymorphized_substs, movability)+                }+                _ => ty.super_fold_with(self),+            }+        }+    }++    InternalSubsts::for_item(tcx, def_id, |param, _| {+        let is_unused = unused.contains(param.index).unwrap_or(false);+        debug!("polymorphize: param={:?} is_unused={:?}", param, is_unused);+        match param.kind {+            // Upvar case: If parameter is a type parameter..+            ty::GenericParamDefKind::Type { .. } if+                // ..and has upvars..+                has_upvars &&+                // ..and this param has the same type as the tupled upvars..+                upvars_ty == Some(substs[param.index as usize].expect_ty()) => {+                    // ..then double-check that polymorphization marked it used..+                    debug_assert!(!is_unused);+                    // ..and polymorphize any closures/generators captured as upvars.+                    let upvars_ty = upvars_ty.unwrap();+                    let polymorphized_upvars_ty = upvars_ty.fold_with(+                        &mut PolymorphizationFolder { tcx });+                    debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty);+                    ty::GenericArg::from(polymorphized_upvars_ty)+                },++            // Simple case: If parameter is a const or type parameter..+            ty::GenericParamDefKind::Const | ty::GenericParamDefKind::Type { .. } if+                // ..and is within range and unused..+                unused.contains(param.index).unwrap_or(false) =>+                    // ..then use the identity for this parameter.+                    tcx.mk_param_from_def(param),++            // Otherwise, use the parameter as before.+            _ => substs[param.index as usize],

And I think this should actually happen somewhat frequently with iterator adapters in generic functions

davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    if unused.is_empty() {+        // Exit early if every parameter was used.+        return substs;+    }++    // If this is a closure or generator then we need to handle the case where another closure+    // from the function is captured as an upvar and hasn't been polymorphized. In this case,+    // the unpolymorphized upvar closure would result in a polymorphized closure producing+    // multiple mono items (and eventually symbol clashes).+    let upvars_ty = if tcx.is_closure(def_id) {+        Some(substs.as_closure().tupled_upvars_ty())+    } else if tcx.type_of(def_id).is_generator() {+        Some(substs.as_generator().tupled_upvars_ty())+    } else {+        None+    };+    let has_upvars = upvars_ty.map(|ty| ty.tuple_fields().count() > 0).unwrap_or(false);+    debug!("polymorphize: upvars_ty={:?} has_upvars={:?}", upvars_ty, has_upvars);++    struct PolymorphizationFolder<'tcx> {+        tcx: TyCtxt<'tcx>,+    };++    impl ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> {+        fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {+            self.tcx+        }++        fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {+            debug!("fold_ty: ty={:?}", ty);+            match ty.kind {+                ty::Closure(def_id, substs) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_closure(def_id, polymorphized_substs)+                }+                ty::Generator(def_id, substs, movability) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_generator(def_id, polymorphized_substs, movability)+                }+                _ => ty.super_fold_with(self),+            }+        }+    }++    InternalSubsts::for_item(tcx, def_id, |param, _| {+        let is_unused = unused.contains(param.index).unwrap_or(false);+        debug!("polymorphize: param={:?} is_unused={:?}", param, is_unused);+        match param.kind {+            // Upvar case: If parameter is a type parameter..+            ty::GenericParamDefKind::Type { .. } if+                // ..and has upvars..+                has_upvars &&+                // ..and this param has the same type as the tupled upvars..+                upvars_ty == Some(substs[param.index as usize].expect_ty()) => {+                    // ..then double-check that polymorphization marked it used..+                    debug_assert!(!is_unused);+                    // ..and polymorphize any closures/generators captured as upvars.+                    let upvars_ty = upvars_ty.unwrap();+                    let polymorphized_upvars_ty = upvars_ty.fold_with(+                        &mut PolymorphizationFolder { tcx });+                    debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty);+                    ty::GenericArg::from(polymorphized_upvars_ty)+                },++            // Simple case: If parameter is a const or type parameter..+            ty::GenericParamDefKind::Const | ty::GenericParamDefKind::Type { .. } if+                // ..and is within range and unused..+                unused.contains(param.index).unwrap_or(false) =>+                    // ..then use the identity for this parameter.+                    tcx.mk_param_from_def(param),++            // Otherwise, use the parameter as before.+            _ => substs[param.index as usize],

My concern is the following: https://rust.godbolt.org/z/fGeseM

We currently create 2 instances of slice::Iter::map here, while after this change we probably only create one

davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

+// build-pass+// compile-flags:-Zpolymorphize=on -Zsymbol-mangling-version=v0++fn foo(f: impl Fn()) {+    let x = |_: ()| ();++    // Don't use `f` in `y`, but refer to `x` so that the closure substs contain a reference to+    // `x` that will differ for each instantiation despite polymorphisation of the varying+    // argument.+    let y = || x(());

What happens if y considers f used and x doesn't?

davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    if unused.is_empty() {+        // Exit early if every parameter was used.+        return substs;+    }++    // If this is a closure or generator then we need to handle the case where another closure+    // from the function is captured as an upvar and hasn't been polymorphized. In this case,+    // the unpolymorphized upvar closure would result in a polymorphized closure producing+    // multiple mono items (and eventually symbol clashes).+    let upvars_ty = if tcx.is_closure(def_id) {

I had a misconception on what we are actually doing here :+1:

davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    if unused.is_empty() {+        // Exit early if every parameter was used.+        return substs;+    }++    // If this is a closure or generator then we need to handle the case where another closure+    // from the function is captured as an upvar and hasn't been polymorphized. In this case,+    // the unpolymorphized upvar closure would result in a polymorphized closure producing+    // multiple mono items (and eventually symbol clashes).+    let upvars_ty = if tcx.is_closure(def_id) {+        Some(substs.as_closure().tupled_upvars_ty())+    } else if tcx.type_of(def_id).is_generator() {+        Some(substs.as_generator().tupled_upvars_ty())+    } else {+        None+    };+    let has_upvars = upvars_ty.map(|ty| ty.tuple_fields().count() > 0).unwrap_or(false);+    debug!("polymorphize: upvars_ty={:?} has_upvars={:?}", upvars_ty, has_upvars);++    struct PolymorphizationFolder<'tcx> {+        tcx: TyCtxt<'tcx>,+    };++    impl ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> {+        fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {+            self.tcx+        }++        fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {+            debug!("fold_ty: ty={:?}", ty);+            match ty.kind {+                ty::Closure(def_id, substs) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_closure(def_id, polymorphized_substs)+                }+                ty::Generator(def_id, substs, movability) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_generator(def_id, polymorphized_substs, movability)+                }+                _ => ty.super_fold_with(self),+            }+        }+    }++    InternalSubsts::for_item(tcx, def_id, |param, _| {+        let is_unused = unused.contains(param.index).unwrap_or(false);+        debug!("polymorphize: param={:?} is_unused={:?}", param, is_unused);+        match param.kind {+            // Upvar case: If parameter is a type parameter..+            ty::GenericParamDefKind::Type { .. } if+                // ..and has upvars..+                has_upvars &&+                // ..and this param has the same type as the tupled upvars..+                upvars_ty == Some(substs[param.index as usize].expect_ty()) => {+                    // ..then double-check that polymorphization marked it used..+                    debug_assert!(!is_unused);+                    // ..and polymorphize any closures/generators captured as upvars.+                    let upvars_ty = upvars_ty.unwrap();+                    let polymorphized_upvars_ty = upvars_ty.fold_with(+                        &mut PolymorphizationFolder { tcx });+                    debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty);+                    ty::GenericArg::from(polymorphized_upvars_ty)+                },++            // Simple case: If parameter is a const or type parameter..+            ty::GenericParamDefKind::Const | ty::GenericParamDefKind::Type { .. } if+                // ..and is within range and unused..+                unused.contains(param.index).unwrap_or(false) =>+                    // ..then use the identity for this parameter.+                    tcx.mk_param_from_def(param),++            // Otherwise, use the parameter as before.+            _ => substs[param.index as usize],

It would require us to also change that early exit here afaict.

    if unused.is_empty() {
        // Exit early if every parameter was used.
        return substs;
    }
davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    if unused.is_empty() {+        // Exit early if every parameter was used.+        return substs;+    }++    // If this is a closure or generator then we need to handle the case where another closure+    // from the function is captured as an upvar and hasn't been polymorphized. In this case,+    // the unpolymorphized upvar closure would result in a polymorphized closure producing+    // multiple mono items (and eventually symbol clashes).+    let upvars_ty = if tcx.is_closure(def_id) {+        Some(substs.as_closure().tupled_upvars_ty())+    } else if tcx.type_of(def_id).is_generator() {+        Some(substs.as_generator().tupled_upvars_ty())+    } else {+        None+    };+    let has_upvars = upvars_ty.map(|ty| ty.tuple_fields().count() > 0).unwrap_or(false);+    debug!("polymorphize: upvars_ty={:?} has_upvars={:?}", upvars_ty, has_upvars);++    struct PolymorphizationFolder<'tcx> {+        tcx: TyCtxt<'tcx>,+    };++    impl ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> {+        fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {+            self.tcx+        }++        fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {+            debug!("fold_ty: ty={:?}", ty);+            match ty.kind {+                ty::Closure(def_id, substs) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_closure(def_id, polymorphized_substs)+                }+                ty::Generator(def_id, substs, movability) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_generator(def_id, polymorphized_substs, movability)+                }+                _ => ty.super_fold_with(self),+            }+        }+    }++    InternalSubsts::for_item(tcx, def_id, |param, _| {+        let is_unused = unused.contains(param.index).unwrap_or(false);+        debug!("polymorphize: param={:?} is_unused={:?}", param, is_unused);+        match param.kind {+            // Upvar case: If parameter is a type parameter..+            ty::GenericParamDefKind::Type { .. } if+                // ..and has upvars..+                has_upvars &&+                // ..and this param has the same type as the tupled upvars..+                upvars_ty == Some(substs[param.index as usize].expect_ty()) => {+                    // ..then double-check that polymorphization marked it used..+                    debug_assert!(!is_unused);+                    // ..and polymorphize any closures/generators captured as upvars.+                    let upvars_ty = upvars_ty.unwrap();+                    let polymorphized_upvars_ty = upvars_ty.fold_with(+                        &mut PolymorphizationFolder { tcx });+                    debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty);+                    ty::GenericArg::from(polymorphized_upvars_ty)+                },++            // Simple case: If parameter is a const or type parameter..+            ty::GenericParamDefKind::Const | ty::GenericParamDefKind::Type { .. } if+                // ..and is within range and unused..+                unused.contains(param.index).unwrap_or(false) =>+                    // ..then use the identity for this parameter.+                    tcx.mk_param_from_def(param),++            // Otherwise, use the parameter as before.+            _ => substs[param.index as usize],

this would fix this while also optimizing things like

fn test<T>() {
    [1, 2, 3].iter().map(|_| ()).collect::<Vec<()>>();
}

fn main() {
    test::<String>();
    test::<Vec<String>>();
}
davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    if unused.is_empty() {+        // Exit early if every parameter was used.+        return substs;+    }++    // If this is a closure or generator then we need to handle the case where another closure+    // from the function is captured as an upvar and hasn't been polymorphized. In this case,+    // the unpolymorphized upvar closure would result in a polymorphized closure producing+    // multiple mono items (and eventually symbol clashes).+    let upvars_ty = if tcx.is_closure(def_id) {+        Some(substs.as_closure().tupled_upvars_ty())+    } else if tcx.type_of(def_id).is_generator() {+        Some(substs.as_generator().tupled_upvars_ty())+    } else {+        None+    };+    let has_upvars = upvars_ty.map(|ty| ty.tuple_fields().count() > 0).unwrap_or(false);+    debug!("polymorphize: upvars_ty={:?} has_upvars={:?}", upvars_ty, has_upvars);++    struct PolymorphizationFolder<'tcx> {+        tcx: TyCtxt<'tcx>,+    };++    impl ty::TypeFolder<'tcx> for PolymorphizationFolder<'tcx> {+        fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {+            self.tcx+        }++        fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {+            debug!("fold_ty: ty={:?}", ty);+            match ty.kind {+                ty::Closure(def_id, substs) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_closure(def_id, polymorphized_substs)+                }+                ty::Generator(def_id, substs, movability) => {+                    let polymorphized_substs = polymorphize(self.tcx, def_id, substs);+                    self.tcx.mk_generator(def_id, polymorphized_substs, movability)+                }+                _ => ty.super_fold_with(self),+            }+        }+    }++    InternalSubsts::for_item(tcx, def_id, |param, _| {+        let is_unused = unused.contains(param.index).unwrap_or(false);+        debug!("polymorphize: param={:?} is_unused={:?}", param, is_unused);+        match param.kind {+            // Upvar case: If parameter is a type parameter..+            ty::GenericParamDefKind::Type { .. } if+                // ..and has upvars..+                has_upvars &&+                // ..and this param has the same type as the tupled upvars..+                upvars_ty == Some(substs[param.index as usize].expect_ty()) => {+                    // ..then double-check that polymorphization marked it used..+                    debug_assert!(!is_unused);+                    // ..and polymorphize any closures/generators captured as upvars.+                    let upvars_ty = upvars_ty.unwrap();+                    let polymorphized_upvars_ty = upvars_ty.fold_with(+                        &mut PolymorphizationFolder { tcx });+                    debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty);+                    ty::GenericArg::from(polymorphized_upvars_ty)+                },++            // Simple case: If parameter is a const or type parameter..+            ty::GenericParamDefKind::Const | ty::GenericParamDefKind::Type { .. } if+                // ..and is within range and unused..+                unused.contains(param.index).unwrap_or(false) =>+                    // ..then use the identity for this parameter.+                    tcx.mk_param_from_def(param),++            // Otherwise, use the parameter as before.+            _ => substs[param.index as usize],

can't we just always polymorphize here ?

            _ => {
                let polymorphized_ty = substs[param.index as usize].fold_with(
                        &mut PolymorphizationFolder { tcx });
                ty::GenericArg::from(polymorphized_ty)
            },
davidtwco

comment created time in 4 days

Pull request review commentrust-lang/rust

instance: polymorphize upvar closures/generators

 impl<'tcx> Instance<'tcx> {     } } +fn polymorphize<'tcx>(+    tcx: TyCtxt<'tcx>,+    def_id: DefId,+    substs: SubstsRef<'tcx>,+) -> SubstsRef<'tcx> {+    debug!("polymorphize({:?}, {:?})", def_id, substs);+    let unused = tcx.unused_generic_params(def_id);+    debug!("polymorphize: unused={:?}", unused);++    if unused.is_empty() {+        // Exit early if every parameter was used.+        return substs;+    }++    // If this is a closure or generator then we need to handle the case where another closure+    // from the function is captured as an upvar and hasn't been polymorphized. In this case,+    // the unpolymorphized upvar closure would result in a polymorphized closure producing+    // multiple mono items (and eventually symbol clashes).+    let upvars_ty = if tcx.is_closure(def_id) {

is there a reason you aren't doing this as part of unused_generic_params?

davidtwco

comment created time in 4 days

issue commentrust-lang/rust

`*a == *b` moves when dereferencing &Rc<RefCell<dyn Trait>>

Is this a duplicate of #31740?

cuviper

comment created time in 4 days

pull request commentrust-lang/rust

make `ConstEvaluatable` more strict

they have no way to get away from it other than completely rewriting their code

Note that this does not change behavior (as the const expr has to not depend on it's generic parameters to work rn, so it should always be possible to replace all generic params with dummies).

We also only allowed this in repeat expressions, so the following doesn't work:

fn foo<T>() -> [u8; std::mem::size_of::<*mut T>()] {
    todo!()
}

It might be interesting to look into associated constants for const wf, which would mean that we keep allowing

struct Foo<T>(T);

impl<T> Foo<T> {
    const ASSOC: usize = 17;
    
    fn test() -> [u8; Self::ASSOC] {
        todo!();
    }
}

which means that this PR will only forbid things like [u8; std::mem::size_of::<*mut T>()] which seems a lot less worrying to me.

lcnr

comment created time in 4 days

Pull request review commentrust-lang/rust

make `ConstEvaluatable` more strict

 declare_lint! {     }; } +declare_lint! {+    pub CONST_EVALUATABLE_UNCHECKED,+    Warn,+    "detects a generic constant is used in a type without a emitting a warning",+    @future_incompatible = FutureIncompatibleInfo {+        reference: "TODO",

yeah, waiting on t-lang decision

lcnr

comment created time in 4 days

pull request commentrust-lang/rust

Add `array` lang item and `[T; N]::map(f: FnMut(T) -> S)`

Looks like this may lead to impl Iterator for [T; N].

I don't think we want to implement Iterator of arrays, but I am not really sure what you mean with "lead to" here. THis seems more closely related to Option::map than Iterator.

We do want to implement Iterator(#65819) and FromIterator(#69985) for arrays but this method is still a lot more concise than arr.into_iter().map(func).collect::<Result<_, _>>().unwrap().

JulianKnodt

comment created time in 4 days

push eventlcnr/rust

Bastian Kauschke

commit sha 644c8949121da0c16f65b772bf6e217748d94530

test min_const_generics using revisions

view details

push time in 4 days

Pull request review commentrust-lang/rust

Add `array` lang item and `[T; N]::map(f: FnMut(T) -> S)`

 macro_rules! array_impl_default { }  array_impl_default! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}++#[cfg(not(bootstrap))]+#[lang = "array"]+impl<T, const N: usize> [T; N] {+    /// Returns an array of the same size as self, with `f` applied to each element.+    ///+    /// # Examples+    /// ```+    /// # #![feature(array_map)]+    /// let x = [1, 2, 3];+    /// let y = x.map(|v| v + 1);+    /// assert_eq!(y, [2, 3, 4]);+    /// ```+    #[unstable(feature = "array_map", issue = "77777")]+    pub fn map<F, U>(self, mut f: F) -> [U; N]+    where+        F: FnMut(T) -> U,+    {+        use crate::mem::MaybeUninit;+        struct Guard<T, const N: usize> {+            dst: *mut T,+            initialized: usize,+        }++        impl<T, const N: usize> Drop for Guard<T, N> {+            fn drop(&mut self) {+                debug_assert!(self.initialized <= N);++                let initialized_part =+                    crate::ptr::slice_from_raw_parts_mut(self.dst, self.initialized);+                // SAFETY: this raw slice will contain only initialized objects+                // that's why, it is allowed to drop it.+                unsafe {+                    crate::ptr::drop_in_place(initialized_part);+                }+            }+        }+        let mut dst = MaybeUninit::uninit_array::<N>();+        let mut guard: Guard<U, N> = Guard { dst: &mut dst as *mut _ as *mut U, initialized: 0 };+        for (src, dst) in IntoIter::new(self).zip(&mut dst) {+            dst.write(f(src));+            guard.initialized += 1;+        }+        // FIXME convert to crate::mem::transmute when works with generics+        // unsafe { crate::mem::transmute::<[MaybeUninit<U>; N], [U; N]>(dst) }+        crate::mem::forget(guard);+        // SAFETY: At this point we've properly initialized the whole array+        // and we just need to cast it to the correct type
        // and we just need to cast it to the correct type.

nit

JulianKnodt

comment created time in 4 days

Pull request review commentrust-lang/rust

Add `array` lang item and `[T; N]::map(f: FnMut(T) -> S)`

 macro_rules! array_impl_default { }  array_impl_default! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}++#[cfg(not(bootstrap))]+#[lang = "array"]+impl<T, const N: usize> [T; N] {+    /// Returns an array of the same size as self, with `f` applied to each element.+    ///+    /// # Examples+    /// ```+    /// # #![feature(array_map)]+    /// let x = [1, 2, 3];+    /// let y = x.map(|v| v + 1);+    /// assert_eq!(y, [2, 3, 4]);+    /// ```+    #[unstable(feature = "array_map", issue = "77777")]+    pub fn map<F, U>(self, mut f: F) -> [U; N]+    where+        F: FnMut(T) -> U,+    {+        use crate::mem::MaybeUninit;+        struct Guard<T, const N: usize> {+            dst: *mut T,+            initialized: usize,+        }++        impl<T, const N: usize> Drop for Guard<T, N> {+            fn drop(&mut self) {+                debug_assert!(self.initialized <= N);++                let initialized_part =+                    crate::ptr::slice_from_raw_parts_mut(self.dst, self.initialized);+                // SAFETY: this raw slice will contain only initialized objects+                // that's why, it is allowed to drop it.+                unsafe {+                    crate::ptr::drop_in_place(initialized_part);+                }+            }+        }+        let mut dst = MaybeUninit::uninit_array::<N>();+        let mut guard: Guard<U, N> = Guard { dst: &mut dst as *mut _ as *mut U, initialized: 0 };+        for (src, dst) in IntoIter::new(self).zip(&mut dst) {+            dst.write(f(src));+            guard.initialized += 1;+        }+        // FIXME convert to crate::mem::transmute when works with generics
        // FIXME: Convert to crate::mem::transmute once it works with generics.

nit

JulianKnodt

comment created time in 4 days

pull request commentrust-lang/rust

Implement the `min_const_generics` feature gate

Moved some tests to use revisions. imo this is not that relevant here so we should do the remaining tests as a followup

lcnr

comment created time in 4 days

push eventlcnr/rust

Bastian Kauschke

commit sha 37c29adabc638f9c601daf5b78d0f6de63e35f99

allow complex expressions in assoc consts

view details

Bastian Kauschke

commit sha 377837d26d2a724e477da6d9d8d008637ee9e36d

test min_const_generics using revisions

view details

push time in 4 days

push eventlcnr/rust

Bastian Kauschke

commit sha 004f2e2cfee0fba519b3107be00cee554c781538

review

view details

Bastian Kauschke

commit sha b935252069758a05cd39f0299acf2d0b6debeeac

add tests

view details

push time in 4 days

Pull request review commentrust-lang/rust

Add `array` lang item and `[T; N]::map(f: FnMut(T) -> S)`

 macro_rules! array_impl_default { }  array_impl_default! {32, T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T}++#[lang = "array"]+#[cfg(not(bootstrap))]+impl<T, const N: usize> [T; N] {+    /// Returns an array of the same aize as self, with `f` applied to each element.+    ///+    /// # Examples+    /// ```+    /// let x = [1,2,3];+    /// let y = x.map(|v| v + 1);+    /// assert_eq!(y, [2,3,4]);+    /// ```+    #[unstable(feature = "array_map", issue = "77777")]+    fn map<F, S>(self, f: F) -> [S; N]+    where+        F: FnMut(T) -> S,+    {+        use crate::mem::MaybeUninit;+        let dst = MaybeUninit::uninit_array::<N>();+        for (i, e) in self.into_iter().enumerate() {+            dst[i] = MaybeUninit::new(f(e));

dst, see the implementation of fn make on how this can be handled: https://github.com/rust-lang/rust/blob/c448b373b57d0f1adefb70e07a44b1cccc9d2393/library/core/src/array/mod.rs#L357-L385

JulianKnodt

comment created time in 4 days

push eventlcnr/rust

Bastian Kauschke

commit sha dc1cc5fff27f835b97cf20913a025798776ce24e

review

view details

push time in 4 days

pull request commentrust-lang/rust

[CRATER] make `ConstEvaluatable` more strict

How is this a small perf win? :thinking:

lcnr

comment created time in 5 days

pull request commentrust-lang/rust

Implement the `min_const_generics` feature gate

These tests are copied from const_generics tests, right? Can we remove the original tests now? They don't really give us anything new.

They do, min const generics eagerly evaluates constants without supplying the parent generics, IMO this is different enough for us to consider running all tests both with min_const_generics and const_generics.

lcnr

comment created time in 5 days

pull request commentrust-lang/rust

[CRATER] make `ConstEvaluatable` more strict

Converted the error to a future incompat lint. Let's see if we have to move is_polymorphic into a query.

@bors try @rust-timer queue

lcnr

comment created time in 5 days

push eventlcnr/rust

flip1995

commit sha f7acea2683c6124854bfe20e7127e4dfba344d3e

Register redundant_field_names and non_expressive_names as early passes

view details

flip1995

commit sha 485229c4a3d6a2fbe40f5a6976a33144a27497c6

Fix fallout in redundant_field_names

view details

flip1995

commit sha efd3dcff97f67f376e354c047133ce9044c52991

Fix fallout in similar_names

view details

Eduardo Broto

commit sha bb37a0f948b02e6434dbe3ea615960052d37f784

Avoid triggering similar names on code from expansion

view details

Alexis Bourget

commit sha 2853448426ce76926baa7e6e6173c15228e4951a

Document the ref keyword

view details

Stefan Lankes

commit sha 6813c1c69baf870a479c70e23ad0550d1d9aa9be

revise RwLock, which is derived from the wasm implementation - increasing the readability of `Condvar` - simplify the interface to the libos HermitCore

view details

Stefan Lankes

commit sha 3acc3ef10d2099a4b3118e8c705b36f4bbaf6f64

minor changes to pass the format check

view details

Stefan Lankes

commit sha beb1b1fa5b1047c7caf8a1d499725df3c1ad8cad

reorder crates to pass the format check

view details

Stefan Lankes

commit sha f9c609164251abc136eb9bda55c92cb99adb5c86

remove some compiler warnings

view details

Trevor Spiteri

commit sha 6dfe144bdd4413ac55cbb2ad2edfb1daa0c4bf15

stabilize const_nonzero_int_methods

view details

Trevor Spiteri

commit sha 9739b512a892628534e730ffcd9756b3218c8de8

stabilize some const_checked_int_methods

view details

Trevor Spiteri

commit sha c1c674c2dbfe3f6dc47d11368c1b5ee4ab008799

stabilize const_saturating_int_methods

view details

Trevor Spiteri

commit sha 056d925167318636fcf975c8ffb81efebdc9bca3

stabilize const_int_sign

view details

Trevor Spiteri

commit sha 2a84e313df095fd0e81b9348b68bd9b1d1caa551

stabilize const_ascii_ctype_on_intrinsics

view details

Adam Perry

commit sha d275739c09f266479d6db388cbf55ba6ca791b9d

Derive common traits for panic::Location. Add documentation about the host/target behavior of Location::file.

view details

Jamie Cunliffe

commit sha fc52b47e8013da325fc0a0f5d3897143243ba206

va_args implementation for AAPCS. Implement the va args in codegen for AAPCS, this will be used as the default va_args implementation for AArch64 rather than the va_args llvm-ir as it currently is. Copyright (c) 2020, Arm Limited.

view details

Alexis Bourget

commit sha 837a761b398a6ff6a97f7f61e390dae9efbeab79

Document the where keyword

view details

Andrey Zgarbul

commit sha 7d4a92d4f8dc03409984695d78893fffdd3ff1f9

remove LengthAtMost32 on AsRef/Borrow impl for array

view details

Roman Proskuryakov

commit sha eff62069ad602090e8d27b83cffd9e77479ed4be

Remove the usage of the LengthAtMost32 trait

view details

Roman Proskuryakov

commit sha 4ad40a8737ab4ffaf6352ec4560fd86cb0b4ade8

Remove LengthAtMost32

view details

push time in 5 days

pull request commentrust-lang/rust

Note about endianness of returned value of {integer}::from_be_bytes and friends

@bors r+ rollup

lzutao

comment created time in 5 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

 pub type GenericBounds = Vec<GenericBound>; pub enum ParamKindOrd {     Lifetime,     Type,-    Const,+    Const { unordered: bool },

can you also add a comment here mentioning that min_const_generics requires const params to come after types.

JulianKnodt

comment created time in 5 days

Pull request review commentrust-lang/rust

Remove restriction on type parameters preceding consts w/ feature const-generics

-error: type parameters must be declared prior to const parameters-  --> $DIR/argument_order.rs:4:28-   |-LL | struct Bad<const N: usize, T> {-   |           -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`- error: lifetime parameters must be declared prior to const parameters   --> $DIR/argument_order.rs:9:32    | LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {-   |               -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>`--error: type parameters must be declared prior to const parameters-  --> $DIR/argument_order.rs:9:36-   |-LL | struct AlsoBad<const N: usize, 'a, T, 'b, const M: usize, U> {-   |               ---------------------^----------------------^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, 'b, T, U, const N: usize, const M: usize>`--warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes-  --> $DIR/argument_order.rs:1:12-   |-LL | #![feature(const_generics)]-   |            ^^^^^^^^^^^^^^-   |-   = note: `#[warn(incomplete_features)]` on by default-   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information+   |               -----------------^^-----^^-------------------- help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, T, U, const N: usize, const M: usize>`

You probably also have to overwrite the Ord impl for ParamKindOrd here.

This error messages should not reorder types and consts if const_generics is active

IOW this error message should mention

help: reorder the parameters: lifetimes, then consts and types: `<'a, 'b, const N: usize, T, const M: usize, U>`
JulianKnodt

comment created time in 5 days

pull request commentrust-lang/rust

[CRATER] make `ConstEvaluatable` more strict

It looks like there is one relevant regression here:

https://github.com/vlad9486/pq-newhope/blob/e9cdcb8828efeb38d6ed544870a582ca5e2fa543/src/poly/poly.rs#L314

lcnr

comment created time in 5 days

push eventlcnr/rust

Bastian Kauschke

commit sha b462e7dc7abc8b4252918ba731d2a3d9fc5cf746

allow complex expressions in assoc consts

view details

push time in 6 days

push eventlcnr/rust

Bastian Kauschke

commit sha 42469de09f96034696744ad035fbb24532d654c0

allow complex expressions in assoc consts

view details

push time in 6 days

pull request commentrust-lang/rust

Implement the `min_const_generics` feature gate

submodules should be fixed, I ported all type-dependent tests for now without any issues,

imo the remaining tests can be done in a separate PR.

lcnr

comment created time in 6 days

push eventlcnr/rust

Guillaume Gomez

commit sha 633d1a5af96db7eccb8aeeb07ff31b06aaf07b5f

Clean up E0720 explanation

view details

Dan Aloni

commit sha 28e27566782e5f2636b9c93a172c19024630233d

librustc_typeck: use diag item instead of string compare

view details

Dan Aloni

commit sha d077767ee72221f2a436692ef85115381671a765

Update src/librustc_typeck/check/op.rs Co-authored-by: Bastian Kauschke <bastian_kauschke@hotmail.de>

view details

Aaron Hill

commit sha ac9dfc3e7785c9bba96ebac4fd51726189e1bf91

Normalize opaque types when converting `ParamEnv` to `Reveal::All` Fixes #65918

view details

Aaron Hill

commit sha 117a60e1f5045e317d3f76ce60be28d18c694608

Erase regions in try_eval_bits

view details

Aaron Hill

commit sha 90aee14eb95ac0b9ddb7cf5db6d003155e94800c

Skip computing param_env and size if not needed

view details

Aaron Hill

commit sha 5e2e927e0107916b825b164c82be44877ac6ab54

Fix rebase fallout

view details

Bastian Kauschke

commit sha 49b1971263971db49e821f81bb54991b7de5ab43

add const generics

view details

Pietro Albini

commit sha cb76f821942053091706b7bb2c4dc416bb09bfb9

ci: avoid symlinking the build directory on self-hosted builders

view details

Pietro Albini

commit sha fe5a40eb14f233554a30c038cf8944b2d2adf9ff

ci: add aarch64-gnu as a fallible auto builder

view details

Guillaume Gomez

commit sha 403164569170e3f5c06db8b66257ac61db7cff4b

Clean up E0728 explanation

view details

Rich Kadel

commit sha 12ddd6073abecb7a515a43bee37408596e322345

Fixed coverage map issues; better aligned with LLVM APIs Found some problems with the coverage map encoding when testing with more than one counter per function. While debugging, I realized some better ways to structure the Rust implementation of the coverage mapping generator. I refactored somewhat, resulting in less code overall, expanded coverage of LLVM Coverage Map capabilities, and much closer alignment with LLVM data structures, APIs, and naming. This should be easier to follow and easier to maintain.

view details

Guillaume Gomez

commit sha 1d2e3fff69b654c3dfd6a810e193db29bb1868fa

Clean up E0730 explanation

view details

Andy Russell

commit sha 0b320086425937b17bda5ee9e856ac6441d71d96

report kind of deprecated item in message This is important for fields, which are incorrectly referred to as "items".

view details

Ximin Luo

commit sha 1f25a4b3ae87327f045fbfec82b5af4c8da6ecd6

config.toml.example: Update remap-debuginfo doc to be more general & accurate

view details

Guillaume Gomez

commit sha f22a34e84d4dba9b17bb3e68051ee82bd85f3c94

Clean up E0734 explanation

view details

Joseph Ryan

commit sha c692ed468c8dc4b9f549ef839b4b490e3b84d19c

Move `Error` and `RenderInfo` out of `html` module

view details

Joseph Ryan

commit sha 5bc97946ca35a789b690668bb6b27ca41bfeb5b2

Refactor html backend to use generic interface

view details

Joseph Ryan

commit sha 6a4396b98c6fcb405429a9798a9ab6554f015b7e

Extract `Cache` and other types from `html` module

view details

Joseph Ryan

commit sha a7909522547cb35b32a4f11b78b2b54864189295

Pull out more types from html

view details

push time in 6 days

Pull request review commentrust-lang/rust

Implement the `min_const_generics` feature gate

 pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {             GenericParamKind::Type { default: Some(ref ty), .. } => icx.to_ty(ty),             GenericParamKind::Const { ty: ref hir_ty, .. } => {                 let ty = icx.to_ty(hir_ty);-                let err = match ty.peel_refs().kind {-                    ty::FnPtr(_) => Some("function pointers"),-                    ty::RawPtr(_) => Some("raw pointers"),-                    _ => None,+                let err_ty_str;+                let err = if tcx.features().min_const_generics {+                    match ty.kind {+                        ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,+                        _ => {+                            err_ty_str = format!("`{}`", ty);+                            Some(err_ty_str.as_str())+                        }+                    }+                } else {+                    match ty.peel_refs().kind {+                        ty::FnPtr(_) => Some("function pointers"),+                        ty::RawPtr(_) => Some("raw pointers"),+                        _ => None,+                    }                 };                 if let Some(unsupported_type) = err {-                    tcx.sess-                        .struct_span_err(-                            hir_ty.span,-                            &format!(-                                "using {} as const generic parameters is forbidden",-                                unsupported_type-                            ),-                        )-                        .emit();+                    let mut err = tcx.sess.struct_span_err(

added a note for now, adding a better help can be left as followup imo

lcnr

comment created time in 6 days

push eventlcnr/rust

Bastian Kauschke

commit sha f1adeba2f7b53e21b0db62fa6106ac0acb965966

add min_const_generics feature gate

view details

Bastian Kauschke

commit sha 771f115f7f3720fe2d8e0c240a3b4fd650ebc3a4

forbid generic params in complex consts

view details

Bastian Kauschke

commit sha d68a2dbaa8d082f60274b614bffd6a6c470a20e3

forbid complex types for generic parameters

view details

Bastian Kauschke

commit sha baf18b802bc099dba4eb7e8aaf19b67b96e0dade

add tracking issue

view details

Bastian Kauschke

commit sha 791752c0b313c86837c0cfe68d32ba387d8b9af3

impl review

view details

push time in 6 days

more