Merge from rustc
This commit is contained in:
commit
3e97b415c3
951 changed files with 14585 additions and 6933 deletions
15
Cargo.lock
15
Cargo.lock
|
|
@ -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",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(¶m.ty, &itctx)
|
||||
self.lower_ty_direct(¶m.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,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -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, &[])),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use rustc_middle::mir::visit::{
|
||||
MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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. [...] "
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
use crate::constraints::ConstraintSccIndex;
|
||||
use crate::RegionInferenceContext;
|
||||
use itertools::Itertools;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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::{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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/")]
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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" }
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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, _) => {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
|
||||
use crate::base::ast::NestedMetaItem;
|
||||
use crate::errors;
|
||||
use crate::expand::{self, AstFragment, Invocation};
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
#![feature(absolute_path)]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::fs;
|
||||
|
|
|
|||
|
|
@ -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::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue