This PR is a rebase of the original PR by @eddyb https://github.com/rust-lang/rust/pull/21836 with some unrebasable parts manually reapplied, feature gate added + type equality restriction added as described below.
This implementation is partial because the type equality restriction is applied to all type ascription expressions and not only those in lvalue contexts. Thus, all difficulties with detection of these contexts and translation of coercions having effect in runtime are avoided.
So, you can't write things with coercions like `let slice = &[1, 2, 3]: &[u8];`. It obviously makes type ascription less useful than it should be, but it's still much more useful than not having type ascription at all.
In particular, things like `let v = something.iter().collect(): Vec<_>;` and `let u = t.into(): U;` work as expected and I'm pretty happy with these improvements alone.
Part of https://github.com/rust-lang/rust/issues/23416
nodes in statement position.
Extended #[cfg] folder to allow removal of statements, and
of expressions in optional positions like expression lists and trailing
block expressions.
Extended lint checker to recognize lint levels on expressions and
locals.
this has the funky side-effect of also allowing constant evaluation of function calls to functions that are not `const fn` as long as `check_const` didn't mark that function `NOT_CONST`
It's still not possible to call a normal function from a `const fn`, but let statements' initialization value can get const evaluated (this caused the fallout in the overflowing tests)
we can now do this:
```rust
const fn add(x: usize, y: usize) -> usize { x + y }
const ARR: [i32; add(1, 2)] = [5, 6, 7];
```
also added a test for destructuring in const fn args
```rust
const fn i((a, b): (u32, u32)) -> u32 { a + b } //~ ERROR: E0022
```
This is a **[breaking change]**, since it turns some runtime panics into compile-time errors. This statement is true for ANY improvement to the const evaluator.
This commit stabilizes and deprecates library APIs whose FCP has closed in the
last cycle, specifically:
Stabilized APIs:
* `fs::canonicalize`
* `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists,
is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait.
* `Formatter::fill`
* `Formatter::width`
* `Formatter::precision`
* `Formatter::sign_plus`
* `Formatter::sign_minus`
* `Formatter::alternate`
* `Formatter::sign_aware_zero_pad`
* `string::ParseError`
* `Utf8Error::valid_up_to`
* `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}`
* `<[T]>::split_{first,last}{,_mut}`
* `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated
but will be once 1.5 is released.
* `str::{R,}MatchIndices`
* `str::{r,}match_indices`
* `char::from_u32_unchecked`
* `VecDeque::insert`
* `VecDeque::shrink_to_fit`
* `VecDeque::as_slices`
* `VecDeque::as_mut_slices`
* `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`)
* `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`)
* `Vec::resize`
* `str::slice_mut_unchecked`
* `FileTypeExt`
* `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}`
* `BinaryHeap::from` - `from_vec` deprecated in favor of this
* `BinaryHeap::into_vec` - plus a `Into` impl
* `BinaryHeap::into_sorted_vec`
Deprecated APIs
* `slice::ref_slice`
* `slice::mut_ref_slice`
* `iter::{range_inclusive, RangeInclusive}`
* `std::dynamic_lib`
Closes#27706Closes#27725
cc #27726 (align not stabilized yet)
Closes#27734Closes#27737Closes#27742Closes#27743Closes#27772Closes#27774Closes#27777Closes#27781
cc #27788 (a few remaining methods though)
Closes#27790Closes#27793Closes#27796Closes#27810
cc #28147 (not all parts stabilized)
Stricter checking of stability attributes + enforcement of their invariants at compile time
(+ removed dead file librustc_front/attr.rs)
I intended to enforce use of `reason` for unstable items as well (it normally presents for new items), but it turned out too intrusive, many older unstable items don't have `reason`s.
r? @aturon
I'm studying how stability works and do some refactoring along the way, so it's probably not the last PR.
This lint warning was originally intended to help against misuse of the old Rust
`int` and `uint` types in FFI bindings where the Rust `int` was not equal to the
C `int`. This confusion no longer exists (as Rust's types are now `isize` and
`usize`), and as a result the need for this lint has become much less over time.
Additionally, starting with [the RFC for libc][rfc] it's likely that `isize` and
`usize` will be quite common in FFI bindings (e.g. they're the definition of
`size_t` and `ssize_t` on many platforms).
[rfc]: https://github.com/rust-lang/rfcs/pull/1291
This commit disables these lints to instead consider `isize` and `usize` valid
types to have in FFI signatures.
paths, and construct paths for all definitions. Also, stop rewriting
DefIds for closures, and instead just load the closure data from
the original def-id, which may be in another crate.
This lint warning was originally intended to help against misuse of the old Rust
`int` and `uint` types in FFI bindings where the Rust `int` was not equal to the
C `int`. This confusion no longer exists (as Rust's types are now `isize` and
`usize`), and as a result the need for this lint has become much less over time.
Additionally, starting with [the RFC for libc][rfc] it's likely that `isize` and
`usize` will be quite common in FFI bindings (e.g. they're the definition of
`size_t` and `ssize_t` on many platforms).
[rfc]: https://github.com/rust-lang/rfcs/pull/1291
This commit disables these lints to instead consider `isize` and `usize` valid
types to have in FFI signatures.
This PR removes random remaining `Ident`s outside of libsyntax and performs general cleanup
In particular, interfaces of `Name` and `Ident` are tidied up, `Name`s and `Ident`s being small `Copy` aggregates are always passed to functions by value, and `Ident`s are never used as keys in maps, because `Ident` comparisons are tricky.
Although this PR closes https://github.com/rust-lang/rust/issues/6993 there's still work related to it:
- `Name` can be made `NonZero` to compress numerous `Option<Name>`s and `Option<Ident>`s but it requires const unsafe functions.
- Implementation of `PartialEq` on `Ident` should be eliminated and replaced with explicit hygienic, non-hygienic or member-wise comparisons.
- Finally, large parts of AST can potentially be converted to `Name`s in the same way as HIR to clearly separate identifiers used in hygienic and non-hygienic contexts.
r? @nrc
Make sure Name, SyntaxContext and Ident are passed by value
Make sure Idents don't serve as keys (or parts of keys) in maps, Ident comparison is not well defined
[breaking-change] for lint authors
You must now implement LateLintPass or EarlyLintPass as well as LintPass and use either register_late_lint_pass or register_early_lint_pass, rather than register_lint_pass.
There is a minor [breaking-change] for lint authors - some functions which were previously defined on `lint::Context` have moved to a trait - `LintContext`, you may need to import that trait to avoid name resolution errors.
Since enums are namespaced now, should we also remove the `Fk` prefixes from `FnKind` and remove the reexport? (The reexport must be removed because otherwise it clashes with glob imports containing `ItemFn`). IMO writing `FnKind::Method` is much clearer than `FkMethod`.
This is purposely separate to the "rust-intrinsic" ABI, because these
intrinsics are theoretically going to become stable, and should be fine
to be independent of the compiler/language internals since they're
intimately to the platform.
This commit removes all unstable and deprecated functions in the standard
library. A release was recently cut (1.3) which makes this a good time for some
spring cleaning of the deprecated functions.
Makes the lint a bit more accurate, and improves the quality of the diagnostic
messages by explicitly returning an error message.
The new lint is also a little more aggressive: specifically, it now
rejects tuples, and it recurses into function pointers.
The "hint" mechanism is essentially used as a workaround to compute
types for expressions which have not yet been type-checked. This
commit clarifies that usage, and limits the effects to the places
where it is currently necessary.
Fixes#26210.
The "hint" mechanism is essentially used as a workaround to compute
types for expressions which have not yet been type-checked. This
commit clarifies that usage, and limits the effects to the places
where it is currently necessary.
Fixes#26210.
and deprecate/remove unsigned_negation lint.
This is useful to avoid causing breaking changes in case #![deny(unknown_lints)]
is used and lint is removed.
Fixes#24249
I've tagged all items that were missing docs to allow them to compile for now, the ones in core/num should probably be documented at least.
This is also a breaking change for any crates using `#[deny(missing_docs)]` that have undocumented constants, not sure there is any way to avoid this without making it a separate lint?
This patch implements the next chunk of flattening out the type checking context. In a series of patches I moved around the necessary state and logic in order to delete the `Typer` and `ClosureTyper` traits. My next goal is to clean the interfaces and start to move the normalization code behind them.
r? @nrc I hope my PR is coherent, doing this too late at night ;)
Fixes#26646.
Loops over all `#[repr(..)]` attributes instead of stopping at the first one to make sure they are all marked as used. Previously it stopped after the first `#[repr(C)]` was found causing all other attributes to be skipped by the linter.
This commit finalizes the work of the past commits by fully moving the fulfillment context into
the InferCtxt, cleaning up related context interfaces, removing the Typer and ClosureTyper
traits and cleaning up related intefaces
This catches the case when a trait defines a default method that calls
itself, but on a type that isn't necessarily `Self`, e.g. there's no
reason that `T = Self` in the following, so the call isn't necessarily
recursive (`T` may override the call).
trait Bar {
fn method<T: Bar>(&self, x: &T) {
x.method(x)
}
}
Fixes#26333.
This first patch starts by moving around pieces of state related to
type checking. The goal is to slowly unify the type checking state
into a single typing context. This initial patch moves the
ParameterEnvironment into the InferCtxt and moves shared tables
from Inherited and ty::ctxt into their own struct Tables. This
is the foundational work to refactoring the type checker to
enable future evolution of the language and tooling.
It now says '#[feature] may not be used on the stable release channel'.
I had to convert this error from a lint to a normal compiler error.
I left the lint previously-used for this in place since removing it is
a breaking change. It will just go unused until the end of time.
Fixes#24125
It now says '#[feature] may not be used on the stable release channel'.
I had to convert this error from a lint to a normal compiler error.
I left the lint previously-used for this in place since removing it is
a breaking change. It will just go unused until the end of time.
Fixes#24125
This commit shards the broad `core` feature of the libcore library into finer
grained features. This split groups together similar APIs and enables tracking
each API separately, giving a better sense of where each feature is within the
stabilization process.
A few minor APIs were deprecated along the way:
* Iterator::reverse_in_place
* marker::NoCopy
The caching essentially eliminates "stability checking" time (my attempt to clean-up junk got tangled up with stability, so I added the caching while I was at it).
r? @eddyb
This is a port of @eddyb's `const-fn` branch. I rebased it, tweaked a few things, and added tests as well as a feature gate. The set of tests is still pretty rudimentary, I'd appreciate suggestions on new tests to write. Also, a double-check that the feature-gate covers all necessary cases.
One question: currently, the feature-gate allows the *use* of const functions from stable code, just not the definition. This seems to fit our usual strategy, and implies that we might (perhaps) allow some constant functions in libstd someday, even before stabilizing const-fn, if we were willing to commit to the existence of const fns but found some details of their impl unsatisfactory.
r? @pnkfelix
- add feature gate
- add basic tests
- adjust parser to eliminate conflict between `const fn` and associated
constants
- allow `const fn` in traits/trait-impls, but forbid later in type check
- correct some merge conflicts
It is hard to find the actual unstable feature which caused the error when using a list of stable and unstable features as the span marks the whole line
```
src/k8055.rs:22:1: 22:64 error: unstable feature
src/k8055.rs:22 #![feature(slice_patterns, rustc_private, core, convert, libc)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
This PR spawns an error for each unstable feature in the list:
```
est.rs:1:12: 1:26 error: unstable feature [-D unstable-features]
test.rs:1 #![feature(slice_patterns, rustc_private, core, convert, libc)]
^~~~~~~~~~~~~~
test.rs:1:28: 1:41 error: unstable feature [-D unstable-features]
test.rs:1 #![feature(slice_patterns, rustc_private, core, convert, libc)]
^~~~~~~~~~~~~
test.rs:1:43: 1:47 error: unstable feature [-D unstable-features]
test.rs:1 #![feature(slice_patterns, rustc_private, core, convert, libc)]
^~~~
test.rs:1:49: 1:56 error: unstable feature [-D unstable-features]
test.rs:1 #![feature(slice_patterns, rustc_private, core, convert, libc)]
^~~~~~~
test.rs:1:58: 1:62 error: unstable feature [-D unstable-features]
test.rs:1 #![feature(slice_patterns, rustc_private, core, convert, libc)]
^~~~
```
[breaking-change] Technically breaking, since code that had been using
these transmutes before will no longer compile. However, it was
undefined behavior, so really, it's a good thing. Fixing your code would
require some re-working to use an UnsafeCell instead.
Closes#13146
Puts implementations in bins hashed by the fast-reject key, and
only looks up the relevant impls, reducing O(n^2)-ishness
Before: 688.92user 5.08system 8:56.70elapsed 129%CPU (0avgtext+0avgdata 1208164maxresident)k, LLVM 379.142s
After: 637.78user 5.11system 8:17.48elapsed 129%CPU (0avgtext+0avgdata 1201448maxresident)k LLVM 375.552s
Performance increase is +7%-ish
This commit stabilizes the `std::num` module:
* The `Int` and `Float` traits are deprecated in favor of (1) the
newly-added inherent methods and (2) the generic traits available in
rust-lang/num.
* The `Zero` and `One` traits are reintroduced in `std::num`, which
together with various other traits allow you to recover the most
common forms of generic programming.
* The `FromStrRadix` trait, and associated free function, is deprecated
in favor of inherent implementations.
* A wide range of methods and constants for both integers and floating
point numbers are now `#[stable]`, having been adjusted for integer
guidelines.
* `is_positive` and `is_negative` are renamed to `is_sign_positive` and
`is_sign_negative`, in order to address #22985
* The `Wrapping` type is moved to `std::num` and stabilized;
`WrappingOps` is deprecated in favor of inherent methods on the
integer types, and direct implementation of operations on
`Wrapping<X>` for each concrete integer type `X`.
Closes#22985Closes#21069
[breaking-change]
r? @alexcrichton
This commit stabilizes the `std::num` module:
* The `Int` and `Float` traits are deprecated in favor of (1) the
newly-added inherent methods and (2) the generic traits available in
rust-lang/num.
* The `Zero` and `One` traits are reintroduced in `std::num`, which
together with various other traits allow you to recover the most
common forms of generic programming.
* The `FromStrRadix` trait, and associated free function, is deprecated
in favor of inherent implementations.
* A wide range of methods and constants for both integers and floating
point numbers are now `#[stable]`, having been adjusted for integer
guidelines.
* `is_positive` and `is_negative` are renamed to `is_sign_positive` and
`is_sign_negative`, in order to address #22985
* The `Wrapping` type is moved to `std::num` and stabilized;
`WrappingOps` is deprecated in favor of inherent methods on the
integer types, and direct implementation of operations on
`Wrapping<X>` for each concrete integer type `X`.
Closes#22985Closes#21069
[breaking-change]
Due to a long-standing conservative approach to trait exports, all traits are
considered exported. However, the missing_docs lint uses the export map to
determine if something is public and ought to have documentation. This commit
modifies the lint to check if traits are private before emitting the warning.
Closes#11592
Due to a long-standing conservative approach to trait exports, all traits are
considered exported. However, the missing_docs lint uses the export map to
determine if something is public and ought to have documentation. This commit
modifies the lint to check if traits are private before emitting the warning.
Closes#11592
This permits all coercions to be performed in casts, but adds lints to warn in those cases.
Part of this patch moves cast checking to a later stage of type checking. We acquire obligations to check casts as part of type checking where we previously checked them. Once we have type checked a function or module, then we check any cast obligations which have been acquired. That means we have more type information available to check casts (this was crucial to making coercions work properly in place of some casts), but it means that casts cannot feed input into type inference.
[breaking change]
* Adds two new lints for trivial casts and trivial numeric casts, these are warn by default, but can cause errors if you build with warnings as errors. Previously, trivial numeric casts and casts to trait objects were allowed.
* The unused casts lint has gone.
* Interactions between casting and type inference have changed in subtle ways. Two ways this might manifest are:
- You may need to 'direct' casts more with extra type information, for example, in some cases where `foo as _ as T` succeeded, you may now need to specify the type for `_`
- Casts do not influence inference of integer types. E.g., the following used to type check:
```
let x = 42;
let y = &x as *const u32;
```
Because the cast would inform inference that `x` must have type `u32`. This no longer applies and the compiler will fallback to `i32` for `x` and thus there will be a type error in the cast. The solution is to add more type information:
```
let x: u32 = 42;
let y = &x as *const u32;
```
This is a [breaking-change]. When indexing a generic map (hashmap, etc) using the `[]` operator, it is now necessary to borrow explicitly, so change `map[key]` to `map[&key]` (consistent with the `get` routine). However, indexing of string-valued maps with constant strings can now be written `map["abc"]`.
r? @japaric
cc @aturon @Gankro
This commit:
* Introduces `std::convert`, providing an implementation of
RFC 529.
* Deprecates the `AsPath`, `AsOsStr`, and `IntoBytes` traits, all
in favor of the corresponding generic conversion traits.
Consequently, various IO APIs now take `AsRef<Path>` rather than
`AsPath`, and so on. Since the types provided by `std` implement both
traits, this should cause relatively little breakage.
* Deprecates many `from_foo` constructors in favor of `from`.
* Changes `PathBuf::new` to take no argument (creating an empty buffer,
as per convention). The previous behavior is now available as
`PathBuf::from`.
* De-stabilizes `IntoCow`. It's not clear whether we need this separate trait.
Closes#22751Closes#14433
[breaking-change]
This commit clarifies some of the unstable features in the `str` module by
moving them out of the blanket `core` and `collections` features.
The following methods were moved to the `str_char` feature which generally
encompasses decoding specific characters from a `str` and dealing with the
result. It is unclear if any of these methods need to be stabilized for 1.0 and
the most conservative route for now is to continue providing them but to leave
them as unstable under a more specific name.
* `is_char_boundary`
* `char_at`
* `char_range_at`
* `char_at_reverse`
* `char_range_at_reverse`
* `slice_shift_char`
The following methods were moved into the generic `unicode` feature as they are
specifically enabled by the `unicode` crate itself.
* `nfd_chars`
* `nfkd_chars`
* `nfc_chars`
* `graphemes`
* `grapheme_indices`
* `width`
This commit performs another pass over the `std::char` module for stabilization.
Some minor cleanup is performed such as migrating documentation from libcore to
libunicode (where the `std`-facing trait resides) as well as a slight
reorganiation in libunicode itself. Otherwise, the stability modifications made
are:
* `char::from_digit` is now stable
* `CharExt::is_digit` is now stable
* `CharExt::to_digit` is now stable
* `CharExt::to_{lower,upper}case` are now stable after being modified to return
an iterator over characters. While the implementation today has not changed
this should allow us to implement the full set of case conversions in unicode
where some characters can map to multiple when doing an upper or lower case
mapping.
* `StrExt::to_{lower,upper}case` was added as unstable for a convenience of not
having to worry about characters expanding to more characters when you just
want the whole string to get into upper or lower case.
This is a breaking change due to the change in the signatures of the
`CharExt::to_{upper,lower}case` methods. Code can be updated to use functions
like `flat_map` or `collect` to handle the difference.
[breaking-change]
Closes#20333
This commit performs another pass over the `std::char` module for stabilization.
Some minor cleanup is performed such as migrating documentation from libcore to
libunicode (where the `std`-facing trait resides) as well as a slight
reorganiation in libunicode itself. Otherwise, the stability modifications made
are:
* `char::from_digit` is now stable
* `CharExt::is_digit` is now stable
* `CharExt::to_digit` is now stable
* `CharExt::to_{lower,upper}case` are now stable after being modified to return
an iterator over characters. While the implementation today has not changed
this should allow us to implement the full set of case conversions in unicode
where some characters can map to multiple when doing an upper or lower case
mapping.
* `StrExt::to_{lower,upper}case` was added as unstable for a convenience of not
having to worry about characters expanding to more characters when you just
want the whole string to get into upper or lower case.
This is a breaking change due to the change in the signatures of the
`CharExt::to_{upper,lower}case` methods. Code can be updated to use functions
like `flat_map` or `collect` to handle the difference.
[breaking-change]
us to construct trait-references and do other things without forcing a
full evaluation of the supertraits. One downside of this scheme is that
we must invoke `ensure_super_predicates` before using any construct that
might require knowing about the super-predicates.
This changes the type of some public constants/statics in libunicode.
Notably some `&'static &'static [(char, char)]` have changed
to `&'static [(char, char)]`. The regexp crate seems to be the
sole user of these, yet this is technically a [breaking-change]
This pulls out the implementations of most built-in lints into a
separate crate, to reduce edit-compile-test iteration times with
librustc_lint and increase parallelism. This should enable lints to be
refactored, added and deleted much more easily as it slashes the
edit-compile cycle to get a minimal working compiler to test with (`make
rustc-stage1`) from
librustc -> librustc_typeck -> ... -> librustc_driver ->
libcore -> ... -> libstd
to
librustc_lint -> librustc_driver -> libcore -> ... libstd
which is significantly faster, mainly due to avoiding the librustc build
itself.
The intention would be to move as much as possible of the infrastructure
into the crate too, but the plumbing is deeply intertwined with librustc
itself at the moment. Also, there are lints for which diagnostics are
registered directly in the compiler code, not in their own crate
traversal, and their definitions have to remain in librustc.
This is a [breaking-change] for direct users of the compiler APIs:
callers of `rustc::session::build_session` or
`rustc::session::build_session_` need to manually call
`rustc_lint::register_builtins` on their return value.
This should make #22206 easier.