diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d2d4a7e3d42f..521f8ef0f5ae 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -156,12 +156,6 @@ jobs:
- name: checkout submodules
run: src/ci/scripts/checkout-submodules.sh
-
- - name: Setup Python
- uses: actions/setup-python@v5
- with:
- python-version: '3.x'
- if: runner.environment == 'github-hosted'
- name: install MinGW
run: src/ci/scripts/install-mingw.sh
diff --git a/Cargo.lock b/Cargo.lock
index 0e950e288072..54b1bf593e0a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2652,14 +2652,11 @@ version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
dependencies = [
- "compiler_builtins",
"crc32fast",
"flate2",
"hashbrown",
"indexmap",
"memchr",
- "rustc-std-workspace-alloc",
- "rustc-std-workspace-core",
"ruzstd 0.5.0",
"wasmparser",
]
@@ -2675,6 +2672,18 @@ dependencies = [
"ruzstd 0.6.0",
]
+[[package]]
+name = "object"
+version = "0.36.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434"
+dependencies = [
+ "compiler_builtins",
+ "memchr",
+ "rustc-std-workspace-alloc",
+ "rustc-std-workspace-core",
+]
+
[[package]]
name = "odht"
version = "0.3.1"
@@ -4201,6 +4210,7 @@ dependencies = [
"rustc_middle",
"rustc_span",
"rustc_target",
+ "rustc_type_ir",
"smallvec",
"tracing",
]
@@ -4392,7 +4402,6 @@ dependencies = [
"rustc_hir_pretty",
"rustc_index",
"rustc_macros",
- "rustc_next_trait_solver",
"rustc_query_system",
"rustc_serialize",
"rustc_session",
@@ -4509,6 +4518,7 @@ dependencies = [
"rustc_serialize",
"rustc_type_ir",
"rustc_type_ir_macros",
+ "tracing",
]
[[package]]
@@ -5356,7 +5366,7 @@ dependencies = [
"hermit-abi",
"libc",
"miniz_oxide",
- "object 0.32.2",
+ "object 0.36.0",
"panic_abort",
"panic_unwind",
"profiler_builtins",
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 910fbb876974..9cb193b4a678 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -488,6 +488,7 @@ pub struct Crate {
/// E.g., `#[test]`, `#[derive(..)]`, `#[rustfmt::skip]` or `#[feature = "foo"]`.
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct MetaItem {
+ pub unsafety: Safety,
pub path: Path,
pub kind: MetaItemKind,
pub span: Span,
@@ -1392,7 +1393,7 @@ pub enum ExprKind {
/// An array (e.g, `[a, b, c, d]`).
Array(ThinVec
>),
/// Allow anonymous constants from an inline `const` block
- ConstBlock(P),
+ ConstBlock(AnonConst),
/// A function call
///
/// The first field resolves to the function itself,
@@ -2823,7 +2824,12 @@ pub struct NormalAttr {
impl NormalAttr {
pub fn from_ident(ident: Ident) -> Self {
Self {
- item: AttrItem { path: Path::from_ident(ident), args: AttrArgs::Empty, tokens: None },
+ item: AttrItem {
+ unsafety: Safety::Default,
+ path: Path::from_ident(ident),
+ args: AttrArgs::Empty,
+ tokens: None,
+ },
tokens: None,
}
}
@@ -2831,6 +2837,7 @@ impl NormalAttr {
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub struct AttrItem {
+ pub unsafety: Safety,
pub path: Path,
pub args: AttrArgs,
// Tokens for the meta item, e.g. just the `foo` within `#[foo]` or `#![foo]`.
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index d5c9fc960c86..676a2377c3b3 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -1,6 +1,8 @@
//! Functions dealing with attributes and meta items.
-use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute};
+use crate::ast::{
+ AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute, Safety,
+};
use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit};
use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem, NormalAttr};
use crate::ast::{Path, PathSegment, DUMMY_NODE_ID};
@@ -238,7 +240,12 @@ impl AttrItem {
}
pub fn meta(&self, span: Span) -> Option {
- Some(MetaItem { path: self.path.clone(), kind: self.meta_kind()?, span })
+ Some(MetaItem {
+ unsafety: Safety::Default,
+ path: self.path.clone(),
+ kind: self.meta_kind()?,
+ span,
+ })
}
pub fn meta_kind(&self) -> Option {
@@ -371,7 +378,10 @@ impl MetaItem {
_ => path.span.hi(),
};
let span = path.span.with_hi(hi);
- Some(MetaItem { path, kind, span })
+ // FIXME: This parses `unsafe()` not as unsafe attribute syntax in `MetaItem`,
+ // but as a parenthesized list. This (and likely `MetaItem`) should be changed in
+ // such a way that builtin macros don't accept extraneous `unsafe()`.
+ Some(MetaItem { unsafety: Safety::Default, path, kind, span })
}
}
@@ -555,11 +565,12 @@ pub fn mk_doc_comment(
pub fn mk_attr(
g: &AttrIdGenerator,
style: AttrStyle,
+ unsafety: Safety,
path: Path,
args: AttrArgs,
span: Span,
) -> Attribute {
- mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span)
+ mk_attr_from_item(g, AttrItem { unsafety, path, args, tokens: None }, None, style, span)
}
pub fn mk_attr_from_item(
@@ -577,15 +588,22 @@ pub fn mk_attr_from_item(
}
}
-pub fn mk_attr_word(g: &AttrIdGenerator, style: AttrStyle, name: Symbol, span: Span) -> Attribute {
+pub fn mk_attr_word(
+ g: &AttrIdGenerator,
+ style: AttrStyle,
+ unsafety: Safety,
+ name: Symbol,
+ span: Span,
+) -> Attribute {
let path = Path::from_ident(Ident::new(name, span));
let args = AttrArgs::Empty;
- mk_attr(g, style, path, args, span)
+ mk_attr(g, style, unsafety, path, args, span)
}
pub fn mk_attr_nested_word(
g: &AttrIdGenerator,
style: AttrStyle,
+ unsafety: Safety,
outer: Symbol,
inner: Symbol,
span: Span,
@@ -601,12 +619,13 @@ pub fn mk_attr_nested_word(
delim: Delimiter::Parenthesis,
tokens: inner_tokens,
});
- mk_attr(g, style, path, attr_args, span)
+ mk_attr(g, style, unsafety, path, attr_args, span)
}
pub fn mk_attr_name_value_str(
g: &AttrIdGenerator,
style: AttrStyle,
+ unsafety: Safety,
name: Symbol,
val: Symbol,
span: Span,
@@ -621,7 +640,7 @@ pub fn mk_attr_name_value_str(
});
let path = Path::from_ident(Ident::new(name, span));
let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr));
- mk_attr(g, style, path, args, span)
+ mk_attr(g, style, unsafety, path, args, span)
}
pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator- {
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index a04c648ac731..cc33ce2cb562 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -647,8 +647,10 @@ fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) {
let Attribute { kind, id: _, style: _, span } = attr;
match kind {
AttrKind::Normal(normal) => {
- let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } =
- &mut **normal;
+ let NormalAttr {
+ item: AttrItem { unsafety: _, path, args, tokens },
+ tokens: attr_tokens,
+ } = &mut **normal;
vis.visit_path(path);
visit_attr_args(args, vis);
visit_lazy_tts(tokens, vis);
@@ -678,7 +680,7 @@ fn noop_visit_meta_list_item(li: &mut NestedMetaItem, vis: &mut T
}
fn noop_visit_meta_item(mi: &mut MetaItem, vis: &mut T) {
- let MetaItem { path: _, kind, span } = mi;
+ let MetaItem { unsafety: _, path: _, kind, span } = mi;
match kind {
MetaItemKind::Word => {}
MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)),
@@ -840,7 +842,7 @@ fn visit_nonterminal(nt: &mut token::Nonterminal, vis: &mut T) {
token::NtTy(ty) => vis.visit_ty(ty),
token::NtLiteral(expr) => vis.visit_expr(expr),
token::NtMeta(item) => {
- let AttrItem { path, args, tokens } = item.deref_mut();
+ let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut();
vis.visit_path(path);
visit_attr_args(args, vis);
visit_lazy_tts(tokens, vis);
@@ -1417,7 +1419,7 @@ pub fn noop_visit_expr(
match kind {
ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis),
ExprKind::ConstBlock(anon_const) => {
- vis.visit_expr(anon_const);
+ vis.visit_anon_const(anon_const);
}
ExprKind::Repeat(expr, count) => {
vis.visit_expr(expr);
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index de285aed1656..fa97c8db3267 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -959,7 +959,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
ExprKind::Array(subexpressions) => {
walk_list!(visitor, visit_expr, subexpressions);
}
- ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_expr(anon_const)),
+ ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)),
ExprKind::Repeat(element, count) => {
try_visit!(visitor.visit_expr(element));
try_visit!(visitor.visit_anon_const(count));
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index eb206a09be31..77f95869e9da 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -75,8 +75,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
let kind = match &e.kind {
ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
ExprKind::ConstBlock(c) => {
- self.has_inline_consts = true;
- hir::ExprKind::ConstBlock(self.lower_expr(c))
+ let c = self.with_new_scopes(c.value.span, |this| hir::ConstBlock {
+ def_id: this.local_def_id(c.id),
+ hir_id: this.lower_node_id(c.id),
+ body: this.lower_const_body(c.value.span, Some(&c.value)),
+ });
+ hir::ExprKind::ConstBlock(c)
}
ExprKind::Repeat(expr, count) => {
let expr = self.lower_expr(expr);
@@ -1801,6 +1805,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let attr = attr::mk_attr_nested_word(
&self.tcx.sess.psess.attr_id_generator,
AttrStyle::Outer,
+ Safety::Default,
sym::allow,
sym::unreachable_code,
self.lower_span(span),
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 741a44eb0c52..44f37b5533a6 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -236,6 +236,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}
+ fn visit_inline_const(&mut self, constant: &'hir ConstBlock) {
+ self.insert(DUMMY_SP, constant.hir_id, Node::ConstBlock(constant));
+
+ self.with_parent(constant.hir_id, |this| {
+ intravisit::walk_inline_const(this, constant);
+ });
+ }
+
fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
self.insert(expr.span, expr.hir_id, Node::Expr(expr));
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 023dc6d52c3e..1c6b5b9af195 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -96,8 +96,6 @@ struct LoweringContext<'a, 'hir> {
/// Bodies inside the owner being lowered.
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
- /// Whether there were inline consts that typeck will split out into bodies
- has_inline_consts: bool,
/// Attributes inside the owner being lowered.
attrs: SortedMap,
/// Collect items that were created by lowering the current owner.
@@ -160,7 +158,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
item_local_id_counter: hir::ItemLocalId::ZERO,
node_id_to_local_id: Default::default(),
trait_map: Default::default(),
- has_inline_consts: false,
// Lowering state.
catch_scope: None,
@@ -570,7 +567,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let current_attrs = std::mem::take(&mut self.attrs);
let current_bodies = std::mem::take(&mut self.bodies);
- let current_has_inline_consts = std::mem::take(&mut self.has_inline_consts);
let current_node_ids = std::mem::take(&mut self.node_id_to_local_id);
let current_trait_map = std::mem::take(&mut self.trait_map);
let current_owner =
@@ -597,7 +593,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.attrs = current_attrs;
self.bodies = current_bodies;
- self.has_inline_consts = current_has_inline_consts;
self.node_id_to_local_id = current_node_ids;
self.trait_map = current_trait_map;
self.current_hir_id_owner = current_owner;
@@ -634,7 +629,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let attrs = std::mem::take(&mut self.attrs);
let mut bodies = std::mem::take(&mut self.bodies);
let trait_map = std::mem::take(&mut self.trait_map);
- let has_inline_consts = std::mem::take(&mut self.has_inline_consts);
#[cfg(debug_assertions)]
for (id, attrs) in attrs.iter() {
@@ -652,7 +646,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.tcx.hash_owner_nodes(node, &bodies, &attrs);
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, has_inline_consts };
+ let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
@@ -911,6 +905,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let kind = match attr.kind {
AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr {
item: AttrItem {
+ unsafety: normal.item.unsafety,
path: normal.item.path.clone(),
args: self.lower_attr_args(&normal.item.args),
tokens: None,
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index a9dca9b6a293..764d942836c2 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -561,6 +561,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
gate_all!(mut_ref, "mutable by-reference bindings are experimental");
gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental");
gate_all!(global_registration, "global registration is experimental");
+ gate_all!(unsafe_attributes, "`#[unsafe()]` markers for attributes are experimental");
if !visitor.features.never_patterns {
if let Some(spans) = spans.get(&sym::never_patterns) {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index ca26b436b82e..f32b63a39f0a 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -16,7 +16,7 @@ use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, To
use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree};
use rustc_ast::util::classify;
use rustc_ast::util::comments::{Comment, CommentStyle};
-use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind};
+use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind, Safety};
use rustc_ast::{attr, BindingMode, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term};
use rustc_ast::{GenericArg, GenericBound, SelfKind};
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
@@ -249,6 +249,7 @@ pub fn print_crate<'a>(
let fake_attr = attr::mk_attr_nested_word(
g,
ast::AttrStyle::Inner,
+ Safety::Default,
sym::feature,
sym::prelude_import,
DUMMY_SP,
@@ -259,7 +260,13 @@ pub fn print_crate<'a>(
// root, so this is not needed, and actually breaks things.
if edition.is_rust_2015() {
// `#![no_std]`
- let fake_attr = attr::mk_attr_word(g, ast::AttrStyle::Inner, sym::no_std, DUMMY_SP);
+ let fake_attr = attr::mk_attr_word(
+ g,
+ ast::AttrStyle::Inner,
+ Safety::Default,
+ sym::no_std,
+ DUMMY_SP,
+ );
s.print_attribute(&fake_attr);
}
}
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index 993ccc5b9560..1e117c46b6e2 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -380,9 +380,8 @@ impl<'a> State<'a> {
ast::ExprKind::Array(exprs) => {
self.print_expr_vec(exprs);
}
- ast::ExprKind::ConstBlock(expr) => {
- self.word_space("const");
- self.print_expr(expr, FixupContext::default());
+ ast::ExprKind::ConstBlock(anon_const) => {
+ self.print_expr_anon_const(anon_const, attrs);
}
ast::ExprKind::Repeat(element, count) => {
self.print_expr_repeat(element, count);
diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs
index ff11e4db1213..97408fa20d79 100644
--- a/compiler/rustc_borrowck/src/constraints/mod.rs
+++ b/compiler/rustc_borrowck/src/constraints/mod.rs
@@ -1,7 +1,7 @@
use rustc_data_structures::graph::scc::Sccs;
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::mir::ConstraintCategory;
-use rustc_middle::ty::{RegionVid, VarianceDiagInfo};
+use rustc_middle::ty::{RegionVid, TyCtxt, VarianceDiagInfo};
use rustc_span::Span;
use std::fmt;
use std::ops::Index;
@@ -97,7 +97,7 @@ pub struct OutlivesConstraint<'tcx> {
pub category: ConstraintCategory<'tcx>,
/// Variance diagnostic information
- pub variance_info: VarianceDiagInfo<'tcx>,
+ pub variance_info: VarianceDiagInfo>,
/// If this constraint is promoted from closure requirements.
pub from_closure: bool,
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index b57cf9066cf3..0e3140ca98b0 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -2304,5 +2304,5 @@ pub struct BlameConstraint<'tcx> {
pub category: ConstraintCategory<'tcx>,
pub from_closure: bool,
pub cause: ObligationCause<'tcx>,
- pub variance_info: ty::VarianceDiagInfo<'tcx>,
+ pub variance_info: ty::VarianceDiagInfo>,
}
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index 9863c4a38832..2c34fc583c83 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -1,14 +1,14 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::ErrorGuaranteed;
+use rustc_infer::infer::relate::{ObligationEmittingRelation, StructurallyRelateAliases};
+use rustc_infer::infer::relate::{Relate, RelateResult, TypeRelation};
use rustc_infer::infer::NllRegionVariableOrigin;
-use rustc_infer::infer::{ObligationEmittingRelation, StructurallyRelateAliases};
use rustc_infer::traits::{Obligation, PredicateObligations};
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::span_bug;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::fold::FnMutDelegate;
-use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
@@ -82,7 +82,7 @@ pub struct NllTypeRelating<'me, 'bccx, 'tcx> {
/// - Bivariant means that it doesn't matter.
ambient_variance: ty::Variance,
- ambient_variance_info: ty::VarianceDiagInfo<'tcx>,
+ ambient_variance_info: ty::VarianceDiagInfo>,
}
impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
@@ -296,7 +296,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
&mut self,
sup: ty::Region<'tcx>,
sub: ty::Region<'tcx>,
- info: ty::VarianceDiagInfo<'tcx>,
+ info: ty::VarianceDiagInfo>,
) {
let sub = self.type_checker.borrowck_context.universal_regions.to_region_vid(sub);
let sup = self.type_checker.borrowck_context.universal_regions.to_region_vid(sup);
@@ -314,7 +314,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
}
}
-impl<'bccx, 'tcx> TypeRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
+impl<'bccx, 'tcx> TypeRelation> for NllTypeRelating<'_, 'bccx, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.type_checker.infcx.tcx
}
@@ -324,10 +324,10 @@ impl<'bccx, 'tcx> TypeRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
}
#[instrument(skip(self, info), level = "trace", ret)]
- fn relate_with_variance>(
+ fn relate_with_variance>>(
&mut self,
variance: ty::Variance,
- info: ty::VarianceDiagInfo<'tcx>,
+ info: ty::VarianceDiagInfo>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@@ -445,7 +445,7 @@ impl<'bccx, 'tcx> TypeRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
b: ty::Binder<'tcx, T>,
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
where
- T: Relate<'tcx>,
+ T: Relate>,
{
// We want that
//
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index a3d6a1c73607..2d1269e1b6ad 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -110,6 +110,9 @@ builtin_macros_derive_path_args_list = traits in `#[derive(...)]` don't accept a
builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept values
.suggestion = remove the value
+builtin_macros_derive_unsafe_path = traits in `#[derive(...)]` don't accept `unsafe(...)`
+ .suggestion = remove the `unsafe(...)`
+
builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time
.cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead
.custom = use `std::env::var({$var_expr})` to read the variable at run time
diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
index e9b63b4abebb..16184ec75113 100644
--- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
+++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
@@ -17,7 +17,7 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
));
let start_span = parser.token.span;
- let AttrItem { path, args, tokens: _ } = match parser.parse_attr_item(false) {
+ let AttrItem { unsafety, path, args, tokens: _ } = match parser.parse_attr_item(false) {
Ok(ai) => ai,
Err(err) => {
err.emit();
@@ -33,6 +33,7 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
krate.attrs.push(mk_attr(
&psess.attr_id_generator,
AttrStyle::Inner,
+ unsafety,
path,
args,
start_span.to(end_span),
diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs
index d14858e5c1db..b5cbfdf0ec6e 100644
--- a/compiler/rustc_builtin_macros/src/derive.rs
+++ b/compiler/rustc_builtin_macros/src/derive.rs
@@ -2,7 +2,7 @@ use crate::cfg_eval::cfg_eval;
use crate::errors;
use rustc_ast as ast;
-use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
+use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, Safety, StmtKind};
use rustc_expand::base::{
Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier,
};
@@ -60,6 +60,7 @@ impl MultiItemModifier for Expander {
// Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the
// paths.
report_path_args(sess, meta);
+ report_unsafe_args(sess, meta);
meta.path.clone()
})
.map(|path| DeriveResolution {
@@ -159,3 +160,13 @@ fn report_path_args(sess: &Session, meta: &ast::MetaItem) {
}
}
}
+
+fn report_unsafe_args(sess: &Session, meta: &ast::MetaItem) {
+ match meta.unsafety {
+ Safety::Unsafe(span) => {
+ sess.dcx().emit_err(errors::DeriveUnsafePath { span });
+ }
+ Safety::Default => {}
+ Safety::Safe(_) => unreachable!(),
+ }
+}
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index d157703723be..b14eb2b5ee60 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -295,6 +295,13 @@ pub(crate) struct DerivePathArgsValue {
pub(crate) span: Span,
}
+#[derive(Diagnostic)]
+#[diag(builtin_macros_derive_unsafe_path)]
+pub(crate) struct DeriveUnsafePath {
+ #[primary_span]
+ pub(crate) span: Span,
+}
+
#[derive(Diagnostic)]
#[diag(builtin_macros_no_default_variant)]
#[help]
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 38ac2f15fe75..ba4e5cfd1307 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -203,6 +203,7 @@ impl<'a> MutVisitor for EntryPointCleaner<'a> {
let allow_dead_code = attr::mk_attr_nested_word(
&self.sess.psess.attr_id_generator,
ast::AttrStyle::Outer,
+ ast::Safety::Default,
sym::allow,
sym::dead_code,
self.def_site,
diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
index 3c11d67e7489..8c66888d1007 100644
--- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs
@@ -38,6 +38,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
match node {
hir::Node::Ctor(_)
| hir::Node::AnonConst(_)
+ | hir::Node::ConstBlock(_)
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => {
hir::Constness::Const
}
@@ -56,7 +57,6 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
if is_const { hir::Constness::Const } else { hir::Constness::NotConst }
}
hir::Node::Expr(e) if let hir::ExprKind::Closure(c) = e.kind => c.constness,
- hir::Node::Expr(e) if let hir::ExprKind::ConstBlock(_) = e.kind => hir::Constness::Const,
_ => {
if let Some(fn_kind) = node.fn_kind() {
if fn_kind.constness() == hir::Constness::Const {
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index b3d41908260e..37dfd8305126 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -666,7 +666,7 @@ impl<'a> ExtCtxt<'a> {
// Builds `#[name]`.
pub fn attr_word(&self, name: Symbol, span: Span) -> ast::Attribute {
let g = &self.sess.psess.attr_id_generator;
- attr::mk_attr_word(g, ast::AttrStyle::Outer, name, span)
+ attr::mk_attr_word(g, ast::AttrStyle::Outer, ast::Safety::Default, name, span)
}
// Builds `#[name = val]`.
@@ -674,12 +674,26 @@ impl<'a> ExtCtxt<'a> {
// Note: `span` is used for both the identifier and the value.
pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute {
let g = &self.sess.psess.attr_id_generator;
- attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, name, val, span)
+ attr::mk_attr_name_value_str(
+ g,
+ ast::AttrStyle::Outer,
+ ast::Safety::Default,
+ name,
+ val,
+ span,
+ )
}
// Builds `#[outer(inner)]`.
pub fn attr_nested_word(&self, outer: Symbol, inner: Symbol, span: Span) -> ast::Attribute {
let g = &self.sess.psess.attr_id_generator;
- attr::mk_attr_nested_word(g, ast::AttrStyle::Outer, outer, inner, span)
+ attr::mk_attr_nested_word(
+ g,
+ ast::AttrStyle::Outer,
+ ast::Safety::Default,
+ outer,
+ inner,
+ span,
+ )
}
}
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index d8f0f221189a..c28a09eb57c7 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -778,7 +778,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
if let SyntaxExtensionKind::Derive(..) = ext {
self.gate_proc_macro_input(&item);
}
- let meta = ast::MetaItem { kind: MetaItemKind::Word, span, path };
+ // The `MetaItem` representing the trait to derive can't
+ // have an unsafe around it (as of now).
+ let meta = ast::MetaItem {
+ unsafety: ast::Safety::Default,
+ kind: MetaItemKind::Word,
+ span,
+ path,
+ };
let items = match expander.expand(self.cx, span, &meta, item, is_const) {
ExpandResult::Ready(items) => items,
ExpandResult::Retry(item) => {
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 8b7e93fd5558..9b5e4e50d3ca 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -59,6 +59,16 @@ pub enum AttributeType {
CrateLevel,
}
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum AttributeSafety {
+ /// Normal attribute that does not need `#[unsafe(...)]`
+ Normal,
+
+ /// Unsafe attribute that requires safety obligations
+ /// to be discharged
+ Unsafe,
+}
+
#[derive(Clone, Copy)]
pub enum AttributeGate {
/// Is gated by a given feature gate, reason
@@ -172,11 +182,23 @@ macro_rules! template {
}
macro_rules! ungated {
+ (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => {
+ BuiltinAttribute {
+ name: sym::$attr,
+ encode_cross_crate: $encode_cross_crate,
+ type_: $typ,
+ safety: AttributeSafety::Unsafe,
+ template: $tpl,
+ gate: Ungated,
+ duplicates: $duplicates,
+ }
+ };
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr $(,)?) => {
BuiltinAttribute {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
type_: $typ,
+ safety: AttributeSafety::Normal,
template: $tpl,
gate: Ungated,
duplicates: $duplicates,
@@ -185,11 +207,34 @@ macro_rules! ungated {
}
macro_rules! gated {
+ (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => {
+ BuiltinAttribute {
+ name: sym::$attr,
+ encode_cross_crate: $encode_cross_crate,
+ type_: $typ,
+ safety: AttributeSafety::Unsafe,
+ template: $tpl,
+ duplicates: $duplicates,
+ gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)),
+ }
+ };
+ (unsafe $attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $msg:expr $(,)?) => {
+ BuiltinAttribute {
+ name: sym::$attr,
+ encode_cross_crate: $encode_cross_crate,
+ type_: $typ,
+ safety: AttributeSafety::Unsafe,
+ template: $tpl,
+ duplicates: $duplicates,
+ gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)),
+ }
+ };
($attr:ident, $typ:expr, $tpl:expr, $duplicates:expr, $encode_cross_crate:expr, $gate:ident, $msg:expr $(,)?) => {
BuiltinAttribute {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
type_: $typ,
+ safety: AttributeSafety::Normal,
template: $tpl,
duplicates: $duplicates,
gate: Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)),
@@ -200,6 +245,7 @@ macro_rules! gated {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
type_: $typ,
+ safety: AttributeSafety::Normal,
template: $tpl,
duplicates: $duplicates,
gate: Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)),
@@ -228,6 +274,7 @@ macro_rules! rustc_attr {
name: sym::$attr,
encode_cross_crate: $encode_cross_crate,
type_: $typ,
+ safety: AttributeSafety::Normal,
template: $tpl,
duplicates: $duplicates,
gate: Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)),
@@ -258,6 +305,7 @@ pub struct BuiltinAttribute {
/// Otherwise, it can only be used in the local crate.
pub encode_cross_crate: EncodeCrossCrate,
pub type_: AttributeType,
+ pub safety: AttributeSafety,
pub template: AttributeTemplate,
pub duplicates: AttributeDuplicates,
pub gate: AttributeGate,
@@ -375,9 +423,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),
ungated!(no_link, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, EncodeCrossCrate::No),
- ungated!(export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
- ungated!(link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
- ungated!(no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
+ ungated!(unsafe export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
+ ungated!(unsafe link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, EncodeCrossCrate::No),
+ ungated!(unsafe no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, EncodeCrossCrate::No),
ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding, EncodeCrossCrate::Yes),
@@ -486,11 +534,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
),
gated!(
- ffi_pure, Normal, template!(Word), WarnFollowing,
+ unsafe ffi_pure, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, experimental!(ffi_pure)
),
gated!(
- ffi_const, Normal, template!(Word), WarnFollowing,
+ unsafe ffi_const, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::No, experimental!(ffi_const)
),
gated!(
@@ -850,6 +898,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// FIXME: This can be `true` once we always use `tcx.is_diagnostic_item`.
encode_cross_crate: EncodeCrossCrate::Yes,
type_: Normal,
+ safety: AttributeSafety::Normal,
template: template!(NameValueStr: "name"),
duplicates: ErrorFollowing,
gate: Gated(
@@ -1096,6 +1145,10 @@ pub fn is_valid_for_get_attr(name: Symbol) -> bool {
})
}
+pub fn is_unsafe_attr(name: Symbol) -> bool {
+ BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| attr.safety == AttributeSafety::Unsafe)
+}
+
pub static BUILTIN_ATTRIBUTE_MAP: LazyLock> =
LazyLock::new(|| {
let mut map = FxHashMap::default();
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index 9cbf836ec76f..9db9073e2f02 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -123,8 +123,8 @@ pub use accepted::ACCEPTED_FEATURES;
pub use builtin_attrs::AttributeDuplicates;
pub use builtin_attrs::{
deprecated_attributes, encode_cross_crate, find_gated_cfg, is_builtin_attr_name,
- is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute,
- GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
+ is_unsafe_attr, is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType,
+ BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
};
pub use removed::REMOVED_FEATURES;
pub use unstable::{Features, INCOMPATIBLE_FEATURES, UNSTABLE_FEATURES};
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 8add2b927614..d67422849d8a 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -620,6 +620,8 @@ declare_features! (
(unstable, type_changing_struct_update, "1.58.0", Some(86555)),
/// Allows unnamed fields of struct and union type
(incomplete, unnamed_fields, "1.74.0", Some(49804)),
+ /// Allows unsafe attributes.
+ (unstable, unsafe_attributes, "CURRENT_RUSTC_VERSION", Some(123757)),
/// Allows unsafe on extern declarations and safety qualifiers over internal items.
(unstable, unsafe_extern_blocks, "CURRENT_RUSTC_VERSION", Some(123743)),
/// Allows unsized fn parameters.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 770dfcb98c91..87ff39a8294c 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -907,9 +907,6 @@ pub struct OwnerNodes<'tcx> {
pub nodes: IndexVec>,
/// Content of local bodies.
pub bodies: SortedMap>,
- /// Whether the body contains inline constants that are created for the query system during typeck
- /// of the body.
- pub has_inline_consts: bool,
}
impl<'tcx> OwnerNodes<'tcx> {
@@ -1626,6 +1623,14 @@ pub struct AnonConst {
pub span: Span,
}
+/// An inline constant expression `const { something }`.
+#[derive(Copy, Clone, Debug, HashStable_Generic)]
+pub struct ConstBlock {
+ pub hir_id: HirId,
+ pub def_id: LocalDefId,
+ pub body: BodyId,
+}
+
/// An expression.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Expr<'hir> {
@@ -1912,7 +1917,7 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool {
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub enum ExprKind<'hir> {
/// Allow anonymous constants from an inline `const` block
- ConstBlock(&'hir Expr<'hir>),
+ ConstBlock(ConstBlock),
/// An array (e.g., `[a, b, c, d]`).
Array(&'hir [Expr<'hir>]),
/// A function call.
@@ -2345,7 +2350,9 @@ impl ImplItemId {
}
}
-/// Represents anything within an `impl` block.
+/// Represents an associated item within an impl block.
+///
+/// Refer to [`Impl`] for an impl block declaration.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct ImplItem<'hir> {
pub ident: Ident,
@@ -3327,6 +3334,10 @@ pub enum ItemKind<'hir> {
Impl(&'hir Impl<'hir>),
}
+/// Represents an impl block declaration.
+///
+/// E.g., `impl $Type { .. }` or `impl $Trait for $Type { .. }`
+/// Refer to [`ImplItem`] for an associated item within an impl block.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Impl<'hir> {
pub safety: Safety,
@@ -3644,6 +3655,7 @@ pub enum Node<'hir> {
Variant(&'hir Variant<'hir>),
Field(&'hir FieldDef<'hir>),
AnonConst(&'hir AnonConst),
+ ConstBlock(&'hir ConstBlock),
Expr(&'hir Expr<'hir>),
ExprField(&'hir ExprField<'hir>),
Stmt(&'hir Stmt<'hir>),
@@ -3704,6 +3716,7 @@ impl<'hir> Node<'hir> {
Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
Node::Param(..)
| Node::AnonConst(..)
+ | Node::ConstBlock(..)
| Node::Expr(..)
| Node::Stmt(..)
| Node::Block(..)
@@ -3801,6 +3814,7 @@ impl<'hir> Node<'hir> {
}
Node::AnonConst(constant) => Some((constant.def_id, constant.body)),
+ Node::ConstBlock(constant) => Some((constant.def_id, constant.body)),
_ => None,
}
@@ -3869,6 +3883,7 @@ impl<'hir> Node<'hir> {
expect_variant, &'hir Variant<'hir>, Node::Variant(n), n;
expect_field, &'hir FieldDef<'hir>, Node::Field(n), n;
expect_anon_const, &'hir AnonConst, Node::AnonConst(n), n;
+ expect_inline_const, &'hir ConstBlock, Node::ConstBlock(n), n;
expect_expr, &'hir Expr<'hir>, Node::Expr(n), n;
expect_expr_field, &'hir ExprField<'hir>, Node::ExprField(n), n;
expect_stmt, &'hir Stmt<'hir>, Node::Stmt(n), n;
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index e37473df956d..5a16f266dab3 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -344,6 +344,9 @@ pub trait Visitor<'v>: Sized {
fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
walk_anon_const(self, c)
}
+ fn visit_inline_const(&mut self, c: &'v ConstBlock) -> Self::Result {
+ walk_inline_const(self, c)
+ }
fn visit_expr(&mut self, ex: &'v Expr<'v>) -> Self::Result {
walk_expr(self, ex)
}
@@ -718,6 +721,14 @@ pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonCo
visitor.visit_nested_body(constant.body)
}
+pub fn walk_inline_const<'v, V: Visitor<'v>>(
+ visitor: &mut V,
+ constant: &'v ConstBlock,
+) -> V::Result {
+ try_visit!(visitor.visit_id(constant.hir_id));
+ visitor.visit_nested_body(constant.body)
+}
+
pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) -> V::Result {
try_visit!(visitor.visit_id(expression.hir_id));
match expression.kind {
@@ -725,7 +736,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
walk_list!(visitor, visit_expr, subexpressions);
}
ExprKind::ConstBlock(ref const_block) => {
- try_visit!(visitor.visit_expr(const_block))
+ try_visit!(visitor.visit_inline_const(const_block))
}
ExprKind::Repeat(ref element, ref count) => {
try_visit!(visitor.visit_expr(element));
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index 1ebd4b80e183..baa1635f7313 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -93,8 +93,7 @@ impl<'tcx, HirCtx: crate::HashStableContext> HashStable for OwnerNodes<'
// `local_id_to_def_id` is also ignored because is dependent on the body, then just hashing
// the body satisfies the condition of two nodes being different have different
// `hash_stable` results.
- let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _, has_inline_consts: _ } =
- *self;
+ let OwnerNodes { opt_hash_including_bodies, nodes: _, bodies: _ } = *self;
opt_hash_including_bodies.unwrap().hash_stable(hcx, hasher);
}
}
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 8a0623ef93e3..72e5995e892e 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -15,6 +15,7 @@ use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
use rustc_middle::middle::resolve_bound_vars::ResolvedArg;
use rustc_middle::middle::stability::EvalResult;
use rustc_middle::span_bug;
+use rustc_middle::ty::error::TypeErrorToStringExt;
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index 30b03b43872a..72e431926ca3 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -407,14 +407,11 @@ fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx h
match expr.kind {
// Manually recurse over closures and inline consts, because they are the only
// case of nested bodies that share the parent environment.
- hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
+ hir::ExprKind::Closure(&hir::Closure { body, .. })
+ | hir::ExprKind::ConstBlock(hir::ConstBlock { body, .. }) => {
let body = visitor.tcx.hir().body(body);
visitor.visit_body(body);
}
- hir::ExprKind::ConstBlock(expr) => visitor.enter_body(expr.hir_id, |this| {
- this.cx.var_parent = None;
- resolve_local(this, None, Some(expr));
- }),
hir::ExprKind::AssignOp(_, left_expr, right_expr) => {
debug!(
"resolve_expr - enabling pessimistic_yield, was previously {}",
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 9af959681fbf..abdf85ad707b 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -177,10 +177,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
}
}
}
- Node::Expr(&hir::Expr {
- kind: hir::ExprKind::Closure { .. } | hir::ExprKind::ConstBlock { .. },
- ..
- }) => Some(tcx.typeck_root_def_id(def_id.to_def_id())),
+ Node::ConstBlock(_)
+ | Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
+ Some(tcx.typeck_root_def_id(def_id.to_def_id()))
+ }
Node::Item(item) => match item.kind {
ItemKind::OpaqueTy(&hir::OpaqueTy {
origin:
@@ -415,7 +415,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
}
// provide junk type parameter defs for const blocks.
- if let Node::Expr(Expr { kind: ExprKind::ConstBlock(..), .. }) = node {
+ if let Node::ConstBlock(_) = node {
own_params.push(ty::GenericParamDef {
index: next_index(),
name: Symbol::intern(""),
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 6811f62de07b..2684467a4381 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -485,7 +485,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
}
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
- Node::Expr(&Expr { kind: ExprKind::ConstBlock(..), .. }) => {
+
+ Node::ConstBlock(_) => {
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
args.as_inline_const().ty()
}
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 65b02a2ec565..8fe81851f932 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -190,6 +190,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
}
});
+ // Freeze definitions as we don't add new ones at this point. This improves performance by
+ // allowing lock-free access to them.
+ tcx.untracked().definitions.freeze();
+
// FIXME: Remove this when we implement creating `DefId`s
// for anon constants during their parents' typeck.
// Typeck all body owners in parallel will produce queries
@@ -201,10 +205,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
}
});
- // Freeze definitions as we don't add new ones at this point. This improves performance by
- // allowing lock-free access to them.
- tcx.untracked().definitions.freeze();
-
tcx.ensure().check_unused_traits(());
}
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 6983bbcb052c..6f2febd86b0f 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -84,6 +84,7 @@ impl<'a> State<'a> {
Node::ImplItem(a) => self.print_impl_item(a),
Node::Variant(a) => self.print_variant(a),
Node::AnonConst(a) => self.print_anon_const(a),
+ Node::ConstBlock(a) => self.print_inline_const(a),
Node::Expr(a) => self.print_expr(a),
Node::ExprField(a) => self.print_expr_field(a),
Node::Stmt(a) => self.print_stmt(a),
@@ -1049,10 +1050,10 @@ impl<'a> State<'a> {
self.end()
}
- fn print_inline_const(&mut self, constant: &hir::Expr<'_>) {
+ fn print_inline_const(&mut self, constant: &hir::ConstBlock) {
self.ibox(INDENT_UNIT);
self.word_space("const");
- self.print_expr(constant);
+ self.ann.nested(self, Nested::Body(constant.body));
self.end()
}
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 93726ce2b3eb..dbaa6e398c88 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -41,6 +41,7 @@ use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag};
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
+use rustc_infer::infer::relate::RelateResult;
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause};
use rustc_infer::traits::{Obligation, PredicateObligation};
@@ -51,7 +52,6 @@ use rustc_middle::ty::adjustment::{
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
};
use rustc_middle::ty::error::TypeError;
-use rustc_middle::ty::relate::RelateResult;
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt};
use rustc_session::parse::feature_err;
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 7dd7b3ff055e..d5d360ca0479 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -31,6 +31,7 @@ use rustc_errors::{
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefId;
+use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{ExprKind, HirId, QPath};
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _;
@@ -40,7 +41,7 @@ use rustc_infer::infer::InferOk;
use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::ObligationCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
-use rustc_middle::ty::error::{ExpectedFound, TypeError::Sorts};
+use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt};
use rustc_middle::{bug, span_bug};
@@ -334,7 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
ExprKind::DropTemps(e) => self.check_expr_with_expectation(e, expected),
ExprKind::Array(args) => self.check_expr_array(args, expected, expr),
- ExprKind::ConstBlock(ref block) => self.check_expr_with_expectation(block, expected),
+ ExprKind::ConstBlock(ref block) => self.check_expr_const_block(block, expected),
ExprKind::Repeat(element, ref count) => {
self.check_expr_repeat(element, count, expected, expr)
}
@@ -682,7 +683,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.suggest_mismatched_types_on_tail(
&mut err, expr, ty, e_ty, target_id,
);
- let error = Some(Sorts(ExpectedFound { expected: ty, found: e_ty }));
+ let error =
+ Some(TypeError::Sorts(ExpectedFound { expected: ty, found: e_ty }));
self.annotate_loop_expected_due_to_inference(err, expr, error);
if let Some(val) =
self.err_ctxt().ty_kind_suggestion(self.param_env, ty)
@@ -1456,6 +1458,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
+ fn check_expr_const_block(
+ &self,
+ block: &'tcx hir::ConstBlock,
+ expected: Expectation<'tcx>,
+ ) -> Ty<'tcx> {
+ let body = self.tcx.hir().body(block.body);
+
+ // Create a new function context.
+ let def_id = block.def_id;
+ let fcx = FnCtxt::new(self, self.param_env, def_id);
+ crate::GatherLocalsVisitor::new(&fcx).visit_body(body);
+
+ let ty = fcx.check_expr_with_expectation(body.value, expected);
+ fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::ConstSized);
+ fcx.write_ty(block.hir_id, ty);
+ ty
+ }
+
fn check_expr_repeat(
&self,
element: &'tcx hir::Expr<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index caaf4142f7d1..9ab89f3444c9 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1051,10 +1051,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.take_while(|(_, node)| {
// look at parents until we find the first body owner
node.body_id().is_none()
- && !matches!(
- node,
- Node::Expr(Expr { kind: ExprKind::ConstBlock { .. }, .. })
- )
})
.any(|(parent_id, _)| self.is_loop(parent_id));
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 4386e68ce867..466397817dae 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -149,6 +149,10 @@ impl<'a, 'tcx> Visitor<'tcx> for InferBorrowKindVisitor<'a, 'tcx> {
self.visit_body(body);
self.fcx.analyze_closure(expr.hir_id, expr.span, body_id, body, capture_clause);
}
+ hir::ExprKind::ConstBlock(anon_const) => {
+ let body = self.fcx.tcx.hir().body(anon_const.body);
+ self.visit_body(body);
+ }
_ => {}
}
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 8727c0f87dc8..b67d29fce921 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -3,7 +3,6 @@
// generic parameters.
use crate::FnCtxt;
-use hir::def::DefKind;
use rustc_data_structures::unord::ExtendUnord;
use rustc_errors::{ErrorGuaranteed, StashKey};
use rustc_hir as hir;
@@ -17,7 +16,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::TypeSuperFoldable;
use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_trait_selection::solve;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
@@ -296,11 +295,11 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
hir::ExprKind::Field(..) | hir::ExprKind::OffsetOf(..) => {
self.visit_field_id(e.hir_id);
}
- hir::ExprKind::ConstBlock(_) => {
- let feed = self.tcx().create_def(self.fcx.body_id, kw::Empty, DefKind::InlineConst);
- feed.def_span(e.span);
- feed.local_def_id_to_hir_id(e.hir_id);
- self.typeck_results.inline_consts.insert(e.hir_id.local_id, feed.def_id());
+ hir::ExprKind::ConstBlock(anon_const) => {
+ self.visit_node_id(e.span, anon_const.hir_id);
+
+ let body = self.tcx().hir().body(anon_const.body);
+ self.visit_body(body);
}
_ => {}
}
diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml
index c1565a7d40fd..5136ab79a0f8 100644
--- a/compiler/rustc_infer/Cargo.toml
+++ b/compiler/rustc_infer/Cargo.toml
@@ -18,6 +18,7 @@ rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
+rustc_type_ir = { path = "../rustc_type_ir" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
tracing = "0.1"
# tidy-alphabetical-end
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 17e6d6250ad5..046d908d148d 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -27,8 +27,8 @@
use super::*;
+use crate::infer::relate::{Relate, StructurallyRelateAliases, TypeRelation};
use rustc_middle::bug;
-use rustc_middle::ty::relate::{Relate, TypeRelation};
use rustc_middle::ty::{Const, ImplSubject};
/// Whether we should define opaque types or just treat them opaquely.
@@ -90,7 +90,7 @@ impl<'tcx> InferCtxt<'tcx> {
}
}
-pub trait ToTrace<'tcx>: Relate<'tcx> + Copy {
+pub trait ToTrace<'tcx>: Relate> + Copy {
fn to_trace(
cause: &ObligationCause<'tcx>,
a_is_expected: bool,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index fe0a246abbc6..ed483c6cbeb4 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -58,6 +58,7 @@ use crate::traits::{
PredicateObligation,
};
+use crate::infer::relate::{self, RelateResult, TypeRelation};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diag, DiagCtxt, DiagStyledString,
@@ -71,8 +72,8 @@ use rustc_hir::lang_items::LangItem;
use rustc_macros::extension;
use rustc_middle::bug;
use rustc_middle::dep_graph::DepContext;
+use rustc_middle::ty::error::TypeErrorToStringExt;
use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError, PrintTraitRefExt as _};
-use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
use rustc_middle::ty::Upcast;
use rustc_middle::ty::{
self, error::TypeError, IsSuggestable, List, Region, Ty, TyCtxt, TypeFoldable,
@@ -2686,7 +2687,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
/// with the other type. A TyVar inference type is compatible with any type, and an IntVar or
/// FloatVar inference type are compatible with themselves or their concrete types (Int and
/// Float types, respectively). When comparing two ADTs, these rules apply recursively.
- pub fn same_type_modulo_infer>(&self, a: T, b: T) -> bool {
+ pub fn same_type_modulo_infer>>(&self, a: T, b: T) -> bool {
let (a, b) = self.resolve_vars_if_possible((a, b));
SameTypeModuloInfer(self).relate(a, b).is_ok()
}
@@ -2694,7 +2695,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
struct SameTypeModuloInfer<'a, 'tcx>(&'a InferCtxt<'tcx>);
-impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
+impl<'tcx> TypeRelation> for SameTypeModuloInfer<'_, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.0.tcx
}
@@ -2703,10 +2704,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
"SameTypeModuloInfer"
}
- fn relate_with_variance>(
+ fn relate_with_variance>>(
&mut self,
_variance: ty::Variance,
- _info: ty::VarianceDiagInfo<'tcx>,
+ _info: ty::VarianceDiagInfo>,
a: T,
b: T,
) -> relate::RelateResult<'tcx, T> {
@@ -2754,7 +2755,7 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
b: ty::Binder<'tcx, T>,
) -> relate::RelateResult<'tcx, ty::Binder<'tcx, T>>
where
- T: relate::Relate<'tcx>,
+ T: relate::Relate>,
{
Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 19ef2d61fca3..b88677b3a4ec 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -21,13 +21,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
sp: Span,
body_owner_def_id: DefId,
) {
- use ty::error::TypeError::*;
debug!("note_and_explain_type_err err={:?} cause={:?}", err, cause);
let tcx = self.tcx;
match err {
- ArgumentSorts(values, _) | Sorts(values) => {
+ TypeError::ArgumentSorts(values, _) | TypeError::Sorts(values) => {
match (*values.expected.kind(), *values.found.kind()) {
(ty::Closure(..), ty::Closure(..)) => {
diag.note("no two closures, even if identical, have the same type");
@@ -483,7 +482,7 @@ impl Trait for X {
values.found.kind(),
);
}
- CyclicTy(ty) => {
+ TypeError::CyclicTy(ty) => {
// Watch out for various cases of cyclic types and try to explain.
if ty.is_closure() || ty.is_coroutine() || ty.is_coroutine_closure() {
diag.note(
@@ -494,7 +493,7 @@ impl Trait for X {
);
}
}
- TargetFeatureCast(def_id) => {
+ TypeError::TargetFeatureCast(def_id) => {
let target_spans = tcx.get_attrs(def_id, sym::target_feature).map(|attr| attr.span);
diag.note(
"functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 4476611d9c82..c606ab808ef8 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1,9 +1,6 @@
pub use at::DefineOpaqueTypes;
pub use freshen::TypeFreshener;
pub use lexical_region_resolve::RegionResolutionError;
-pub use relate::combine::CombineFields;
-pub use relate::combine::ObligationEmittingRelation;
-pub use relate::StructurallyRelateAliases;
pub use rustc_macros::{TypeFoldable, TypeVisitable};
pub use rustc_middle::ty::IntVarValue;
pub use BoundRegionConversionTime::*;
@@ -11,6 +8,7 @@ pub use RegionVariableOrigin::*;
pub use SubregionOrigin::*;
pub use ValuePairs::*;
+use crate::infer::relate::{CombineFields, RelateResult};
use crate::traits::{
self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine,
};
@@ -39,7 +37,6 @@ use rustc_middle::traits::select;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::fold::BoundVarReplacerDelegate;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
-use rustc_middle::ty::relate::RelateResult;
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid};
@@ -62,7 +59,7 @@ pub mod opaque_types;
pub mod outlives;
mod projection;
pub mod region_constraints;
-mod relate;
+pub mod relate;
pub mod resolve;
pub(crate) mod snapshot;
pub mod type_variable;
diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
index 29c11d4247d0..978b92fd8980 100644
--- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
+++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs
@@ -1,15 +1,12 @@
use std::collections::hash_map::Entry;
use rustc_data_structures::fx::FxHashMap;
+use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::TypeVisitableExt;
-use rustc_middle::ty::{
- self,
- error::TypeError,
- relate::{self, Relate, RelateResult, TypeRelation},
- Ty, TyCtxt,
-};
+use rustc_middle::ty::{self, Ty, TyCtxt};
use crate::infer::region_constraints::VerifyIfEq;
+use crate::infer::relate::{self as relate, Relate, RelateResult, TypeRelation};
/// Given a "verify-if-eq" type test like:
///
@@ -135,7 +132,7 @@ impl<'tcx> MatchAgainstHigherRankedOutlives<'tcx> {
}
}
-impl<'tcx> TypeRelation<'tcx> for MatchAgainstHigherRankedOutlives<'tcx> {
+impl<'tcx> TypeRelation> for MatchAgainstHigherRankedOutlives<'tcx> {
fn tag(&self) -> &'static str {
"MatchAgainstHigherRankedOutlives"
}
@@ -145,10 +142,10 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstHigherRankedOutlives<'tcx> {
}
#[instrument(level = "trace", skip(self))]
- fn relate_with_variance>(
+ fn relate_with_variance>>(
&mut self,
variance: ty::Variance,
- _: ty::VarianceDiagInfo<'tcx>,
+ _: ty::VarianceDiagInfo>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@@ -208,7 +205,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstHigherRankedOutlives<'tcx> {
value: ty::Binder<'tcx, T>,
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
where
- T: Relate<'tcx>,
+ T: Relate>,
{
self.pattern_depth.shift_in(1);
let result = Ok(pattern.rebind(self.relate(pattern.skip_binder(), value.skip_binder())?));
diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
index 255ca52d3e98..5b159d627312 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
@@ -1,11 +1,11 @@
use super::*;
+use crate::infer::relate::RelateResult;
use crate::infer::snapshot::CombinedSnapshot;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::graph::{scc::Sccs, vec_graph::VecGraph};
use rustc_index::Idx;
use rustc_middle::span_bug;
use rustc_middle::ty::error::TypeError;
-use rustc_middle::ty::relate::RelateResult;
impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
/// Searches new universes created during `snapshot`, looking for
@@ -276,7 +276,7 @@ impl<'a, 'b, 'tcx> LeakCheck<'a, 'b, 'tcx> {
other_region: ty::Region<'tcx>,
) -> TypeError<'tcx> {
debug!("error: placeholder={:?}, other_region={:?}", placeholder, other_region);
- TypeError::RegionsInsufficientlyPolymorphic(placeholder.bound.kind, other_region)
+ TypeError::RegionsInsufficientlyPolymorphic(placeholder.bound, other_region)
}
}
diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_infer/src/infer/relate/_match.rs
similarity index 82%
rename from compiler/rustc_middle/src/ty/_match.rs
rename to compiler/rustc_infer/src/infer/relate/_match.rs
index f30270abd5c1..30a066a265ac 100644
--- a/compiler/rustc_middle/src/ty/_match.rs
+++ b/compiler/rustc_infer/src/infer/relate/_match.rs
@@ -1,8 +1,10 @@
-use crate::ty::error::TypeError;
-use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use crate::ty::{self, InferConst, Ty, TyCtxt};
+use rustc_middle::ty::error::{ExpectedFound, TypeError};
+use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
use tracing::{debug, instrument};
+use super::{structurally_relate_tys, Relate, RelateResult, TypeRelation};
+use crate::infer::relate;
+
/// A type "A" *matches* "B" if the fresh types in B could be
/// instantiated with values so as to make it equal to A. Matching is
/// intended to be used only on freshened types, and it basically
@@ -29,7 +31,7 @@ impl<'tcx> MatchAgainstFreshVars<'tcx> {
}
}
-impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
+impl<'tcx> TypeRelation> for MatchAgainstFreshVars<'tcx> {
fn tag(&self) -> &'static str {
"MatchAgainstFreshVars"
}
@@ -38,10 +40,10 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
self.tcx
}
- fn relate_with_variance>(
+ fn relate_with_variance>>(
&mut self,
_: ty::Variance,
- _: ty::VarianceDiagInfo<'tcx>,
+ _: ty::VarianceDiagInfo>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@@ -72,12 +74,12 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
) => Ok(a),
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
- Err(TypeError::Sorts(relate::expected_found(a, b)))
+ Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
}
(&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(self.tcx(), guar)),
- _ => relate::structurally_relate_tys(self, a, b),
+ _ => structurally_relate_tys(self, a, b),
}
}
@@ -97,7 +99,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
}
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
- return Err(TypeError::ConstMismatch(relate::expected_found(a, b)));
+ return Err(TypeError::ConstMismatch(ExpectedFound::new(true, a, b)));
}
_ => {}
@@ -112,7 +114,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
b: ty::Binder<'tcx, T>,
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
where
- T: Relate<'tcx>,
+ T: Relate>,
{
Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
}
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index b193f4bcede6..30cb2bab9008 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -22,12 +22,13 @@ use super::glb::Glb;
use super::lub::Lub;
use super::type_relating::TypeRelating;
use super::StructurallyRelateAliases;
+use super::{RelateResult, TypeRelation};
+use crate::infer::relate;
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
use crate::traits::{Obligation, PredicateObligations};
use rustc_middle::bug;
use rustc_middle::infer::unify_key::EffectVarValue;
-use rustc_middle::ty::error::TypeError;
-use rustc_middle::ty::relate::{RelateResult, TypeRelation};
+use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast};
use rustc_middle::ty::{IntType, UintType};
use rustc_span::Span;
@@ -121,7 +122,7 @@ impl<'tcx> InferCtxt<'tcx> {
(_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => {
match relation.structurally_relate_aliases() {
StructurallyRelateAliases::Yes => {
- ty::relate::structurally_relate_tys(relation, a, b)
+ relate::structurally_relate_tys(relation, a, b)
}
StructurallyRelateAliases::No => {
relation.register_type_relate_obligation(a, b);
@@ -132,7 +133,7 @@ impl<'tcx> InferCtxt<'tcx> {
// All other cases of inference are errors
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
- Err(TypeError::Sorts(ty::relate::expected_found(a, b)))
+ Err(TypeError::Sorts(ExpectedFound::new(true, a, b)))
}
// During coherence, opaque types should be treated as *possibly*
@@ -144,7 +145,7 @@ impl<'tcx> InferCtxt<'tcx> {
Ok(a)
}
- _ => ty::relate::structurally_relate_tys(relation, a, b),
+ _ => relate::structurally_relate_tys(relation, a, b),
}
}
@@ -234,11 +235,11 @@ impl<'tcx> InferCtxt<'tcx> {
Ok(b)
}
StructurallyRelateAliases::Yes => {
- ty::relate::structurally_relate_consts(relation, a, b)
+ relate::structurally_relate_consts(relation, a, b)
}
}
}
- _ => ty::relate::structurally_relate_consts(relation, a, b),
+ _ => relate::structurally_relate_consts(relation, a, b),
}
}
@@ -303,7 +304,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
}
}
-pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
+pub trait ObligationEmittingRelation<'tcx>: TypeRelation> {
fn span(&self) -> Span;
fn param_env(&self) -> ty::ParamEnv<'tcx>;
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 225c126fcf81..5478afda455f 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -1,15 +1,16 @@
use std::mem;
use super::StructurallyRelateAliases;
+use super::{ObligationEmittingRelation, Relate, RelateResult, TypeRelation};
+use crate::infer::relate;
use crate::infer::type_variable::TypeVariableValue;
-use crate::infer::{InferCtxt, ObligationEmittingRelation, RegionVariableOrigin};
+use crate::infer::{InferCtxt, RegionVariableOrigin};
use rustc_data_structures::sso::SsoHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::def_id::DefId;
use rustc_middle::bug;
use rustc_middle::infer::unify_key::ConstVariableValue;
use rustc_middle::ty::error::TypeError;
-use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::visit::MaxUniverse;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{AliasRelationDirection, InferConst, Term, TypeVisitable, TypeVisitableExt};
@@ -228,7 +229,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// Attempts to generalize `source_term` for the type variable `target_vid`.
/// This checks for cycles -- that is, whether `source_term` references `target_vid`.
- fn generalize> + Relate<'tcx>>(
+ fn generalize> + Relate>>(
&self,
span: Span,
structurally_relate_aliases: StructurallyRelateAliases,
@@ -395,7 +396,7 @@ impl<'tcx> Generalizer<'_, 'tcx> {
}
}
-impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
+impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.infcx.tcx
}
@@ -430,10 +431,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
}
#[instrument(level = "debug", skip(self, variance, b), ret)]
- fn relate_with_variance>(
+ fn relate_with_variance>>(
&mut self,
variance: ty::Variance,
- _info: ty::VarianceDiagInfo<'tcx>,
+ _info: ty::VarianceDiagInfo>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@@ -695,7 +696,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
_: ty::Binder<'tcx, T>,
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
where
- T: Relate<'tcx>,
+ T: Relate>,
{
let result = self.relate(a.skip_binder(), a.skip_binder())?;
Ok(a.rebind(result))
diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs
index a224a86492ab..98e8f07c7a21 100644
--- a/compiler/rustc_infer/src/infer/relate/glb.rs
+++ b/compiler/rustc_infer/src/infer/relate/glb.rs
@@ -1,6 +1,6 @@
//! Greatest lower bound. See [`lattice`].
-use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
+use super::{Relate, RelateResult, TypeRelation};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::Span;
@@ -21,7 +21,7 @@ impl<'combine, 'infcx, 'tcx> Glb<'combine, 'infcx, 'tcx> {
}
}
-impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
+impl<'tcx> TypeRelation> for Glb<'_, '_, 'tcx> {
fn tag(&self) -> &'static str {
"Glb"
}
@@ -30,10 +30,10 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
self.fields.tcx()
}
- fn relate_with_variance>(
+ fn relate_with_variance>>(
&mut self,
variance: ty::Variance,
- _info: ty::VarianceDiagInfo<'tcx>,
+ _info: ty::VarianceDiagInfo>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@@ -81,7 +81,7 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
b: ty::Binder<'tcx, T>,
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
where
- T: Relate<'tcx>,
+ T: Relate>,
{
// GLB of a binder and itself is just itself
if a == b {
diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
index d3001eb5838b..cfce28aca5d6 100644
--- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
+++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
@@ -1,10 +1,10 @@
//! Helper routines for higher-ranked things. See the `doc` module at
//! the end of the file for details.
+use super::RelateResult;
use crate::infer::snapshot::CombinedSnapshot;
use crate::infer::InferCtxt;
use rustc_middle::ty::fold::FnMutDelegate;
-use rustc_middle::ty::relate::RelateResult;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
impl<'tcx> InferCtxt<'tcx> {
diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs
index c0c51a2820b3..f05b984142ae 100644
--- a/compiler/rustc_infer/src/infer/relate/lattice.rs
+++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -21,7 +21,7 @@ use super::combine::ObligationEmittingRelation;
use crate::infer::{DefineOpaqueTypes, InferCtxt};
use crate::traits::ObligationCause;
-use rustc_middle::ty::relate::RelateResult;
+use super::RelateResult;
use rustc_middle::ty::TyVar;
use rustc_middle::ty::{self, Ty};
diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs
index 83ab77707709..28dbaa94f95d 100644
--- a/compiler/rustc_infer/src/infer/relate/lub.rs
+++ b/compiler/rustc_infer/src/infer/relate/lub.rs
@@ -6,7 +6,7 @@ use super::StructurallyRelateAliases;
use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
use crate::traits::{ObligationCause, PredicateObligations};
-use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
+use super::{Relate, RelateResult, TypeRelation};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::Span;
@@ -21,7 +21,7 @@ impl<'combine, 'infcx, 'tcx> Lub<'combine, 'infcx, 'tcx> {
}
}
-impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
+impl<'tcx> TypeRelation> for Lub<'_, '_, 'tcx> {
fn tag(&self) -> &'static str {
"Lub"
}
@@ -30,10 +30,10 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
self.fields.tcx()
}
- fn relate_with_variance>(
+ fn relate_with_variance>>(
&mut self,
variance: ty::Variance,
- _info: ty::VarianceDiagInfo<'tcx>,
+ _info: ty::VarianceDiagInfo>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@@ -81,7 +81,7 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
b: ty::Binder<'tcx, T>,
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
where
- T: Relate<'tcx>,
+ T: Relate>,
{
// LUB of a binder and itself is just itself
if a == b {
diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs
index 86a01130167a..627c527cba15 100644
--- a/compiler/rustc_infer/src/infer/relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/mod.rs
@@ -1,6 +1,14 @@
//! This module contains the definitions of most `TypeRelation`s in the type system
//! (except for some relations used for diagnostics and heuristics in the compiler).
+//! As well as the implementation of `Relate` for interned things (`Ty`/`Const`/etc).
+pub use rustc_middle::ty::relate::*;
+
+pub use self::_match::MatchAgainstFreshVars;
+pub use self::combine::CombineFields;
+pub use self::combine::ObligationEmittingRelation;
+
+pub mod _match;
pub(super) mod combine;
mod generalize;
mod glb;
@@ -8,15 +16,3 @@ mod higher_ranked;
mod lattice;
mod lub;
mod type_relating;
-
-/// Whether aliases should be related structurally or not. Used
-/// to adjust the behavior of generalization and combine.
-///
-/// This should always be `No` unless in a few special-cases when
-/// instantiating canonical responses and in the new solver. Each
-/// such case should have a comment explaining why it is used.
-#[derive(Debug, Copy, Clone)]
-pub enum StructurallyRelateAliases {
- Yes,
- No,
-}
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs
index e55a58788212..fd0bc9f44f75 100644
--- a/compiler/rustc_infer/src/infer/relate/type_relating.rs
+++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -1,12 +1,11 @@
use super::combine::CombineFields;
use crate::infer::BoundRegionConversionTime::HigherRankedType;
-use crate::infer::{
- DefineOpaqueTypes, ObligationEmittingRelation, StructurallyRelateAliases, SubregionOrigin,
-};
+use crate::infer::{DefineOpaqueTypes, SubregionOrigin};
use crate::traits::{Obligation, PredicateObligations};
-use rustc_middle::ty::relate::{
- relate_args_invariantly, relate_args_with_variances, Relate, RelateResult, TypeRelation,
+use super::{
+ relate_args_invariantly, relate_args_with_variances, ObligationEmittingRelation, Relate,
+ RelateResult, StructurallyRelateAliases, TypeRelation,
};
use rustc_middle::ty::TyVar;
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -29,7 +28,7 @@ impl<'combine, 'infcx, 'tcx> TypeRelating<'combine, 'infcx, 'tcx> {
}
}
-impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
+impl<'tcx> TypeRelation> for TypeRelating<'_, '_, 'tcx> {
fn tag(&self) -> &'static str {
"TypeRelating"
}
@@ -56,10 +55,10 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
}
}
- fn relate_with_variance>(
+ fn relate_with_variance>>(
&mut self,
variance: ty::Variance,
- _info: ty::VarianceDiagInfo<'tcx>,
+ _info: ty::VarianceDiagInfo>,
a: T,
b: T,
) -> RelateResult<'tcx, T> {
@@ -226,7 +225,7 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
b: ty::Binder<'tcx, T>,
) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
where
- T: Relate<'tcx>,
+ T: Relate>,
{
if a == b {
// Do nothing
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 87c433a5dc0b..8c9abeafacfe 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -51,7 +51,7 @@ use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_hir::intravisit::FnKind as HirFnKind;
-use rustc_hir::{Body, FnDecl, GenericParamKind, Node, PatKind, PredicateOrigin};
+use rustc_hir::{Body, FnDecl, GenericParamKind, PatKind, PredicateOrigin};
use rustc_middle::bug;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::layout::LayoutOf;
@@ -1423,11 +1423,20 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub {
self.perform_lint(cx, "item", foreign_item.owner_id.def_id, foreign_item.vis_span, true);
}
- fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
- if matches!(cx.tcx.parent_hir_node(field.hir_id), Node::Variant(_)) {
- return;
- }
- self.perform_lint(cx, "field", field.def_id, field.vis_span, false);
+ fn check_field_def(&mut self, _cx: &LateContext<'_>, _field: &hir::FieldDef<'_>) {
+ // - If an ADT definition is reported then we don't need to check fields
+ // (as it would add unnecessary complexity to the source code, the struct
+ // definition is in the immediate proximity to give the "real" visibility).
+ // - If an ADT is not reported because it's not `pub` - we don't need to
+ // check fields.
+ // - If an ADT is not reported because it's reachable - we also don't need
+ // to check fields because then they are reachable by construction if they
+ // are pub.
+ //
+ // Therefore in no case we check the fields.
+ //
+ // cf. https://github.com/rust-lang/rust/pull/126013#issuecomment-2152839205
+ // cf. https://github.com/rust-lang/rust/pull/126040#issuecomment-2152944506
}
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 44a3e9760e1e..ad283117d7e0 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -581,7 +581,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
self.tcx.crate_types().iter().all(|c| *c == CrateType::Rlib),
hash,
extra_filename,
- false, // is_host
path_kind,
);
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 73443de35538..90fe52a34385 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -222,7 +222,6 @@ use rustc_data_structures::owned_slice::slice_owned;
use rustc_data_structures::svh::Svh;
use rustc_errors::{DiagArgValue, IntoDiagArg};
use rustc_fs_util::try_canonicalize;
-use rustc_session::config;
use rustc_session::cstore::CrateSource;
use rustc_session::filesearch::FileSearch;
use rustc_session::search_paths::PathKind;
@@ -309,7 +308,6 @@ impl<'a> CrateLocator<'a> {
is_rlib: bool,
hash: Option,
extra_filename: Option<&'a str>,
- is_host: bool,
path_kind: PathKind,
) -> CrateLocator<'a> {
let needs_object_code = sess.opts.output_types.should_codegen();
@@ -340,17 +338,9 @@ impl<'a> CrateLocator<'a> {
},
hash,
extra_filename,
- target: if is_host { &sess.host } else { &sess.target },
- triple: if is_host {
- TargetTriple::from_triple(config::host_triple())
- } else {
- sess.opts.target_triple.clone()
- },
- filesearch: if is_host {
- sess.host_filesearch(path_kind)
- } else {
- sess.target_filesearch(path_kind)
- },
+ target: &sess.target,
+ triple: sess.opts.target_triple.clone(),
+ filesearch: sess.target_filesearch(path_kind),
is_proc_macro: false,
crate_rejections: CrateRejections::default(),
}
@@ -424,12 +414,18 @@ impl<'a> CrateLocator<'a> {
debug!("testing {}", spf.path.display());
let f = &spf.file_name_str;
- let (hash, kind) = if f.starts_with(rlib_prefix) && f.ends_with(rlib_suffix) {
- (&f[rlib_prefix.len()..(f.len() - rlib_suffix.len())], CrateFlavor::Rlib)
- } else if f.starts_with(rmeta_prefix) && f.ends_with(rmeta_suffix) {
- (&f[rmeta_prefix.len()..(f.len() - rmeta_suffix.len())], CrateFlavor::Rmeta)
- } else if f.starts_with(dylib_prefix) && f.ends_with(dylib_suffix.as_ref()) {
- (&f[dylib_prefix.len()..(f.len() - dylib_suffix.len())], CrateFlavor::Dylib)
+ let (hash, kind) = if let Some(f) = f.strip_prefix(rlib_prefix)
+ && let Some(f) = f.strip_suffix(rlib_suffix)
+ {
+ (f, CrateFlavor::Rlib)
+ } else if let Some(f) = f.strip_prefix(rmeta_prefix)
+ && let Some(f) = f.strip_suffix(rmeta_suffix)
+ {
+ (f, CrateFlavor::Rmeta)
+ } else if let Some(f) = f.strip_prefix(dylib_prefix)
+ && let Some(f) = f.strip_suffix(dylib_suffix.as_ref())
+ {
+ (f, CrateFlavor::Dylib)
} else {
if f.starts_with(staticlib_prefix) && f.ends_with(staticlib_suffix.as_ref()) {
self.crate_rejections.via_kind.push(CrateMismatch {
diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml
index ab0c598ea0c1..d1cdabc293dd 100644
--- a/compiler/rustc_middle/Cargo.toml
+++ b/compiler/rustc_middle/Cargo.toml
@@ -28,7 +28,6 @@ rustc_hir = { path = "../rustc_hir" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
-rustc_next_trait_solver = { path = "../rustc_next_trait_solver" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index bf6ab8000645..de786c38326f 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -62,7 +62,7 @@ macro_rules! arena_types {
[] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>,
[] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>,
[] canonical_goal_evaluation:
- rustc_next_trait_solver::solve::inspect::CanonicalGoalEvaluationStep<
+ rustc_type_ir::solve::inspect::CanonicalGoalEvaluationStep<
rustc_middle::ty::TyCtxt<'tcx>
>,
[] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>,
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 8a3bbf71eb61..305ba1ef3bbc 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -1,5 +1,3 @@
-use std::borrow::Cow;
-
use crate::hir::ModuleItems;
use crate::middle::debugger_visualizer::DebuggerVisualizerFile;
use crate::query::LocalCrate;
@@ -256,26 +254,13 @@ impl<'hir> Map<'hir> {
/// Given a `LocalDefId`, returns the `BodyId` associated with it,
/// if the node is a body owner, otherwise returns `None`.
- pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option>> {
- Some(match self.tcx.def_kind(id) {
- // Inline consts do not have bodies of their own, so create one to make the follow-up logic simpler.
- DefKind::InlineConst => {
- let e = self.expect_expr(self.tcx.local_def_id_to_hir_id(id));
- Cow::Owned(Body {
- params: &[],
- value: match e.kind {
- ExprKind::ConstBlock(body) => body,
- _ => span_bug!(e.span, "InlineConst was not a ConstBlock: {e:#?}"),
- },
- })
- }
- _ => Cow::Borrowed(self.body(self.tcx.hir_node_by_def_id(id).body_id()?)),
- })
+ pub fn maybe_body_owned_by(self, id: LocalDefId) -> Option<&'hir Body<'hir>> {
+ Some(self.body(self.tcx.hir_node_by_def_id(id).body_id()?))
}
/// Given a body owner's id, returns the `BodyId` associated with it.
#[track_caller]
- pub fn body_owned_by(self, id: LocalDefId) -> Cow<'hir, Body<'hir>> {
+ pub fn body_owned_by(self, id: LocalDefId) -> &'hir Body<'hir> {
self.maybe_body_owned_by(id).unwrap_or_else(|| {
let hir_id = self.tcx.local_def_id_to_hir_id(id);
span_bug!(
@@ -338,7 +323,7 @@ impl<'hir> Map<'hir> {
/// Returns an iterator of the `DefId`s for all body-owners in this
/// crate. If you would prefer to iterate over the bodies
- /// themselves, you can do `self.hir().krate().owners.iter()`.
+ /// themselves, you can do `self.hir().krate().body_ids.iter()`.
#[inline]
pub fn body_owners(self) -> impl Iterator
- + 'hir {
self.tcx.hir_crate_items(()).body_owners.iter().copied()
@@ -525,17 +510,7 @@ impl<'hir> Map<'hir> {
/// Whether the expression pointed at by `hir_id` belongs to a `const` evaluation context.
/// Used exclusively for diagnostics, to avoid suggestion function calls.
pub fn is_inside_const_context(self, hir_id: HirId) -> bool {
- for (_, node) in self.parent_iter(hir_id) {
- if let Some((def_id, _)) = node.associated_body() {
- return self.body_const_context(def_id).is_some();
- }
- if let Node::Expr(e) = node {
- if let ExprKind::ConstBlock(_) = e.kind {
- return true;
- }
- }
- }
- false
+ self.body_const_context(self.enclosing_body_owner(hir_id)).is_some()
}
/// Retrieves the `HirId` for `id`'s enclosing function *if* the `id` block or return is
@@ -918,6 +893,7 @@ impl<'hir> Map<'hir> {
Node::Variant(variant) => variant.span,
Node::Field(field) => field.span,
Node::AnonConst(constant) => constant.span,
+ Node::ConstBlock(constant) => self.body(constant.body).value.span,
Node::Expr(expr) => expr.span,
Node::ExprField(field) => field.span,
Node::Stmt(stmt) => stmt.span,
@@ -1187,6 +1163,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id))
}
Node::AnonConst(_) => node_str("const"),
+ Node::ConstBlock(_) => node_str("const"),
Node::Expr(_) => node_str("expr"),
Node::ExprField(_) => node_str("expr field"),
Node::Stmt(_) => node_str("stmt"),
@@ -1336,6 +1313,11 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> {
intravisit::walk_anon_const(self, c)
}
+ fn visit_inline_const(&mut self, c: &'hir ConstBlock) {
+ self.body_owners.push(c.def_id);
+ intravisit::walk_inline_const(self, c)
+ }
+
fn visit_expr(&mut self, ex: &'hir Expr<'hir>) {
if let ExprKind::Closure(closure) = ex.kind {
self.body_owners.push(closure.def_id);
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index c5c87c506b77..853572656879 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -196,6 +196,11 @@ impl Scalar {
Self::from_int(i, Size::from_bits(64))
}
+ #[inline]
+ pub fn from_i128(i: i128) -> Self {
+ Self::from_int(i, Size::from_bits(128))
+ }
+
#[inline]
pub fn from_target_isize(i: i64, cx: &impl HasDataLayout) -> Self {
Self::from_int(i, cx.data_layout().pointer_size)
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index a3d2140eb1b1..3d79ec0092f8 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -5,9 +5,9 @@ use rustc_data_structures::base_n::BaseNString;
use rustc_data_structures::base_n::ToBaseN;
use rustc_data_structures::base_n::CASE_INSENSITIVE;
use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
+use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher, ToStableHashKey};
+use rustc_data_structures::unord::UnordMap;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_hir::ItemId;
use rustc_index::Idx;
@@ -241,7 +241,17 @@ impl<'tcx> fmt::Display for MonoItem<'tcx> {
}
}
-#[derive(Debug)]
+impl ToStableHashKey> for MonoItem<'_> {
+ type KeyType = Fingerprint;
+
+ fn to_stable_hash_key(&self, hcx: &StableHashingContext<'_>) -> Self::KeyType {
+ let mut hasher = StableHasher::new();
+ self.hash_stable(&mut hcx.clone(), &mut hasher);
+ hasher.finish()
+ }
+}
+
+#[derive(Debug, HashStable)]
pub struct CodegenUnit<'tcx> {
/// A name for this CGU. Incremental compilation requires that
/// name be unique amongst **all** crates. Therefore, it should
@@ -430,38 +440,19 @@ impl<'tcx> CodegenUnit<'tcx> {
}
}
-impl<'a, 'tcx> HashStable> for CodegenUnit<'tcx> {
- fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
- let CodegenUnit {
- ref items,
- name,
- // The size estimate is not relevant to the hash
- size_estimate: _,
- primary: _,
- is_code_coverage_dead_code_cgu,
- } = *self;
+impl ToStableHashKey> for CodegenUnit<'_> {
+ type KeyType = String;
- name.hash_stable(hcx, hasher);
- is_code_coverage_dead_code_cgu.hash_stable(hcx, hasher);
-
- let mut items: Vec<(Fingerprint, _)> = items
- .iter()
- .map(|(mono_item, &attrs)| {
- let mut hasher = StableHasher::new();
- mono_item.hash_stable(hcx, &mut hasher);
- let mono_item_fingerprint = hasher.finish();
- (mono_item_fingerprint, attrs)
- })
- .collect();
-
- items.sort_unstable_by_key(|i| i.0);
- items.hash_stable(hcx, hasher);
+ fn to_stable_hash_key(&self, _: &StableHashingContext<'_>) -> Self::KeyType {
+ // Codegen unit names are conceptually required to be stable across
+ // compilation session so that object file names match up.
+ self.name.to_string()
}
}
pub struct CodegenUnitNameBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
- cache: FxHashMap,
+ cache: UnordMap,
}
impl<'tcx> CodegenUnitNameBuilder<'tcx> {
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 63678ab659df..202d587f0ad2 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -32,7 +32,7 @@ use std::hash::{Hash, Hasher};
pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
// FIXME: Remove this import and import via `solve::`
-pub use rustc_next_trait_solver::solve::BuiltinImplSource;
+pub use rustc_type_ir::solve::BuiltinImplSource;
/// Depending on the stage of compilation, we want projection to be
/// more or less conservative.
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index 66e50307733d..50b6c77e1b29 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -7,13 +7,12 @@
use crate::error::DropCheckOverflow;
use crate::infer::canonical::{Canonical, QueryResponse};
-use crate::ty::error::TypeError;
use crate::ty::GenericArg;
use crate::ty::{self, Ty, TyCtxt};
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
use rustc_span::Span;
// FIXME: Remove this import and import via `traits::solve`.
-pub use rustc_next_trait_solver::solve::NoSolution;
+pub use rustc_type_ir::solve::NoSolution;
pub mod type_op {
use crate::ty::fold::TypeFoldable;
@@ -91,12 +90,6 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize>>;
-impl<'tcx> From> for NoSolution {
- fn from(_: TypeError<'tcx>) -> NoSolution {
- NoSolution
- }
-}
-
#[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable)]
pub struct DropckOutlivesResult<'tcx> {
pub kinds: Vec>,
diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs
index c8c16ec1e2ce..0d9ce402c64e 100644
--- a/compiler/rustc_middle/src/traits/solve.rs
+++ b/compiler/rustc_middle/src/traits/solve.rs
@@ -1,8 +1,8 @@
use rustc_ast_ir::try_visit;
use rustc_data_structures::intern::Interned;
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
-use rustc_next_trait_solver as ir;
-pub use rustc_next_trait_solver::solve::*;
+use rustc_type_ir as ir;
+pub use rustc_type_ir::solve::*;
use crate::infer::canonical::QueryRegionConstraints;
use crate::ty::{
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index 5f9b870331c9..886dbd317afa 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -200,6 +200,12 @@ impl<'tcx> AdtDef<'tcx> {
}
}
+impl<'tcx> rustc_type_ir::inherent::AdtDef> for AdtDef<'tcx> {
+ fn def_id(self) -> DefId {
+ self.did()
+ }
+}
+
#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, TyEncodable, TyDecodable)]
pub enum AdtKind {
Struct,
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index dc13cc5437d5..cc1daeb64191 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -149,6 +149,10 @@ impl<'tcx> Const<'tcx> {
}
impl<'tcx> rustc_type_ir::inherent::Const> for Const<'tcx> {
+ fn try_to_target_usize(self, interner: TyCtxt<'tcx>) -> Option {
+ self.try_to_target_usize(interner)
+ }
+
fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst) -> Self {
Const::new_infer(tcx, infer)
}
@@ -168,6 +172,10 @@ impl<'tcx> rustc_type_ir::inherent::Const> for Const<'tcx> {
fn new_unevaluated(interner: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Self {
Const::new_unevaluated(interner, uv)
}
+
+ fn new_expr(interner: TyCtxt<'tcx>, expr: ty::Expr<'tcx>) -> Self {
+ Const::new_expr(interner, expr)
+ }
}
impl<'tcx> Const<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 6b35b1f2d13c..65d744239a6a 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -69,6 +69,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_target::abi::{FieldIdx, Layout, LayoutS, TargetDataLayout, VariantIdx};
use rustc_target::spec::abi;
+use rustc_type_ir::fold::TypeFoldable;
use rustc_type_ir::TyKind::*;
use rustc_type_ir::WithCachedTypeInfo;
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags};
@@ -135,9 +136,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type ParamEnv = ty::ParamEnv<'tcx>;
type Predicate = Predicate<'tcx>;
type Clause = Clause<'tcx>;
-
type Clauses = ty::Clauses<'tcx>;
+ fn expand_abstract_consts>>(self, t: T) -> T {
+ self.expand_abstract_consts(t)
+ }
+
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo]) -> Self::CanonicalVars {
self.mk_canonical_var_infos(infos)
}
@@ -148,6 +152,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.generics_of(def_id)
}
+ type VariancesOf = &'tcx [ty::Variance];
+
+ fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf {
+ self.variances_of(def_id)
+ }
+
fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
self.type_of(def_id)
}
@@ -205,7 +215,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.mk_args(args)
}
- fn mk_args_from_iter(self, args: impl Iterator
- ) -> Self::GenericArgs {
+ fn mk_args_from_iter(self, args: I) -> T::Output
+ where
+ I: Iterator
- ,
+ T: CollectAndApply,
+ {
self.mk_args_from_iter(args)
}
@@ -224,6 +238,14 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.arena.alloc(step)
}
+ fn mk_type_list_from_iter(self, args: I) -> T::Output
+ where
+ I: Iterator
- ,
+ T: CollectAndApply,
+ {
+ self.mk_type_list_from_iter(args)
+ }
+
fn parent(self, def_id: Self::DefId) -> Self::DefId {
self.parent(def_id)
}
@@ -231,6 +253,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
fn recursion_limit(self) -> usize {
self.recursion_limit().0
}
+
+ type Features = &'tcx rustc_feature::Features;
+
+ fn features(self) -> Self::Features {
+ self.features()
+ }
}
impl<'tcx> rustc_type_ir::inherent::Abi> for abi::Abi {
@@ -249,6 +277,12 @@ impl<'tcx> rustc_type_ir::inherent::Safety> for hir::Safety {
}
}
+impl<'tcx> rustc_type_ir::inherent::Features> for &'tcx rustc_feature::Features {
+ fn generic_const_exprs(self) -> bool {
+ self.generic_const_exprs
+ }
+}
+
type InternedSet<'tcx, T> = ShardedHashMap, ()>;
pub struct CtxtInterners<'tcx> {
@@ -740,7 +774,6 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
1,
),
bodies,
- has_inline_consts: false,
})));
self.feed_owner_id().hir_attrs(attrs);
}
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index 9e2c626478ac..32dc9fa5fc62 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -1,89 +1,26 @@
use crate::ty::print::{with_forced_trimmed_paths, FmtPrinter, PrettyPrinter};
-use crate::ty::{self, BoundRegionKind, Region, Ty, TyCtxt};
+use crate::ty::{self, Ty, TyCtxt};
+
use rustc_errors::pluralize;
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind};
-use rustc_hir::def_id::DefId;
-use rustc_macros::{TypeFoldable, TypeVisitable};
-use rustc_span::symbol::Symbol;
-use rustc_target::spec::abi;
+use rustc_macros::extension;
+pub use rustc_type_ir::error::ExpectedFound;
+
use std::borrow::Cow;
use std::hash::{DefaultHasher, Hash, Hasher};
use std::path::PathBuf;
-#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable)]
-pub struct ExpectedFound {
- pub expected: T,
- pub found: T,
-}
+pub type TypeError<'tcx> = rustc_type_ir::error::TypeError>;
-impl ExpectedFound {
- pub fn new(a_is_expected: bool, a: T, b: T) -> Self {
- if a_is_expected {
- ExpectedFound { expected: a, found: b }
- } else {
- ExpectedFound { expected: b, found: a }
- }
- }
-}
-
-// Data structures used in type unification
-#[derive(Copy, Clone, Debug, TypeVisitable, PartialEq, Eq)]
-#[rustc_pass_by_value]
-pub enum TypeError<'tcx> {
- Mismatch,
- ConstnessMismatch(ExpectedFound),
- PolarityMismatch(ExpectedFound),
- SafetyMismatch(ExpectedFound),
- AbiMismatch(ExpectedFound),
- Mutability,
- ArgumentMutability(usize),
- TupleSize(ExpectedFound),
- FixedArraySize(ExpectedFound),
- ArgCount,
- FieldMisMatch(Symbol, Symbol),
-
- RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>),
- RegionsInsufficientlyPolymorphic(BoundRegionKind, Region<'tcx>),
- RegionsPlaceholderMismatch,
-
- Sorts(ExpectedFound>),
- ArgumentSorts(ExpectedFound>, usize),
- Traits(ExpectedFound),
- VariadicMismatch(ExpectedFound),
-
- /// Instantiating a type variable with the given type would have
- /// created a cycle (because it appears somewhere within that
- /// type).
- CyclicTy(Ty<'tcx>),
- CyclicConst(ty::Const<'tcx>),
- ProjectionMismatched(ExpectedFound),
- ExistentialMismatch(ExpectedFound<&'tcx ty::List>>),
- ConstMismatch(ExpectedFound>),
-
- IntrinsicCast,
- /// Safe `#[target_feature]` functions are not assignable to safe function pointers.
- TargetFeatureCast(DefId),
-}
-
-impl TypeError<'_> {
- pub fn involves_regions(self) -> bool {
- match self {
- TypeError::RegionsDoesNotOutlive(_, _)
- | TypeError::RegionsInsufficientlyPolymorphic(_, _)
- | TypeError::RegionsPlaceholderMismatch => true,
- _ => false,
- }
- }
-}
-
-/// Explains the source of a type err in a short, human readable way. This is meant to be placed
-/// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
-/// afterwards to present additional details, particularly when it comes to lifetime-related
-/// errors.
+/// Explains the source of a type err in a short, human readable way.
+/// This is meant to be placed in parentheses after some larger message.
+/// You should also invoke `note_and_explain_type_err()` afterwards
+/// to present additional details, particularly when it comes to lifetime-
+/// related errors.
+#[extension(pub trait TypeErrorToStringExt<'tcx>)]
impl<'tcx> TypeError<'tcx> {
- pub fn to_string(self, tcx: TyCtxt<'tcx>) -> Cow<'static, str> {
- use self::TypeError::*;
+ fn to_string(self, tcx: TyCtxt<'tcx>) -> Cow<'static, str> {
fn report_maybe_different(expected: &str, found: &str) -> String {
// A naive approach to making sure that we're not reporting silly errors such as:
// (expected closure, found closure).
@@ -95,24 +32,26 @@ impl<'tcx> TypeError<'tcx> {
}
match self {
- CyclicTy(_) => "cyclic type of infinite size".into(),
- CyclicConst(_) => "encountered a self-referencing constant".into(),
- Mismatch => "types differ".into(),
- ConstnessMismatch(values) => {
+ TypeError::CyclicTy(_) => "cyclic type of infinite size".into(),
+ TypeError::CyclicConst(_) => "encountered a self-referencing constant".into(),
+ TypeError::Mismatch => "types differ".into(),
+ TypeError::ConstnessMismatch(values) => {
format!("expected {} bound, found {} bound", values.expected, values.found).into()
}
- PolarityMismatch(values) => {
+ TypeError::PolarityMismatch(values) => {
format!("expected {} polarity, found {} polarity", values.expected, values.found)
.into()
}
- SafetyMismatch(values) => {
+ TypeError::SafetyMismatch(values) => {
format!("expected {} fn, found {} fn", values.expected, values.found).into()
}
- AbiMismatch(values) => {
+ TypeError::AbiMismatch(values) => {
format!("expected {} fn, found {} fn", values.expected, values.found).into()
}
- ArgumentMutability(_) | Mutability => "types differ in mutability".into(),
- TupleSize(values) => format!(
+ TypeError::ArgumentMutability(_) | TypeError::Mutability => {
+ "types differ in mutability".into()
+ }
+ TypeError::TupleSize(values) => format!(
"expected a tuple with {} element{}, found one with {} element{}",
values.expected,
pluralize!(values.expected),
@@ -120,7 +59,7 @@ impl<'tcx> TypeError<'tcx> {
pluralize!(values.found)
)
.into(),
- FixedArraySize(values) => format!(
+ TypeError::FixedArraySize(values) => format!(
"expected an array with a fixed size of {} element{}, found one with {} element{}",
values.expected,
pluralize!(values.expected),
@@ -128,20 +67,21 @@ impl<'tcx> TypeError<'tcx> {
pluralize!(values.found)
)
.into(),
- ArgCount => "incorrect number of function parameters".into(),
- FieldMisMatch(adt, field) => format!("field type mismatch: {adt}.{field}").into(),
- RegionsDoesNotOutlive(..) => "lifetime mismatch".into(),
+ TypeError::ArgCount => "incorrect number of function parameters".into(),
+ TypeError::RegionsDoesNotOutlive(..) => "lifetime mismatch".into(),
// Actually naming the region here is a bit confusing because context is lacking
- RegionsInsufficientlyPolymorphic(..) => {
+ TypeError::RegionsInsufficientlyPolymorphic(..) => {
"one type is more general than the other".into()
}
- RegionsPlaceholderMismatch => "one type is more general than the other".into(),
- ArgumentSorts(values, _) | Sorts(values) => {
+ TypeError::RegionsPlaceholderMismatch => {
+ "one type is more general than the other".into()
+ }
+ TypeError::ArgumentSorts(values, _) | TypeError::Sorts(values) => {
let expected = values.expected.sort_string(tcx);
let found = values.found.sort_string(tcx);
report_maybe_different(&expected, &found).into()
}
- Traits(values) => {
+ TypeError::Traits(values) => {
let (mut expected, mut found) = with_forced_trimmed_paths!((
tcx.def_path_str(values.expected),
tcx.def_path_str(values.found),
@@ -153,59 +93,34 @@ impl<'tcx> TypeError<'tcx> {
report_maybe_different(&format!("trait `{expected}`"), &format!("trait `{found}`"))
.into()
}
- VariadicMismatch(ref values) => format!(
+ TypeError::VariadicMismatch(ref values) => format!(
"expected {} fn, found {} function",
if values.expected { "variadic" } else { "non-variadic" },
if values.found { "variadic" } else { "non-variadic" }
)
.into(),
- ProjectionMismatched(ref values) => format!(
+ TypeError::ProjectionMismatched(ref values) => format!(
"expected `{}`, found `{}`",
tcx.def_path_str(values.expected),
tcx.def_path_str(values.found)
)
.into(),
- ExistentialMismatch(ref values) => report_maybe_different(
+ TypeError::ExistentialMismatch(ref values) => report_maybe_different(
&format!("trait `{}`", values.expected),
&format!("trait `{}`", values.found),
)
.into(),
- ConstMismatch(ref values) => {
+ TypeError::ConstMismatch(ref values) => {
format!("expected `{}`, found `{}`", values.expected, values.found).into()
}
- IntrinsicCast => "cannot coerce intrinsics to function pointers".into(),
- TargetFeatureCast(_) => {
+ TypeError::IntrinsicCast => "cannot coerce intrinsics to function pointers".into(),
+ TypeError::TargetFeatureCast(_) => {
"cannot coerce functions with `#[target_feature]` to safe function pointers".into()
}
}
}
}
-impl<'tcx> TypeError<'tcx> {
- pub fn must_include_note(self) -> bool {
- use self::TypeError::*;
- match self {
- CyclicTy(_) | CyclicConst(_) | SafetyMismatch(_) | ConstnessMismatch(_)
- | PolarityMismatch(_) | Mismatch | AbiMismatch(_) | FixedArraySize(_)
- | ArgumentSorts(..) | Sorts(_) | VariadicMismatch(_) | TargetFeatureCast(_) => false,
-
- Mutability
- | ArgumentMutability(_)
- | TupleSize(_)
- | ArgCount
- | FieldMisMatch(..)
- | RegionsDoesNotOutlive(..)
- | RegionsInsufficientlyPolymorphic(..)
- | RegionsPlaceholderMismatch
- | Traits(_)
- | ProjectionMismatched(_)
- | ExistentialMismatch(_)
- | ConstMismatch(_)
- | IntrinsicCast => true,
- }
- }
-}
-
impl<'tcx> Ty<'tcx> {
pub fn sort_string(self, tcx: TyCtxt<'tcx>) -> Cow<'static, str> {
match *self.kind() {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index e0fbf127e708..7ff1b7998227 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -60,6 +60,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{ExpnId, ExpnKind, Span};
use rustc_target::abi::{Align, FieldIdx, Integer, IntegerType, VariantIdx};
pub use rustc_target::abi::{ReprFlags, ReprOptions};
+pub use rustc_type_ir::relate::VarianceDiagInfo;
pub use rustc_type_ir::{DebugWithInfcx, InferCtxtLike, WithInfcx};
use tracing::{debug, instrument};
pub use vtable::*;
@@ -114,7 +115,7 @@ pub use self::rvalue_scopes::RvalueScopes;
pub use self::sty::{
AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig,
CoroutineArgsExt, EarlyBinder, FnSig, InlineConstArgs, InlineConstArgsParts, ParamConst,
- ParamTy, PolyFnSig, TyKind, TypeAndMut, UpvarArgs, VarianceDiagInfo,
+ ParamTy, PolyFnSig, TyKind, TypeAndMut, UpvarArgs,
};
pub use self::trait_def::TraitDef;
pub use self::typeck_results::{
@@ -122,7 +123,6 @@ pub use self::typeck_results::{
TypeckResults, UserType, UserTypeAnnotationIndex,
};
-pub mod _match;
pub mod abstract_const;
pub mod adjustment;
pub mod cast;
@@ -313,38 +313,6 @@ impl Visibility {
}
}
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
-pub enum BoundConstness {
- /// `Type: Trait`
- NotConst,
- /// `Type: const Trait`
- Const,
- /// `Type: ~const Trait`
- ///
- /// Requires resolving to const only when we are in a const context.
- ConstIfConst,
-}
-
-impl BoundConstness {
- pub fn as_str(self) -> &'static str {
- match self {
- Self::NotConst => "",
- Self::Const => "const",
- Self::ConstIfConst => "~const",
- }
- }
-}
-
-impl fmt::Display for BoundConstness {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- Self::NotConst => f.write_str("normal"),
- Self::Const => f.write_str("const"),
- Self::ConstIfConst => f.write_str("~const"),
- }
- }
-}
-
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, TyEncodable, TyDecodable, HashStable)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ClosureSizeProfileData<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index e24e64b23013..b169d672a846 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -1,383 +1,54 @@
-//! Generalized type relating mechanism.
-//!
-//! A type relation `R` relates a pair of values `(A, B)`. `A and B` are usually
-//! types or regions but can be other things. Examples of type relations are
-//! subtyping, type equality, etc.
+use std::iter;
+
+use rustc_hir as hir;
+use rustc_target::spec::abi;
+pub use rustc_type_ir::relate::*;
use crate::ty::error::{ExpectedFound, TypeError};
-use crate::ty::{
- self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, GenericArg, GenericArgKind,
- GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable,
-};
-use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
-use rustc_macros::TypeVisitable;
-use rustc_target::spec::abi;
-use std::iter;
-use tracing::{debug, instrument};
+use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
+use crate::ty::{self as ty, Ty, TyCtxt};
-use super::Pattern;
+pub type RelateResult<'tcx, T> = rustc_type_ir::relate::RelateResult, T>;
-pub type RelateResult<'tcx, T> = Result>;
-
-pub trait TypeRelation<'tcx>: Sized {
- fn tcx(&self) -> TyCtxt<'tcx>;
-
- /// Returns a static string we can use for printouts.
- fn tag(&self) -> &'static str;
-
- /// Generic relation routine suitable for most anything.
- fn relate>(&mut self, a: T, b: T) -> RelateResult<'tcx, T> {
- Relate::relate(self, a, b)
- }
-
- /// Relate the two args for the given item. The default
- /// is to look up the variance for the item and proceed
- /// accordingly.
- fn relate_item_args(
- &mut self,
- item_def_id: DefId,
- a_arg: GenericArgsRef<'tcx>,
- b_arg: GenericArgsRef<'tcx>,
- ) -> RelateResult<'tcx, GenericArgsRef<'tcx>> {
- debug!(
- "relate_item_args(item_def_id={:?}, a_arg={:?}, b_arg={:?})",
- item_def_id, a_arg, b_arg
- );
-
- let tcx = self.tcx();
- let opt_variances = tcx.variances_of(item_def_id);
- relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true)
- }
-
- /// Switch variance for the purpose of relating `a` and `b`.
- fn relate_with_variance>(
- &mut self,
- variance: ty::Variance,
- info: ty::VarianceDiagInfo<'tcx>,
- a: T,
- b: T,
- ) -> RelateResult<'tcx, T>;
-
- // Overridable relations. You shouldn't typically call these
- // directly, instead call `relate()`, which in turn calls
- // these. This is both more uniform but also allows us to add
- // additional hooks for other types in the future if needed
- // without making older code, which called `relate`, obsolete.
-
- fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>>;
-
- fn regions(
- &mut self,
- a: ty::Region<'tcx>,
- b: ty::Region<'tcx>,
- ) -> RelateResult<'tcx, ty::Region<'tcx>>;
-
- fn consts(
- &mut self,
- a: ty::Const<'tcx>,
- b: ty::Const<'tcx>,
- ) -> RelateResult<'tcx, ty::Const<'tcx>>;
-
- fn binders(
- &mut self,
- a: ty::Binder<'tcx, T>,
- b: ty::Binder<'tcx, T>,
- ) -> RelateResult<'tcx, ty::Binder<'tcx, T>>
- where
- T: Relate<'tcx>;
+/// Whether aliases should be related structurally or not. Used
+/// to adjust the behavior of generalization and combine.
+///
+/// This should always be `No` unless in a few special-cases when
+/// instantiating canonical responses and in the new solver. Each
+/// such case should have a comment explaining why it is used.
+#[derive(Debug, Copy, Clone)]
+pub enum StructurallyRelateAliases {
+ Yes,
+ No,
}
-pub trait Relate<'tcx>: TypeFoldable> + PartialEq + Copy {
- fn relate>(
- relation: &mut R,
- a: Self,
- b: Self,
- ) -> RelateResult<'tcx, Self>;
-}
-
-///////////////////////////////////////////////////////////////////////////
-// Relate impls
-
-#[inline]
-pub fn relate_args_invariantly<'tcx, R: TypeRelation<'tcx>>(
- relation: &mut R,
- a_arg: GenericArgsRef<'tcx>,
- b_arg: GenericArgsRef<'tcx>,
-) -> RelateResult<'tcx, GenericArgsRef<'tcx>> {
- relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| {
- relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)
- }))
-}
-
-pub fn relate_args_with_variances<'tcx, R: TypeRelation<'tcx>>(
- relation: &mut R,
- ty_def_id: DefId,
- variances: &[ty::Variance],
- a_arg: GenericArgsRef<'tcx>,
- b_arg: GenericArgsRef<'tcx>,
- fetch_ty_for_diag: bool,
-) -> RelateResult<'tcx, GenericArgsRef<'tcx>> {
- let tcx = relation.tcx();
-
- let mut cached_ty = None;
- let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| {
- let variance = variances[i];
- let variance_info = if variance == ty::Invariant && fetch_ty_for_diag {
- let ty =
- *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, a_arg));
- ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
- } else {
- ty::VarianceDiagInfo::default()
- };
- relation.relate_with_variance(variance, variance_info, a, b)
- });
-
- tcx.mk_args_from_iter(params)
-}
-
-impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
- fn relate>(
- relation: &mut R,
- a: ty::FnSig<'tcx>,
- b: ty::FnSig<'tcx>,
- ) -> RelateResult<'tcx, ty::FnSig<'tcx>> {
- let tcx = relation.tcx();
-
- if a.c_variadic != b.c_variadic {
- return Err(TypeError::VariadicMismatch(expected_found(a.c_variadic, b.c_variadic)));
- }
- let safety = relation.relate(a.safety, b.safety)?;
- let abi = relation.relate(a.abi, b.abi)?;
-
- if a.inputs().len() != b.inputs().len() {
- return Err(TypeError::ArgCount);
- }
-
- let inputs_and_output = iter::zip(a.inputs(), b.inputs())
- .map(|(&a, &b)| ((a, b), false))
- .chain(iter::once(((a.output(), b.output()), true)))
- .map(|((a, b), is_output)| {
- if is_output {
- relation.relate(a, b)
- } else {
- relation.relate_with_variance(
- ty::Contravariant,
- ty::VarianceDiagInfo::default(),
- a,
- b,
- )
- }
- })
- .enumerate()
- .map(|(i, r)| match r {
- Err(TypeError::Sorts(exp_found) | TypeError::ArgumentSorts(exp_found, _)) => {
- Err(TypeError::ArgumentSorts(exp_found, i))
- }
- Err(TypeError::Mutability | TypeError::ArgumentMutability(_)) => {
- Err(TypeError::ArgumentMutability(i))
- }
- r => r,
- });
- Ok(ty::FnSig {
- inputs_and_output: tcx.mk_type_list_from_iter(inputs_and_output)?,
- c_variadic: a.c_variadic,
- safety,
- abi,
- })
- }
-}
-
-impl<'tcx> Relate<'tcx> for ty::BoundConstness {
- fn relate>(
- _relation: &mut R,
- a: ty::BoundConstness,
- b: ty::BoundConstness,
- ) -> RelateResult<'tcx, ty::BoundConstness> {
- if a != b { Err(TypeError::ConstnessMismatch(expected_found(a, b))) } else { Ok(a) }
- }
-}
-
-impl<'tcx> Relate<'tcx> for hir::Safety {
- fn relate>(
- _relation: &mut R,
- a: hir::Safety,
- b: hir::Safety,
- ) -> RelateResult<'tcx, hir::Safety> {
- if a != b { Err(TypeError::SafetyMismatch(expected_found(a, b))) } else { Ok(a) }
- }
-}
-
-impl<'tcx> Relate<'tcx> for abi::Abi {
- fn relate>(
- _relation: &mut R,
- a: abi::Abi,
- b: abi::Abi,
- ) -> RelateResult<'tcx, abi::Abi> {
- if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(expected_found(a, b))) }
- }
-}
-
-impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> {
- fn relate>(
- relation: &mut R,
- a: ty::AliasTy<'tcx>,
- b: ty::AliasTy<'tcx>,
- ) -> RelateResult<'tcx, ty::AliasTy<'tcx>> {
- if a.def_id != b.def_id {
- Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id)))
- } else {
- let args = match a.kind(relation.tcx()) {
- ty::Opaque => relate_args_with_variances(
- relation,
- a.def_id,
- relation.tcx().variances_of(a.def_id),
- a.args,
- b.args,
- false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
- )?,
- ty::Projection | ty::Weak | ty::Inherent => {
- relate_args_invariantly(relation, a.args, b.args)?
- }
- };
- Ok(ty::AliasTy::new(relation.tcx(), a.def_id, args))
- }
- }
-}
-
-impl<'tcx> Relate<'tcx> for ty::AliasTerm<'tcx> {
- fn relate>(
- relation: &mut R,
- a: ty::AliasTerm<'tcx>,
- b: ty::AliasTerm<'tcx>,
- ) -> RelateResult<'tcx, ty::AliasTerm<'tcx>> {
- if a.def_id != b.def_id {
- Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id)))
- } else {
- let args = match a.kind(relation.tcx()) {
- ty::AliasTermKind::OpaqueTy => relate_args_with_variances(
- relation,
- a.def_id,
- relation.tcx().variances_of(a.def_id),
- a.args,
- b.args,
- false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
- )?,
- ty::AliasTermKind::ProjectionTy
- | ty::AliasTermKind::WeakTy
- | ty::AliasTermKind::InherentTy
- | ty::AliasTermKind::UnevaluatedConst
- | ty::AliasTermKind::ProjectionConst => {
- relate_args_invariantly(relation, a.args, b.args)?
- }
- };
- Ok(ty::AliasTerm::new(relation.tcx(), a.def_id, args))
- }
- }
-}
-
-impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
- fn relate>(
- relation: &mut R,
- a: ty::ExistentialProjection<'tcx>,
- b: ty::ExistentialProjection<'tcx>,
- ) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> {
- if a.def_id != b.def_id {
- Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id)))
- } else {
- let term = relation.relate_with_variance(
- ty::Invariant,
- ty::VarianceDiagInfo::default(),
- a.term,
- b.term,
- )?;
- let args = relation.relate_with_variance(
- ty::Invariant,
- ty::VarianceDiagInfo::default(),
- a.args,
- b.args,
- )?;
- Ok(ty::ExistentialProjection { def_id: a.def_id, args, term })
- }
- }
-}
-
-impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
- fn relate>(
- relation: &mut R,
- a: ty::TraitRef<'tcx>,
- b: ty::TraitRef<'tcx>,
- ) -> RelateResult<'tcx, ty::TraitRef<'tcx>> {
- // Different traits cannot be related.
- if a.def_id != b.def_id {
- Err(TypeError::Traits(expected_found(a.def_id, b.def_id)))
- } else {
- let args = relate_args_invariantly(relation, a.args, b.args)?;
- Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args))
- }
- }
-}
-
-impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
- fn relate>(
- relation: &mut R,
- a: ty::ExistentialTraitRef<'tcx>,
- b: ty::ExistentialTraitRef<'tcx>,
- ) -> RelateResult<'tcx, ty::ExistentialTraitRef<'tcx>> {
- // Different traits cannot be related.
- if a.def_id != b.def_id {
- Err(TypeError::Traits(expected_found(a.def_id, b.def_id)))
- } else {
- let args = relate_args_invariantly(relation, a.args, b.args)?;
- Ok(ty::ExistentialTraitRef { def_id: a.def_id, args })
- }
- }
-}
-
-#[derive(PartialEq, Copy, Debug, Clone, TypeFoldable, TypeVisitable)]
-struct CoroutineWitness<'tcx>(&'tcx ty::List>);
-
-impl<'tcx> Relate<'tcx> for CoroutineWitness<'tcx> {
- fn relate>(
- relation: &mut R,
- a: CoroutineWitness<'tcx>,
- b: CoroutineWitness<'tcx>,
- ) -> RelateResult<'tcx, CoroutineWitness<'tcx>> {
- assert_eq!(a.0.len(), b.0.len());
- let tcx = relation.tcx();
- let types =
- tcx.mk_type_list_from_iter(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?;
- Ok(CoroutineWitness(types))
- }
-}
-
-impl<'tcx> Relate<'tcx> for ImplSubject<'tcx> {
+impl<'tcx> Relate> for ty::ImplSubject<'tcx> {
#[inline]
- fn relate>(
+ fn relate>>(
relation: &mut R,
- a: ImplSubject<'tcx>,
- b: ImplSubject<'tcx>,
- ) -> RelateResult<'tcx, ImplSubject<'tcx>> {
+ a: ty::ImplSubject<'tcx>,
+ b: ty::ImplSubject<'tcx>,
+ ) -> RelateResult<'tcx, ty::ImplSubject<'tcx>> {
match (a, b) {
- (ImplSubject::Trait(trait_ref_a), ImplSubject::Trait(trait_ref_b)) => {
+ (ty::ImplSubject::Trait(trait_ref_a), ty::ImplSubject::Trait(trait_ref_b)) => {
let trait_ref = ty::TraitRef::relate(relation, trait_ref_a, trait_ref_b)?;
- Ok(ImplSubject::Trait(trait_ref))
+ Ok(ty::ImplSubject::Trait(trait_ref))
}
- (ImplSubject::Inherent(ty_a), ImplSubject::Inherent(ty_b)) => {
+ (ty::ImplSubject::Inherent(ty_a), ty::ImplSubject::Inherent(ty_b)) => {
let ty = Ty::relate(relation, ty_a, ty_b)?;
- Ok(ImplSubject::Inherent(ty))
+ Ok(ty::ImplSubject::Inherent(ty))
}
- (ImplSubject::Trait(_), ImplSubject::Inherent(_))
- | (ImplSubject::Inherent(_), ImplSubject::Trait(_)) => {
+ (ty::ImplSubject::Trait(_), ty::ImplSubject::Inherent(_))
+ | (ty::ImplSubject::Inherent(_), ty::ImplSubject::Trait(_)) => {
bug!("can not relate TraitRef and Ty");
}
}
}
}
-impl<'tcx> Relate<'tcx> for Ty<'tcx> {
+impl<'tcx> Relate> for Ty<'tcx> {
#[inline]
- fn relate>(
+ fn relate>>(
relation: &mut R,
a: Ty<'tcx>,
b: Ty<'tcx>,
@@ -386,9 +57,9 @@ impl<'tcx> Relate<'tcx> for Ty<'tcx> {
}
}
-impl<'tcx> Relate<'tcx> for Pattern<'tcx> {
+impl<'tcx> Relate> for ty::Pattern<'tcx> {
#[inline]
- fn relate>(
+ fn relate>>(
relation: &mut R,
a: Self,
b: Self,
@@ -416,276 +87,8 @@ impl<'tcx> Relate<'tcx> for Pattern<'tcx> {
}
}
-/// Relates `a` and `b` structurally, calling the relation for all nested values.
-/// Any semantic equality, e.g. of projections, and inference variables have to be
-/// handled by the caller.
-#[instrument(level = "trace", skip(relation), ret)]
-pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
- relation: &mut R,
- a: Ty<'tcx>,
- b: Ty<'tcx>,
-) -> RelateResult<'tcx, Ty<'tcx>> {
- let tcx = relation.tcx();
- match (a.kind(), b.kind()) {
- (&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
- // The caller should handle these cases!
- bug!("var types encountered in structurally_relate_tys")
- }
-
- (ty::Bound(..), _) | (_, ty::Bound(..)) => {
- bug!("bound types encountered in structurally_relate_tys")
- }
-
- (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(tcx, guar)),
-
- (&ty::Never, _)
- | (&ty::Char, _)
- | (&ty::Bool, _)
- | (&ty::Int(_), _)
- | (&ty::Uint(_), _)
- | (&ty::Float(_), _)
- | (&ty::Str, _)
- if a == b =>
- {
- Ok(a)
- }
-
- (ty::Param(a_p), ty::Param(b_p)) if a_p.index == b_p.index => {
- debug_assert_eq!(a_p.name, b_p.name, "param types with same index differ in name");
- Ok(a)
- }
-
- (ty::Placeholder(p1), ty::Placeholder(p2)) if p1 == p2 => Ok(a),
-
- (&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args)) if a_def == b_def => {
- let args = relation.relate_item_args(a_def.did(), a_args, b_args)?;
- Ok(Ty::new_adt(tcx, a_def, args))
- }
-
- (&ty::Foreign(a_id), &ty::Foreign(b_id)) if a_id == b_id => Ok(Ty::new_foreign(tcx, a_id)),
-
- (&ty::Dynamic(a_obj, a_region, a_repr), &ty::Dynamic(b_obj, b_region, b_repr))
- if a_repr == b_repr =>
- {
- Ok(Ty::new_dynamic(
- tcx,
- relation.relate(a_obj, b_obj)?,
- relation.relate(a_region, b_region)?,
- a_repr,
- ))
- }
-
- (&ty::Coroutine(a_id, a_args), &ty::Coroutine(b_id, b_args)) if a_id == b_id => {
- // All Coroutine types with the same id represent
- // the (anonymous) type of the same coroutine expression. So
- // all of their regions should be equated.
- let args = relate_args_invariantly(relation, a_args, b_args)?;
- Ok(Ty::new_coroutine(tcx, a_id, args))
- }
-
- (&ty::CoroutineWitness(a_id, a_args), &ty::CoroutineWitness(b_id, b_args))
- if a_id == b_id =>
- {
- // All CoroutineWitness types with the same id represent
- // the (anonymous) type of the same coroutine expression. So
- // all of their regions should be equated.
- let args = relate_args_invariantly(relation, a_args, b_args)?;
- Ok(Ty::new_coroutine_witness(tcx, a_id, args))
- }
-
- (&ty::Closure(a_id, a_args), &ty::Closure(b_id, b_args)) if a_id == b_id => {
- // All Closure types with the same id represent
- // the (anonymous) type of the same closure expression. So
- // all of their regions should be equated.
- let args = relate_args_invariantly(relation, a_args, b_args)?;
- Ok(Ty::new_closure(tcx, a_id, args))
- }
-
- (&ty::CoroutineClosure(a_id, a_args), &ty::CoroutineClosure(b_id, b_args))
- if a_id == b_id =>
- {
- let args = relate_args_invariantly(relation, a_args, b_args)?;
- Ok(Ty::new_coroutine_closure(tcx, a_id, args))
- }
-
- (&ty::RawPtr(a_ty, a_mutbl), &ty::RawPtr(b_ty, b_mutbl)) => {
- if a_mutbl != b_mutbl {
- return Err(TypeError::Mutability);
- }
-
- let (variance, info) = match a_mutbl {
- hir::Mutability::Not => (ty::Covariant, ty::VarianceDiagInfo::None),
- hir::Mutability::Mut => {
- (ty::Invariant, ty::VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
- }
- };
-
- let ty = relation.relate_with_variance(variance, info, a_ty, b_ty)?;
-
- Ok(Ty::new_ptr(tcx, ty, a_mutbl))
- }
-
- (&ty::Ref(a_r, a_ty, a_mutbl), &ty::Ref(b_r, b_ty, b_mutbl)) => {
- if a_mutbl != b_mutbl {
- return Err(TypeError::Mutability);
- }
-
- let (variance, info) = match a_mutbl {
- hir::Mutability::Not => (ty::Covariant, ty::VarianceDiagInfo::None),
- hir::Mutability::Mut => {
- (ty::Invariant, ty::VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
- }
- };
-
- let r = relation.relate(a_r, b_r)?;
- let ty = relation.relate_with_variance(variance, info, a_ty, b_ty)?;
-
- Ok(Ty::new_ref(tcx, r, ty, a_mutbl))
- }
-
- (&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) => {
- let t = relation.relate(a_t, b_t)?;
- match relation.relate(sz_a, sz_b) {
- Ok(sz) => Ok(Ty::new_array_with_const_len(tcx, t, sz)),
- Err(err) => {
- // Check whether the lengths are both concrete/known values,
- // but are unequal, for better diagnostics.
- let sz_a = sz_a.try_to_target_usize(tcx);
- let sz_b = sz_b.try_to_target_usize(tcx);
-
- match (sz_a, sz_b) {
- (Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => {
- Err(TypeError::FixedArraySize(expected_found(sz_a_val, sz_b_val)))
- }
- _ => Err(err),
- }
- }
- }
- }
-
- (&ty::Slice(a_t), &ty::Slice(b_t)) => {
- let t = relation.relate(a_t, b_t)?;
- Ok(Ty::new_slice(tcx, t))
- }
-
- (&ty::Tuple(as_), &ty::Tuple(bs)) => {
- if as_.len() == bs.len() {
- Ok(Ty::new_tup_from_iter(
- tcx,
- iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)),
- )?)
- } else if !(as_.is_empty() || bs.is_empty()) {
- Err(TypeError::TupleSize(expected_found(as_.len(), bs.len())))
- } else {
- Err(TypeError::Sorts(expected_found(a, b)))
- }
- }
-
- (&ty::FnDef(a_def_id, a_args), &ty::FnDef(b_def_id, b_args)) if a_def_id == b_def_id => {
- let args = relation.relate_item_args(a_def_id, a_args, b_args)?;
- Ok(Ty::new_fn_def(tcx, a_def_id, args))
- }
-
- (&ty::FnPtr(a_fty), &ty::FnPtr(b_fty)) => {
- let fty = relation.relate(a_fty, b_fty)?;
- Ok(Ty::new_fn_ptr(tcx, fty))
- }
-
- // Alias tend to mostly already be handled downstream due to normalization.
- (&ty::Alias(a_kind, a_data), &ty::Alias(b_kind, b_data)) => {
- let alias_ty = relation.relate(a_data, b_data)?;
- assert_eq!(a_kind, b_kind);
- Ok(Ty::new_alias(tcx, a_kind, alias_ty))
- }
-
- (&ty::Pat(a_ty, a_pat), &ty::Pat(b_ty, b_pat)) => {
- let ty = relation.relate(a_ty, b_ty)?;
- let pat = relation.relate(a_pat, b_pat)?;
- Ok(Ty::new_pat(tcx, ty, pat))
- }
-
- _ => Err(TypeError::Sorts(expected_found(a, b))),
- }
-}
-
-/// Relates `a` and `b` structurally, calling the relation for all nested values.
-/// Any semantic equality, e.g. of unevaluated consts, and inference variables have
-/// to be handled by the caller.
-///
-/// FIXME: This is not totally structual, which probably should be fixed.
-/// See the HACKs below.
-pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
- relation: &mut R,
- mut a: ty::Const<'tcx>,
- mut b: ty::Const<'tcx>,
-) -> RelateResult<'tcx, ty::Const<'tcx>> {
- debug!("{}.structurally_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
- let tcx = relation.tcx();
-
- if tcx.features().generic_const_exprs {
- a = tcx.expand_abstract_consts(a);
- b = tcx.expand_abstract_consts(b);
- }
-
- debug!("{}.structurally_relate_consts(normed_a = {:?}, normed_b = {:?})", relation.tag(), a, b);
-
- // Currently, the values that can be unified are primitive types,
- // and those that derive both `PartialEq` and `Eq`, corresponding
- // to structural-match types.
- let is_match = match (a.kind(), b.kind()) {
- (ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
- // The caller should handle these cases!
- bug!("var types encountered in structurally_relate_consts: {:?} {:?}", a, b)
- }
-
- (ty::ConstKind::Error(_), _) => return Ok(a),
- (_, ty::ConstKind::Error(_)) => return Ok(b),
-
- (ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index == b_p.index => {
- debug_assert_eq!(a_p.name, b_p.name, "param types with same index differ in name");
- true
- }
- (ty::ConstKind::Placeholder(p1), ty::ConstKind::Placeholder(p2)) => p1 == p2,
- (ty::ConstKind::Value(_, a_val), ty::ConstKind::Value(_, b_val)) => a_val == b_val,
-
- // While this is slightly incorrect, it shouldn't matter for `min_const_generics`
- // and is the better alternative to waiting until `generic_const_exprs` can
- // be stabilized.
- (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => {
- if cfg!(debug_assertions) {
- let a_ty = tcx.type_of(au.def).instantiate(tcx, au.args);
- let b_ty = tcx.type_of(bu.def).instantiate(tcx, bu.args);
- assert_eq!(a_ty, b_ty);
- }
-
- let args = relation.relate_with_variance(
- ty::Variance::Invariant,
- ty::VarianceDiagInfo::default(),
- au.args,
- bu.args,
- )?;
- return Ok(ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst { def: au.def, args }));
- }
- (ty::ConstKind::Expr(ae), ty::ConstKind::Expr(be)) => {
- match (ae.kind, be.kind) {
- (ty::ExprKind::Binop(a_binop), ty::ExprKind::Binop(b_binop))
- if a_binop == b_binop => {}
- (ty::ExprKind::UnOp(a_unop), ty::ExprKind::UnOp(b_unop)) if a_unop == b_unop => {}
- (ty::ExprKind::FunctionCall, ty::ExprKind::FunctionCall) => {}
- (ty::ExprKind::Cast(a_kind), ty::ExprKind::Cast(b_kind)) if a_kind == b_kind => {}
- _ => return Err(TypeError::ConstMismatch(expected_found(a, b))),
- }
-
- let args = relation.relate(ae.args(), be.args())?;
- return Ok(ty::Const::new_expr(tcx, ty::Expr::new(ae.kind, args)));
- }
- _ => false,
- };
- if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(a, b))) }
-}
-
-impl<'tcx> Relate<'tcx> for &'tcx ty::List> {
- fn relate>(
+impl<'tcx> Relate> for &'tcx ty::List> {
+ fn relate>>(
relation: &mut R,
a: Self,
b: Self,
@@ -703,44 +106,65 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> {
b_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
b_v.dedup();
if a_v.len() != b_v.len() {
- return Err(TypeError::ExistentialMismatch(expected_found(a, b)));
+ return Err(TypeError::ExistentialMismatch(ExpectedFound::new(true, a, b)));
}
let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| {
match (ep_a.skip_binder(), ep_b.skip_binder()) {
- (ExistentialPredicate::Trait(a), ExistentialPredicate::Trait(b)) => Ok(ep_a
- .rebind(ExistentialPredicate::Trait(
- relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
- ))),
- (ExistentialPredicate::Projection(a), ExistentialPredicate::Projection(b)) => {
- Ok(ep_a.rebind(ExistentialPredicate::Projection(
+ (ty::ExistentialPredicate::Trait(a), ty::ExistentialPredicate::Trait(b)) => {
+ Ok(ep_a.rebind(ty::ExistentialPredicate::Trait(
relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
)))
}
- (ExistentialPredicate::AutoTrait(a), ExistentialPredicate::AutoTrait(b))
- if a == b =>
- {
- Ok(ep_a.rebind(ExistentialPredicate::AutoTrait(a)))
- }
- _ => Err(TypeError::ExistentialMismatch(expected_found(a, b))),
+ (
+ ty::ExistentialPredicate::Projection(a),
+ ty::ExistentialPredicate::Projection(b),
+ ) => Ok(ep_a.rebind(ty::ExistentialPredicate::Projection(
+ relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
+ ))),
+ (
+ ty::ExistentialPredicate::AutoTrait(a),
+ ty::ExistentialPredicate::AutoTrait(b),
+ ) if a == b => Ok(ep_a.rebind(ty::ExistentialPredicate::AutoTrait(a))),
+ _ => Err(TypeError::ExistentialMismatch(ExpectedFound::new(true, a, b))),
}
});
tcx.mk_poly_existential_predicates_from_iter(v)
}
}
-impl<'tcx> Relate<'tcx> for GenericArgsRef<'tcx> {
- fn relate>(
+impl<'tcx> Relate> for hir::Safety {
+ fn relate>>(
+ _relation: &mut R,
+ a: hir::Safety,
+ b: hir::Safety,
+ ) -> RelateResult<'tcx, hir::Safety> {
+ if a != b { Err(TypeError::SafetyMismatch(ExpectedFound::new(true, a, b))) } else { Ok(a) }
+ }
+}
+
+impl<'tcx> Relate> for abi::Abi {
+ fn relate>>(
+ _relation: &mut R,
+ a: abi::Abi,
+ b: abi::Abi,
+ ) -> RelateResult<'tcx, abi::Abi> {
+ if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(ExpectedFound::new(true, a, b))) }
+ }
+}
+
+impl<'tcx> Relate> for ty::GenericArgsRef<'tcx> {
+ fn relate>>(
relation: &mut R,
- a: GenericArgsRef<'tcx>,
- b: GenericArgsRef<'tcx>,
- ) -> RelateResult<'tcx, GenericArgsRef<'tcx>> {
+ a: ty::GenericArgsRef<'tcx>,
+ b: ty::GenericArgsRef<'tcx>,
+ ) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> {
relate_args_invariantly(relation, a, b)
}
}
-impl<'tcx> Relate<'tcx> for ty::Region<'tcx> {
- fn relate>(
+impl<'tcx> Relate> for ty::Region<'tcx> {
+ fn relate>>(
relation: &mut R,
a: ty::Region<'tcx>,
b: ty::Region<'tcx>,
@@ -749,8 +173,8 @@ impl<'tcx> Relate<'tcx> for ty::Region<'tcx> {
}
}
-impl<'tcx> Relate<'tcx> for ty::Const<'tcx> {
- fn relate>(
+impl<'tcx> Relate> for ty::Const<'tcx> {
+ fn relate>>(
relation: &mut R,
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
@@ -759,85 +183,70 @@ impl<'tcx> Relate<'tcx> for ty::Const<'tcx> {
}
}
-impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for ty::Binder<'tcx, T> {
- fn relate>(
+impl<'tcx> Relate> for ty::Expr<'tcx> {
+ fn relate>>(
relation: &mut R,
- a: ty::Binder<'tcx, T>,
- b: ty::Binder<'tcx, T>,
- ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> {
- relation.binders(a, b)
+ ae: ty::Expr<'tcx>,
+ be: ty::Expr<'tcx>,
+ ) -> RelateResult<'tcx, ty::Expr<'tcx>> {
+ // FIXME(generic_const_exprs): is it possible to relate two consts which are not identical
+ // exprs? Should we care about that?
+ // FIXME(generic_const_exprs): relating the `ty()`s is a little weird since it is supposed to
+ // ICE If they mismatch. Unfortunately `ConstKind::Expr` is a little special and can be thought
+ // of as being generic over the argument types, however this is implicit so these types don't get
+ // related when we relate the args of the item this const arg is for.
+ match (ae.kind, be.kind) {
+ (ty::ExprKind::Binop(a_binop), ty::ExprKind::Binop(b_binop)) if a_binop == b_binop => {}
+ (ty::ExprKind::UnOp(a_unop), ty::ExprKind::UnOp(b_unop)) if a_unop == b_unop => {}
+ (ty::ExprKind::FunctionCall, ty::ExprKind::FunctionCall) => {}
+ (ty::ExprKind::Cast(a_kind), ty::ExprKind::Cast(b_kind)) if a_kind == b_kind => {}
+ _ => return Err(TypeError::Mismatch),
+ }
+
+ let args = relation.relate(ae.args(), be.args())?;
+ Ok(ty::Expr::new(ae.kind, args))
}
}
-impl<'tcx> Relate<'tcx> for GenericArg<'tcx> {
- fn relate>(
+impl<'tcx> Relate> for ty::GenericArg<'tcx> {
+ fn relate>>(
relation: &mut R,
- a: GenericArg<'tcx>,
- b: GenericArg<'tcx>,
- ) -> RelateResult<'tcx, GenericArg<'tcx>> {
+ a: ty::GenericArg<'tcx>,
+ b: ty::GenericArg<'tcx>,
+ ) -> RelateResult<'tcx, ty::GenericArg<'tcx>> {
match (a.unpack(), b.unpack()) {
- (GenericArgKind::Lifetime(a_lt), GenericArgKind::Lifetime(b_lt)) => {
+ (ty::GenericArgKind::Lifetime(a_lt), ty::GenericArgKind::Lifetime(b_lt)) => {
Ok(relation.relate(a_lt, b_lt)?.into())
}
- (GenericArgKind::Type(a_ty), GenericArgKind::Type(b_ty)) => {
+ (ty::GenericArgKind::Type(a_ty), ty::GenericArgKind::Type(b_ty)) => {
Ok(relation.relate(a_ty, b_ty)?.into())
}
- (GenericArgKind::Const(a_ct), GenericArgKind::Const(b_ct)) => {
+ (ty::GenericArgKind::Const(a_ct), ty::GenericArgKind::Const(b_ct)) => {
Ok(relation.relate(a_ct, b_ct)?.into())
}
- (GenericArgKind::Lifetime(unpacked), x) => {
+ (ty::GenericArgKind::Lifetime(unpacked), x) => {
bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
}
- (GenericArgKind::Type(unpacked), x) => {
+ (ty::GenericArgKind::Type(unpacked), x) => {
bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
}
- (GenericArgKind::Const(unpacked), x) => {
+ (ty::GenericArgKind::Const(unpacked), x) => {
bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
}
}
}
}
-impl<'tcx> Relate<'tcx> for ty::PredicatePolarity {
- fn relate>(
- _relation: &mut R,
- a: ty::PredicatePolarity,
- b: ty::PredicatePolarity,
- ) -> RelateResult<'tcx, ty::PredicatePolarity> {
- if a != b { Err(TypeError::PolarityMismatch(expected_found(a, b))) } else { Ok(a) }
- }
-}
-
-impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
- fn relate>(
- relation: &mut R,
- a: ty::TraitPredicate<'tcx>,
- b: ty::TraitPredicate<'tcx>,
- ) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> {
- Ok(ty::TraitPredicate {
- trait_ref: relation.relate(a.trait_ref, b.trait_ref)?,
- polarity: relation.relate(a.polarity, b.polarity)?,
- })
- }
-}
-
-impl<'tcx> Relate<'tcx> for Term<'tcx> {
- fn relate>(
+impl<'tcx> Relate> for ty::Term<'tcx> {
+ fn relate>>(
relation: &mut R,
a: Self,
b: Self,
) -> RelateResult<'tcx, Self> {
Ok(match (a.unpack(), b.unpack()) {
- (TermKind::Ty(a), TermKind::Ty(b)) => relation.relate(a, b)?.into(),
- (TermKind::Const(a), TermKind::Const(b)) => relation.relate(a, b)?.into(),
+ (ty::TermKind::Ty(a), ty::TermKind::Ty(b)) => relation.relate(a, b)?.into(),
+ (ty::TermKind::Const(a), ty::TermKind::Const(b)) => relation.relate(a, b)?.into(),
_ => return Err(TypeError::Mismatch),
})
}
}
-
-///////////////////////////////////////////////////////////////////////////
-// Error handling
-
-pub fn expected_found(a: T, b: T) -> ExpectedFound {
- ExpectedFound::new(true, a, b)
-}
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index cf4854d13646..cc6b1d57f870 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -296,7 +296,6 @@ TrivialTypeTraversalImpls! {
::rustc_target::abi::FieldIdx,
::rustc_target::abi::VariantIdx,
crate::middle::region::Scope,
- crate::ty::FloatTy,
::rustc_ast::InlineAsmOptions,
::rustc_ast::InlineAsmTemplatePiece,
::rustc_ast::NodeId,
@@ -316,7 +315,7 @@ TrivialTypeTraversalImpls! {
crate::traits::Reveal,
crate::ty::adjustment::AutoBorrowMutability,
crate::ty::AdtKind,
- crate::ty::BoundConstness,
+ crate::ty::BoundRegion,
// Including `BoundRegionKind` is a *bit* dubious, but direct
// references to bound region appear in `ty::Error`, and aren't
// really meant to be folded. In general, we can only fold a fully
@@ -324,16 +323,11 @@ TrivialTypeTraversalImpls! {
crate::ty::BoundRegionKind,
crate::ty::AssocItem,
crate::ty::AssocKind,
- crate::ty::AliasTyKind,
crate::ty::Placeholder,
crate::ty::Placeholder,
crate::ty::Placeholder,
crate::ty::LateParamRegion,
- crate::ty::InferTy,
- crate::ty::IntVarValue,
crate::ty::adjustment::PointerCoercion,
- crate::ty::RegionVid,
- crate::ty::Variance,
::rustc_span::Span,
::rustc_span::symbol::Ident,
::rustc_errors::ErrorGuaranteed,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index c83f6b0b9ec6..ba9ed0d5b70a 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -810,6 +810,31 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> {
Ty::new_alias(interner, kind, alias_ty)
}
+ fn new_error(interner: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
+ Ty::new_error(interner, guar)
+ }
+
+ fn new_adt(
+ interner: TyCtxt<'tcx>,
+ adt_def: ty::AdtDef<'tcx>,
+ args: ty::GenericArgsRef<'tcx>,
+ ) -> Self {
+ Ty::new_adt(interner, adt_def, args)
+ }
+
+ fn new_foreign(interner: TyCtxt<'tcx>, def_id: DefId) -> Self {
+ Ty::new_foreign(interner, def_id)
+ }
+
+ fn new_dynamic(
+ interner: TyCtxt<'tcx>,
+ preds: &'tcx List>,
+ region: ty::Region<'tcx>,
+ kind: ty::DynKind,
+ ) -> Self {
+ Ty::new_dynamic(interner, preds, region, kind)
+ }
+
fn new_coroutine(
interner: TyCtxt<'tcx>,
def_id: DefId,
@@ -818,6 +843,51 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> {
Ty::new_coroutine(interner, def_id, args)
}
+ fn new_coroutine_closure(
+ interner: TyCtxt<'tcx>,
+ def_id: DefId,
+ args: ty::GenericArgsRef<'tcx>,
+ ) -> Self {
+ Ty::new_coroutine_closure(interner, def_id, args)
+ }
+
+ fn new_closure(interner: TyCtxt<'tcx>, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> Self {
+ Ty::new_closure(interner, def_id, args)
+ }
+
+ fn new_coroutine_witness(
+ interner: TyCtxt<'tcx>,
+ def_id: DefId,
+ args: ty::GenericArgsRef<'tcx>,
+ ) -> Self {
+ Ty::new_coroutine_witness(interner, def_id, args)
+ }
+
+ fn new_ptr(interner: TyCtxt<'tcx>, ty: Self, mutbl: hir::Mutability) -> Self {
+ Ty::new_ptr(interner, ty, mutbl)
+ }
+
+ fn new_ref(
+ interner: TyCtxt<'tcx>,
+ region: ty::Region<'tcx>,
+ ty: Self,
+ mutbl: hir::Mutability,
+ ) -> Self {
+ Ty::new_ref(interner, region, ty, mutbl)
+ }
+
+ fn new_array_with_const_len(interner: TyCtxt<'tcx>, ty: Self, len: ty::Const<'tcx>) -> Self {
+ Ty::new_array_with_const_len(interner, ty, len)
+ }
+
+ fn new_slice(interner: TyCtxt<'tcx>, ty: Self) -> Self {
+ Ty::new_slice(interner, ty)
+ }
+
+ fn new_tup(interner: TyCtxt<'tcx>, tys: &[Ty<'tcx>]) -> Self {
+ Ty::new_tup(interner, tys)
+ }
+
fn new_tup_from_iter(interner: TyCtxt<'tcx>, iter: It) -> T::Output
where
It: Iterator
- ,
@@ -844,6 +914,18 @@ impl<'tcx> rustc_type_ir::inherent::Ty> for Ty<'tcx> {
) -> Self {
Ty::from_coroutine_closure_kind(interner, kind)
}
+
+ fn new_fn_def(interner: TyCtxt<'tcx>, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> Self {
+ Ty::new_fn_def(interner, def_id, args)
+ }
+
+ fn new_fn_ptr(interner: TyCtxt<'tcx>, sig: ty::Binder<'tcx, ty::FnSig<'tcx>>) -> Self {
+ Ty::new_fn_ptr(interner, sig)
+ }
+
+ fn new_pat(interner: TyCtxt<'tcx>, ty: Self, pat: ty::Pattern<'tcx>) -> Self {
+ Ty::new_pat(interner, ty, pat)
+ }
}
/// Type utilities
@@ -1812,43 +1894,6 @@ impl<'tcx> rustc_type_ir::inherent::Tys> for &'tcx ty::List {
- /// No additional information - this is the default.
- /// We will not add any additional information to error messages.
- #[default]
- None,
- /// We switched our variance because a generic argument occurs inside
- /// the invariant generic argument of another type.
- Invariant {
- /// The generic type containing the generic parameter
- /// that changes the variance (e.g. `*mut T`, `MyStruct`)
- ty: Ty<'tcx>,
- /// The index of the generic parameter being used
- /// (e.g. `0` for `*mut T`, `1` for `MyStruct<'CovariantParam, 'InvariantParam>`)
- param_index: u32,
- },
-}
-
-impl<'tcx> VarianceDiagInfo<'tcx> {
- /// Mirrors `Variance::xform` - used to 'combine' the existing
- /// and new `VarianceDiagInfo`s when our variance changes.
- pub fn xform(self, other: VarianceDiagInfo<'tcx>) -> VarianceDiagInfo<'tcx> {
- // For now, just use the first `VarianceDiagInfo::Invariant` that we see
- match self {
- VarianceDiagInfo::None => other,
- VarianceDiagInfo::Invariant { .. } => self,
- }
- }
-}
-
// Some types are used a lot. Make sure they don't unintentionally get bigger.
#[cfg(target_pointer_width = "64")]
mod size_asserts {
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 69ea9c9843a0..24e3e623ff27 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -217,10 +217,6 @@ pub struct TypeckResults<'tcx> {
/// Container types and field indices of `offset_of!` expressions
offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<(VariantIdx, FieldIdx)>)>,
-
- /// Maps from `HirId`s of const blocks (the `ExprKind::ConstBlock`, not the inner expression's)
- /// to the `DefId` of the corresponding inline const.
- pub inline_consts: FxIndexMap,
}
impl<'tcx> TypeckResults<'tcx> {
@@ -253,7 +249,6 @@ impl<'tcx> TypeckResults<'tcx> {
treat_byte_string_as_slice: Default::default(),
closure_size_eval: Default::default(),
offset_of_data: Default::default(),
- inline_consts: Default::default(),
}
}
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 14d1b502474f..193f0d124bb8 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -568,8 +568,11 @@ fn construct_const<'a, 'tcx>(
..
}) => (*span, ty.span),
Node::AnonConst(ct) => (ct.span, ct.span),
- Node::Expr(&hir::Expr { span, kind: hir::ExprKind::ConstBlock(_), .. }) => (span, span),
- node => span_bug!(tcx.def_span(def), "can't build MIR for {def:?}: {node:#?}"),
+ Node::ConstBlock(_) => {
+ let span = tcx.def_span(def);
+ (span, span)
+ }
+ _ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def),
};
let infcx = tcx.infer_ctxt().build();
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index bd66257e6b68..28f9300b97a8 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -671,9 +671,9 @@ impl<'tcx> Cx<'tcx> {
ExprKind::OffsetOf { container, fields }
}
- hir::ExprKind::ConstBlock(body) => {
- let ty = self.typeck_results().node_type(body.hir_id);
- let did = self.typeck_results().inline_consts[&expr.hir_id.local_id].into();
+ hir::ExprKind::ConstBlock(ref anon_const) => {
+ let ty = self.typeck_results().node_type(anon_const.hir_id);
+ let did = anon_const.def_id.to_def_id();
let typeck_root_def_id = tcx.typeck_root_def_id(did);
let parent_args =
tcx.erase_regions(GenericArgs::identity_for_item(tcx, typeck_root_def_id));
diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs
index bd9e34ae80fc..244ac409fd38 100644
--- a/compiler/rustc_mir_build/src/thir/cx/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs
@@ -165,7 +165,7 @@ impl<'tcx> Cx<'tcx> {
&'a mut self,
owner_id: HirId,
fn_decl: &'tcx hir::FnDecl<'tcx>,
- body: &hir::Body<'tcx>,
+ body: &'tcx hir::Body<'tcx>,
) -> impl Iterator
- > + 'a {
let fn_sig = self.typeck_results.liberated_fn_sigs()[owner_id];
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 145a40ca3cd6..158ca91fcf13 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -637,13 +637,15 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
/// Converts inline const patterns.
fn lower_inline_const(
&mut self,
- expr: &'tcx hir::Expr<'tcx>,
+ block: &'tcx hir::ConstBlock,
id: hir::HirId,
span: Span,
) -> PatKind<'tcx> {
let tcx = self.tcx;
- let def_id = self.typeck_results.inline_consts[&id.local_id];
- let ty = tcx.typeck(def_id).node_type(expr.hir_id);
+ let def_id = block.def_id;
+ let body_id = block.body;
+ let expr = &tcx.hir().body(body_id).value;
+ let ty = tcx.typeck(def_id).node_type(block.hir_id);
// Special case inline consts that are just literals. This is solely
// a performance optimization, as we could also just go through the regular
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index a8741254ffbf..e4670633914e 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -211,7 +211,7 @@ fn remap_mir_for_const_eval_select<'tcx>(
}
fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
- tcx.hir().maybe_body_owned_by(def_id).is_some()
+ tcx.mir_keys(()).contains(&def_id)
}
/// Finds the full set of `DefId`s within the current crate that have
@@ -222,16 +222,6 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet {
// All body-owners have MIR associated with them.
set.extend(tcx.hir().body_owners());
- // Inline consts' bodies are created in
- // typeck instead of during ast lowering, like all other bodies so far.
- for def_id in tcx.hir().body_owners() {
- // Incremental performance optimization: only load typeck results for things that actually have inline consts
- if tcx.hir_owner_nodes(tcx.hir().body_owned_by(def_id).id().hir_id.owner).has_inline_consts
- {
- set.extend(tcx.typeck(def_id).inline_consts.values())
- }
- }
-
// Additionally, tuple struct/variant constructors have MIR, but
// they don't have a BodyId, so we need to build them separately.
struct GatherCtors<'a> {
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 9487692662bb..61680dbfaf52 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -207,8 +207,8 @@
mod move_check;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{par_for_each_in, LRef, MTLock};
+use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
@@ -251,10 +251,10 @@ pub enum MonoItemCollectionStrategy {
pub struct UsageMap<'tcx> {
// Maps every mono item to the mono items used by it.
- used_map: FxHashMap, Vec>>,
+ used_map: UnordMap, Vec>>,
// Maps every mono item to the mono items that use it.
- user_map: FxHashMap, Vec>>,
+ user_map: UnordMap, Vec>>,
}
type MonoItems<'tcx> = Vec>>;
@@ -262,10 +262,10 @@ type MonoItems<'tcx> = Vec>>;
/// The state that is shared across the concurrent threads that are doing collection.
struct SharedState<'tcx> {
/// Items that have been or are currently being recursively collected.
- visited: MTLock>>,
+ visited: MTLock>>,
/// Items that have been or are currently being recursively treated as "mentioned", i.e., their
/// consts are evaluated but nothing is added to the collection.
- mentioned: MTLock>>,
+ mentioned: MTLock>>,
/// Which items are being used where, for better errors.
usage_map: MTLock>,
}
@@ -290,7 +290,7 @@ enum CollectionMode {
impl<'tcx> UsageMap<'tcx> {
fn new() -> UsageMap<'tcx> {
- UsageMap { used_map: FxHashMap::default(), user_map: FxHashMap::default() }
+ UsageMap { used_map: Default::default(), user_map: Default::default() }
}
fn record_used<'a>(
@@ -668,7 +668,7 @@ struct MirUsedCollector<'a, 'tcx> {
used_items: &'a mut MonoItems<'tcx>,
/// See the comment in `collect_items_of_instance` for the purpose of this set.
/// Note that this contains *not-monomorphized* items!
- used_mentioned_items: &'a mut FxHashSet>,
+ used_mentioned_items: &'a mut UnordSet>,
instance: Instance<'tcx>,
visiting_call_terminator: bool,
move_check: move_check::MoveCheckState,
@@ -1272,7 +1272,7 @@ fn collect_items_of_instance<'tcx>(
// mentioned item. So instead we collect all pre-monomorphized `MentionedItem` that were already
// added to `used_items` in a hash set, which can efficiently query in the
// `body.mentioned_items` loop below without even having to monomorphize the item.
- let mut used_mentioned_items = FxHashSet::>::default();
+ let mut used_mentioned_items = Default::default();
let mut collector = MirUsedCollector {
tcx,
body,
@@ -1628,10 +1628,10 @@ fn create_mono_items_for_default_impls<'tcx>(
//=-----------------------------------------------------------------------------
#[instrument(skip(tcx, strategy), level = "debug")]
-pub fn collect_crate_mono_items(
- tcx: TyCtxt<'_>,
+pub(crate) fn collect_crate_mono_items<'tcx>(
+ tcx: TyCtxt<'tcx>,
strategy: MonoItemCollectionStrategy,
-) -> (FxHashSet>, UsageMap<'_>) {
+) -> (Vec>, UsageMap<'tcx>) {
let _prof_timer = tcx.prof.generic_activity("monomorphization_collector");
let roots = tcx
@@ -1641,8 +1641,8 @@ pub fn collect_crate_mono_items(
debug!("building mono item graph, beginning at roots");
let mut state = SharedState {
- visited: MTLock::new(FxHashSet::default()),
- mentioned: MTLock::new(FxHashSet::default()),
+ visited: MTLock::new(UnordSet::default()),
+ mentioned: MTLock::new(UnordSet::default()),
usage_map: MTLock::new(UsageMap::new()),
};
let recursion_limit = tcx.recursion_limit();
@@ -1665,5 +1665,11 @@ pub fn collect_crate_mono_items(
});
}
- (state.visited.into_inner(), state.usage_map.into_inner())
+ // The set of MonoItems was created in an inherently indeterministic order because
+ // of parallelism. We sort it here to ensure that the output is deterministic.
+ let mono_items = tcx.with_stable_hashing_context(move |ref hcx| {
+ state.visited.into_inner().into_sorted(hcx, true)
+ });
+
+ (mono_items, state.usage_map.into_inner())
}
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index b298fe5813f8..eb5f8d92603a 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -1,6 +1,5 @@
#![feature(array_windows)]
#![feature(is_sorted)]
-#![allow(rustc::potential_query_instability)]
use rustc_hir::lang_items::LangItem;
use rustc_middle::bug;
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 21d52004728a..336341f4e746 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -98,8 +98,9 @@ use std::fs::{self, File};
use std::io::{BufWriter, Write};
use std::path::{Path, PathBuf};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sync;
+use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE};
use rustc_hir::definitions::DefPathDataName;
@@ -131,7 +132,7 @@ struct PlacedMonoItems<'tcx> {
/// The codegen units, sorted by name to make things deterministic.
codegen_units: Vec>,
- internalization_candidates: FxHashSet>,
+ internalization_candidates: UnordSet>,
}
// The output CGUs are sorted by name.
@@ -197,9 +198,9 @@ fn place_mono_items<'tcx, I>(cx: &PartitioningCx<'_, 'tcx>, mono_items: I) -> Pl
where
I: Iterator
- >,
{
- let mut codegen_units = FxHashMap::default();
+ let mut codegen_units = UnordMap::default();
let is_incremental_build = cx.tcx.sess.opts.incremental.is_some();
- let mut internalization_candidates = FxHashSet::default();
+ let mut internalization_candidates = UnordSet::default();
// Determine if monomorphizations instantiated in this crate will be made
// available to downstream crates. This depends on whether we are in
@@ -209,7 +210,7 @@ where
cx.tcx.sess.opts.share_generics() && cx.tcx.local_crate_exports_generics();
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
- let cgu_name_cache = &mut FxHashMap::default();
+ let cgu_name_cache = &mut UnordMap::default();
for mono_item in mono_items {
// Handle only root (GloballyShared) items directly here. Inlined (LocalCopy) items
@@ -260,7 +261,7 @@ where
// going via another root item. This includes drop-glue, functions from
// external crates, and local functions the definition of which is
// marked with `#[inline]`.
- let mut reachable_inlined_items = FxHashSet::default();
+ let mut reachable_inlined_items = FxIndexSet::default();
get_reachable_inlined_items(cx.tcx, mono_item, cx.usage_map, &mut reachable_inlined_items);
// Add those inlined items. It's possible an inlined item is reachable
@@ -284,8 +285,9 @@ where
codegen_units.insert(cgu_name, CodegenUnit::new(cgu_name));
}
- let mut codegen_units: Vec<_> = codegen_units.into_values().collect();
- codegen_units.sort_by(|a, b| a.name().as_str().cmp(b.name().as_str()));
+ let mut codegen_units: Vec<_> = cx.tcx.with_stable_hashing_context(|ref hcx| {
+ codegen_units.into_items().map(|(_, cgu)| cgu).collect_sorted(hcx, true)
+ });
for cgu in codegen_units.iter_mut() {
cgu.compute_size_estimate();
@@ -297,7 +299,7 @@ where
tcx: TyCtxt<'tcx>,
item: MonoItem<'tcx>,
usage_map: &UsageMap<'tcx>,
- visited: &mut FxHashSet>,
+ visited: &mut FxIndexSet>,
) {
usage_map.for_each_inlined_used_item(tcx, item, |inlined_item| {
let is_new = visited.insert(inlined_item);
@@ -320,7 +322,7 @@ fn merge_codegen_units<'tcx>(
assert!(codegen_units.is_sorted_by(|a, b| a.name().as_str() <= b.name().as_str()));
// This map keeps track of what got merged into what.
- let mut cgu_contents: FxHashMap> =
+ let mut cgu_contents: UnordMap> =
codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect();
// If N is the maximum number of CGUs, and the CGUs are sorted from largest
@@ -422,22 +424,24 @@ fn merge_codegen_units<'tcx>(
// For CGUs that contain the code of multiple modules because of the
// merging done above, we use a concatenation of the names of all
// contained CGUs.
- let new_cgu_names: FxHashMap = cgu_contents
- .into_iter()
- // This `filter` makes sure we only update the name of CGUs that
- // were actually modified by merging.
- .filter(|(_, cgu_contents)| cgu_contents.len() > 1)
- .map(|(current_cgu_name, cgu_contents)| {
- let mut cgu_contents: Vec<&str> = cgu_contents.iter().map(|s| s.as_str()).collect();
+ let new_cgu_names = UnordMap::from(
+ cgu_contents
+ .items()
+ // This `filter` makes sure we only update the name of CGUs that
+ // were actually modified by merging.
+ .filter(|(_, cgu_contents)| cgu_contents.len() > 1)
+ .map(|(current_cgu_name, cgu_contents)| {
+ let mut cgu_contents: Vec<&str> =
+ cgu_contents.iter().map(|s| s.as_str()).collect();
- // Sort the names, so things are deterministic and easy to
- // predict. We are sorting primitive `&str`s here so we can
- // use unstable sort.
- cgu_contents.sort_unstable();
+ // Sort the names, so things are deterministic and easy to
+ // predict. We are sorting primitive `&str`s here so we can
+ // use unstable sort.
+ cgu_contents.sort_unstable();
- (current_cgu_name, cgu_contents.join("--"))
- })
- .collect();
+ (*current_cgu_name, cgu_contents.join("--"))
+ }),
+ );
for cgu in codegen_units.iter_mut() {
if let Some(new_cgu_name) = new_cgu_names.get(&cgu.name()) {
@@ -511,7 +515,7 @@ fn compute_inlined_overlap<'tcx>(cgu1: &CodegenUnit<'tcx>, cgu2: &CodegenUnit<'t
fn internalize_symbols<'tcx>(
cx: &PartitioningCx<'_, 'tcx>,
codegen_units: &mut [CodegenUnit<'tcx>],
- internalization_candidates: FxHashSet>,
+ internalization_candidates: UnordSet>,
) {
/// For symbol internalization, we need to know whether a symbol/mono-item
/// is used from outside the codegen unit it is defined in. This type is
@@ -522,7 +526,7 @@ fn internalize_symbols<'tcx>(
MultipleCgus,
}
- let mut mono_item_placements = FxHashMap::default();
+ let mut mono_item_placements = UnordMap::default();
let single_codegen_unit = codegen_units.len() == 1;
if !single_codegen_unit {
@@ -739,7 +743,7 @@ fn mono_item_linkage_and_visibility<'tcx>(
(Linkage::External, vis)
}
-type CguNameCache = FxHashMap<(DefId, bool), Symbol>;
+type CguNameCache = UnordMap<(DefId, bool), Symbol>;
fn static_visibility<'tcx>(
tcx: TyCtxt<'tcx>,
@@ -932,7 +936,7 @@ fn debug_dump<'a, 'tcx: 'a>(tcx: TyCtxt<'tcx>, label: &str, cgus: &[CodegenUnit<
//
// Also, unreached inlined items won't be counted here. This is fine.
- let mut inlined_items = FxHashSet::default();
+ let mut inlined_items = UnordSet::default();
let mut root_items = 0;
let mut unique_inlined_items = 0;
@@ -1164,7 +1168,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co
}
if tcx.sess.opts.unstable_opts.print_mono_items.is_some() {
- let mut item_to_cgus: FxHashMap<_, Vec<_>> = Default::default();
+ let mut item_to_cgus: UnordMap<_, Vec<_>> = Default::default();
for cgu in codegen_units {
for (&mono_item, &data) in cgu.items() {
@@ -1240,7 +1244,7 @@ fn dump_mono_items_stats<'tcx>(
let mut file = BufWriter::new(file);
// Gather instantiated mono items grouped by def_id
- let mut items_per_def_id: FxHashMap<_, Vec<_>> = Default::default();
+ let mut items_per_def_id: FxIndexMap<_, Vec<_>> = Default::default();
for cgu in codegen_units {
cgu.items()
.keys()
diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml
index 8bcc21d82f85..c30d21fd7843 100644
--- a/compiler/rustc_next_trait_solver/Cargo.toml
+++ b/compiler/rustc_next_trait_solver/Cargo.toml
@@ -4,13 +4,16 @@ version = "0.0.0"
edition = "2021"
[dependencies]
-rustc_type_ir = { path = "../rustc_type_ir", default-features = false }
+# tidy-alphabetical-start
derivative = "2.2.0"
-rustc_macros = { path = "../rustc_macros", optional = true }
-rustc_type_ir_macros = { path = "../rustc_type_ir_macros" }
-rustc_serialize = { path = "../rustc_serialize", optional = true }
-rustc_data_structures = { path = "../rustc_data_structures", optional = true }
rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
+rustc_data_structures = { path = "../rustc_data_structures", optional = true }
+rustc_macros = { path = "../rustc_macros", optional = true }
+rustc_serialize = { path = "../rustc_serialize", optional = true }
+rustc_type_ir = { path = "../rustc_type_ir", default-features = false }
+rustc_type_ir_macros = { path = "../rustc_type_ir_macros" }
+tracing = "0.1"
+# tidy-alphabetical-end
[features]
default = ["nightly"]
diff --git a/compiler/rustc_next_trait_solver/src/resolve.rs b/compiler/rustc_next_trait_solver/src/resolve.rs
index 92e05cc4901a..5c00b6978d69 100644
--- a/compiler/rustc_next_trait_solver/src/resolve.rs
+++ b/compiler/rustc_next_trait_solver/src/resolve.rs
@@ -7,11 +7,11 @@ use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
// EAGER RESOLUTION
/// Resolves ty, region, and const vars to their inferred values or their root vars.
-pub struct EagerResolver<
- 'a,
+pub struct EagerResolver<'a, Infcx, I = ::Interner>
+where
Infcx: InferCtxtLike,
- I: Interner = ::Interner,
-> {
+ I: Interner,
+{
infcx: &'a Infcx,
}
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 04f855e4f559..f678d11213c7 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -622,8 +622,6 @@ parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allo
parse_out_of_range_hex_escape = out of range hex escape
.label = must be a character in the range [\x00-\x7f]
-parse_outer_attr_ambiguous = ambiguous outer attributes
-
parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them
parse_outer_attribute_not_allowed_on_if_else = outer attributes are not allowed on `if` and `else` branches
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 3f08a830b0c9..6c1fcbe06fc5 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -495,15 +495,6 @@ pub(crate) struct OuterAttributeNotAllowedOnIfElse {
pub attributes: Span,
}
-#[derive(Diagnostic)]
-#[diag(parse_outer_attr_ambiguous)]
-pub(crate) struct AmbiguousOuterAttributes {
- #[primary_span]
- pub span: Span,
- #[subdiagnostic]
- pub sugg: WrapInParentheses,
-}
-
#[derive(Diagnostic)]
#[diag(parse_missing_in_in_for_loop)]
pub(crate) struct MissingInInForLoop {
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 4acc610d8c40..58fef9b6c456 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -7,7 +7,7 @@ use rustc_ast as ast;
use rustc_ast::attr;
use rustc_ast::token::{self, Delimiter};
use rustc_errors::{codes::*, Diag, PResult};
-use rustc_span::{sym, BytePos, Span};
+use rustc_span::{sym, symbol::kw, BytePos, Span};
use thin_vec::ThinVec;
use tracing::debug;
@@ -252,9 +252,23 @@ impl<'a> Parser<'a> {
maybe_whole!(self, NtMeta, |attr| attr.into_inner());
let do_parse = |this: &mut Self| {
+ let is_unsafe = this.eat_keyword(kw::Unsafe);
+ let unsafety = if is_unsafe {
+ let unsafe_span = this.prev_token.span;
+ this.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span);
+ this.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
+
+ ast::Safety::Unsafe(unsafe_span)
+ } else {
+ ast::Safety::Default
+ };
+
let path = this.parse_path(PathStyle::Mod)?;
let args = this.parse_attr_args()?;
- Ok(ast::AttrItem { path, args, tokens: None })
+ if is_unsafe {
+ this.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
+ }
+ Ok(ast::AttrItem { unsafety, path, args, tokens: None })
};
// Attr items don't have attributes
if capture_tokens { self.collect_tokens_no_attrs(do_parse) } else { do_parse(self) }
@@ -375,10 +389,25 @@ impl<'a> Parser<'a> {
}
let lo = self.token.span;
+ let is_unsafe = self.eat_keyword(kw::Unsafe);
+ let unsafety = if is_unsafe {
+ let unsafe_span = self.prev_token.span;
+ self.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span);
+ self.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
+
+ ast::Safety::Unsafe(unsafe_span)
+ } else {
+ ast::Safety::Default
+ };
+
let path = self.parse_path(PathStyle::Mod)?;
let kind = self.parse_meta_item_kind()?;
+ if is_unsafe {
+ self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
+ }
let span = lo.to(self.prev_token.span);
- Ok(ast::MetaItem { path, kind, span })
+
+ Ok(ast::MetaItem { unsafety, path, kind, span })
}
pub(crate) fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 9677eea06044..2bb6fb53869b 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -130,14 +130,14 @@ pub enum AttemptLocalParseRecovery {
}
impl AttemptLocalParseRecovery {
- pub fn yes(&self) -> bool {
+ pub(super) fn yes(&self) -> bool {
match self {
AttemptLocalParseRecovery::Yes => true,
AttemptLocalParseRecovery::No => false,
}
}
- pub fn no(&self) -> bool {
+ pub(super) fn no(&self) -> bool {
match self {
AttemptLocalParseRecovery::Yes => false,
AttemptLocalParseRecovery::No => true,
@@ -891,7 +891,7 @@ impl<'a> Parser<'a> {
}
}
- pub fn maybe_suggest_struct_literal(
+ pub(super) fn maybe_suggest_struct_literal(
&mut self,
lo: Span,
s: BlockCheckMode,
@@ -2459,7 +2459,7 @@ impl<'a> Parser<'a> {
/// Handle encountering a symbol in a generic argument list that is not a `,` or `>`. In this
/// case, we emit an error and try to suggest enclosing a const argument in braces if it looks
/// like the user has forgotten them.
- pub fn handle_ambiguous_unbraced_const_arg(
+ pub(super) fn handle_ambiguous_unbraced_const_arg(
&mut self,
args: &mut ThinVec,
) -> PResult<'a, bool> {
@@ -2500,7 +2500,7 @@ impl<'a> Parser<'a> {
/// - Single-segment paths (i.e. standalone generic const parameters).
/// All other expressions that can be parsed will emit an error suggesting the expression be
/// wrapped in braces.
- pub fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, P> {
+ pub(super) fn handle_unambiguous_unbraced_const_arg(&mut self) -> PResult<'a, P> {
let start = self.token.span;
let expr = self.parse_expr_res(Restrictions::CONST_EXPR, None).map_err(|mut err| {
err.span_label(
@@ -2559,7 +2559,7 @@ impl<'a> Parser<'a> {
Some(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }))
}
- pub fn recover_const_param_declaration(
+ pub(super) fn recover_const_param_declaration(
&mut self,
ty_generics: Option<&Generics>,
) -> PResult<'a, Option> {
@@ -2589,7 +2589,11 @@ impl<'a> Parser<'a> {
/// When encountering code like `foo::< bar + 3 >` or `foo::< bar - baz >` we suggest
/// `foo::<{ bar + 3 }>` and `foo::<{ bar - baz }>`, respectively. We only provide a suggestion
/// if we think that the resulting expression would be well formed.
- pub fn recover_const_arg(&mut self, start: Span, mut err: Diag<'a>) -> PResult<'a, GenericArg> {
+ pub(super) fn recover_const_arg(
+ &mut self,
+ start: Span,
+ mut err: Diag<'a>,
+ ) -> PResult<'a, GenericArg> {
let is_op_or_dot = AssocOp::from_token(&self.token)
.and_then(|op| {
if let AssocOp::Greater
@@ -2690,7 +2694,7 @@ impl<'a> Parser<'a> {
}
/// Creates a dummy const argument, and reports that the expression must be enclosed in braces
- pub fn dummy_const_arg_needs_braces(&self, mut err: Diag<'a>, span: Span) -> GenericArg {
+ pub(super) fn dummy_const_arg_needs_braces(&self, mut err: Diag<'a>, span: Span) -> GenericArg {
err.multipart_suggestion(
"expressions must be enclosed in braces to be used as const generic \
arguments",
@@ -2961,7 +2965,7 @@ impl<'a> Parser<'a> {
/// * `=====`
/// * `<<<<<`
///
- pub fn is_vcs_conflict_marker(
+ pub(super) fn is_vcs_conflict_marker(
&mut self,
long_kind: &TokenKind,
short_kind: &TokenKind,
@@ -2981,14 +2985,14 @@ impl<'a> Parser<'a> {
None
}
- pub fn recover_vcs_conflict_marker(&mut self) {
+ pub(super) fn recover_vcs_conflict_marker(&mut self) {
if let Err(err) = self.err_vcs_conflict_marker() {
err.emit();
FatalError.raise();
}
}
- pub fn err_vcs_conflict_marker(&mut self) -> PResult<'a, ()> {
+ pub(crate) fn err_vcs_conflict_marker(&mut self) -> PResult<'a, ()> {
let Some(start) = self.conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt)
else {
return Ok(());
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 1b99bc015b60..e15d6ab2123a 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -328,9 +328,7 @@ impl<'a> Parser<'a> {
this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::NotYetParsed)
})?;
- self.error_ambiguous_outer_attrs(&lhs, lhs_span, rhs.span);
- let span = lhs_span.to(rhs.span);
-
+ let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span);
lhs = match op {
AssocOp::Add
| AssocOp::Subtract
@@ -429,23 +427,11 @@ impl<'a> Parser<'a> {
});
}
- fn error_ambiguous_outer_attrs(&self, lhs: &P, lhs_span: Span, rhs_span: Span) {
- if let Some(attr) = lhs.attrs.iter().find(|a| a.style == AttrStyle::Outer) {
- self.dcx().emit_err(errors::AmbiguousOuterAttributes {
- span: attr.span.to(rhs_span),
- sugg: errors::WrapInParentheses::Expression {
- left: attr.span.shrink_to_lo(),
- right: lhs_span.shrink_to_hi(),
- },
- });
- }
- }
-
/// Possibly translate the current token to an associative operator.
/// The method does not advance the current token.
///
/// Also performs recovery for `and` / `or` which are mistaken for `&&` and `||` respectively.
- pub fn check_assoc_op(&self) -> Option> {
+ pub(super) fn check_assoc_op(&self) -> Option> {
let (op, span) = match (AssocOp::from_token(&self.token), self.token.ident()) {
// When parsing const expressions, stop parsing when encountering `>`.
(
@@ -520,8 +506,7 @@ impl<'a> Parser<'a> {
None
};
let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span);
- self.error_ambiguous_outer_attrs(&lhs, lhs.span, rhs_span);
- let span = lhs.span.to(rhs_span);
+ let span = self.mk_expr_sp(&lhs, lhs.span, rhs_span);
let limits =
if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed };
let range = self.mk_range(Some(lhs), rhs, limits);
@@ -739,8 +724,7 @@ impl<'a> Parser<'a> {
expr_kind: fn(P, P) -> ExprKind,
) -> PResult<'a, P> {
let mk_expr = |this: &mut Self, lhs: P, rhs: P| {
- this.error_ambiguous_outer_attrs(&lhs, lhs_span, rhs.span);
- this.mk_expr(lhs_span.to(rhs.span), expr_kind(lhs, rhs))
+ this.mk_expr(this.mk_expr_sp(&lhs, lhs_span, rhs.span), expr_kind(lhs, rhs))
};
// Save the state of the parser before parsing type normally, in case there is a
@@ -1022,7 +1006,11 @@ impl<'a> Parser<'a> {
}
}
- pub fn parse_dot_suffix_expr(&mut self, lo: Span, base: P) -> PResult<'a, P> {
+ pub(super) fn parse_dot_suffix_expr(
+ &mut self,
+ lo: Span,
+ base: P,
+ ) -> PResult<'a, P> {
// At this point we've consumed something like `expr.` and `self.token` holds the token
// after the dot.
match self.token.uninterpolate().kind {
@@ -3858,6 +3846,16 @@ impl<'a> Parser<'a> {
self.mk_expr(span, ExprKind::Err(guar))
}
+ /// Create expression span ensuring the span of the parent node
+ /// is larger than the span of lhs and rhs, including the attributes.
+ fn mk_expr_sp(&self, lhs: &P, lhs_span: Span, rhs_span: Span) -> Span {
+ lhs.attrs
+ .iter()
+ .find(|a| a.style == AttrStyle::Outer)
+ .map_or(lhs_span, |a| a.span)
+ .to(rhs_span)
+ }
+
fn collect_tokens_for_expr(
&mut self,
attrs: AttrWrapper,
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 37c99958fc88..3f5a4afdad8a 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2265,7 +2265,7 @@ pub(crate) struct FnParseMode {
/// to true.
/// * The span is from Edition 2015. In particular, you can get a
/// 2015 span inside a 2021 crate using macros.
- pub req_name: ReqName,
+ pub(super) req_name: ReqName,
/// If this flag is set to `true`, then plain, semicolon-terminated function
/// prototypes are not allowed here.
///
@@ -2284,7 +2284,7 @@ pub(crate) struct FnParseMode {
/// This field should only be set to false if the item is inside of a trait
/// definition or extern block. Within an impl block or a module, it should
/// always be set to true.
- pub req_body: bool,
+ pub(super) req_body: bool,
}
/// Parsing of functions and methods.
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 8f733b4fcbbc..adf04fcf2241 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -11,22 +11,21 @@ mod stmt;
mod ty;
use crate::lexer::UnmatchedDelim;
-pub use attr_wrapper::AttrWrapper;
+use attr_wrapper::AttrWrapper;
pub use diagnostics::AttemptLocalParseRecovery;
pub(crate) use expr::ForbiddenLetReason;
pub(crate) use item::FnParseMode;
pub use pat::{CommaRecoveryMode, RecoverColon, RecoverComma};
-pub use path::PathStyle;
+use path::PathStyle;
-use core::fmt;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind};
use rustc_ast::tokenstream::{AttributesData, DelimSpacing, DelimSpan, Spacing};
use rustc_ast::tokenstream::{TokenStream, TokenTree, TokenTreeCursor};
use rustc_ast::util::case::Case;
use rustc_ast::{
- self as ast, AttrArgs, AttrArgsEq, AttrId, ByRef, Const, CoroutineKind, DelimArgs, Expr,
- ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, Visibility,
+ self as ast, AnonConst, AttrArgs, AttrArgsEq, AttrId, ByRef, Const, CoroutineKind, DelimArgs,
+ Expr, ExprKind, Extern, HasAttrs, HasTokens, Mutability, Recovered, Safety, StrLit, Visibility,
VisibilityKind, DUMMY_NODE_ID,
};
use rustc_ast_pretty::pprust;
@@ -37,7 +36,7 @@ use rustc_session::parse::ParseSess;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use std::ops::Range;
-use std::{mem, slice};
+use std::{fmt, mem, slice};
use thin_vec::ThinVec;
use tracing::debug;
@@ -146,7 +145,7 @@ pub struct Parser<'a> {
/// The current token.
pub token: Token,
/// The spacing for the current token.
- pub token_spacing: Spacing,
+ token_spacing: Spacing,
/// The previous token.
pub prev_token: Token,
pub capture_cfg: bool,
@@ -187,7 +186,7 @@ pub struct Parser<'a> {
current_closure: Option,
/// Whether the parser is allowed to do recovery.
/// This is disabled when parsing macro arguments, see #103534
- pub recovery: Recovery,
+ recovery: Recovery,
}
// This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure
@@ -197,10 +196,10 @@ rustc_data_structures::static_assert_size!(Parser<'_>, 264);
/// Stores span information about a closure.
#[derive(Clone, Debug)]
-pub struct ClosureSpans {
- pub whole_closure: Span,
- pub closing_pipe: Span,
- pub body: Span,
+struct ClosureSpans {
+ whole_closure: Span,
+ closing_pipe: Span,
+ body: Span,
}
/// Indicates a range of tokens that should be replaced by
@@ -220,13 +219,13 @@ pub struct ClosureSpans {
/// the first macro inner attribute to invoke a proc-macro).
/// When create a `TokenStream`, the inner attributes get inserted
/// into the proper place in the token stream.
-pub type ReplaceRange = (Range, Vec<(FlatToken, Spacing)>);
+type ReplaceRange = (Range, Vec<(FlatToken, Spacing)>);
/// Controls how we capture tokens. Capturing can be expensive,
/// so we try to avoid performing capturing in cases where
/// we will never need an `AttrTokenStream`.
#[derive(Copy, Clone, Debug)]
-pub enum Capturing {
+enum Capturing {
/// We aren't performing any capturing - this is the default mode.
No,
/// We are capturing tokens
@@ -374,13 +373,13 @@ pub enum FollowedByType {
}
#[derive(Copy, Clone, Debug)]
-pub enum Trailing {
+enum Trailing {
No,
Yes,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum TokenDescription {
+pub(super) enum TokenDescription {
ReservedIdentifier,
Keyword,
ReservedKeyword,
@@ -388,7 +387,7 @@ pub enum TokenDescription {
}
impl TokenDescription {
- pub fn from_token(token: &Token) -> Option {
+ pub(super) fn from_token(token: &Token) -> Option {
match token.kind {
_ if token.is_special_ident() => Some(TokenDescription::ReservedIdentifier),
_ if token.is_used_keyword() => Some(TokenDescription::Keyword),
@@ -502,7 +501,7 @@ impl<'a> Parser<'a> {
/// Expect next token to be edible or inedible token. If edible,
/// then consume it; if inedible, then return without consuming
/// anything. Signal a fatal error if next token is unexpected.
- pub fn expect_one_of(
+ fn expect_one_of(
&mut self,
edible: &[TokenKind],
inedible: &[TokenKind],
@@ -572,7 +571,7 @@ impl<'a> Parser<'a> {
/// the main purpose of this function is to reduce the cluttering of the suggestions list
/// which using the normal eat method could introduce in some cases.
#[inline]
- pub fn eat_noexpect(&mut self, tok: &TokenKind) -> bool {
+ fn eat_noexpect(&mut self, tok: &TokenKind) -> bool {
let is_present = self.check_noexpect(tok);
if is_present {
self.bump()
@@ -1262,9 +1261,12 @@ impl<'a> Parser<'a> {
}
self.eat_keyword(kw::Const);
let (attrs, blk) = self.parse_inner_attrs_and_block()?;
- let expr = self.mk_expr(blk.span, ExprKind::Block(blk, None));
- let blk_span = expr.span;
- Ok(self.mk_expr_with_attrs(span.to(blk_span), ExprKind::ConstBlock(expr), attrs))
+ let anon_const = AnonConst {
+ id: DUMMY_NODE_ID,
+ value: self.mk_expr(blk.span, ExprKind::Block(blk, None)),
+ };
+ let blk_span = anon_const.value.span;
+ Ok(self.mk_expr_with_attrs(span.to(blk_span), ExprKind::ConstBlock(anon_const), attrs))
}
/// Parses mutability (`mut` or nothing).
@@ -1517,7 +1519,7 @@ impl<'a> Parser<'a> {
}
}
- pub fn collect_tokens_no_attrs(
+ fn collect_tokens_no_attrs(
&mut self,
f: impl FnOnce(&mut Self) -> PResult<'a, R>,
) -> PResult<'a, R> {
@@ -1538,8 +1540,10 @@ impl<'a> Parser<'a> {
})
}
- // debug view of the parser's token stream, up to `{lookahead}` tokens
- pub fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug + '_ {
+ // Debug view of the parser's token stream, up to `{lookahead}` tokens.
+ // Only used when debugging.
+ #[allow(unused)]
+ pub(crate) fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug + '_ {
struct DebugParser<'dbg> {
parser: &'dbg Parser<'dbg>,
lookahead: usize,
@@ -1615,7 +1619,7 @@ pub(crate) fn make_unclosed_delims_error(
/// is then 'parsed' to build up an `AttrTokenStream` with nested
/// `AttrTokenTree::Delimited` tokens.
#[derive(Debug, Clone)]
-pub enum FlatToken {
+enum FlatToken {
/// A token - this holds both delimiter (e.g. '{' and '}')
/// and non-delimiter tokens
Token(Token),
diff --git a/compiler/rustc_parse/src/parser/mut_visit/tests.rs b/compiler/rustc_parse/src/parser/mut_visit/tests.rs
index b3cb28af657e..677bcdf7fcdf 100644
--- a/compiler/rustc_parse/src/parser/mut_visit/tests.rs
+++ b/compiler/rustc_parse/src/parser/mut_visit/tests.rs
@@ -21,14 +21,12 @@ impl MutVisitor for ToZzIdentMutVisitor {
}
}
-// Maybe add to `expand.rs`.
-macro_rules! assert_pred {
- ($pred:expr, $predname:expr, $a:expr , $b:expr) => {{
- let pred_val = $pred;
+macro_rules! assert_matches_codepattern {
+ ($a:expr , $b:expr) => {{
let a_val = $a;
let b_val = $b;
- if !(pred_val(&a_val, &b_val)) {
- panic!("expected args satisfying {}, got {} and {}", $predname, a_val, b_val);
+ if !matches_codepattern(&a_val, &b_val) {
+ panic!("expected args satisfying `matches_codepattern`, got {} and {}", a_val, b_val);
}
}};
}
@@ -41,9 +39,7 @@ fn ident_transformation() {
let mut krate =
string_to_crate("#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string());
zz_visitor.visit_crate(&mut krate);
- assert_pred!(
- matches_codepattern,
- "matches_codepattern",
+ assert_matches_codepattern!(
print_crate_items(&krate),
"#[zz]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string()
);
@@ -61,9 +57,7 @@ fn ident_transformation_in_defs() {
.to_string(),
);
zz_visitor.visit_crate(&mut krate);
- assert_pred!(
- matches_codepattern,
- "matches_codepattern",
+ assert_matches_codepattern!(
print_crate_items(&krate),
"macro_rules! zz{(zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+))}".to_string()
);
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index fcedc1a4af3a..9beecd9849fb 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -20,7 +20,7 @@ use tracing::debug;
/// Specifies how to parse a path.
#[derive(Copy, Clone, PartialEq)]
-pub enum PathStyle {
+pub(super) enum PathStyle {
/// In some contexts, notably in expressions, paths with generic arguments are ambiguous
/// with something else. For example, in expressions `segment < ....` can be interpreted
/// as a comparison and `segment ( ....` can be interpreted as a function call.
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index be539d15386f..104aae9b257e 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -31,7 +31,7 @@ impl<'a> Parser<'a> {
/// Parses a statement. This stops just before trailing semicolons on everything but items.
/// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
// Public for rustfmt usage.
- pub fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option> {
+ pub(super) fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option> {
Ok(self.parse_stmt_without_recovery(false, force_collect).unwrap_or_else(|e| {
e.emit();
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 2033f3878875..5bed0317e5eb 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -127,7 +127,7 @@ impl<'a> Parser<'a> {
/// Parse a type suitable for a field definition.
/// The difference from `parse_ty` is that this version
/// allows anonymous structs and unions.
- pub fn parse_ty_for_field_def(&mut self) -> PResult<'a, P> {
+ pub(super) fn parse_ty_for_field_def(&mut self) -> PResult<'a, P