Skip to content

Commit a1b4991

Browse files
committed
Auto merge of #123108 - matthiaskrgr:rollup-zossklv, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #108675 (Document `adt_const_params` feature in Unstable Book) - #122120 (Suggest associated type bounds on problematic associated equality bounds) - #122589 (Fix diagnostics for async block cloning) - #122835 (Require `DerefMut` and `DerefPure` on `deref!()` patterns when appropriate) - #123049 (In `ConstructCoroutineInClosureShim`, pass receiver by mut ref, not mut pointer) - #123055 (enable cargo miri test doctests) - #123057 (unix fs: Make hurd using explicit new rather than From) - #123087 (Change `f16` and `f128` clippy stubs to be nonpanicking) - #123103 (Rename `Inherited` -> `TypeckRootCtxt`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 47ecded + 781b225 commit a1b4991

Some content is hidden

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

51 files changed

+632
-171
lines changed

Diff for: compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![allow(rustc::untranslatable_diagnostic)]
55

66
use either::Either;
7+
use hir::ClosureKind;
78
use rustc_data_structures::captures::Captures;
89
use rustc_data_structures::fx::FxIndexSet;
910
use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag, MultiSpan};
@@ -463,6 +464,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
463464
} else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = move_spans
464465
{
465466
// We already suggest cloning for these cases in `explain_captures`.
467+
} else if let UseSpans::ClosureUse {
468+
closure_kind:
469+
ClosureKind::Coroutine(CoroutineKind::Desugared(_, CoroutineSource::Block)),
470+
args_span: _,
471+
capture_kind_span: _,
472+
path_span,
473+
} = move_spans
474+
{
475+
self.suggest_cloning(err, ty, expr, path_span);
466476
} else if self.suggest_hoisting_call_outside_loop(err, expr) {
467477
// The place where the the type moves would be misleading to suggest clone.
468478
// #121466
@@ -621,7 +631,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
621631
}
622632

623633
// FIXME: We make sure that this is a normal top-level binding,
624-
// but we could suggest `todo!()` for all uninitalized bindings in the pattern pattern
634+
// but we could suggest `todo!()` for all uninitialized bindings in the pattern pattern
625635
if let hir::StmtKind::Let(hir::LetStmt { span, ty, init: None, pat, .. }) =
626636
&ex.kind
627637
&& let hir::PatKind::Binding(..) = pat.kind
@@ -749,7 +759,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
749759
true
750760
}
751761

752-
/// In a move error that occurs on a call wihtin a loop, we try to identify cases where cloning
762+
/// In a move error that occurs on a call within a loop, we try to identify cases where cloning
753763
/// the value would lead to a logic error. We infer these cases by seeing if the moved value is
754764
/// part of the logic to break the loop, either through an explicit `break` or if the expression
755765
/// is part of a `while let`.
@@ -950,7 +960,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
950960
{
951961
// FIXME: We could check that the call's *parent* takes `&mut val` to make the
952962
// suggestion more targeted to the `mk_iter(val).next()` case. Maybe do that only to
953-
// check for wheter to suggest `let value` or `let mut value`.
963+
// check for whether to suggest `let value` or `let mut value`.
954964

955965
let span = in_loop.span;
956966
if !finder.found_breaks.is_empty()

Diff for: compiler/rustc_hir/src/hir.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -2289,21 +2289,15 @@ pub enum ImplItemKind<'hir> {
22892289
Type(&'hir Ty<'hir>),
22902290
}
22912291

2292-
/// Bind a type to an associated type (i.e., `A = Foo`).
2292+
/// An associated item binding.
22932293
///
2294-
/// Bindings like `A: Debug` are represented as a special type `A =
2295-
/// $::Debug` that is understood by the HIR ty lowering code.
2294+
/// ### Examples
22962295
///
2297-
/// FIXME(alexreg): why have a separate type for the binding case,
2298-
/// wouldn't it be better to make the `ty` field an enum like the
2299-
/// following?
2300-
///
2301-
/// ```ignore (pseudo-rust)
2302-
/// enum TypeBindingKind {
2303-
/// Equals(...),
2304-
/// Binding(...),
2305-
/// }
2306-
/// ```
2296+
/// * `Trait<A = Ty, B = Ty>`
2297+
/// * `Trait<G<Ty> = Ty>`
2298+
/// * `Trait<A: Bound>`
2299+
/// * `Trait<C = { Ct }>` (under feature `associated_const_equality`)
2300+
/// * `Trait<f(): Bound>` (under feature `return_type_notation`)
23072301
#[derive(Debug, Clone, Copy, HashStable_Generic)]
23082302
pub struct TypeBinding<'hir> {
23092303
pub hir_id: HirId,
@@ -2336,7 +2330,7 @@ impl<'hir> From<AnonConst> for Term<'hir> {
23362330
pub enum TypeBindingKind<'hir> {
23372331
/// E.g., `Foo<Bar: Send>`.
23382332
Constraint { bounds: &'hir [GenericBound<'hir>] },
2339-
/// E.g., `Foo<Bar = ()>`, `Foo<Bar = ()>`
2333+
/// E.g., `Foo<Bar = ()>`.
23402334
Equality { term: Term<'hir> },
23412335
}
23422336

Diff for: compiler/rustc_hir/src/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ language_item_table! {
199199

200200
Deref, sym::deref, deref_trait, Target::Trait, GenericRequirement::Exact(0);
201201
DerefMut, sym::deref_mut, deref_mut_trait, Target::Trait, GenericRequirement::Exact(0);
202+
DerefPure, sym::deref_pure, deref_pure_trait, Target::Trait, GenericRequirement::Exact(0);
202203
DerefTarget, sym::deref_target, deref_target, Target::AssocTy, GenericRequirement::None;
203204
Receiver, sym::receiver, receiver_trait, Target::Trait, GenericRequirement::None;
204205

Diff for: compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs

+107-62
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,85 @@ use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamNa
99
use super::HirTyLowerer;
1010

1111
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12+
/// Prohibit or lint against *bare* trait object types depending on the edition.
13+
///
14+
/// *Bare* trait object types are ones that aren't preceeded by the keyword `dyn`.
15+
/// In edition 2021 and onward we emit a hard error for them.
16+
pub(super) fn prohibit_or_lint_bare_trait_object_ty(
17+
&self,
18+
self_ty: &hir::Ty<'_>,
19+
in_path: bool,
20+
) {
21+
let tcx = self.tcx();
22+
23+
let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
24+
self_ty.kind
25+
else {
26+
return;
27+
};
28+
29+
let needs_bracket = in_path
30+
&& !tcx
31+
.sess
32+
.source_map()
33+
.span_to_prev_source(self_ty.span)
34+
.ok()
35+
.is_some_and(|s| s.trim_end().ends_with('<'));
36+
37+
let is_global = poly_trait_ref.trait_ref.path.is_global();
38+
39+
let mut sugg = vec![(
40+
self_ty.span.shrink_to_lo(),
41+
format!(
42+
"{}dyn {}",
43+
if needs_bracket { "<" } else { "" },
44+
if is_global { "(" } else { "" },
45+
),
46+
)];
47+
48+
if is_global || needs_bracket {
49+
sugg.push((
50+
self_ty.span.shrink_to_hi(),
51+
format!(
52+
"{}{}",
53+
if is_global { ")" } else { "" },
54+
if needs_bracket { ">" } else { "" },
55+
),
56+
));
57+
}
58+
59+
if self_ty.span.edition().at_least_rust_2021() {
60+
let msg = "trait objects must include the `dyn` keyword";
61+
let label = "add `dyn` keyword before this trait";
62+
let mut diag =
63+
rustc_errors::struct_span_code_err!(tcx.dcx(), self_ty.span, E0782, "{}", msg);
64+
if self_ty.span.can_be_used_for_suggestions()
65+
&& !self.maybe_suggest_impl_trait(self_ty, &mut diag)
66+
{
67+
// FIXME: Only emit this suggestion if the trait is object safe.
68+
diag.multipart_suggestion_verbose(label, sugg, Applicability::MachineApplicable);
69+
}
70+
// Check if the impl trait that we are considering is an impl of a local trait.
71+
self.maybe_suggest_blanket_trait_impl(self_ty, &mut diag);
72+
self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
73+
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
74+
} else {
75+
let msg = "trait objects without an explicit `dyn` are deprecated";
76+
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
77+
if self_ty.span.can_be_used_for_suggestions() {
78+
lint.multipart_suggestion_verbose(
79+
"if this is an object-safe trait, use `dyn`",
80+
sugg,
81+
Applicability::MachineApplicable,
82+
);
83+
}
84+
self.maybe_suggest_blanket_trait_impl(self_ty, lint);
85+
});
86+
}
87+
}
88+
1289
/// Make sure that we are in the condition to suggest the blanket implementation.
13-
pub(super) fn maybe_lint_blanket_trait_impl<G: EmissionGuarantee>(
90+
fn maybe_suggest_blanket_trait_impl<G: EmissionGuarantee>(
1491
&self,
1592
self_ty: &hir::Ty<'_>,
1693
diag: &mut Diag<'_, G>,
@@ -75,9 +152,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
75152
}
76153

77154
/// Make sure that we are in the condition to suggest `impl Trait`.
78-
fn maybe_lint_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) -> bool {
155+
fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) -> bool {
79156
let tcx = self.tcx();
80157
let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
158+
// FIXME: If `type_alias_impl_trait` is enabled, also look for `Trait0<Ty = Trait1>`
159+
// and suggest `Trait0<Ty = impl Trait1>`.
81160
let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) {
82161
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, generics, _), .. }) => {
83162
(sig, generics, None)
@@ -186,71 +265,37 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
186265
false
187266
}
188267

189-
pub(super) fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
190-
let tcx = self.tcx();
191-
if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
192-
self_ty.kind
193-
{
194-
let needs_bracket = in_path
195-
&& !tcx
196-
.sess
197-
.source_map()
198-
.span_to_prev_source(self_ty.span)
199-
.ok()
200-
.is_some_and(|s| s.trim_end().ends_with('<'));
201-
202-
let is_global = poly_trait_ref.trait_ref.path.is_global();
203-
204-
let mut sugg = Vec::from_iter([(
205-
self_ty.span.shrink_to_lo(),
206-
format!(
207-
"{}dyn {}",
208-
if needs_bracket { "<" } else { "" },
209-
if is_global { "(" } else { "" },
210-
),
211-
)]);
268+
fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) {
269+
let mut parents = self.tcx().hir().parent_iter(self_ty.hir_id);
212270

213-
if is_global || needs_bracket {
214-
sugg.push((
215-
self_ty.span.shrink_to_hi(),
216-
format!(
217-
"{}{}",
218-
if is_global { ")" } else { "" },
219-
if needs_bracket { ">" } else { "" },
220-
),
221-
));
271+
if let Some((_, hir::Node::TypeBinding(binding))) = parents.next()
272+
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(obj_ty) } = binding.kind
273+
{
274+
if let Some((_, hir::Node::TraitRef(..))) = parents.next()
275+
&& let Some((_, hir::Node::Ty(ty))) = parents.next()
276+
&& let hir::TyKind::TraitObject(..) = ty.kind
277+
{
278+
// Assoc ty bounds aren't permitted inside trait object types.
279+
return;
222280
}
223281

224-
if self_ty.span.edition().at_least_rust_2021() {
225-
let msg = "trait objects must include the `dyn` keyword";
226-
let label = "add `dyn` keyword before this trait";
227-
let mut diag =
228-
rustc_errors::struct_span_code_err!(tcx.dcx(), self_ty.span, E0782, "{}", msg);
229-
if self_ty.span.can_be_used_for_suggestions()
230-
&& !self.maybe_lint_impl_trait(self_ty, &mut diag)
231-
{
232-
diag.multipart_suggestion_verbose(
233-
label,
234-
sugg,
235-
Applicability::MachineApplicable,
236-
);
237-
}
238-
// check if the impl trait that we are considering is a impl of a local trait
239-
self.maybe_lint_blanket_trait_impl(self_ty, &mut diag);
240-
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
282+
let lo = if binding.gen_args.span_ext.is_dummy() {
283+
binding.ident.span
241284
} else {
242-
let msg = "trait objects without an explicit `dyn` are deprecated";
243-
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
244-
if self_ty.span.can_be_used_for_suggestions() {
245-
lint.multipart_suggestion_verbose(
246-
"if this is an object-safe trait, use `dyn`",
247-
sugg,
248-
Applicability::MachineApplicable,
249-
);
250-
}
251-
self.maybe_lint_blanket_trait_impl(self_ty, lint);
252-
});
285+
binding.gen_args.span_ext
286+
};
287+
let hi = obj_ty.span;
288+
289+
if !lo.eq_ctxt(hi) {
290+
return;
253291
}
292+
293+
diag.span_suggestion_verbose(
294+
lo.between(hi),
295+
"you might have meant to write a bound here",
296+
": ",
297+
Applicability::MaybeIncorrect,
298+
);
254299
}
255300
}
256301
}

Diff for: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2339,12 +2339,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23392339
)
23402340
}
23412341
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
2342-
self.maybe_lint_bare_trait(hir_ty, in_path);
2342+
self.prohibit_or_lint_bare_trait_object_ty(hir_ty, in_path);
2343+
23432344
let repr = match repr {
23442345
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
23452346
TraitObjectSyntax::DynStar => ty::DynStar,
23462347
};
2347-
23482348
self.lower_trait_object_ty(
23492349
hir_ty.span,
23502350
hir_ty.hir_id,

Diff for: compiler/rustc_hir_typeck/src/_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
243243
let can_coerce_to_return_ty = match self.ret_coercion.as_ref() {
244244
Some(ret_coercion) => {
245245
let ret_ty = ret_coercion.borrow().expected_ty();
246-
let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
246+
let ret_ty = self.infcx.shallow_resolve(ret_ty);
247247
self.can_coerce(arm_ty, ret_ty)
248248
&& prior_arm.map_or(true, |(_, ty, _)| self.can_coerce(ty, ret_ty))
249249
// The match arms need to unify for the case of `impl Trait`.

Diff for: compiler/rustc_hir_typeck/src/closure.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
848848
bound_vars,
849849
);
850850

851-
let c_result = self.inh.infcx.canonicalize_response(result);
851+
let c_result = self.infcx.canonicalize_response(result);
852852
self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result);
853853

854854
// Normalize only after registering in `user_provided_sigs`.

Diff for: compiler/rustc_hir_typeck/src/fallback.rs

-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
347347
.any(|n| roots_reachable_from_non_diverging.visited(n));
348348

349349
let infer_var_infos: UnordBag<_> = self
350-
.inh
351350
.infer_var_info
352351
.borrow()
353352
.items()

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
526526
pub(in super::super) fn resolve_rvalue_scopes(&self, def_id: DefId) {
527527
let scope_tree = self.tcx.region_scope_tree(def_id);
528528
let rvalue_scopes = { rvalue_scopes::resolve_rvalue_scopes(self, scope_tree, def_id) };
529-
let mut typeck_results = self.inh.typeck_results.borrow_mut();
529+
let mut typeck_results = self.typeck_results.borrow_mut();
530530
typeck_results.rvalue_scopes = rvalue_scopes;
531531
}
532532

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod suggestions;
77
use crate::coercion::DynamicCoerceMany;
88
use crate::fallback::DivergingFallbackBehavior;
99
use crate::fn_ctxt::checks::DivergingBlockBehavior;
10-
use crate::{CoroutineTypes, Diverges, EnclosingBreakables, Inherited};
10+
use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt};
1111
use hir::def_id::CRATE_DEF_ID;
1212
use rustc_errors::{DiagCtxt, ErrorGuaranteed};
1313
use rustc_hir as hir;
@@ -108,7 +108,7 @@ pub struct FnCtxt<'a, 'tcx> {
108108

109109
pub(super) enclosing_breakables: RefCell<EnclosingBreakables<'tcx>>,
110110

111-
pub(super) inh: &'a Inherited<'tcx>,
111+
pub(super) root_ctxt: &'a TypeckRootCtxt<'tcx>,
112112

113113
pub(super) fallback_has_occurred: Cell<bool>,
114114

@@ -118,12 +118,12 @@ pub struct FnCtxt<'a, 'tcx> {
118118

119119
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
120120
pub fn new(
121-
inh: &'a Inherited<'tcx>,
121+
root_ctxt: &'a TypeckRootCtxt<'tcx>,
122122
param_env: ty::ParamEnv<'tcx>,
123123
body_id: LocalDefId,
124124
) -> FnCtxt<'a, 'tcx> {
125125
let (diverging_fallback_behavior, diverging_block_behavior) =
126-
parse_never_type_options_attr(inh.tcx);
126+
parse_never_type_options_attr(root_ctxt.tcx);
127127
FnCtxt {
128128
body_id,
129129
param_env,
@@ -137,7 +137,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
137137
stack: Vec::new(),
138138
by_id: Default::default(),
139139
}),
140-
inh,
140+
root_ctxt,
141141
fallback_has_occurred: Cell::new(false),
142142
diverging_fallback_behavior,
143143
diverging_block_behavior,
@@ -206,9 +206,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
206206
}
207207

208208
impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
209-
type Target = Inherited<'tcx>;
209+
type Target = TypeckRootCtxt<'tcx>;
210210
fn deref(&self) -> &Self::Target {
211-
self.inh
211+
self.root_ctxt
212212
}
213213
}
214214

0 commit comments

Comments
 (0)