Merge from rustc

This commit is contained in:
The Miri Conjob Bot 2024-02-10 05:02:28 +00:00
commit 3e97b415c3
951 changed files with 14585 additions and 6933 deletions

View file

@ -556,7 +556,7 @@ checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
[[package]]
name = "clippy"
version = "0.1.77"
version = "0.1.78"
dependencies = [
"anstream",
"clippy_config",
@ -584,7 +584,7 @@ dependencies = [
[[package]]
name = "clippy_config"
version = "0.1.77"
version = "0.1.78"
dependencies = [
"rustc-semver",
"serde",
@ -607,7 +607,7 @@ dependencies = [
[[package]]
name = "clippy_lints"
version = "0.1.77"
version = "0.1.78"
dependencies = [
"arrayvec",
"cargo_metadata 0.18.0",
@ -632,7 +632,7 @@ dependencies = [
[[package]]
name = "clippy_utils"
version = "0.1.77"
version = "0.1.78"
dependencies = [
"arrayvec",
"clippy_config",
@ -1003,7 +1003,7 @@ checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
[[package]]
name = "declare_clippy_lint"
version = "0.1.77"
version = "0.1.78"
dependencies = [
"itertools",
"quote",
@ -2090,9 +2090,9 @@ dependencies = [
[[package]]
name = "jobserver"
version = "0.1.27"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6"
dependencies = [
"libc",
]
@ -4374,6 +4374,7 @@ dependencies = [
"rustc_middle",
"rustc_session",
"rustc_span",
"rustc_ty_utils",
"tracing",
]

View file

@ -7,7 +7,7 @@ Language
--------
- [Document Rust ABI compatibility between various types](https://github.com/rust-lang/rust/pull/115476/)
- [Also: guarantee that char and u32 are ABI-compatible](https://github.com/rust-lang/rust/pull/118032/)
- [Warn against ambiguous wide pointer comparisons](https://github.com/rust-lang/rust/pull/117758/)
- [Add lint `ambiguous_wide_pointer_comparisons` that supersedes `clippy::vtable_address_comparisons`](https://github.com/rust-lang/rust/pull/117758)
<a id="1.76.0-Compiler"></a>

View file

@ -22,8 +22,6 @@
#![cfg_attr(test, feature(test))]
#![feature(strict_provenance)]
#![deny(unsafe_op_in_unsafe_fn)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![allow(internal_features)]
#![allow(clippy::mut_from_ref)] // Arena allocators are one of the places where this pattern is fine.

View file

@ -18,8 +18,6 @@
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(stmt_expr_attributes)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;

View file

@ -205,7 +205,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&sym.qself,
&sym.path,
ParamMode::Optional,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
hir::InlineAsmOperand::SymStatic { path, def_id }

View file

@ -85,7 +85,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let ty = l
.ty
.as_ref()
.map(|t| self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
.map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
let init = l.kind.init().map(|init| self.lower_expr(init));
let hir_id = self.lower_node_id(l.id);
let pat = self.lower_pat(&l.pat);

View file

@ -218,7 +218,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&delegation.qself,
&delegation.path,
ParamMode::Optional,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
let block = delegation.body.as_deref();

View file

@ -1,4 +1,6 @@
use rustc_errors::{codes::*, DiagnosticArgFromDisplay};
use rustc_errors::{
codes::*, AddToDiagnostic, Diagnostic, DiagnosticArgFromDisplay, SubdiagnosticMessageOp,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{symbol::Ident, Span, Symbol};
@ -38,14 +40,8 @@ pub struct InvalidAbi {
pub struct InvalidAbiReason(pub &'static str);
impl rustc_errors::AddToDiagnostic for InvalidAbiReason {
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
where
F: Fn(
&mut rustc_errors::Diagnostic,
rustc_errors::SubdiagnosticMessage,
) -> rustc_errors::SubdiagnosticMessage,
{
impl AddToDiagnostic for InvalidAbiReason {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
#[allow(rustc::untranslatable_diagnostic)]
diag.note(self.0);
}

View file

@ -99,7 +99,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
seg,
ParamMode::Optional,
ParenthesizedGenericArgs::Err,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
// Method calls can't have bound modifiers
None,
@ -141,13 +141,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::Cast(expr, ty) => {
let expr = self.lower_expr(expr);
let ty =
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
hir::ExprKind::Cast(expr, ty)
}
ExprKind::Type(expr, ty) => {
let expr = self.lower_expr(expr);
let ty =
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
hir::ExprKind::Type(expr, ty)
}
ExprKind::AddrOf(k, m, ohs) => {
@ -267,7 +267,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::Optional,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
hir::ExprKind::Path(qpath)
@ -295,7 +295,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::OffsetOf(container, fields) => hir::ExprKind::OffsetOf(
self.lower_ty(
container,
&ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf),
ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf),
),
self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))),
),
@ -314,7 +314,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&se.qself,
&se.path,
ParamMode::Optional,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
)),
self.arena
@ -1241,7 +1241,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::Optional,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
// Destructure like a tuple struct.
@ -1261,7 +1261,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::Optional,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
// Destructure like a unit struct.
@ -1286,7 +1286,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&se.qself,
&se.path,
ParamMode::Optional,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
let fields_omitted = match &se.rest {

View file

@ -15,7 +15,7 @@ struct NodeCollector<'a, 'hir> {
bodies: &'a SortedMap<ItemLocalId, &'hir Body<'hir>>,
/// Outputs
nodes: IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>,
nodes: IndexVec<ItemLocalId, ParentedNode<'hir>>,
parenting: LocalDefIdMap<ItemLocalId>,
/// The parent of this node
@ -29,16 +29,19 @@ pub(super) fn index_hir<'hir>(
tcx: TyCtxt<'hir>,
item: hir::OwnerNode<'hir>,
bodies: &SortedMap<ItemLocalId, &'hir Body<'hir>>,
) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, LocalDefIdMap<ItemLocalId>) {
let mut nodes = IndexVec::new();
num_nodes: usize,
) -> (IndexVec<ItemLocalId, ParentedNode<'hir>>, LocalDefIdMap<ItemLocalId>) {
let zero_id = ItemLocalId::new(0);
let err_node = ParentedNode { parent: zero_id, node: Node::Err(item.span()) };
let mut nodes = IndexVec::from_elem_n(err_node, num_nodes);
// This node's parent should never be accessed: the owner's parent is computed by the
// hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
// used.
nodes.push(Some(ParentedNode { parent: ItemLocalId::INVALID, node: item.into() }));
nodes[zero_id] = ParentedNode { parent: ItemLocalId::INVALID, node: item.into() };
let mut collector = NodeCollector {
tcx,
owner: item.def_id(),
parent_node: ItemLocalId::new(0),
parent_node: zero_id,
nodes,
bodies,
parenting: Default::default(),
@ -54,6 +57,14 @@ pub(super) fn index_hir<'hir>(
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
};
for (local_id, node) in collector.nodes.iter_enumerated() {
if let Node::Err(span) = node.node {
let hir_id = HirId { owner: item.def_id(), local_id };
let msg = format!("ID {hir_id} not encountered when visiting item HIR");
tcx.dcx().span_delayed_bug(*span, msg);
}
}
(collector.nodes, collector.parenting)
}
@ -88,7 +99,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
}
}
self.nodes.insert(hir_id.local_id, ParentedNode { parent: self.parent_node, node });
self.nodes[hir_id.local_id] = ParentedNode { parent: self.parent_node, node };
}
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
@ -254,6 +265,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
}
fn visit_path_segment(&mut self, path_segment: &'hir PathSegment<'hir>) {
// FIXME: walk path segment with `path_segment.hir_id` parent.
self.insert(path_segment.ident.span, path_segment.hir_id, Node::PathSegment(path_segment));
intravisit::walk_path_segment(self, path_segment);
}
@ -348,4 +360,23 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
self.visit_nested_foreign_item(id);
}
fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) {
match predicate {
WherePredicate::BoundPredicate(pred) => {
self.insert(pred.span, pred.hir_id, Node::WhereBoundPredicate(pred));
self.with_parent(pred.hir_id, |this| {
intravisit::walk_where_predicate(this, predicate)
})
}
_ => intravisit::walk_where_predicate(self, predicate),
}
}
fn visit_array_length(&mut self, len: &'hir ArrayLen) {
match len {
ArrayLen::Infer(inf) => self.insert(inf.span, inf.hir_id, Node::ArrayLenInfer(inf)),
ArrayLen::Body(..) => intravisit::walk_array_len(self, len),
}
}
}

View file

@ -189,7 +189,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
Const::No,
id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
},
@ -218,7 +218,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let itctx = ImplTraitContext::Universal;
let (generics, decl) =
this.lower_generics(generics, header.constness, id, &itctx, |this| {
this.lower_generics(generics, header.constness, id, itctx, |this| {
this.lower_fn_decl(
decl,
id,
@ -263,7 +263,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&generics,
Const::No,
id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| match ty {
None => {
let guar = this.dcx().span_delayed_bug(
@ -274,7 +274,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
Some(ty) => this.lower_ty(
ty,
&ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
),
},
);
@ -285,7 +285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
Const::No,
id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
this.arena.alloc_from_iter(
enum_definition.variants.iter().map(|x| this.lower_variant(x)),
@ -299,7 +299,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
Const::No,
id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| this.lower_variant_data(hir_id, struct_def),
);
hir::ItemKind::Struct(struct_def, generics)
@ -309,7 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
Const::No,
id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| this.lower_variant_data(hir_id, vdata),
);
hir::ItemKind::Union(vdata, generics)
@ -339,7 +339,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// parent lifetime.
let itctx = ImplTraitContext::Universal;
let (generics, (trait_ref, lowered_ty)) =
self.lower_generics(ast_generics, *constness, id, &itctx, |this| {
self.lower_generics(ast_generics, *constness, id, itctx, |this| {
let modifiers = TraitBoundModifiers {
constness: match *constness {
Const::Yes(span) => BoundConstness::Maybe(span),
@ -354,13 +354,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
this.lower_trait_ref(
modifiers,
trait_ref,
&ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
)
});
let lowered_ty = this.lower_ty(
ty,
&ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf),
ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf),
);
(trait_ref, lowered_ty)
@ -400,11 +400,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
constness,
id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let bounds = this.lower_param_bounds(
bounds,
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
);
let items = this.arena.alloc_from_iter(
items.iter().map(|item| this.lower_trait_item_ref(item)),
@ -420,11 +420,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
Const::No,
id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
this.lower_param_bounds(
bounds,
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
)
},
);
@ -464,7 +464,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
body: Option<&Expr>,
impl_trait_position: ImplTraitPosition,
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(impl_trait_position));
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(impl_trait_position));
(ty, self.lower_const_body(span, body))
}
@ -569,7 +569,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
});
}
let path = if trees.is_empty() && !prefix.segments.is_empty() {
// Condition should match `build_reduced_graph_for_use_tree`.
let path = if trees.is_empty()
&& !(prefix.segments.is_empty()
|| prefix.segments.len() == 1
&& prefix.segments[0].ident.name == kw::PathRoot)
{
// For empty lists we need to lower the prefix so it is checked for things
// like stability later.
let res = self.lower_import_res(id, span);
@ -633,7 +638,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let fdec = &sig.decl;
let itctx = ImplTraitContext::Universal;
let (generics, (fn_dec, fn_args)) =
self.lower_generics(generics, Const::No, i.id, &itctx, |this| {
self.lower_generics(generics, Const::No, i.id, itctx, |this| {
(
// Disallow `impl Trait` in foreign items.
this.lower_fn_decl(
@ -650,8 +655,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
}
ForeignItemKind::Static(t, m, _) => {
let ty = self
.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
let ty =
self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
hir::ForeignItemKind::Static(ty, *m)
}
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
@ -722,11 +727,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
&ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy),
ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy),
);
self.arena.alloc(t)
} else {
self.lower_ty(&f.ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy))
self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy))
};
let hir_id = self.lower_node_id(f.id);
self.lower_attrs(hir_id, &f.attrs);
@ -755,12 +760,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
Const::No,
i.id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let ty = this.lower_ty(
ty,
&ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),
);
let ty = this
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x)));
hir::TraitItemKind::Const(ty, body)
@ -803,18 +806,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
&generics,
Const::No,
i.id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let ty = ty.as_ref().map(|x| {
this.lower_ty(
x,
&ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy),
ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy),
)
});
hir::TraitItemKind::Type(
this.lower_param_bounds(
bounds,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
ty,
)
@ -882,10 +885,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
Const::No,
i.id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| {
let ty = this
.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
let ty =
this.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
let body = this.lower_const_body(i.span, expr.as_deref());
hir::ImplItemKind::Const(ty, body)
@ -916,7 +919,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&generics,
Const::No,
i.id,
&ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
|this| match ty {
None => {
let guar = this.dcx().span_delayed_bug(
@ -929,7 +932,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
Some(ty) => {
let ty = this.lower_ty(
ty,
&ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
);
hir::ImplItemKind::Type(ty)
}
@ -1323,7 +1326,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// synthesize a host effect param for them. We reject `const` on them during AST validation.
let constness = if kind == FnDeclKind::Inherent { sig.header.constness } else { Const::No };
let itctx = ImplTraitContext::Universal;
let (generics, decl) = self.lower_generics(generics, constness, id, &itctx, |this| {
let (generics, decl) = self.lower_generics(generics, constness, id, itctx, |this| {
this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
});
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
@ -1401,7 +1404,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics: &Generics,
constness: Const,
parent_node_id: NodeId,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
f: impl FnOnce(&mut Self) -> T,
) -> (&'hir hir::Generics<'hir>, T) {
debug_assert!(self.impl_trait_defs.is_empty());
@ -1607,7 +1610,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
bounds: &[GenericBound],
colon_span: Option<Span>,
parent_span: Span,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
origin: PredicateOrigin,
) -> Option<hir::WherePredicate<'hir>> {
// Do not create a clause if we do not have anything inside it.
@ -1681,10 +1684,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
bound_generic_params: self
.lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
bounded_ty: self
.lower_ty(bounded_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
.lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
bounds: self.lower_param_bounds(
bounds,
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
span: self.lower_span(*span),
origin: PredicateOrigin::WhereClause,
@ -1695,7 +1698,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
lifetime: self.lower_lifetime(lifetime),
bounds: self.lower_param_bounds(
bounds,
&ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
in_where_clause: true,
})
@ -1703,9 +1706,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => {
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
lhs_ty: self
.lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
.lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
rhs_ty: self
.lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
.lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
span: self.lower_span(*span),
})
}

View file

@ -36,8 +36,6 @@
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(let_chains)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate tracing;
@ -675,7 +673,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} else {
(None, None)
};
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies);
let num_nodes = self.item_local_id_counter.as_usize();
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
@ -1006,7 +1005,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_assoc_ty_constraint(
&mut self,
constraint: &AssocConstraint,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
) -> hir::TypeBinding<'hir> {
debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
// lower generic arguments of identifier in constraint
@ -1085,32 +1084,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::TypeBindingKind::Equality { term }
}
AssocConstraintKind::Bound { bounds } => {
enum DesugarKind<'a> {
enum DesugarKind {
ImplTrait,
Error(&'a ImplTraitPosition),
Error(ImplTraitPosition),
Bound,
}
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
let desugar_kind = match itctx {
// We are in the return position:
//
// fn foo() -> impl Iterator<Item: Debug>
//
// so desugar to
//
// fn foo() -> impl Iterator<Item = impl Debug>
ImplTraitContext::ReturnPositionOpaqueTy { .. }
| ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait,
// We are in the argument position, but within a dyn type:
// in an argument, RPIT, or TAIT, if we are within a dyn type:
//
// fn foo(x: dyn Iterator<Item: Debug>)
//
// so desugar to
// then desugar to:
//
// fn foo(x: dyn Iterator<Item = impl Debug>)
ImplTraitContext::Universal if self.is_in_dyn_type => DesugarKind::ImplTrait,
//
// This is because dyn traits must have all of their associated types specified.
ImplTraitContext::ReturnPositionOpaqueTy { .. }
| ImplTraitContext::TypeAliasesOpaqueTy { .. }
| ImplTraitContext::Universal
if self.is_in_dyn_type =>
{
DesugarKind::ImplTrait
}
ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => {
DesugarKind::Error(position)
@ -1163,7 +1160,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
DesugarKind::Error(position) => {
let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
span: constraint.span,
position: DiagnosticArgFromDisplay(position),
position: DiagnosticArgFromDisplay(&position),
});
let err_ty =
&*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
@ -1210,7 +1207,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_generic_arg(
&mut self,
arg: &ast::GenericArg,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
) -> hir::GenericArg<'hir> {
match arg {
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(lt)),
@ -1289,7 +1286,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
#[instrument(level = "debug", skip(self))]
fn lower_ty(&mut self, t: &Ty, itctx: &ImplTraitContext) -> &'hir hir::Ty<'hir> {
fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
self.arena.alloc(self.lower_ty_direct(t, itctx))
}
@ -1299,7 +1296,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself: &Option<ptr::P<QSelf>>,
path: &Path,
param_mode: ParamMode,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
) -> hir::Ty<'hir> {
// Check whether we should interpret this as a bare trait object.
// This check mirrors the one in late resolution. We only introduce this special case in
@ -1341,7 +1338,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.ty(span, hir::TyKind::Tup(tys))
}
fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'hir> {
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
let kind = match &t.kind {
TyKind::Infer => hir::TyKind::Infer,
TyKind::Err => {
@ -1460,13 +1457,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::ReturnPositionOpaqueTy { origin, fn_kind } => self
.lower_opaque_impl_trait(
span,
*origin,
origin,
*def_node_id,
bounds,
Some(*fn_kind),
Some(fn_kind),
itctx,
),
&ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
.lower_opaque_impl_trait(
span,
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty },
@ -1513,9 +1510,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.create_feature_err(
MisplacedImplTrait {
span: t.span,
position: DiagnosticArgFromDisplay(position),
position: DiagnosticArgFromDisplay(&position),
},
*feature,
feature,
)
.emit();
hir::TyKind::Err(guar)
@ -1523,7 +1520,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::Disallowed(position) => {
let guar = self.dcx().emit_err(MisplacedImplTrait {
span: t.span,
position: DiagnosticArgFromDisplay(position),
position: DiagnosticArgFromDisplay(&position),
});
hir::TyKind::Err(guar)
}
@ -1581,7 +1578,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
opaque_ty_node_id: NodeId,
bounds: &GenericBounds,
fn_kind: Option<FnDeclKind>,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
) -> hir::TyKind<'hir> {
// Make sure we know that some funky desugaring has been going on here.
// This is a first: there is code in other places like for loop
@ -1848,7 +1845,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
}
};
self.lower_ty_direct(&param.ty, &itctx)
self.lower_ty_direct(&param.ty, itctx)
}));
let output = match coro {
@ -1876,7 +1873,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
}
};
hir::FnRetTy::Return(self.lower_ty(ty, &itctx))
hir::FnRetTy::Return(self.lower_ty(ty, itctx))
}
FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
},
@ -1977,7 +1974,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
output: &FnRetTy,
coro: CoroutineKind,
opaque_ty_span: Span,
nested_impl_trait_context: ImplTraitContext,
itctx: ImplTraitContext,
) -> hir::GenericBound<'hir> {
// Compute the `T` in `Future<Output = T>` from the return type.
let output_ty = match output {
@ -1985,7 +1982,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
// `impl Future` opaque type that `async fn` implicitly
// generates.
self.lower_ty(ty, &nested_impl_trait_context)
self.lower_ty(ty, itctx)
}
FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
};
@ -2025,7 +2022,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_param_bound(
&mut self,
tpb: &GenericBound,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
) -> hir::GenericBound<'hir> {
match tpb {
GenericBound::Trait(p, modifiers) => hir::GenericBound::Trait(
@ -2164,7 +2161,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.map(|def| {
self.lower_ty(
def,
&ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
)
});
@ -2174,7 +2171,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
GenericParamKind::Const { ty, kw_span: _, default } => {
let ty = self
.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
// Not only do we deny const param defaults in binders but we also map them to `None`
// since later compiler stages cannot handle them (and shouldn't need to be able to).
@ -2204,7 +2201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
modifiers: ast::TraitBoundModifiers,
p: &TraitRef,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
) -> hir::TraitRef<'hir> {
let path = match self.lower_qpath(
p.ref_id,
@ -2224,7 +2221,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_poly_trait_ref(
&mut self,
p: &PolyTraitRef,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
modifiers: ast::TraitBoundModifiers,
) -> hir::PolyTraitRef<'hir> {
let bound_generic_params =
@ -2233,7 +2230,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
}
fn lower_mt(&mut self, mt: &MutTy, itctx: &ImplTraitContext) -> hir::MutTy<'hir> {
fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
}
@ -2241,7 +2238,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_param_bounds(
&mut self,
bounds: &[GenericBound],
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
) -> hir::GenericBounds<'hir> {
self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
}
@ -2249,7 +2246,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_param_bounds_mut<'s>(
&'s mut self,
bounds: &'s [GenericBound],
itctx: &'s ImplTraitContext,
itctx: ImplTraitContext,
) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
}
@ -2285,7 +2282,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
bounds,
/* colon_span */ None,
span,
&ImplTraitContext::Universal,
ImplTraitContext::Universal,
hir::PredicateOrigin::ImplTrait,
);

View file

@ -38,7 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself,
path,
ParamMode::Optional,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
@ -55,7 +55,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself,
path,
ParamMode::Optional,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);
break hir::PatKind::Path(qpath);
@ -66,7 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself,
path,
ParamMode::Optional,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
);

View file

@ -27,7 +27,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself: &Option<ptr::P<QSelf>>,
p: &Path,
param_mode: ParamMode,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
// modifiers of the impl/bound if this is a trait path
modifiers: Option<ast::TraitBoundModifiers>,
) -> hir::QPath<'hir> {
@ -205,7 +205,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
segment,
param_mode,
ParenthesizedGenericArgs::Err,
&ImplTraitContext::Disallowed(ImplTraitPosition::Path),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
None,
)
@ -220,7 +220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
segment: &PathSegment,
param_mode: ParamMode,
parenthesized_generic_args: ParenthesizedGenericArgs,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
constness: Option<ast::BoundConstness>,
// Additional features ungated with a bound modifier like `async`.
// This is passed down to the implicit associated type binding in
@ -374,7 +374,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
data: &AngleBracketedArgs,
param_mode: ParamMode,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
) -> (GenericArgsCtor<'hir>, bool) {
let has_non_lt_args = data.args.iter().any(|arg| match arg {
AngleBracketedArg::Arg(ast::GenericArg::Lifetime(_))
@ -405,7 +405,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_parenthesized_parameter_data(
&mut self,
data: &ParenthesizedArgs,
itctx: &ImplTraitContext,
itctx: ImplTraitContext,
bound_modifier_allowed_features: Option<Lrc<[Symbol]>>,
) -> (GenericArgsCtor<'hir>, bool) {
// Switch to `PassThrough` mode for anonymous lifetimes; this
@ -415,7 +415,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// we generally don't permit such things (see #51008).
let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|ty| {
self.lower_ty_direct(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
self.lower_ty_direct(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
}));
let output_ty = match output {
// Only allow `impl Trait` in return position. i.e.:
@ -429,7 +429,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} else {
self.lower_ty(
ty,
&ImplTraitContext::FeatureGated(
ImplTraitContext::FeatureGated(
ImplTraitPosition::FnTraitReturn,
sym::impl_trait_in_fn_trait_return,
),
@ -437,7 +437,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
FnRetTy::Ty(ty) => {
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
}
FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])),
};

View file

@ -1,7 +1,7 @@
//! Errors emitted by ast_passes.
use rustc_ast::ParamKindOrd;
use rustc_errors::{codes::*, AddToDiagnostic, Applicability};
use rustc_errors::{codes::*, AddToDiagnostic, Applicability, Diagnostic, SubdiagnosticMessageOp};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{symbol::Ident, Span, Symbol};
@ -372,13 +372,7 @@ pub struct EmptyLabelManySpans(pub Vec<Span>);
// The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each
impl AddToDiagnostic for EmptyLabelManySpans {
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
where
F: Fn(
&mut rustc_errors::Diagnostic,
rustc_errors::SubdiagnosticMessage,
) -> rustc_errors::SubdiagnosticMessage,
{
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
diag.span_labels(self.0, "");
}
}
@ -735,13 +729,7 @@ pub struct StableFeature {
}
impl AddToDiagnostic for StableFeature {
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
where
F: Fn(
&mut rustc_errors::Diagnostic,
rustc_errors::SubdiagnosticMessage,
) -> rustc_errors::SubdiagnosticMessage,
{
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
diag.arg("name", self.name);
diag.arg("since", self.since);
diag.help(fluent::ast_passes_stable_since);

View file

@ -11,8 +11,6 @@
#![feature(if_let_guard)]
#![feature(iter_is_partitioned)]
#![feature(let_chains)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
pub mod ast_validation;
mod errors;

View file

@ -1,8 +1,6 @@
#![allow(internal_features)]
#![feature(rustdoc_internals)]
#![doc(rust_logo)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![feature(box_patterns)]
mod helpers;

View file

@ -8,8 +8,6 @@
#![feature(rustdoc_internals)]
#![doc(rust_logo)]
#![feature(let_chains)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::path_utils::allow_two_phase_borrow;
use crate::place_ext::PlaceExt;
use crate::BorrowIndex;

View file

@ -1,3 +1,6 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use rustc_errors::{codes::*, struct_span_code_err, DiagCtxt, DiagnosticBuilder};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;

View file

@ -1,6 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::graph::scc::Sccs;
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::mir::ConstraintCategory;

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! This file provides API for compiler consumers.
use rustc_hir::def_id::LocalDefId;

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::graph::WithSuccessors;
use rustc_index::bit_set::BitSet;

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_middle::mir::visit::{
MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext,
};

View file

@ -1,6 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_errors::DiagnosticBuilder;
use rustc_infer::infer::canonical::Canonical;
use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;

View file

@ -1,5 +1,8 @@
// ignore-tidy-filelength
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use either::Either;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexSet;
@ -401,66 +404,60 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
let typeck = self.infcx.tcx.typeck(self.mir_def_id());
let hir_id = hir.parent_id(expr.hir_id);
if let Some(parent) = self.infcx.tcx.opt_hir_node(hir_id) {
let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
&& let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
{
(def_id.as_local(), args, 1)
} else if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::Call(call, args) = parent_expr.kind
&& let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind()
{
(def_id.as_local(), args, 0)
} else {
(None, &[][..], 0)
let parent = self.infcx.tcx.hir_node(hir_id);
let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
&& let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
{
(def_id.as_local(), args, 1)
} else if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::Call(call, args) = parent_expr.kind
&& let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind()
{
(def_id.as_local(), args, 0)
} else {
(None, &[][..], 0)
};
if let Some(def_id) = def_id
&& let node =
self.infcx.tcx.hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id))
&& let Some(fn_sig) = node.fn_sig()
&& let Some(ident) = node.ident()
&& let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
&& let Some(arg) = fn_sig.decl.inputs.get(pos + offset)
{
let mut span: MultiSpan = arg.span.into();
span.push_span_label(
arg.span,
"this parameter takes ownership of the value".to_string(),
);
let descr = match node.fn_kind() {
Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function",
Some(hir::intravisit::FnKind::Method(..)) => "method",
Some(hir::intravisit::FnKind::Closure) => "closure",
};
if let Some(def_id) = def_id
&& let Some(node) = self
.infcx
.tcx
.opt_hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id))
&& let Some(fn_sig) = node.fn_sig()
&& let Some(ident) = node.ident()
&& let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
&& let Some(arg) = fn_sig.decl.inputs.get(pos + offset)
{
let mut span: MultiSpan = arg.span.into();
span.push_span_label(
arg.span,
"this parameter takes ownership of the value".to_string(),
);
let descr = match node.fn_kind() {
Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function",
Some(hir::intravisit::FnKind::Method(..)) => "method",
Some(hir::intravisit::FnKind::Closure) => "closure",
};
span.push_span_label(ident.span, format!("in this {descr}"));
err.span_note(
span,
format!(
"consider changing this parameter type in {descr} `{ident}` to \
span.push_span_label(ident.span, format!("in this {descr}"));
err.span_note(
span,
format!(
"consider changing this parameter type in {descr} `{ident}` to \
borrow instead if owning the value isn't necessary",
),
);
}
let place = &self.move_data.move_paths[mpi].place;
let ty = place.ty(self.body, self.infcx.tcx).ty;
if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
&& let hir::ExprKind::Path(hir::QPath::LangItem(
LangItem::IntoIterIntoIter,
_,
)) = call_expr.kind
{
// Do not suggest `.clone()` in a `for` loop, we already suggest borrowing.
} else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } =
move_spans
{
// We already suggest cloning for these cases in `explain_captures`.
} else {
self.suggest_cloning(err, ty, expr, move_span);
}
),
);
}
let place = &self.move_data.move_paths[mpi].place;
let ty = place.ty(self.body, self.infcx.tcx).ty;
if let hir::Node::Expr(parent_expr) = parent
&& let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
&& let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IntoIterIntoIter, _)) =
call_expr.kind
{
// Do not suggest `.clone()` in a `for` loop, we already suggest borrowing.
} else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = move_spans
{
// We already suggest cloning for these cases in `explain_captures`.
} else {
self.suggest_cloning(err, ty, expr, move_span);
}
}
if let Some(pat) = finder.pat {
@ -1762,7 +1759,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn_decl: hir::FnDecl { inputs, .. },
..
}) = e.kind
&& let Some(hir::Node::Expr(body)) = self.tcx.opt_hir_node(body.hir_id)
&& let hir::Node::Expr(body) = self.tcx.hir_node(body.hir_id)
{
self.suggest_arg = "this: &Self".to_string();
if inputs.len() > 0 {
@ -1828,11 +1825,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
if let Some(hir::Node::ImplItem(hir::ImplItem {
if let hir::Node::ImplItem(hir::ImplItem {
kind: hir::ImplItemKind::Fn(_fn_sig, body_id),
..
})) = self.infcx.tcx.opt_hir_node(self.mir_hir_id())
&& let Some(hir::Node::Expr(expr)) = self.infcx.tcx.opt_hir_node(body_id.hir_id)
}) = self.infcx.tcx.hir_node(self.mir_hir_id())
&& let hir::Node::Expr(expr) = self.infcx.tcx.hir_node(body_id.hir_id)
{
let mut finder = ExpressionFinder {
capture_span: *capture_kind_span,
@ -2400,8 +2397,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let proper_span = proper_span.source_callsite();
if let Some(scope) = self.body.source_scopes.get(source_info.scope)
&& let ClearCrossCrate::Set(scope_data) = &scope.local_data
&& let Some(node) = self.infcx.tcx.opt_hir_node(scope_data.lint_root)
&& let Some(id) = node.body_id()
&& let Some(id) = self.infcx.tcx.hir_node(scope_data.lint_root).body_id()
&& let hir::ExprKind::Block(block, _) = self.infcx.tcx.hir().body(id).value.kind
{
for stmt in block.stmts {

View file

@ -1,5 +1,8 @@
//! Print diagnostics to explain why values are borrowed.
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use rustc_errors::{Applicability, Diagnostic};
use rustc_hir as hir;
use rustc_hir::intravisit::Visitor;
@ -87,7 +90,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind
&& let [hir::PathSegment { ident, args: None, .. }] = p.segments
&& let hir::def::Res::Local(hir_id) = p.res
&& let Some(hir::Node::Pat(pat)) = tcx.opt_hir_node(hir_id)
&& let hir::Node::Pat(pat) = tcx.hir_node(hir_id)
{
err.span_label(pat.span, format!("binding `{ident}` declared here"));
}

View file

@ -1,6 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use std::collections::BTreeSet;
use rustc_middle::mir::visit::{PlaceContext, Visitor};

View file

@ -1,6 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use std::collections::VecDeque;
use std::rc::Rc;

View file

@ -1,3 +1,6 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty};

View file

@ -1,3 +1,6 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use hir::ExprKind;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
use rustc_hir as hir;
@ -396,7 +399,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let upvar_hir_id = captured_place.get_root_variable();
if let Some(Node::Pat(pat)) = self.infcx.tcx.opt_hir_node(upvar_hir_id)
if let Node::Pat(pat) = self.infcx.tcx.hir_node(upvar_hir_id)
&& let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, upvar_ident, _) =
pat.kind
{
@ -688,15 +691,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
break;
}
f_in_trait_opt.and_then(|f_in_trait| {
match self.infcx.tcx.opt_hir_node(f_in_trait) {
Some(Node::TraitItem(hir::TraitItem {
match self.infcx.tcx.hir_node(f_in_trait) {
Node::TraitItem(hir::TraitItem {
kind:
hir::TraitItemKind::Fn(
hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. },
_,
),
..
})) => {
}) => {
let hir::Ty { span, .. } = inputs[local.index() - 1];
Some(span)
}
@ -759,10 +762,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
//
// `let &b = a;` -> `let &(mut b) = a;`
if let Some(hir_id) = hir_id
&& let Some(hir::Node::Local(hir::Local {
&& let hir::Node::Local(hir::Local {
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
..
})) = self.infcx.tcx.opt_hir_node(hir_id)
}) = self.infcx.tcx.hir_node(hir_id)
&& let Ok(name) =
self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span)
{
@ -1206,7 +1209,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};
if let Some(hir_id) = hir_id
&& let Some(hir::Node::Local(local)) = self.infcx.tcx.opt_hir_node(hir_id)
&& let hir::Node::Local(local) = self.infcx.tcx.hir_node(hir_id)
{
let tables = self.infcx.tcx.typeck(def_id.as_local().unwrap());
if let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait()

View file

@ -1,6 +1,9 @@
//! Contains utilities for generating suggestions for borrowck errors related to unsatisfied
//! outlives constraints.
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::Diagnostic;
use rustc_middle::ty::RegionVid;

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! Error reporting machinery for lifetime errors.
use rustc_data_structures::fx::FxIndexSet;
@ -216,7 +214,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let Some(id) = placeholder.bound.kind.get_id()
&& let Some(placeholder_id) = id.as_local()
&& let gat_hir_id = self.infcx.tcx.local_def_id_to_hir_id(placeholder_id)
&& let Some(generics_impl) = hir.get_parent(gat_hir_id).generics()
&& let Some(generics_impl) =
hir.get_parent(hir.parent_id(gat_hir_id)).generics()
{
Some((gat_hir_id, generics_impl))
} else {

View file

@ -1,6 +1,10 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use std::fmt::{self, Display};
use std::iter;
use rustc_data_structures::fx::IndexEntry;
use rustc_errors::Diagnostic;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
@ -14,7 +18,7 @@ use crate::{universal_regions::DefiningTy, MirBorrowckCtxt};
/// A name for a particular region used in emitting diagnostics. This name could be a generated
/// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct RegionName {
/// The name of the region (interned).
pub(crate) name: Symbol,
@ -25,7 +29,7 @@ pub(crate) struct RegionName {
/// Denotes the source of a region that is named by a `RegionName`. For example, a free region that
/// was named by the user would get `NamedLateParamRegion` and `'static` lifetime would get `Static`.
/// This helps to print the right kinds of diagnostics.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy)]
pub(crate) enum RegionNameSource {
/// A bound (not free) region that was instantiated at the def site (not an HRTB).
NamedEarlyParamRegion(Span),
@ -42,7 +46,7 @@ pub(crate) enum RegionNameSource {
/// The region corresponding to the return type of a closure.
AnonRegionFromOutput(RegionNameHighlight, &'static str),
/// The region from a type yielded by a coroutine.
AnonRegionFromYieldTy(Span, String),
AnonRegionFromYieldTy(Span, Symbol),
/// An anonymous region from an async fn.
AnonRegionFromAsyncFn(Span),
/// An anonymous region from an impl self type or trait
@ -51,7 +55,7 @@ pub(crate) enum RegionNameSource {
/// Describes what to highlight to explain to the user that we're giving an anonymous region a
/// synthesized name, and how to highlight it.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy)]
pub(crate) enum RegionNameHighlight {
/// The anonymous region corresponds to a reference that was found by traversing the type in the HIR.
MatchedHirTy(Span),
@ -59,11 +63,11 @@ pub(crate) enum RegionNameHighlight {
MatchedAdtAndSegment(Span),
/// The anonymous region corresponds to a region where the type annotation is completely missing
/// from the code, e.g. in a closure arguments `|x| { ... }`, where `x` is a reference.
CannotMatchHirTy(Span, String),
CannotMatchHirTy(Span, Symbol),
/// The anonymous region corresponds to a region where the type annotation is completely missing
/// from the code, and *even if* we print out the full name of the type, the region name won't
/// be included. This currently occurs for opaque types like `impl Future`.
Occluded(Span, String),
Occluded(Span, Symbol),
}
impl RegionName {
@ -247,25 +251,28 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
assert!(self.regioncx.universal_regions().is_universal_region(fr));
if let Some(value) = self.region_names.try_borrow_mut().unwrap().get(&fr) {
return Some(value.clone());
match self.region_names.borrow_mut().entry(fr) {
IndexEntry::Occupied(precomputed_name) => Some(*precomputed_name.get()),
IndexEntry::Vacant(slot) => {
let new_name = self
.give_name_from_error_region(fr)
.or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr))
.or_else(|| {
self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(fr)
});
if let Some(new_name) = new_name {
slot.insert(new_name);
}
debug!("give_region_a_name: gave name {:?}", new_name);
new_name
}
}
let value = self
.give_name_from_error_region(fr)
.or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr))
.or_else(|| self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(fr));
if let Some(value) = &value {
self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
}
debug!("give_region_a_name: gave name {:?}", value);
value
}
/// Checks for the case where `fr` maps to something that the
@ -457,9 +464,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
);
if type_name.contains(&format!("'{counter}")) {
// Only add a label if we can confirm that a region was labelled.
RegionNameHighlight::CannotMatchHirTy(span, type_name)
RegionNameHighlight::CannotMatchHirTy(span, Symbol::intern(&type_name))
} else {
RegionNameHighlight::Occluded(span, type_name)
RegionNameHighlight::Occluded(span, Symbol::intern(&type_name))
}
}
@ -888,7 +895,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
Some(RegionName {
name: self.synthesize_region_name(),
source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name),
source: RegionNameSource::AnonRegionFromYieldTy(yield_span, Symbol::intern(&type_name)),
})
}
@ -980,7 +987,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
Some(RegionName {
name: region_name,
source: RegionNameSource::AnonRegionFromArgument(
RegionNameHighlight::CannotMatchHirTy(arg_span, arg_name?.to_string()),
RegionNameHighlight::CannotMatchHirTy(arg_span, arg_name?),
),
})
} else {

View file

@ -1,6 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::region_infer::RegionInferenceContext;
use rustc_index::IndexSlice;
use rustc_middle::mir::{Body, Local};

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::location::{LocationIndex, LocationTable};
use crate::BorrowIndex;
use polonius_engine::AllFacts as PoloniusFacts;

View file

@ -111,14 +111,16 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
let (input_body, promoted) = tcx.mir_promoted(def);
debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
if input_body.borrow().should_skip() {
debug!("Skipping borrowck because of injected body");
let input_body: &Body<'_> = &input_body.borrow();
if input_body.should_skip() || input_body.tainted_by_errors.is_some() {
debug!("Skipping borrowck because of injected body or tainted body");
// Let's make up a borrowck result! Fun times!
let result = BorrowCheckResult {
concrete_opaque_types: FxIndexMap::default(),
closure_requirements: None,
used_mut_upvars: SmallVec::new(),
tainted_by_errors: None,
tainted_by_errors: input_body.tainted_by_errors,
};
return tcx.arena.alloc(result);
}
@ -127,7 +129,6 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
let infcx =
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexSlice<_, _> = &promoted.borrow();
let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, None).0;
debug!("mir_borrowck done");

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_index::IndexVec;
use rustc_middle::mir::{BasicBlock, Body, Location};

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexMap;
use rustc_index::{IndexSlice, IndexVec};

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! The entry point of the NLL borrow checker.
use polonius_engine::{Algorithm, Output};
@ -184,7 +182,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
// Solve the region constraints.
let (closure_region_requirements, nll_errors) =
regioncx.solve(infcx, param_env, body, polonius_output.clone());
regioncx.solve(infcx, body, polonius_output.clone());
if !nll_errors.is_empty() {
// Suppress unhelpful extra errors in `infer_opaque_types`.

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
use crate::places_conflict;
use crate::AccessDepth;

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::borrow_set::LocalsStateAtExit;
use rustc_hir as hir;
use rustc_middle::mir::ProjectionElem;

View file

@ -50,8 +50,6 @@
//! and either equal or disjoint.
//! - If we did run out of access, the borrow can access a part of it.
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::ArtificialField;
use crate::Overlap;
use crate::{AccessDepth, Deep, Shallow};

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::graph::dominators::Dominators;
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue};

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{
Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind,

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an
//! place are formed by stripping away fields and derefs, except that
//! we stop when we reach the deref of a shared reference. [...] "

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! As part of generating the regions, if you enable `-Zdump-mir=nll`,
//! we will generate an annotated copy of the MIR that includes the
//! state of region inference. This code handles emitting the region

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! This module provides linkage between RegionInferenceContext and
//! `rustc_graphviz` traits, specialized to attaching borrowck analysis
//! data to rendered labels.

View file

@ -658,7 +658,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
pub(super) fn solve(
&mut self,
infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
body: &Body<'tcx>,
polonius_output: Option<Rc<PoloniusOutput>>,
) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>) {
@ -674,7 +673,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// eagerly.
let mut outlives_requirements = infcx.tcx.is_typeck_child(mir_def_id).then(Vec::new);
self.check_type_tests(infcx, body, outlives_requirements.as_mut(), &mut errors_buffer);
self.check_type_tests(infcx, outlives_requirements.as_mut(), &mut errors_buffer);
debug!(?errors_buffer);
debug!(?outlives_requirements);
@ -932,7 +931,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
fn check_type_tests(
&self,
infcx: &InferCtxt<'tcx>,
body: &Body<'tcx>,
mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
errors_buffer: &mut RegionErrors<'tcx>,
) {
@ -957,12 +955,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
if let Some(propagated_outlives_requirements) = &mut propagated_outlives_requirements {
if self.try_promote_type_test(
infcx,
body,
type_test,
propagated_outlives_requirements,
) {
if self.try_promote_type_test(infcx, type_test, propagated_outlives_requirements) {
continue;
}
}
@ -1016,7 +1009,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
fn try_promote_type_test(
&self,
infcx: &InferCtxt<'tcx>,
body: &Body<'tcx>,
type_test: &TypeTest<'tcx>,
propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>,
) -> bool {
@ -1179,35 +1171,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
Some(ClosureOutlivesSubject::Ty(ClosureOutlivesSubjectTy::bind(tcx, ty)))
}
/// Returns a universally quantified region that outlives the
/// value of `r` (`r` may be existentially or universally
/// quantified).
///
/// Since `r` is (potentially) an existential region, it has some
/// value which may include (a) any number of points in the CFG
/// and (b) any number of `end('x)` elements of universally
/// quantified regions. To convert this into a single universal
/// region we do as follows:
///
/// - Ignore the CFG points in `'r`. All universally quantified regions
/// include the CFG anyhow.
/// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding
/// a result `'y`.
#[instrument(skip(self), level = "debug", ret)]
pub(crate) fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
debug!(r = %self.region_value_str(r));
// Find the smallest universal region that contains all other
// universal regions within `region`.
let mut lub = self.universal_regions.fr_fn_body;
let r_scc = self.constraint_sccs.scc(r);
for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
}
lub
}
/// Like `universal_upper_bound`, but returns an approximation more suitable
/// for diagnostics. If `r` contains multiple disjoint universal regions
/// (e.g. 'a and 'b in `fn foo<'a, 'b> { ... }`, we pick the lower-numbered region.

View file

@ -418,6 +418,8 @@ fn check_opaque_type_parameter_valid(
.into_iter()
.map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
.collect();
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
return Err(tcx
.dcx()
.struct_span_err(span, "non-defining opaque type use in defining scope")

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::constraints::ConstraintSccIndex;
use crate::RegionInferenceContext;
use itertools::Itertools;

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::fx::FxIndexSet;
use rustc_index::bit_set::SparseBitMatrix;

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use crate::BorrowckInferCtxt;
use rustc_index::IndexSlice;
use rustc_infer::infer::NllRegionVariableOrigin;

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
//! This pass type-checks the MIR to ensure it is not broken.
use std::rc::Rc;
@ -213,7 +211,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
CustomTypeOp::new(
|ocx| {
ocx.infcx.register_member_constraints(
param_env,
opaque_type_key,
decl.hidden_type.ty,
decl.hidden_type.span,
@ -1984,6 +1981,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
ConstraintCategory::SizedBound,
);
}
&Rvalue::NullaryOp(NullOp::DebugAssertions, _) => {}
Rvalue::ShallowInitBox(operand, ty) => {
self.check_operand(operand, location);

View file

@ -12,6 +12,9 @@
//! The code in this file doesn't *do anything* with those results; it
//! just returns them for other code to use.
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Diagnostic;
use rustc_hir::def_id::{DefId, LocalDefId};

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use rustc_data_structures::fx::FxIndexSet;
use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::{

View file

@ -1,6 +1,6 @@
use rustc_errors::{
codes::*, AddToDiagnostic, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
Level, MultiSpan, SingleLabelManySpans,
codes::*, AddToDiagnostic, DiagCtxt, Diagnostic, DiagnosticBuilder, EmissionGuarantee,
IntoDiagnostic, Level, MultiSpan, SingleLabelManySpans, SubdiagnosticMessageOp,
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{symbol::Ident, Span, Symbol};
@ -611,13 +611,7 @@ pub(crate) struct FormatUnusedArg {
// Allow the singular form to be a subdiagnostic of the multiple-unused
// form of diagnostic.
impl AddToDiagnostic for FormatUnusedArg {
fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, f: F)
where
F: Fn(
&mut rustc_errors::Diagnostic,
rustc_errors::SubdiagnosticMessage,
) -> rustc_errors::SubdiagnosticMessage,
{
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) {
diag.arg("named", self.named);
let msg = f(diag, crate::fluent_generated::builtin_macros_format_unused_arg.into());
diag.span_label(self.span, msg);

View file

@ -2,6 +2,8 @@
//! injecting code into the crate before it is lowered to HIR.
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![feature(rustdoc_internals)]
#![doc(rust_logo)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]

View file

@ -767,6 +767,15 @@ fn codegen_stmt<'tcx>(
NullOp::OffsetOf(fields) => {
layout.offset_of_subfield(fx, fields.iter()).bytes()
}
NullOp::DebugAssertions => {
let val = fx.tcx.sess.opts.debug_assertions;
let val = CValue::by_val(
fx.bcx.ins().iconst(types::I8, i64::try_from(val).unwrap()),
fx.layout_of(fx.tcx.types.bool),
);
lval.write_cvalue(fx, val);
return;
}
};
let val = CValue::by_val(
fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(val).unwrap()),

View file

@ -3,6 +3,8 @@
#![cfg_attr(doc, doc(rust_logo))]
#![feature(rustc_private)]
// Note: please avoid adding other feature gates where possible
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
#![warn(unreachable_pub)]

View file

@ -27,8 +27,6 @@
#![recursion_limit="256"]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
extern crate rustc_apfloat;
extern crate rustc_ast;

View file

@ -461,6 +461,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
}
ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
ty::CoroutineClosure(..) => build_closure_env_di_node(cx, unique_type_id),
ty::Coroutine(..) => enums::build_coroutine_di_node(cx, unique_type_id),
ty::Adt(def, ..) => match def.adt_kind() {
AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id),
@ -1068,6 +1069,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
let (&def_id, up_var_tys) = match closure_or_coroutine_ty.kind() {
ty::Coroutine(def_id, args) => (def_id, args.as_coroutine().prefix_tys()),
ty::Closure(def_id, args) => (def_id, args.as_closure().upvar_tys()),
ty::CoroutineClosure(def_id, args) => (def_id, args.as_coroutine_closure().upvar_tys()),
_ => {
bug!(
"build_upvar_field_di_nodes() called with non-closure-or-coroutine-type: {:?}",
@ -1153,7 +1155,8 @@ fn build_closure_env_di_node<'ll, 'tcx>(
unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> {
let closure_env_type = unique_type_id.expect_ty();
let &ty::Closure(def_id, _args) = closure_env_type.kind() else {
let &(ty::Closure(def_id, _) | ty::CoroutineClosure(def_id, _)) = closure_env_type.kind()
else {
bug!("build_closure_env_di_node() called with non-closure-type: {:?}", closure_env_type)
};
let containing_scope = get_namespace_for_item(cx, def_id);

View file

@ -1985,10 +1985,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
match in_elem.kind() {
ty::RawPtr(p) => {
let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
let metadata = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
});
assert!(!check_sized); // we are in codegen, so we shouldn't see these types
require!(
metadata.is_unit(),
InvalidMonomorphization::CastFatPointer { span, name, ty: in_elem }
@ -2000,10 +1999,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
}
match out_elem.kind() {
ty::RawPtr(p) => {
let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
let metadata = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
});
assert!(!check_sized); // we are in codegen, so we shouldn't see these types
require!(
metadata.is_unit(),
InvalidMonomorphization::CastFatPointer { span, name, ty: out_elem }

View file

@ -15,8 +15,6 @@
#![feature(let_chains)]
#![feature(min_specialization)]
#![feature(impl_trait_in_assoc_type)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate rustc_macros;

View file

@ -9,7 +9,7 @@ ar_archive_writer = "0.1.5"
bitflags = "2.4.1"
cc = "1.0.69"
itertools = "0.11"
jobserver = "0.1.27"
jobserver = "0.1.28"
pathdiff = "0.2.0"
regex = "1.4"
rustc_arena = { path = "../rustc_arena" }

View file

@ -2,6 +2,8 @@
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![feature(associated_type_bounds)]
#![feature(box_patterns)]
#![feature(if_let_guard)]

View file

@ -672,17 +672,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let val = match null_op {
mir::NullOp::SizeOf => {
assert!(bx.cx().type_is_sized(ty));
layout.size.bytes()
let val = layout.size.bytes();
bx.cx().const_usize(val)
}
mir::NullOp::AlignOf => {
assert!(bx.cx().type_is_sized(ty));
layout.align.abi.bytes()
let val = layout.align.abi.bytes();
bx.cx().const_usize(val)
}
mir::NullOp::OffsetOf(fields) => {
layout.offset_of_subfield(bx.cx(), fields.iter()).bytes()
let val = layout.offset_of_subfield(bx.cx(), fields.iter()).bytes();
bx.cx().const_usize(val)
}
mir::NullOp::DebugAssertions => {
let val = bx.tcx().sess.opts.debug_assertions;
bx.cx().const_bool(val)
}
};
let val = bx.cx().const_usize(val);
let tcx = self.cx.tcx();
OperandRef {
val: OperandValue::Immediate(val),

View file

@ -1,5 +1,6 @@
use rustc_middle::mir;
use rustc_middle::mir::NonDivergingIntrinsic;
use rustc_session::config::OptLevel;
use super::FunctionCx;
use super::LocalRef;
@ -67,8 +68,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.codegen_coverage(bx, coverage, statement.source_info.scope);
}
mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
let op_val = self.codegen_operand(bx, op);
bx.assume(op_val.immediate());
if !matches!(bx.tcx().sess.opts.optimize, OptLevel::No | OptLevel::Less) {
let op_val = self.codegen_operand(bx, op);
bx.assume(op_val.immediate());
}
}
mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
mir::CopyNonOverlapping { ref count, ref src, ref dst },

View file

@ -246,13 +246,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
);
}
let val = match null_op {
mir::NullOp::SizeOf => layout.size.bytes(),
mir::NullOp::AlignOf => layout.align.abi.bytes(),
mir::NullOp::SizeOf => {
let val = layout.size.bytes();
Scalar::from_target_usize(val, self)
}
mir::NullOp::AlignOf => {
let val = layout.align.abi.bytes();
Scalar::from_target_usize(val, self)
}
mir::NullOp::OffsetOf(fields) => {
layout.offset_of_subfield(self, fields.iter()).bytes()
let val = layout.offset_of_subfield(self, fields.iter()).bytes();
Scalar::from_target_usize(val, self)
}
mir::NullOp::DebugAssertions => {
// The checks hidden behind this are always better done by the interpreter
// itself, because it knows the runtime state better.
Scalar::from_bool(false)
}
};
self.write_scalar(Scalar::from_target_usize(val, self), &dest)?;
self.write_scalar(val, &dest)?;
}
ShallowInitBox(ref operand, _) => {

View file

@ -377,12 +377,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// to fields, which can yield non-normalized types. So we need to provide a
// normalization function.
let normalize = |ty| self.tcx.normalize_erasing_regions(self.param_env, ty);
let (meta, only_if_sized) = ty.ptr_metadata_ty(*self.tcx, normalize);
assert!(
!only_if_sized,
"there should be no more 'maybe has that metadata' types during interpretation"
);
meta
ty.ptr_metadata_ty(*self.tcx, normalize)
};
return Ok(meta_ty(caller) == meta_ty(callee));
}

View file

@ -5,9 +5,9 @@ Rust MIR: a lowered representation of Rust.
*/
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![feature(rustdoc_internals)]
#![doc(rust_logo)]
#![deny(rustc::untranslatable_diagnostic)]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(decl_macro)]

View file

@ -544,7 +544,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
Rvalue::Cast(_, _, _) => {}
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) => {}
Rvalue::NullaryOp(
NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::DebugAssertions,
_,
) => {}
Rvalue::ShallowInitBox(_, _) => {}
Rvalue::UnaryOp(_, operand) => {

View file

@ -60,6 +60,8 @@ impl<'tcx> MirPass<'tcx> for Validator {
ty::Closure(..) => Abi::RustCall,
ty::CoroutineClosure(..) => Abi::RustCall,
ty::Coroutine(..) => Abi::Rust,
// No need to do MIR validation on error bodies
ty::Error(_) => return,
_ => {
span_bug!(body.span, "unexpected body ty: {:?} phase {:?}", body_ty, mir_phase)
}
@ -1139,7 +1141,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
Rvalue::Repeat(_, _)
| Rvalue::ThreadLocalRef(_)
| Rvalue::AddressOf(_, _)
| Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _)
| Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::DebugAssertions, _)
| Rvalue::Discriminant(_) => {}
}
self.super_rvalue(rvalue, location);

View file

@ -11,7 +11,7 @@ either = "1.0"
elsa = "=1.7.1"
ena = "0.14.2"
indexmap = { version = "2.0.0" }
jobserver_crate = { version = "0.1.27", package = "jobserver" }
jobserver_crate = { version = "0.1.28", package = "jobserver" }
libc = "0.2"
measureme = "11"
rustc-hash = "1.1.0"

View file

@ -23,7 +23,10 @@ static GLOBAL_CLIENT: LazyLock<Result<Client, String>> = LazyLock::new(|| {
if matches!(
error.kind(),
FromEnvErrorKind::NoEnvVar | FromEnvErrorKind::NoJobserver | FromEnvErrorKind::Unsupported
FromEnvErrorKind::NoEnvVar
| FromEnvErrorKind::NoJobserver
| FromEnvErrorKind::NegativeFd
| FromEnvErrorKind::Unsupported
) {
return Ok(default_client());
}

View file

@ -11,8 +11,6 @@
#![allow(rustc::default_hash_types)]
#![allow(rustc::potential_query_instability)]
#![cfg_attr(not(parallel_compiler), feature(cell_leak))]
#![deny(rustc::diagnostic_outside_of_impl)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(unsafe_op_in_unsafe_fn)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]

View file

@ -12,8 +12,6 @@
#![feature(let_chains)]
#![feature(panic_update_hook)]
#![feature(result_flattening)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#[macro_use]
extern crate tracing;

View file

@ -5,8 +5,6 @@
#![feature(rustdoc_internals)]
#![doc(rust_logo)]
#![deny(rustdoc::invalid_codeblock_attributes)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
// This higher-order macro defines the error codes that are in use. It is used
// in the `rustc_errors` crate. Removed error codes are listed in the comment

View file

@ -3,8 +3,6 @@
#![feature(lazy_cell)]
#![feature(rustc_attrs)]
#![feature(type_alias_impl_trait)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![allow(internal_features)]
#[macro_use]

View file

@ -77,11 +77,12 @@ where
/// Add a subdiagnostic to an existing diagnostic where `f` is invoked on every message used
/// (to optionally perform eager translation).
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
where
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage;
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F);
}
pub trait SubdiagnosticMessageOp =
Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage;
/// Trait implemented by lint types. This should not be implemented manually. Instead, use
/// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic].
#[rustc_diagnostic_item = "DecorateLint"]

View file

@ -2,7 +2,7 @@ use crate::diagnostic::DiagnosticLocation;
use crate::{fluent_generated as fluent, AddToDiagnostic};
use crate::{
DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, ErrCode, IntoDiagnostic,
IntoDiagnosticArg, Level,
IntoDiagnosticArg, Level, SubdiagnosticMessageOp,
};
use rustc_ast as ast;
use rustc_ast_pretty::pprust;
@ -299,7 +299,7 @@ pub struct SingleLabelManySpans {
pub label: &'static str,
}
impl AddToDiagnostic for SingleLabelManySpans {
fn add_to_diagnostic_with<F>(self, diag: &mut crate::Diagnostic, _: F) {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut crate::Diagnostic, _: F) {
diag.span_labels(self.spans, self.label);
}
}

View file

@ -5,6 +5,8 @@
// tidy-alphabetical-start
#![allow(incomplete_features)]
#![allow(internal_features)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![doc(rust_logo)]
#![feature(array_windows)]
@ -19,6 +21,7 @@
#![feature(never_type)]
#![feature(rustc_attrs)]
#![feature(rustdoc_internals)]
#![feature(trait_alias)]
#![feature(try_blocks)]
#![feature(yeet_expr)]
// tidy-alphabetical-end
@ -35,6 +38,7 @@ pub use codes::*;
pub use diagnostic::{
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgName,
DiagnosticArgValue, DiagnosticStyledString, IntoDiagnosticArg, StringPart, SubDiagnostic,
SubdiagnosticMessageOp,
};
pub use diagnostic_builder::{
BugAbort, DiagnosticBuilder, EmissionGuarantee, FatalAbort, IntoDiagnostic,
@ -429,6 +433,10 @@ struct DiagCtxtInner {
/// The number of non-lint errors that have been emitted, including duplicates.
err_count: usize,
/// The number of stashed errors. Unlike the other counts, this can go up
/// and down, so it doesn't guarantee anything.
stashed_err_count: usize,
/// The error count shown to the user at the end.
deduplicated_err_count: usize,
/// The warning count shown to the user at the end.
@ -598,6 +606,7 @@ impl DiagCtxt {
flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
lint_err_count: 0,
err_count: 0,
stashed_err_count: 0,
deduplicated_err_count: 0,
deduplicated_warn_count: 0,
has_printed: false,
@ -654,6 +663,7 @@ impl DiagCtxt {
let mut inner = self.inner.borrow_mut();
inner.lint_err_count = 0;
inner.err_count = 0;
inner.stashed_err_count = 0;
inner.deduplicated_err_count = 0;
inner.deduplicated_warn_count = 0;
inner.has_printed = false;
@ -675,10 +685,8 @@ impl DiagCtxt {
let key = (span.with_parent(None), key);
if diag.is_error() {
if diag.is_lint.is_some() {
inner.lint_err_count += 1;
} else {
inner.err_count += 1;
if diag.is_lint.is_none() {
inner.stashed_err_count += 1;
}
}
@ -694,10 +702,8 @@ impl DiagCtxt {
let key = (span.with_parent(None), key);
let diag = inner.stashed_diagnostics.remove(&key)?;
if diag.is_error() {
if diag.is_lint.is_some() {
inner.lint_err_count -= 1;
} else {
inner.err_count -= 1;
if diag.is_lint.is_none() {
inner.stashed_err_count -= 1;
}
}
Some(DiagnosticBuilder::new_diagnostic(self, diag))
@ -845,6 +851,7 @@ impl DiagCtxt {
self.struct_span_warn(span, msg).emit()
}
#[track_caller]
pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
self.struct_span_bug(span, msg).emit()
}
@ -922,13 +929,22 @@ impl DiagCtxt {
self.struct_bug(msg).emit()
}
/// This excludes lint errors and delayed bugs.
/// This excludes lint errors, delayed bugs, and stashed errors.
#[inline]
pub fn err_count(&self) -> usize {
self.inner.borrow().err_count
}
/// This excludes lint errors and delayed bugs.
/// This excludes normal errors, lint errors and delayed bugs. Unless
/// absolutely necessary, avoid using this. It's dubious because stashed
/// errors can later be cancelled, so the presence of a stashed error at
/// some point of time doesn't guarantee anything -- there are no
/// `ErrorGuaranteed`s here.
pub fn stashed_err_count(&self) -> usize {
self.inner.borrow().stashed_err_count
}
/// This excludes lint errors, delayed bugs, and stashed errors.
pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
self.inner.borrow().has_errors().then(|| {
// FIXME(nnethercote) find a way to store an `ErrorGuaranteed`.
@ -937,8 +953,8 @@ impl DiagCtxt {
})
}
/// This excludes delayed bugs. Unless absolutely necessary, prefer
/// `has_errors` to this method.
/// This excludes delayed bugs and stashed errors. Unless absolutely
/// necessary, prefer `has_errors` to this method.
pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> {
let inner = self.inner.borrow();
let result = inner.has_errors() || inner.lint_err_count > 0;
@ -949,8 +965,8 @@ impl DiagCtxt {
})
}
/// Unless absolutely necessary, prefer `has_errors` or
/// `has_errors_or_lint_errors` to this method.
/// This excludes stashed errors. Unless absolutely necessary, prefer
/// `has_errors` or `has_errors_or_lint_errors` to this method.
pub fn has_errors_or_lint_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
let inner = self.inner.borrow();
let result =
@ -1224,10 +1240,8 @@ impl DiagCtxtInner {
for (_, diag) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
// Decrement the count tracking the stash; emitting will increment it.
if diag.is_error() {
if diag.is_lint.is_some() {
self.lint_err_count -= 1;
} else {
self.err_count -= 1;
if diag.is_lint.is_none() {
self.stashed_err_count -= 1;
}
} else {
// Unless they're forced, don't flush stashed warnings when

View file

@ -1,5 +1,3 @@
#![deny(rustc::untranslatable_diagnostic)]
use crate::base::ast::NestedMetaItem;
use crate::errors;
use crate::expand::{self, AstFragment, Invocation};

View file

@ -10,7 +10,7 @@
#![feature(proc_macro_internals)]
#![feature(proc_macro_span)]
#![feature(try_blocks)]
#![deny(rustc::untranslatable_diagnostic)]
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(internal_features)]
#[macro_use]

View file

@ -77,7 +77,7 @@ declare_features! (
/// Allows empty structs and enum variants with braces.
(accepted, braced_empty_structs, "1.8.0", Some(29720)),
/// Allows `c"foo"` literals.
(accepted, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723)),
(accepted, c_str_literals, "1.77.0", Some(105723)),
/// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
(accepted, cfg_attr_multi, "1.33.0", Some(54881)),
/// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.

View file

@ -15,8 +15,6 @@
#![feature(rustdoc_internals)]
#![doc(rust_logo)]
#![feature(lazy_cell)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
mod accepted;
mod builtin_attrs;

View file

@ -33,7 +33,7 @@ declare_features! (
// -------------------------------------------------------------------------
/// Allows using the `amdgpu-kernel` ABI.
(removed, abi_amdgpu_kernel, "CURRENT_RUSTC_VERSION", Some(51575), None),
(removed, abi_amdgpu_kernel, "1.77.0", Some(51575), None),
(removed, advanced_slice_patterns, "1.0.0", Some(62254),
Some("merged into `#![feature(slice_patterns)]`")),
(removed, allocator, "1.0.0", None, None),

View file

@ -356,7 +356,7 @@ declare_features! (
/// Allows `#[track_caller]` on async functions.
(unstable, async_fn_track_caller, "1.73.0", Some(110011)),
/// Allows `for await` loops.
(unstable, async_for_loop, "CURRENT_RUSTC_VERSION", Some(118898)),
(unstable, async_for_loop, "1.77.0", Some(118898)),
/// Allows builtin # foo() syntax
(unstable, builtin_syntax, "1.71.0", Some(110680)),
/// Treat `extern "C"` function as nounwind.
@ -370,7 +370,7 @@ declare_features! (
/// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.
(unstable, cfg_sanitize, "1.41.0", Some(39699)),
/// Allows `cfg(sanitizer_cfi_generalize_pointers)` and `cfg(sanitizer_cfi_normalize_integers)`.
(unstable, cfg_sanitizer_cfi, "CURRENT_RUSTC_VERSION", Some(89653)),
(unstable, cfg_sanitizer_cfi, "1.77.0", Some(89653)),
/// Allows `cfg(target_abi = "...")`.
(unstable, cfg_target_abi, "1.55.0", Some(80970)),
/// Allows `cfg(target(abi = "..."))`.
@ -514,7 +514,7 @@ declare_features! (
(unstable, marker_trait_attr, "1.30.0", Some(29864)),
/// Allows exhaustive pattern matching on types that contain uninhabited types in cases that are
/// unambiguously sound.
(incomplete, min_exhaustive_patterns, "CURRENT_RUSTC_VERSION", Some(119612)),
(incomplete, min_exhaustive_patterns, "1.77.0", Some(119612)),
/// A minimal, sound subset of specialization intended to be used by the
/// standard library until the soundness issues with specialization
/// are fixed.
@ -550,7 +550,7 @@ declare_features! (
/// Allows using enums in offset_of!
(unstable, offset_of_enum, "1.75.0", Some(120141)),
/// Allows using multiple nested field accesses in offset_of!
(unstable, offset_of_nested, "CURRENT_RUSTC_VERSION", Some(120140)),
(unstable, offset_of_nested, "1.77.0", Some(120140)),
/// Allows using `#[optimize(X)]`.
(unstable, optimize_attribute, "1.34.0", Some(54882)),
/// Allows macro attributes on expressions, statements and non-inline modules.

View file

@ -4,8 +4,6 @@
#![feature(rustdoc_internals)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_span)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::default_hash_types)]
use proc_macro::TokenStream;

View file

@ -1,6 +1,4 @@
#![feature(absolute_path)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use std::ffi::CString;
use std::fs;

View file

@ -276,8 +276,6 @@
#![feature(rustdoc_internals)]
#![doc(rust_logo)]
#![allow(internal_features)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
use LabelText::*;

View file

@ -163,10 +163,6 @@ impl Lifetime {
(LifetimeSuggestionPosition::Normal, self.ident.span)
}
}
pub fn is_static(&self) -> bool {
self.res == LifetimeName::Static
}
}
/// A `Path` is essentially Rust's notion of a name; for instance,
@ -835,7 +831,7 @@ pub struct OwnerNodes<'tcx> {
// The zeroth node's parent should never be accessed: the owner's parent is computed by the
// hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
// used.
pub nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
/// Content of local bodies.
pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
}
@ -843,9 +839,8 @@ pub struct OwnerNodes<'tcx> {
impl<'tcx> OwnerNodes<'tcx> {
pub fn node(&self) -> OwnerNode<'tcx> {
use rustc_index::Idx;
let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
node
// Indexing must ensure it is an OwnerNode.
self.nodes[ItemLocalId::new(0)].node.as_owner().unwrap()
}
}
@ -860,9 +855,7 @@ impl fmt::Debug for OwnerNodes<'_> {
.nodes
.iter_enumerated()
.map(|(id, parented_node)| {
let parented_node = parented_node.as_ref().map(|node| node.parent);
debug_fn(move |f| write!(f, "({id:?}, {parented_node:?})"))
debug_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
})
.collect::<Vec<_>>(),
)
@ -3351,13 +3344,15 @@ impl<'hir> OwnerNode<'hir> {
}
}
pub fn span(&self) -> Span {
// Span by reference to pass to `Node::Err`.
#[allow(rustc::pass_by_value)]
pub fn span(&self) -> &'hir Span {
match self {
OwnerNode::Item(Item { span, .. })
| OwnerNode::ForeignItem(ForeignItem { span, .. })
| OwnerNode::ImplItem(ImplItem { span, .. })
| OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
| OwnerNode::TraitItem(TraitItem { span, .. }) => span,
OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => inner_span,
}
}
@ -3486,17 +3481,19 @@ pub enum Node<'hir> {
Arm(&'hir Arm<'hir>),
Block(&'hir Block<'hir>),
Local(&'hir Local<'hir>),
/// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
/// with synthesized constructors.
Ctor(&'hir VariantData<'hir>),
Lifetime(&'hir Lifetime),
GenericParam(&'hir GenericParam<'hir>),
Crate(&'hir Mod<'hir>),
Infer(&'hir InferArg),
WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
// FIXME: Merge into `Node::Infer`.
ArrayLenInfer(&'hir InferArg),
// Span by reference to minimize `Node`'s size
#[allow(rustc::pass_by_value)]
Err(&'hir Span),
}
impl<'hir> Node<'hir> {
@ -3541,7 +3538,10 @@ impl<'hir> Node<'hir> {
| Node::Crate(..)
| Node::Ty(..)
| Node::TraitRef(..)
| Node::Infer(..) => None,
| Node::Infer(..)
| Node::WhereBoundPredicate(..)
| Node::ArrayLenInfer(..)
| Node::Err(..) => None,
}
}

View file

@ -108,8 +108,8 @@ impl<'a> FnKind<'a> {
/// An abstract representation of the HIR `rustc_middle::hir::map::Map`.
pub trait Map<'hir> {
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
fn find(&self, hir_id: HirId) -> Option<Node<'hir>>;
/// Retrieves the `Node` corresponding to `id`.
fn hir_node(&self, hir_id: HirId) -> Node<'hir>;
fn body(&self, id: BodyId) -> &'hir Body<'hir>;
fn item(&self, id: ItemId) -> &'hir Item<'hir>;
fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
@ -119,7 +119,7 @@ pub trait Map<'hir> {
// Used when no map is actually available, forcing manual implementation of nested visitors.
impl<'hir> Map<'hir> for ! {
fn find(&self, _: HirId) -> Option<Node<'hir>> {
fn hir_node(&self, _: HirId) -> Node<'hir> {
*self;
}
fn body(&self, _: BodyId) -> &'hir Body<'hir> {
@ -669,6 +669,7 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'
pub fn walk_array_len<'v, V: Visitor<'v>>(visitor: &mut V, len: &'v ArrayLen) {
match len {
// FIXME: Use `visit_infer` here.
ArrayLen::Infer(InferArg { hir_id, span: _ }) => visitor.visit_id(*hir_id),
ArrayLen::Body(c) => visitor.visit_anon_const(c),
}

View file

@ -9,8 +9,6 @@
#![feature(never_type)]
#![feature(rustc_attrs)]
#![feature(variant_count)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
#![allow(internal_features)]
#[macro_use]

View file

@ -33,10 +33,6 @@ hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the as
hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion = use a fully qualified path with explicit lifetimes
hir_analysis_async_trait_impl_should_be_async =
method `{$method_name}` should be async because the method from the trait is async
.trait_item_label = required because the trait method is async
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
.label = deref recursion limit reached
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
@ -210,6 +206,9 @@ hir_analysis_manual_implementation =
.label = manual implementations of `{$trait_name}` are experimental
.help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
hir_analysis_method_should_return_future = method should be `async` or return a future, but it is synchronous
.note = this method is `async` so it expects a future to be returned
hir_analysis_missing_one_of_trait_item = not all trait items implemented, missing one of: `{$missing_items_msg}`
.label = missing one of `{$missing_items_msg}` in implementation
.note = required because of this annotation

View file

@ -243,9 +243,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
speculative: bool,
dup_bindings: &mut FxHashMap<DefId, Span>,
path_span: Span,
constness: ty::BoundConstness,
only_self_bounds: OnlySelfBounds,
polarity: ty::ImplPolarity,
) -> Result<(), ErrorGuaranteed> {
// Given something like `U: SomeTrait<T = X>`, we want to produce a
// predicate like `<U as SomeTrait>::T = X`. This is somewhat

View file

@ -16,7 +16,7 @@ use rustc_middle::ty::{
self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, TyCtxt,
};
use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS;
use rustc_span::{symbol::kw, Span};
use rustc_span::symbol::kw;
use smallvec::SmallVec;
/// Report an error that a generic argument did not match the generic parameter that was
@ -404,7 +404,6 @@ pub fn create_args_for_parent_generic_args<'tcx: 'a, 'a>(
/// Used specifically for function calls.
pub fn check_generic_arg_count_for_call(
tcx: TyCtxt<'_>,
span: Span,
def_id: DefId,
generics: &ty::Generics,
seg: &hir::PathSegment<'_>,
@ -418,17 +417,7 @@ pub fn check_generic_arg_count_for_call(
};
let has_self = generics.parent.is_none() && generics.has_self;
check_generic_arg_count(
tcx,
span,
def_id,
seg,
generics,
gen_args,
gen_pos,
has_self,
seg.infer_args,
)
check_generic_arg_count(tcx, def_id, seg, generics, gen_args, gen_pos, has_self, seg.infer_args)
}
/// Checks that the correct number of generic arguments have been provided.
@ -436,7 +425,6 @@ pub fn check_generic_arg_count_for_call(
#[instrument(skip(tcx, gen_pos), level = "debug")]
pub(crate) fn check_generic_arg_count(
tcx: TyCtxt<'_>,
span: Span,
def_id: DefId,
seg: &hir::PathSegment<'_>,
gen_params: &ty::Generics,

View file

@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
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(
"use `dyn`",
"if this is an object-safe trait, use `dyn`",
sugg,
Applicability::MachineApplicable,
);

View file

@ -12,7 +12,7 @@ use crate::astconv::errors::prohibit_assoc_ty_binding;
use crate::astconv::generics::{check_generic_arg_count, create_args_for_parent_generic_args};
use crate::bounds::Bounds;
use crate::collect::HirPlaceholderCollector;
use crate::errors::{AmbiguousLifetimeBound, TypeofReservedKeywordUsed};
use crate::errors::AmbiguousLifetimeBound;
use crate::middle::resolve_bound_vars as rbv;
use crate::require_c_abi_if_c_variadic;
use rustc_ast::TraitObjectSyntax;
@ -25,13 +25,13 @@ use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{walk_generics, Visitor as _};
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
use rustc_hir::{GenericArg, GenericArgs};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::middle::stability::AllowUnstable;
use rustc_middle::ty::{
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, IsSuggestable, ParamEnv, Ty,
TyCtxt, TypeVisitableExt,
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
TypeVisitableExt,
};
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
use rustc_span::edit_distance::find_best_match_for_name;
@ -379,7 +379,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let mut arg_count = check_generic_arg_count(
tcx,
span,
def_id,
seg,
generics,
@ -773,9 +772,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
speculative,
&mut dup_bindings,
binding.span,
constness,
only_self_bounds,
polarity,
);
// Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
}
@ -2493,7 +2490,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let opaque_ty = tcx.hir().item(item_id);
match opaque_ty.kind {
hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => {
hir::ItemKind::OpaqueTy(&hir::OpaqueTy { .. }) => {
let local_def_id = item_id.owner_id.def_id;
// If this is an RPITIT and we are using the new RPITIT lowering scheme, we
// generate the def_id of an associated type for the trait and return as
@ -2503,7 +2500,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} else {
local_def_id.to_def_id()
};
self.impl_trait_ty_to_ty(def_id, lifetimes, origin, in_trait)
self.impl_trait_ty_to_ty(def_id, lifetimes, in_trait)
}
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
}
@ -2539,21 +2536,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Ty::new_array_with_const_len(tcx, self.ast_ty_to_ty(ty), length)
}
hir::TyKind::Typeof(e) => {
let ty_erased = tcx.type_of(e.def_id).instantiate_identity();
let ty = tcx.fold_regions(ty_erased, |r, _| {
if r.is_erased() { tcx.lifetimes.re_static } else { r }
});
let span = ast_ty.span;
let (ty, opt_sugg) = if let Some(ty) = ty.make_suggestable(tcx, false) {
(ty, Some((span, Applicability::MachineApplicable)))
} else {
(ty, None)
};
tcx.dcx().emit_err(TypeofReservedKeywordUsed { span, ty, opt_sugg });
ty
}
hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
hir::TyKind::Infer => {
// Infer also appears as the type of arguments or return
// values in an ExprKind::Closure, or as
@ -2573,7 +2556,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
&self,
def_id: DefId,
lifetimes: &[hir::GenericArg<'_>],
origin: OpaqueTyOrigin,
in_trait: bool,
) -> Ty<'tcx> {
debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);

View file

@ -1,5 +1,5 @@
use super::potentially_plural_count;
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture};
use hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
@ -10,7 +10,7 @@ use rustc_hir::{GenericParamKind, ImplItemKind};
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::util;
use rustc_infer::traits::{util, FulfillmentError};
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::util::ExplicitSelf;
@ -74,7 +74,6 @@ fn check_method_is_structurally_compatible<'tcx>(
compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?;
compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?;
compare_synthetic_generics(tcx, impl_m, trait_m, delay)?;
compare_asyncness(tcx, impl_m, trait_m, delay)?;
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?;
Ok(())
}
@ -414,36 +413,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
}
}
fn compare_asyncness<'tcx>(
tcx: TyCtxt<'tcx>,
impl_m: ty::AssocItem,
trait_m: ty::AssocItem,
delay: bool,
) -> Result<(), ErrorGuaranteed> {
if tcx.asyncness(trait_m.def_id).is_async() {
match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() {
ty::Alias(ty::Opaque, ..) => {
// allow both `async fn foo()` and `fn foo() -> impl Future`
}
ty::Error(_) => {
// We don't know if it's ok, but at least it's already an error.
}
_ => {
return Err(tcx
.dcx()
.create_err(crate::errors::AsyncTraitImplShouldBeAsync {
span: tcx.def_span(impl_m.def_id),
method_name: trait_m.name,
trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
})
.emit_unless(delay));
}
};
}
Ok(())
}
/// Given a method def-id in an impl, compare the method signature of the impl
/// against the trait that it's implementing. In doing so, infer the hidden types
/// that this method's signature provides to satisfy each return-position `impl Trait`
@ -695,8 +664,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
// RPITs.
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
return Err(reported);
if let Err(guar) = try_report_async_mismatch(tcx, infcx, &errors, trait_m, impl_m, impl_sig)
{
return Err(guar);
}
let guar = infcx.err_ctxt().report_fulfillment_errors(errors);
return Err(guar);
}
// Finally, resolve all regions. This catches wily misuses of
@ -1990,6 +1964,10 @@ pub(super) fn check_type_bounds<'tcx>(
impl_ty: ty::AssocItem,
impl_trait_ref: ty::TraitRef<'tcx>,
) -> Result<(), ErrorGuaranteed> {
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
// other `Foo` impls are incoherent.
tcx.ensure().coherent_trait(impl_trait_ref.def_id)?;
let param_env = tcx.param_env(impl_ty.def_id);
debug!(?param_env);
@ -2248,3 +2226,47 @@ fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str {
ty::AssocKind::Type => "type",
}
}
/// Manually check here that `async fn foo()` wasn't matched against `fn foo()`,
/// and extract a better error if so.
fn try_report_async_mismatch<'tcx>(
tcx: TyCtxt<'tcx>,
infcx: &InferCtxt<'tcx>,
errors: &[FulfillmentError<'tcx>],
trait_m: ty::AssocItem,
impl_m: ty::AssocItem,
impl_sig: ty::FnSig<'tcx>,
) -> Result<(), ErrorGuaranteed> {
if !tcx.asyncness(trait_m.def_id).is_async() {
return Ok(());
}
let ty::Alias(ty::Projection, ty::AliasTy { def_id: async_future_def_id, .. }) =
*tcx.fn_sig(trait_m.def_id).skip_binder().skip_binder().output().kind()
else {
bug!("expected `async fn` to return an RPITIT");
};
for error in errors {
if let traits::BindingObligation(def_id, _) = *error.root_obligation.cause.code()
&& def_id == async_future_def_id
&& let Some(proj) = error.root_obligation.predicate.to_opt_poly_projection_pred()
&& let Some(proj) = proj.no_bound_vars()
&& infcx.can_eq(
error.root_obligation.param_env,
proj.term.ty().unwrap(),
impl_sig.output(),
)
{
// FIXME: We should suggest making the fn `async`, but extracting
// the right span is a bit difficult.
return Err(tcx.sess.dcx().emit_err(MethodShouldReturnFuture {
span: tcx.def_span(impl_m.def_id),
method_name: trait_m.name,
trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
}));
}
}
Ok(())
}

Some files were not shown because too many files have changed in this diff Show more