Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
// tidy-alphabetical-start
#![allow(clippy::mut_from_ref)] // Arena allocators are one place where this pattern is fine.
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(never_type))]
#![cfg_attr(test, feature(test))]
#![deny(unsafe_op_in_unsafe_fn)]
#![doc(test(no_crate_inject, attr(deny(warnings), allow(internal_features))))]
#![feature(decl_macro)]
#![feature(dropck_eyepatch)]
#![feature(never_type)]
#![feature(rustc_attrs)]
#![feature(unwrap_infallible)]
// tidy-alphabetical-end
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

// tidy-alphabetical-start
#![cfg_attr(feature = "nightly", allow(internal_features))]
#![cfg_attr(feature = "nightly", feature(never_type))]
#![cfg_attr(feature = "nightly", cfg_attr(bootstrap, feature(never_type)))]
Comment thread
WaffleLapkin marked this conversation as resolved.
#![cfg_attr(feature = "nightly", feature(rustc_attrs))]
// tidy-alphabetical-end

Expand Down
12 changes: 0 additions & 12 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
// Function pointers cannot be `const`
self.check_late_bound_lifetime_defs(&fn_ptr_ty.generic_params);
}
ast::TyKind::Never => {
gate!(self, never_type, ty.span, "the `!` type is experimental");
}
ast::TyKind::Pat(..) => {
gate!(self, pattern_types, ty.span, "pattern types are unstable");
}
Expand Down Expand Up @@ -294,15 +291,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
}

fn visit_generic_args(&mut self, args: &'a ast::GenericArgs) {
// This check needs to happen here because the never type can be returned from a function,
// but cannot be used in any other context. If this check was in `visit_fn_ret_ty`, it
// include both functions and generics like `impl Fn() -> !`.
if let ast::GenericArgs::Parenthesized(generic_args) = args
&& let ast::FnRetTy::Ty(ref ty) = generic_args.output
&& matches!(ty.kind, ast::TyKind::Never)
{
gate!(self, never_type, ty.span, "the `!` type is experimental");
}
visit::walk_generic_args(self, args);
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

// tidy-alphabetical-start
#![allow(internal_features)]
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(default_field_values)]
#![feature(deref_patterns)]
#![feature(file_buffered)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(option_into_flat_iter)]
#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(array_try_map)]
#![feature(decl_macro)]
#![feature(deref_patterns)]
#![feature(never_type)]
#![feature(slice_ptr_get)]
#![feature(trait_alias)]
#![feature(unqualified_local_imports)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#![allow(internal_features)]
#![allow(rustc::default_hash_types)]
#![allow(rustc::potential_query_instability)]
#![cfg_attr(bootstrap, feature(never_type))]
#![cfg_attr(test, feature(test))]
#![deny(unsafe_op_in_unsafe_fn)]
#![feature(allocator_api)]
Expand All @@ -24,7 +25,6 @@
#![feature(map_try_insert)]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(nonzero_internals)]
#![feature(pattern_type_macro)]
#![feature(pattern_types)]
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0725.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ command line flags.
Erroneous code example:

```ignore (can't specify compiler flags from doctests)
#![feature(never_type)] // error: the feature `never_type` is not in
// the list of allowed features
#![feature(extern_item_impls)]
//~^ error: the feature `extern_item_impls`
// is not in the list of allowed features
```

Delete the offending feature attribute, or add it to the list of allowed
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
//! This module contains the code for creating and emitting diagnostics.

// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(associated_type_defaults)]
#![feature(default_field_values)]
#![feature(macro_metavar_expr_concat)]
#![feature(negative_impls)]
#![feature(never_type)]
// tidy-alphabetical-end

extern crate self as rustc_errors;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ declare_features! (
(accepted, native_link_modifiers_verbatim, "1.67.0", Some(81490)),
/// Allows specifying the whole-archive link modifier
(accepted, native_link_modifiers_whole_archive, "1.61.0", Some(81490)),
/// Allows the `!` type.
(accepted, never_type, "CURRENT_RUSTC_VERSION", Some(35121)),
/// Allows using non lexical lifetimes (RFC 2094).
(accepted, nll, "1.63.0", Some(43234)),
/// Allows using `#![no_std]`.
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -673,8 +673,6 @@ declare_features! (
(unstable, negative_impls, "1.44.0", Some(68318)),
/// Allows the `!` pattern.
(incomplete, never_patterns, "1.76.0", Some(118155)),
/// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
(unstable, never_type, "1.13.0", Some(35121)),
/// Switch `..` syntax to use the new (`Copy + IntoIterator`) range types.
(unstable, new_range, "1.86.0", Some(123741)),
/// Allows `#![no_core]`.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html

// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(associated_type_defaults)]
#![feature(closure_track_caller)]
#![feature(const_default)]
#![feature(const_trait_impl)]
#![feature(default_field_values)]
#![feature(derive_const)]
#![feature(exhaustive_patterns)]
#![feature(never_type)]
#![recursion_limit = "256"]
// tidy-alphabetical-end

Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,7 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
// resolves to itself. We interpret this as the
// no values of the hidden type ever being constructed,
// so we can just make the hidden type be `!`.
// For backwards compatibility reasons, we fall back to
// `()` until we the diverging default is changed.
EarlyBinder::bind(tcx, tcx.types.unit)
EarlyBinder::bind(tcx, tcx.types.never)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks right to me, but I feel like I don't have enough type system knowledge to be 100% sure about this change.

I wonder why this wasn't affected by the rustc_never_type_options attribute, was that an accident?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC this wasn't affected by the attribute on purpose, but I don't remember the details.

}
}
DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ This API is completely unstable and subject to change.
*/

// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(default_field_values)]
#![feature(gen_blocks)]
#![feature(iter_intersperse)]
#![feature(never_type)]
#![feature(slice_partition_dedup)]
#![feature(try_blocks)]
#![feature(unwrap_infallible)]
Expand Down
13 changes: 1 addition & 12 deletions compiler/rustc_hir_typeck/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_errors::{
use rustc_hir as hir;
use rustc_hir::ExprKind;
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::{self, Ty};
use rustc_middle::ty::Ty;
use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
use rustc_span::{Ident, Span, Spanned, Symbol};

Expand Down Expand Up @@ -262,17 +262,6 @@ pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe {
},
}

#[derive(Diagnostic)]
#[help("specify the types explicitly")]
#[diag("this function depends on never type fallback being `()`")]
pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> {
#[note("in edition 2024, the requirement `{$obligation}` will fail")]
pub obligation_span: Span,
pub obligation: ty::Predicate<'tcx>,
#[subdiagnostic]
pub sugg: SuggestAnnotations,
}

#[derive(Clone)]
pub(crate) enum SuggestAnnotation {
Unit(Span),
Expand Down
59 changes: 1 addition & 58 deletions compiler/rustc_hir_typeck/src/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::ty::{self, FloatVid, Ty, TyCtxt, TypeSuperVisitable, TypeVisit
use rustc_session::lint;
use rustc_span::def_id::LocalDefId;
use rustc_span::{DUMMY_SP, Span};
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt, TraitEngine};
use rustc_trait_selection::traits::TraitEngine;
use tracing::debug;

use crate::{FnCtxt, diagnostics};
Expand Down Expand Up @@ -235,11 +235,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
// a type variable is that is coerced
let coercion_graph = self.create_coercion_graph();

self.lint_obligations_broken_by_never_type_fallback_change(
&diverging_root_vids,
&coercion_graph,
);

if !diverging_root_vids.is_empty() {
let unsafe_infer_vars = compute_unsafe_infer_vars(self, self.body_def_id);

Expand Down Expand Up @@ -303,58 +298,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
}
}

fn lint_obligations_broken_by_never_type_fallback_change(
&self,
diverging_vids: &[ty::TyVid],
coercions: &VecGraph<ty::TyVid, true>,
) {
let DivergingFallbackBehavior::ToUnit = self.diverging_fallback_behavior else { return };

// Fallback happens if and only if there are diverging variables
if diverging_vids.is_empty() {
return;
}

// Returns errors which happen if fallback is set to `fallback`
let remaining_errors_if_fallback_to = |fallback| {
self.probe(|_| {
let obligations = self.fulfillment_cx.borrow().pending_obligations();
let ocx = ObligationCtxt::new_with_diagnostics(&self.infcx);
ocx.register_obligations(obligations.iter().cloned());

for &diverging_vid in diverging_vids {
let diverging_ty = Ty::new_var(self.tcx, diverging_vid);

ocx.eq(&ObligationCause::dummy(), self.param_env, diverging_ty, fallback)
.expect("expected diverging var to be unconstrained");
}

ocx.try_evaluate_obligations()
})
};

// If we have no errors with `fallback = ()`, but *do* have errors with `fallback = !`,
// then this code will be broken by the never type fallback change.
let unit_errors = remaining_errors_if_fallback_to(self.tcx.types.unit);
if unit_errors.no_errors()
&& let mut never_errors = remaining_errors_if_fallback_to(self.tcx.types.never)
&& let [never_error, ..] = never_errors.as_mut_slice()
{
self.adjust_fulfillment_error_for_expr_obligation(never_error);
let sugg = self.try_to_suggest_annotations(diverging_vids, coercions);
self.tcx.emit_node_span_lint(
lint::builtin::DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK,
self.tcx.local_def_id_to_hir_id(self.body_def_id),
self.tcx.def_span(self.body_def_id),
diagnostics::DependencyOnUnitNeverTypeFallback {
obligation_span: never_error.obligation.cause.span,
obligation: never_error.obligation.predicate,
sugg,
},
)
}
}

/// Returns a graph whose nodes are (unresolved) inference variables and where
/// an edge `?A -> ?B` indicates that the variable `?A` is coerced to `?B`.
fn create_coercion_graph(&self) -> VecGraph<ty::TyVid, true> {
Expand Down
14 changes: 2 additions & 12 deletions compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,24 +493,14 @@ impl<'tcx> LoweredTy<'tcx> {
}

fn never_type_behavior(tcx: TyCtxt<'_>) -> (DivergingFallbackBehavior, DivergingBlockBehavior) {
// FIXME(waffle): rip out the whole system which allows you to choose never type fallback

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to do this immediately after this PR lands, so that this is not forgotten. Rust analyzer seems to have its own copy of this enum, funnily enough.
Can we somehow make sure this is not forgotten?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already have a commit for it in my local checkout, so I'm unlikely to forget:
jj commit (empty) TODO: rip out the never type fallback system, to make it simpler

let (fallback, block) = parse_never_type_options_attr(tcx);
let fallback = fallback.unwrap_or_else(|| default_fallback(tcx));
let fallback = fallback.unwrap_or_else(|| DivergingFallbackBehavior::ToNever);
let block = block.unwrap_or_default();

(fallback, block)
}

/// Returns the default fallback which is used when there is no explicit override via `#![never_type_options(...)]`.
fn default_fallback(tcx: TyCtxt<'_>) -> DivergingFallbackBehavior {
// Edition 2024: fallback to `!`
if tcx.sess.edition().at_least_rust_2024() {
return DivergingFallbackBehavior::ToNever;
}

// Otherwise: fallback to `()`
DivergingFallbackBehavior::ToUnit
}

fn parse_never_type_options_attr(
tcx: TyCtxt<'_>,
) -> (Option<DivergingFallbackBehavior>, Option<DivergingBlockBehavior>) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(never_type))]
#![feature(deref_patterns)]
#![feature(iter_intersperse)]
#![feature(iter_order_by)]
#![feature(never_type)]
#![feature(option_into_flat_iter)]
#![feature(option_reference_flattening)]
#![feature(trim_prefix_suffix)]
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,10 @@ fn register_builtins(store: &mut LintStore) {
"converted into hard error, \
generic items must always be mangled",
);
store.register_removed(
"dependency_on_unit_never_type_fallback",
"the code warned by this lint no longer compiles",
);
}

fn register_internals(store: &mut LintStore) {
Expand Down
Loading
Loading