Skip to content

Rollup of 9 pull requests #123108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Mar 27, 2024
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
17ba73c
Document `adt_const_params` feature in Unstable Book
Shadlock0133 Mar 2, 2023
6b85f07
Small tweaks to the linting code for bare trait object types
fmease Mar 6, 2024
d3d77a8
Update docs of hir::TypeBinding
fmease Mar 6, 2024
22b9e96
Suggest assoc ty bound on bare dyn trait in eq constraint
fmease Mar 6, 2024
3879acb
Suggest assoc ty bound on lifetime in eq constraint
fmease Mar 6, 2024
0c7f8b0
Fix diagnostics for async block cloning
wutchzone Mar 16, 2024
2c433d0
Fix typos
wutchzone Mar 16, 2024
b562795
Require DerefPure for patterns
compiler-errors Mar 21, 2024
5fdc755
Require DerefMut if deref pattern has nested ref mut binding
compiler-errors Mar 21, 2024
fc1d7d2
Extract helper, fix comment on DerefPure
compiler-errors Mar 24, 2024
69af113
enable cargo miri test doctests
onur-ozkan Mar 25, 2024
7b4e507
unix fs: Make hurd and horizon using explicit new rather than From
sthibaul Mar 25, 2024
22bc5c5
In ConstructCoroutineInClosureShim, pass receiver by ref, not pointer
compiler-errors Mar 25, 2024
2cfd532
Change `f16` and `f128` clippy stubs to be nonpanicking
tgross35 Mar 26, 2024
bf7a745
Inherited -> TypeckRootCtxt
compiler-errors Mar 26, 2024
9162776
Rollup merge of #108675 - Shadlock0133:adt_const_params, r=compiler-e…
matthiaskrgr Mar 26, 2024
ff8cdc9
Rollup merge of #122120 - fmease:sugg-assoc-ty-bound-on-eq-bound, r=c…
matthiaskrgr Mar 26, 2024
20770ac
Rollup merge of #122589 - wutchzone:121547, r=compiler-errors
matthiaskrgr Mar 26, 2024
0029a11
Rollup merge of #122835 - compiler-errors:deref-pure, r=Nadrieril
matthiaskrgr Mar 26, 2024
b63dca1
Rollup merge of #123049 - compiler-errors:coroutine-closure-rcvr, r=o…
matthiaskrgr Mar 26, 2024
b8e8d65
Rollup merge of #123055 - onur-ozkan:miri-rustdoc, r=RalfJung
matthiaskrgr Mar 26, 2024
ac5ffa5
Rollup merge of #123057 - sthibaul:systemtime, r=jhpratt
matthiaskrgr Mar 26, 2024
7af95ed
Rollup merge of #123087 - tgross35:clippy-f16-f128-check-stubs, r=bly…
matthiaskrgr Mar 26, 2024
781b225
Rollup merge of #123103 - compiler-errors:inherited-is-a-weird-name, …
matthiaskrgr Mar 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
#![allow(rustc::untranslatable_diagnostic)]

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

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

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

let span = in_loop.span;
if !finder.found_breaks.is_empty()
22 changes: 8 additions & 14 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -2289,21 +2289,15 @@ pub enum ImplItemKind<'hir> {
Type(&'hir Ty<'hir>),
}

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

1 change: 1 addition & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
@@ -199,6 +199,7 @@ language_item_table! {

Deref, sym::deref, deref_trait, Target::Trait, GenericRequirement::Exact(0);
DerefMut, sym::deref_mut, deref_mut_trait, Target::Trait, GenericRequirement::Exact(0);
DerefPure, sym::deref_pure, deref_pure_trait, Target::Trait, GenericRequirement::Exact(0);
DerefTarget, sym::deref_target, deref_target, Target::AssocTy, GenericRequirement::None;
Receiver, sym::receiver, receiver_trait, Target::Trait, GenericRequirement::None;

169 changes: 107 additions & 62 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
Original file line number Diff line number Diff line change
@@ -9,8 +9,85 @@ use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamNa
use super::HirTyLowerer;

impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
/// Prohibit or lint against *bare* trait object types depending on the edition.
///
/// *Bare* trait object types are ones that aren't preceeded by the keyword `dyn`.
/// In edition 2021 and onward we emit a hard error for them.
pub(super) fn prohibit_or_lint_bare_trait_object_ty(
&self,
self_ty: &hir::Ty<'_>,
in_path: bool,
) {
let tcx = self.tcx();

let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
self_ty.kind
else {
return;
};

let needs_bracket = in_path
&& !tcx
.sess
.source_map()
.span_to_prev_source(self_ty.span)
.ok()
.is_some_and(|s| s.trim_end().ends_with('<'));

let is_global = poly_trait_ref.trait_ref.path.is_global();

let mut sugg = vec![(
self_ty.span.shrink_to_lo(),
format!(
"{}dyn {}",
if needs_bracket { "<" } else { "" },
if is_global { "(" } else { "" },
),
)];

if is_global || needs_bracket {
sugg.push((
self_ty.span.shrink_to_hi(),
format!(
"{}{}",
if is_global { ")" } else { "" },
if needs_bracket { ">" } else { "" },
),
));
}

if self_ty.span.edition().at_least_rust_2021() {
let msg = "trait objects must include the `dyn` keyword";
let label = "add `dyn` keyword before this trait";
let mut diag =
rustc_errors::struct_span_code_err!(tcx.dcx(), self_ty.span, E0782, "{}", msg);
if self_ty.span.can_be_used_for_suggestions()
&& !self.maybe_suggest_impl_trait(self_ty, &mut diag)
{
// FIXME: Only emit this suggestion if the trait is object safe.
diag.multipart_suggestion_verbose(label, sugg, Applicability::MachineApplicable);
}
// Check if the impl trait that we are considering is an impl of a local trait.
self.maybe_suggest_blanket_trait_impl(self_ty, &mut diag);
self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
} else {
let msg = "trait objects without an explicit `dyn` are deprecated";
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
if self_ty.span.can_be_used_for_suggestions() {
lint.multipart_suggestion_verbose(
"if this is an object-safe trait, use `dyn`",
sugg,
Applicability::MachineApplicable,
);
}
self.maybe_suggest_blanket_trait_impl(self_ty, lint);
});
}
}

/// Make sure that we are in the condition to suggest the blanket implementation.
pub(super) fn maybe_lint_blanket_trait_impl<G: EmissionGuarantee>(
fn maybe_suggest_blanket_trait_impl<G: EmissionGuarantee>(
&self,
self_ty: &hir::Ty<'_>,
diag: &mut Diag<'_, G>,
@@ -75,9 +152,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
}

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

pub(super) fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
let tcx = self.tcx();
if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
self_ty.kind
{
let needs_bracket = in_path
&& !tcx
.sess
.source_map()
.span_to_prev_source(self_ty.span)
.ok()
.is_some_and(|s| s.trim_end().ends_with('<'));

let is_global = poly_trait_ref.trait_ref.path.is_global();

let mut sugg = Vec::from_iter([(
self_ty.span.shrink_to_lo(),
format!(
"{}dyn {}",
if needs_bracket { "<" } else { "" },
if is_global { "(" } else { "" },
),
)]);
fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) {
let mut parents = self.tcx().hir().parent_iter(self_ty.hir_id);

if is_global || needs_bracket {
sugg.push((
self_ty.span.shrink_to_hi(),
format!(
"{}{}",
if is_global { ")" } else { "" },
if needs_bracket { ">" } else { "" },
),
));
if let Some((_, hir::Node::TypeBinding(binding))) = parents.next()
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(obj_ty) } = binding.kind
{
if let Some((_, hir::Node::TraitRef(..))) = parents.next()
&& let Some((_, hir::Node::Ty(ty))) = parents.next()
&& let hir::TyKind::TraitObject(..) = ty.kind
{
// Assoc ty bounds aren't permitted inside trait object types.
return;
}

if self_ty.span.edition().at_least_rust_2021() {
let msg = "trait objects must include the `dyn` keyword";
let label = "add `dyn` keyword before this trait";
let mut diag =
rustc_errors::struct_span_code_err!(tcx.dcx(), self_ty.span, E0782, "{}", msg);
if self_ty.span.can_be_used_for_suggestions()
&& !self.maybe_lint_impl_trait(self_ty, &mut diag)
{
diag.multipart_suggestion_verbose(
label,
sugg,
Applicability::MachineApplicable,
);
}
// check if the impl trait that we are considering is a impl of a local trait
self.maybe_lint_blanket_trait_impl(self_ty, &mut diag);
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
let lo = if binding.gen_args.span_ext.is_dummy() {
binding.ident.span
} else {
let msg = "trait objects without an explicit `dyn` are deprecated";
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
if self_ty.span.can_be_used_for_suggestions() {
lint.multipart_suggestion_verbose(
"if this is an object-safe trait, use `dyn`",
sugg,
Applicability::MachineApplicable,
);
}
self.maybe_lint_blanket_trait_impl(self_ty, lint);
});
binding.gen_args.span_ext
};
let hi = obj_ty.span;

if !lo.eq_ctxt(hi) {
return;
}

diag.span_suggestion_verbose(
lo.between(hi),
"you might have meant to write a bound here",
": ",
Applicability::MaybeIncorrect,
);
}
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
@@ -2339,12 +2339,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
)
}
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
self.maybe_lint_bare_trait(hir_ty, in_path);
self.prohibit_or_lint_bare_trait_object_ty(hir_ty, in_path);

let repr = match repr {
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
TraitObjectSyntax::DynStar => ty::DynStar,
};

self.lower_trait_object_ty(
hir_ty.span,
hir_ty.hir_id,
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/_match.rs
Original file line number Diff line number Diff line change
@@ -243,7 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let can_coerce_to_return_ty = match self.ret_coercion.as_ref() {
Some(ret_coercion) => {
let ret_ty = ret_coercion.borrow().expected_ty();
let ret_ty = self.inh.infcx.shallow_resolve(ret_ty);
let ret_ty = self.infcx.shallow_resolve(ret_ty);
self.can_coerce(arm_ty, ret_ty)
&& prior_arm.map_or(true, |(_, ty, _)| self.can_coerce(ty, ret_ty))
// The match arms need to unify for the case of `impl Trait`.
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
@@ -848,7 +848,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
bound_vars,
);

let c_result = self.inh.infcx.canonicalize_response(result);
let c_result = self.infcx.canonicalize_response(result);
self.typeck_results.borrow_mut().user_provided_sigs.insert(expr_def_id, c_result);

// Normalize only after registering in `user_provided_sigs`.
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/src/fallback.rs
Original file line number Diff line number Diff line change
@@ -347,7 +347,6 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
.any(|n| roots_reachable_from_non_diverging.visited(n));

let infer_var_infos: UnordBag<_> = self
.inh
.infer_var_info
.borrow()
.items()
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
@@ -526,7 +526,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn resolve_rvalue_scopes(&self, def_id: DefId) {
let scope_tree = self.tcx.region_scope_tree(def_id);
let rvalue_scopes = { rvalue_scopes::resolve_rvalue_scopes(self, scope_tree, def_id) };
let mut typeck_results = self.inh.typeck_results.borrow_mut();
let mut typeck_results = self.typeck_results.borrow_mut();
typeck_results.rvalue_scopes = rvalue_scopes;
}

14 changes: 7 additions & 7 deletions compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ mod suggestions;
use crate::coercion::DynamicCoerceMany;
use crate::fallback::DivergingFallbackBehavior;
use crate::fn_ctxt::checks::DivergingBlockBehavior;
use crate::{CoroutineTypes, Diverges, EnclosingBreakables, Inherited};
use crate::{CoroutineTypes, Diverges, EnclosingBreakables, TypeckRootCtxt};
use hir::def_id::CRATE_DEF_ID;
use rustc_errors::{DiagCtxt, ErrorGuaranteed};
use rustc_hir as hir;
@@ -108,7 +108,7 @@ pub struct FnCtxt<'a, 'tcx> {

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

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

pub(super) fallback_has_occurred: Cell<bool>,

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

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn new(
inh: &'a Inherited<'tcx>,
root_ctxt: &'a TypeckRootCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
body_id: LocalDefId,
) -> FnCtxt<'a, 'tcx> {
let (diverging_fallback_behavior, diverging_block_behavior) =
parse_never_type_options_attr(inh.tcx);
parse_never_type_options_attr(root_ctxt.tcx);
FnCtxt {
body_id,
param_env,
@@ -137,7 +137,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
stack: Vec::new(),
by_id: Default::default(),
}),
inh,
root_ctxt,
fallback_has_occurred: Cell::new(false),
diverging_fallback_behavior,
diverging_block_behavior,
@@ -206,9 +206,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

impl<'a, 'tcx> Deref for FnCtxt<'a, 'tcx> {
type Target = Inherited<'tcx>;
type Target = TypeckRootCtxt<'tcx>;
fn deref(&self) -> &Self::Target {
self.inh
self.root_ctxt
}
}

Loading