Skip to content

Commit d6b151f

Browse files
committed
Auto merge of rust-lang#120251 - matthiaskrgr:rollup-gttrw68, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#119664 (Fix tty detection for msys2's `/dev/ptmx`) - rust-lang#120104 (never_patterns: Count `!` bindings as diverging) - rust-lang#120109 (Move cmath into `sys`) - rust-lang#120143 (Consolidate logic around resolving built-in coroutine trait impls) - rust-lang#120159 (Track `verbose` and `verbose_internals`) - rust-lang#120216 (Fix a `trimmed_def_paths` assertion failure.) - rust-lang#120220 (Document `Token{Stream,Tree}::Display` more thoroughly.) - rust-lang#120233 (Revert stabilization of trait_upcasting feature) r? `@ghost` `@rustbot` modify labels: rollup
2 parents d5fd099 + a787232 commit d6b151f

File tree

109 files changed

+816
-214
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

109 files changed

+816
-214
lines changed

compiler/rustc_feature/src/accepted.rs

-3
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,6 @@ declare_features! (
339339
/// Allows `#[track_caller]` to be used which provides
340340
/// accurate caller location reporting during panic (RFC 2091).
341341
(accepted, track_caller, "1.46.0", Some(47809)),
342-
/// Allows dyn upcasting trait objects via supertraits.
343-
/// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
344-
(accepted, trait_upcasting, "1.76.0", Some(65991)),
345342
/// Allows #[repr(transparent)] on univariant enums (RFC 2645).
346343
(accepted, transparent_enums, "1.42.0", Some(60405)),
347344
/// Allows indexing tuples.

compiler/rustc_feature/src/unstable.rs

+3
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,9 @@ declare_features! (
584584
(unstable, thread_local, "1.0.0", Some(29594)),
585585
/// Allows defining `trait X = A + B;` alias items.
586586
(unstable, trait_alias, "1.24.0", Some(41517)),
587+
/// Allows dyn upcasting trait objects via supertraits.
588+
/// Dyn upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
589+
(unstable, trait_upcasting, "1.56.0", Some(65991)),
587590
/// Allows for transmuting between arrays with sizes that contain generic consts.
588591
(unstable, transmute_generic_consts, "1.70.0", Some(109929)),
589592
/// Allows #[repr(transparent)] on unions (RFC 2645).

compiler/rustc_hir/src/lang_items.rs

+3
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,11 @@ language_item_table! {
213213
Iterator, sym::iterator, iterator_trait, Target::Trait, GenericRequirement::Exact(0);
214214
Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0);
215215
AsyncIterator, sym::async_iterator, async_iterator_trait, Target::Trait, GenericRequirement::Exact(0);
216+
216217
CoroutineState, sym::coroutine_state, coroutine_state, Target::Enum, GenericRequirement::None;
217218
Coroutine, sym::coroutine, coroutine_trait, Target::Trait, GenericRequirement::Minimum(1);
219+
CoroutineResume, sym::coroutine_resume, coroutine_resume, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
220+
218221
Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None;
219222
Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None;
220223

compiler/rustc_hir_typeck/src/check.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use std::cell::RefCell;
22

33
use crate::coercion::CoerceMany;
44
use crate::gather_locals::GatherLocalsVisitor;
5-
use crate::CoroutineTypes;
6-
use crate::FnCtxt;
5+
use crate::{CoroutineTypes, Diverges, FnCtxt};
76
use rustc_hir as hir;
87
use rustc_hir::def::DefKind;
98
use rustc_hir::intravisit::Visitor;
@@ -76,6 +75,12 @@ pub(super) fn check_fn<'a, 'tcx>(
7675
let ty: Option<&hir::Ty<'_>> = try { inputs_hir?.get(idx)? };
7776
let ty_span = ty.map(|ty| ty.span);
7877
fcx.check_pat_top(param.pat, param_ty, ty_span, None, None);
78+
if param.pat.is_never_pattern() {
79+
fcx.function_diverges_because_of_empty_arguments.set(Diverges::Always {
80+
span: param.pat.span,
81+
custom_note: Some("any code following a never pattern is unreachable"),
82+
});
83+
}
7984

8085
// Check that argument is Sized.
8186
if !params_can_be_unsized {
@@ -105,6 +110,7 @@ pub(super) fn check_fn<'a, 'tcx>(
105110
hir::FnRetTy::Return(ty) => ty.span,
106111
};
107112
fcx.require_type_is_sized(declared_ret_ty, return_or_body_span, traits::SizedReturnType);
113+
fcx.is_whole_body.set(true);
108114
fcx.check_return_expr(body.value, false);
109115

110116
// Finalize the return check by taking the LUB of the return types

compiler/rustc_hir_typeck/src/coercion.rs

+23
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
625625
)];
626626

627627
let mut has_unsized_tuple_coercion = false;
628+
let mut has_trait_upcasting_coercion = None;
628629

629630
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
630631
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
@@ -692,6 +693,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
692693
// these here and emit a feature error if coercion doesn't fail
693694
// due to another reason.
694695
match impl_source {
696+
traits::ImplSource::Builtin(
697+
BuiltinImplSource::TraitUpcasting { .. },
698+
_,
699+
) => {
700+
has_trait_upcasting_coercion =
701+
Some((trait_pred.self_ty(), trait_pred.trait_ref.args.type_at(1)));
702+
}
695703
traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
696704
has_unsized_tuple_coercion = true;
697705
}
@@ -702,6 +710,21 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
702710
}
703711
}
704712

713+
if let Some((sub, sup)) = has_trait_upcasting_coercion
714+
&& !self.tcx().features().trait_upcasting
715+
{
716+
// Renders better when we erase regions, since they're not really the point here.
717+
let (sub, sup) = self.tcx.erase_regions((sub, sup));
718+
let mut err = feature_err(
719+
&self.tcx.sess,
720+
sym::trait_upcasting,
721+
self.cause.span,
722+
format!("cannot cast `{sub}` to `{sup}`, trait upcasting coercion is experimental"),
723+
);
724+
err.note(format!("required when coercing `{source}` into `{target}`"));
725+
err.emit();
726+
}
727+
705728
if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion {
706729
feature_err(
707730
&self.tcx.sess,

compiler/rustc_hir_typeck/src/expr.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
208208
// without the final expr (e.g. `try { return; }`). We don't want to generate an
209209
// unreachable_code lint for it since warnings for autogenerated code are confusing.
210210
let is_try_block_generated_unit_expr = match expr.kind {
211-
ExprKind::Call(_, args) if expr.span.is_desugaring(DesugaringKind::TryBlock) => {
212-
args.len() == 1 && args[0].span.is_desugaring(DesugaringKind::TryBlock)
211+
ExprKind::Call(_, [arg]) => {
212+
expr.span.is_desugaring(DesugaringKind::TryBlock)
213+
&& arg.span.is_desugaring(DesugaringKind::TryBlock)
213214
}
214-
215215
_ => false,
216216
};
217217

@@ -220,9 +220,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
220220
self.warn_if_unreachable(expr.hir_id, expr.span, "expression");
221221
}
222222

223-
// Hide the outer diverging and has_errors flags.
223+
// Whether a past expression diverges doesn't affect typechecking of this expression, so we
224+
// reset `diverges` while checking `expr`.
224225
let old_diverges = self.diverges.replace(Diverges::Maybe);
225226

227+
if self.is_whole_body.replace(false) {
228+
// If this expression is the whole body and the function diverges because of its
229+
// arguments, we check this here to ensure the body is considered to diverge.
230+
self.diverges.set(self.function_diverges_because_of_empty_arguments.get())
231+
};
232+
226233
let ty = ensure_sufficient_stack(|| match &expr.kind {
227234
hir::ExprKind::Path(
228235
qpath @ (hir::QPath::Resolved(..) | hir::QPath::TypeRelative(..)),

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14711471
/// Type check a `let` statement.
14721472
pub fn check_decl_local(&self, local: &'tcx hir::Local<'tcx>) {
14731473
self.check_decl(local.into());
1474+
if local.pat.is_never_pattern() {
1475+
self.diverges.set(Diverges::Always {
1476+
span: local.pat.span,
1477+
custom_note: Some("any code following a never pattern is unreachable"),
1478+
});
1479+
}
14741480
}
14751481

14761482
pub fn check_stmt(&self, stmt: &'tcx hir::Stmt<'tcx>) {

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ pub struct FnCtxt<'a, 'tcx> {
103103
/// the diverges flag is set to something other than `Maybe`.
104104
pub(super) diverges: Cell<Diverges>,
105105

106+
/// If one of the function arguments is a never pattern, this counts as diverging code. This
107+
/// affect typechecking of the function body.
108+
pub(super) function_diverges_because_of_empty_arguments: Cell<Diverges>,
109+
110+
/// Whether the currently checked node is the whole body of the function.
111+
pub(super) is_whole_body: Cell<bool>,
112+
106113
pub(super) enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
107114

108115
pub(super) inh: &'a Inherited<'tcx>,
@@ -124,6 +131,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
124131
ret_coercion_span: Cell::new(None),
125132
coroutine_types: None,
126133
diverges: Cell::new(Diverges::Maybe),
134+
function_diverges_because_of_empty_arguments: Cell::new(Diverges::Maybe),
135+
is_whole_body: Cell::new(false),
127136
enclosing_breakables: RefCell::new(EnclosingBreakables {
128137
stack: Vec::new(),
129138
by_id: Default::default(),

compiler/rustc_interface/src/tests.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ fn assert_same_hash(x: &Options, y: &Options) {
9898
assert_same_clone(y);
9999
}
100100

101+
#[track_caller]
101102
fn assert_different_hash(x: &Options, y: &Options) {
102103
assert_ne!(x.dep_tracking_hash(true), y.dep_tracking_hash(true));
103104
assert_ne!(x.dep_tracking_hash(false), y.dep_tracking_hash(false));
@@ -713,7 +714,6 @@ fn test_unstable_options_tracking_hash() {
713714
untracked!(unpretty, Some("expanded".to_string()));
714715
untracked!(unstable_options, true);
715716
untracked!(validate_mir, true);
716-
untracked!(verbose_internals, true);
717717
untracked!(write_long_types_to_disk, false);
718718
// tidy-alphabetical-end
719719

@@ -845,6 +845,7 @@ fn test_unstable_options_tracking_hash() {
845845
};
846846
}
847847
tracked_no_crate_hash!(no_codegen, true);
848+
tracked_no_crate_hash!(verbose_internals, true);
848849
}
849850

850851
#[test]

compiler/rustc_lint/src/deref_into_dyn_supertrait.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@ use crate::{
55

66
use rustc_hir as hir;
77
use rustc_middle::ty;
8+
use rustc_session::lint::FutureIncompatibilityReason;
89
use rustc_span::sym;
910
use rustc_trait_selection::traits::supertraits;
1011

1112
declare_lint! {
1213
/// The `deref_into_dyn_supertrait` lint is output whenever there is a use of the
1314
/// `Deref` implementation with a `dyn SuperTrait` type as `Output`.
1415
///
16+
/// These implementations will become shadowed when the `trait_upcasting` feature is stabilized.
17+
/// The `deref` functions will no longer be called implicitly, so there might be behavior change.
18+
///
1519
/// ### Example
1620
///
1721
/// ```rust,compile_fail
@@ -40,10 +44,15 @@ declare_lint! {
4044
///
4145
/// ### Explanation
4246
///
43-
/// The implicit dyn upcasting coercion take priority over those `Deref` impls.
47+
/// The dyn upcasting coercion feature adds new coercion rules, taking priority
48+
/// over certain other coercion rules, which will cause some behavior change.
4449
pub DEREF_INTO_DYN_SUPERTRAIT,
4550
Warn,
46-
"`Deref` implementation usage with a supertrait trait object for output are shadow by implicit coercion",
51+
"`Deref` implementation usage with a supertrait trait object for output might be shadowed in the future",
52+
@future_incompatible = FutureIncompatibleInfo {
53+
reason: FutureIncompatibilityReason::FutureReleaseSemanticsChange,
54+
reference: "issue #89460 <https://github.com/rust-lang/rust/issues/89460>",
55+
};
4756
}
4857

4958
declare_lint_pass!(DerefIntoDynSupertrait => [DEREF_INTO_DYN_SUPERTRAIT]);

compiler/rustc_lint/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#![feature(iter_intersperse)]
3636
#![feature(iter_order_by)]
3737
#![feature(let_chains)]
38+
#![cfg_attr(not(bootstrap), feature(trait_upcasting))]
3839
#![feature(min_specialization)]
3940
#![feature(never_type)]
4041
#![feature(rustc_attrs)]

compiler/rustc_lint/src/lints.rs

-1
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,6 @@ pub enum BuiltinSpecialModuleNameUsed {
532532
// deref_into_dyn_supertrait.rs
533533
#[derive(LintDiagnostic)]
534534
#[diag(lint_supertrait_as_deref_target)]
535-
#[help]
536535
pub struct SupertraitAsDerefTarget<'a> {
537536
pub self_ty: Ty<'a>,
538537
pub supertrait_principal: PolyExistentialTraitRef<'a>,

compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#![feature(associated_type_bounds)]
5050
#![feature(rustc_attrs)]
5151
#![feature(control_flow_enum)]
52+
#![cfg_attr(not(bootstrap), feature(trait_upcasting))]
5253
#![feature(trusted_step)]
5354
#![feature(try_blocks)]
5455
#![feature(try_reserve_kind)]

compiler/rustc_middle/src/ty/instance.rs

+50
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::ty::print::{FmtPrinter, Printer};
33
use crate::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
44
use crate::ty::{EarlyBinder, GenericArgs, GenericArgsRef, TypeVisitableExt};
55
use rustc_errors::ErrorGuaranteed;
6+
use rustc_hir as hir;
67
use rustc_hir::def::Namespace;
78
use rustc_hir::def_id::{CrateNum, DefId};
89
use rustc_hir::lang_items::LangItem;
@@ -11,6 +12,7 @@ use rustc_macros::HashStable;
1112
use rustc_middle::ty::normalize_erasing_regions::NormalizationError;
1213
use rustc_span::Symbol;
1314

15+
use std::assert_matches::assert_matches;
1416
use std::fmt;
1517

1618
/// A monomorphized `InstanceDef`.
@@ -572,6 +574,54 @@ impl<'tcx> Instance<'tcx> {
572574
Some(Instance { def, args })
573575
}
574576

577+
pub fn try_resolve_item_for_coroutine(
578+
tcx: TyCtxt<'tcx>,
579+
trait_item_id: DefId,
580+
trait_id: DefId,
581+
rcvr_args: ty::GenericArgsRef<'tcx>,
582+
) -> Option<Instance<'tcx>> {
583+
let ty::Coroutine(coroutine_def_id, args) = *rcvr_args.type_at(0).kind() else {
584+
return None;
585+
};
586+
let coroutine_kind = tcx.coroutine_kind(coroutine_def_id).unwrap();
587+
588+
let lang_items = tcx.lang_items();
589+
let coroutine_callable_item = if Some(trait_id) == lang_items.future_trait() {
590+
assert_matches!(
591+
coroutine_kind,
592+
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)
593+
);
594+
hir::LangItem::FuturePoll
595+
} else if Some(trait_id) == lang_items.iterator_trait() {
596+
assert_matches!(
597+
coroutine_kind,
598+
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)
599+
);
600+
hir::LangItem::IteratorNext
601+
} else if Some(trait_id) == lang_items.async_iterator_trait() {
602+
assert_matches!(
603+
coroutine_kind,
604+
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)
605+
);
606+
hir::LangItem::AsyncIteratorPollNext
607+
} else if Some(trait_id) == lang_items.coroutine_trait() {
608+
assert_matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_));
609+
hir::LangItem::CoroutineResume
610+
} else {
611+
return None;
612+
};
613+
614+
if tcx.lang_items().get(coroutine_callable_item) == Some(trait_item_id) {
615+
Some(Instance { def: ty::InstanceDef::Item(coroutine_def_id), args: args })
616+
} else {
617+
// All other methods should be defaulted methods of the built-in trait.
618+
// This is important for `Iterator`'s combinators, but also useful for
619+
// adding future default methods to `Future`, for instance.
620+
debug_assert!(tcx.defaultness(trait_item_id).has_value());
621+
Some(Instance::new(trait_item_id, rcvr_args))
622+
}
623+
}
624+
575625
/// Depending on the kind of `InstanceDef`, the MIR body associated with an
576626
/// instance is expressed in terms of the generic parameters of `self.def_id()`, and in other
577627
/// cases the MIR body is expressed in terms of the types found in the substitution array.

compiler/rustc_middle/src/ty/print/pretty.rs

-2
Original file line numberDiff line numberDiff line change
@@ -3072,8 +3072,6 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
30723072
/// See also [`DelayDm`](rustc_error_messages::DelayDm) and [`with_no_trimmed_paths!`].
30733073
// this is pub to be able to intra-doc-link it
30743074
pub fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> DefIdMap<Symbol> {
3075-
assert!(tcx.sess.opts.trimmed_def_paths);
3076-
30773075
// Trimming paths is expensive and not optimized, since we expect it to only be used for error
30783076
// reporting.
30793077
//

compiler/rustc_session/src/options.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ top_level_options!(
224224
working_dir: RealFileName [TRACKED],
225225
color: ColorConfig [UNTRACKED],
226226

227-
verbose: bool [UNTRACKED],
227+
verbose: bool [TRACKED_NO_CRATE_HASH],
228228
}
229229
);
230230

@@ -1986,7 +1986,7 @@ written to standard error output)"),
19861986
validate_mir: bool = (false, parse_bool, [UNTRACKED],
19871987
"validate MIR after each transformation"),
19881988
#[rustc_lint_opt_deny_field_access("use `Session::verbose_internals` instead of this field")]
1989-
verbose_internals: bool = (false, parse_bool, [UNTRACKED],
1989+
verbose_internals: bool = (false, parse_bool, [TRACKED_NO_CRATE_HASH],
19901990
"in general, enable more debug printouts (default: no)"),
19911991
#[rustc_lint_opt_deny_field_access("use `Session::verify_llvm_ir` instead of this field")]
19921992
verify_llvm_ir: bool = (false, parse_bool, [TRACKED],

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,7 @@ symbols! {
600600
core_panic_macro,
601601
coroutine,
602602
coroutine_clone,
603+
coroutine_resume,
603604
coroutine_state,
604605
coroutines,
605606
cosf32,

0 commit comments

Comments
 (0)