diff --git a/Cargo.lock b/Cargo.lock
index c0d1337ef93a..1018eac13ff1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -284,6 +284,21 @@ dependencies = [
"nom",
]
+[[package]]
+name = "assert_cmd"
+version = "2.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8"
+dependencies = [
+ "anstyle",
+ "bstr",
+ "doc-comment",
+ "predicates",
+ "predicates-core",
+ "predicates-tree",
+ "wait-timeout",
+]
+
[[package]]
name = "autocfg"
version = "1.3.0"
@@ -1095,6 +1110,12 @@ version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
+[[package]]
+name = "difflib"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
+
[[package]]
name = "digest"
version = "0.10.7"
@@ -1197,6 +1218,12 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "doc-comment"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
+
[[package]]
name = "either"
version = "1.12.0"
@@ -2337,6 +2364,33 @@ dependencies = [
"topological-sort",
]
+[[package]]
+name = "mdbook-trpl-listing"
+version = "0.1.0"
+dependencies = [
+ "assert_cmd",
+ "clap",
+ "mdbook",
+ "pulldown-cmark 0.10.3",
+ "pulldown-cmark-to-cmark",
+ "serde_json",
+ "thiserror",
+ "toml 0.8.13",
+ "xmlparser",
+]
+
+[[package]]
+name = "mdbook-trpl-note"
+version = "1.0.0"
+dependencies = [
+ "assert_cmd",
+ "clap",
+ "mdbook",
+ "pulldown-cmark 0.10.3",
+ "pulldown-cmark-to-cmark",
+ "serde_json",
+]
+
[[package]]
name = "measureme"
version = "11.0.1"
@@ -2949,6 +3003,33 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
+[[package]]
+name = "predicates"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8"
+dependencies = [
+ "anstyle",
+ "difflib",
+ "predicates-core",
+]
+
+[[package]]
+name = "predicates-core"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174"
+
+[[package]]
+name = "predicates-tree"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf"
+dependencies = [
+ "predicates-core",
+ "termtree",
+]
+
[[package]]
name = "prettydiff"
version = "0.6.4"
@@ -3018,6 +3099,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993"
dependencies = [
"bitflags 2.5.0",
+ "getopts",
"memchr",
"pulldown-cmark-escape",
"unicase",
@@ -3029,6 +3111,15 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3"
+[[package]]
+name = "pulldown-cmark-to-cmark"
+version = "13.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f609795c8d835f79dcfcf768415b9fb57ef1b74891e99f86e73f43a7a257163b"
+dependencies = [
+ "pulldown-cmark 0.10.3",
+]
+
[[package]]
name = "punycode"
version = "0.4.1"
@@ -3276,6 +3367,8 @@ dependencies = [
"clap",
"env_logger",
"mdbook",
+ "mdbook-trpl-listing",
+ "mdbook-trpl-note",
]
[[package]]
@@ -5386,6 +5479,12 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "termtree"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
+
[[package]]
name = "test"
version = "0.0.0"
@@ -5558,7 +5657,19 @@ dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
- "toml_edit",
+ "toml_edit 0.19.15",
+]
+
+[[package]]
+name = "toml"
+version = "0.8.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit 0.22.13",
]
[[package]]
@@ -5580,7 +5691,20 @@ dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
- "winnow",
+ "winnow 0.5.40",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.22.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c"
+dependencies = [
+ "indexmap",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow 0.6.8",
]
[[package]]
@@ -5990,6 +6114,15 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+[[package]]
+name = "wait-timeout"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "walkdir"
version = "2.5.0"
@@ -6302,6 +6435,15 @@ dependencies = [
"memchr",
]
+[[package]]
+name = "winnow"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "writeable"
version = "0.5.4"
@@ -6319,6 +6461,12 @@ dependencies = [
"rustix",
]
+[[package]]
+name = "xmlparser"
+version = "0.13.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
+
[[package]]
name = "xz2"
version = "0.1.7"
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 7e59b4492993..7a45d909d077 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -167,7 +167,7 @@ impl PathSegment {
}
}
-/// The arguments of a path segment.
+/// The generic arguments and associated item constraints of a path segment.
///
/// E.g., `` as in `Foo` or `(A, B)` as in `Foo(A, B)`.
#[derive(Clone, Encodable, Decodable, Debug)]
@@ -221,14 +221,13 @@ pub struct AngleBracketedArgs {
pub args: ThinVec,
}
-/// Either an argument for a parameter e.g., `'a`, `Vec`, `0`,
-/// or a constraint on an associated item, e.g., `Item = String` or `Item: Bound`.
+/// Either an argument for a generic parameter or a constraint on an associated item.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum AngleBracketedArg {
- /// Argument for a generic parameter.
+ /// A generic argument for a generic parameter.
Arg(GenericArg),
- /// Constraint for an associated item.
- Constraint(AssocConstraint),
+ /// A constraint on an associated item.
+ Constraint(AssocItemConstraint),
}
impl AngleBracketedArg {
@@ -418,7 +417,7 @@ impl Default for WhereClause {
/// A single predicate in a where-clause.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum WherePredicate {
- /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
+ /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
BoundPredicate(WhereBoundPredicate),
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
RegionPredicate(WhereRegionPredicate),
@@ -2034,18 +2033,25 @@ impl UintTy {
}
}
-/// A constraint on an associated type (e.g., `A = Bar` in `Foo` or
-/// `A: TraitA + TraitB` in `Foo`).
+/// A constraint on an associated item.
+///
+/// ### Examples
+///
+/// * the `A = Ty` and `B = Ty` in `Trait`
+/// * the `G = Ty` in `Trait = Ty>`
+/// * the `A: Bound` in `Trait`
+/// * the `RetTy` in `Trait(ArgTy, ArgTy) -> RetTy`
+/// * the `C = { Ct }` in `Trait` (feature `associated_const_equality`)
+/// * the `f(): Bound` in `Trait` (feature `return_type_notation`)
#[derive(Clone, Encodable, Decodable, Debug)]
-pub struct AssocConstraint {
+pub struct AssocItemConstraint {
pub id: NodeId,
pub ident: Ident,
pub gen_args: Option,
- pub kind: AssocConstraintKind,
+ pub kind: AssocItemConstraintKind,
pub span: Span,
}
-/// The kinds of an `AssocConstraint`.
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum Term {
Ty(P),
@@ -2064,12 +2070,17 @@ impl From for Term {
}
}
-/// The kinds of an `AssocConstraint`.
+/// The kind of [associated item constraint][AssocItemConstraint].
#[derive(Clone, Encodable, Decodable, Debug)]
-pub enum AssocConstraintKind {
- /// E.g., `A = Bar`, `A = 3` in `Foo` where A is an associated type.
+pub enum AssocItemConstraintKind {
+ /// An equality constraint for an associated item (e.g., `AssocTy = Ty` in `Trait`).
+ ///
+ /// Also known as an *associated item binding* (we *bind* an associated item to a term).
+ ///
+ /// Furthermore, associated type equality constraints can also be referred to as *associated type
+ /// bindings*. Similarly with associated const equality constraints and *associated const bindings*.
Equality { term: Term },
- /// E.g. `A: TraitA + TraitB` in `Foo`.
+ /// A bound on an associated type (e.g., `AssocTy: Bound` in `Trait`).
Bound { bounds: GenericBounds },
}
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index ede0dd70b305..5c581c270e49 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -175,8 +175,8 @@ pub trait MutVisitor: Sized {
noop_visit_lifetime(l, self);
}
- fn visit_constraint(&mut self, t: &mut AssocConstraint) {
- noop_visit_constraint(t, self);
+ fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) {
+ noop_visit_assoc_item_constraint(c, self);
}
fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) {
@@ -463,8 +463,8 @@ pub fn noop_flat_map_arm(mut arm: Arm, vis: &mut T) -> SmallVec<[
smallvec![arm]
}
-fn noop_visit_constraint(
- AssocConstraint { id, ident, gen_args, kind, span }: &mut AssocConstraint,
+fn noop_visit_assoc_item_constraint(
+ AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint,
vis: &mut T,
) {
vis.visit_id(id);
@@ -473,11 +473,11 @@ fn noop_visit_constraint(
vis.visit_generic_args(gen_args);
}
match kind {
- AssocConstraintKind::Equality { term } => match term {
+ AssocItemConstraintKind::Equality { term } => match term {
Term::Ty(ty) => vis.visit_ty(ty),
Term::Const(c) => vis.visit_anon_const(c),
},
- AssocConstraintKind::Bound { bounds } => visit_bounds(bounds, vis),
+ AssocItemConstraintKind::Bound { bounds } => visit_bounds(bounds, vis),
}
vis.visit_span(span);
}
@@ -607,7 +607,7 @@ fn noop_visit_angle_bracketed_parameter_data(
let AngleBracketedArgs { args, span } = data;
visit_thin_vec(args, |arg| match arg {
AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg),
- AngleBracketedArg::Constraint(constraint) => vis.visit_constraint(constraint),
+ AngleBracketedArg::Constraint(constraint) => vis.visit_assoc_item_constraint(constraint),
});
vis.visit_span(span);
}
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 6382eb6861c7..b2f3b27c77e9 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -246,8 +246,11 @@ pub trait Visitor<'ast>: Sized {
fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result {
walk_generic_arg(self, generic_arg)
}
- fn visit_assoc_constraint(&mut self, constraint: &'ast AssocConstraint) -> Self::Result {
- walk_assoc_constraint(self, constraint)
+ fn visit_assoc_item_constraint(
+ &mut self,
+ constraint: &'ast AssocItemConstraint,
+ ) -> Self::Result {
+ walk_assoc_item_constraint(self, constraint)
}
fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result {
walk_attribute(self, attr)
@@ -558,7 +561,7 @@ where
match arg {
AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)),
AngleBracketedArg::Constraint(c) => {
- try_visit!(visitor.visit_assoc_constraint(c))
+ try_visit!(visitor.visit_assoc_item_constraint(c))
}
}
}
@@ -582,18 +585,18 @@ where
}
}
-pub fn walk_assoc_constraint<'a, V: Visitor<'a>>(
+pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>(
visitor: &mut V,
- constraint: &'a AssocConstraint,
+ constraint: &'a AssocItemConstraint,
) -> V::Result {
try_visit!(visitor.visit_ident(constraint.ident));
visit_opt!(visitor, visit_generic_args, &constraint.gen_args);
match &constraint.kind {
- AssocConstraintKind::Equality { term } => match term {
+ AssocItemConstraintKind::Equality { term } => match term {
Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)),
Term::Const(c) => try_visit!(visitor.visit_anon_const(c)),
},
- AssocConstraintKind::Bound { bounds } => {
+ AssocItemConstraintKind::Bound { bounds } => {
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
}
}
diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs
index eef6e8280afb..e821a08bf181 100644
--- a/compiler/rustc_ast_lowering/src/block.rs
+++ b/compiler/rustc_ast_lowering/src/block.rs
@@ -76,7 +76,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
StmtKind::Empty => {}
StmtKind::MacCall(..) => panic!("shouldn't exist here"),
}
- ast_stmts = &ast_stmts[1..];
+ ast_stmts = tail;
}
(self.arena.alloc_from_iter(stmts), expr)
}
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index ed3046400f60..741a44eb0c52 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -325,10 +325,10 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
});
}
- fn visit_assoc_type_binding(&mut self, type_binding: &'hir TypeBinding<'hir>) {
- self.insert(type_binding.span, type_binding.hir_id, Node::TypeBinding(type_binding));
- self.with_parent(type_binding.hir_id, |this| {
- intravisit::walk_assoc_type_binding(this, type_binding)
+ fn visit_assoc_item_constraint(&mut self, constraint: &'hir AssocItemConstraint<'hir>) {
+ self.insert(constraint.span, constraint.hir_id, Node::AssocItemConstraint(constraint));
+ self.with_parent(constraint.hir_id, |this| {
+ intravisit::walk_assoc_item_constraint(this, constraint)
})
}
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 278049d1347b..5a80fa803f84 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -967,24 +967,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() }
}
- /// Given an associated type constraint like one of these:
- ///
- /// ```ignore (illustrative)
- /// T: Iterator
- /// ^^^^^^^^^^^
- /// T: Iterator-
- /// ^^^^^^^^^^^^
- /// ```
- ///
- /// returns a `hir::TypeBinding` representing `Item`.
- #[instrument(level = "debug", skip(self))]
- fn lower_assoc_ty_constraint(
+ /// Lower an associated item constraint.
+ #[instrument(level = "debug", skip_all)]
+ fn lower_assoc_item_constraint(
&mut self,
- constraint: &AssocConstraint,
+ constraint: &AssocItemConstraint,
itctx: ImplTraitContext,
- ) -> hir::TypeBinding<'hir> {
- debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
- // lower generic arguments of identifier in constraint
+ ) -> hir::AssocItemConstraint<'hir> {
+ debug!(?constraint, ?itctx);
+ // Lower the generic arguments for the associated item.
let gen_args = if let Some(gen_args) = &constraint.gen_args {
let gen_args_ctor = match gen_args {
GenericArgs::AngleBracketed(data) => {
@@ -1000,7 +991,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
};
GenericArgsCtor {
args: Default::default(),
- bindings: &[],
+ constraints: &[],
parenthesized,
span: data.inputs_span,
}
@@ -1030,7 +1021,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
err.emit();
GenericArgsCtor {
args: Default::default(),
- bindings: &[],
+ constraints: &[],
parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
span: data.span,
}
@@ -1052,14 +1043,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.arena.alloc(hir::GenericArgs::none())
};
let kind = match &constraint.kind {
- AssocConstraintKind::Equality { term } => {
+ AssocItemConstraintKind::Equality { term } => {
let term = match term {
Term::Ty(ty) => self.lower_ty(ty, itctx).into(),
Term::Const(c) => self.lower_anon_const(c).into(),
};
- hir::TypeBindingKind::Equality { term }
+ hir::AssocItemConstraintKind::Equality { term }
}
- AssocConstraintKind::Bound { bounds } => {
+ AssocItemConstraintKind::Bound { bounds } => {
// Disallow ATB in dyn types
if self.is_in_dyn_type {
let suggestion = match itctx {
@@ -1083,18 +1074,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
});
let err_ty =
&*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
- hir::TypeBindingKind::Equality { term: err_ty.into() }
+ hir::AssocItemConstraintKind::Equality { term: err_ty.into() }
} else {
- // Desugar `AssocTy: Bounds` into a type binding where the
+ // Desugar `AssocTy: Bounds` into an assoc type binding where the
// later desugars into a trait predicate.
let bounds = self.lower_param_bounds(bounds, itctx);
- hir::TypeBindingKind::Constraint { bounds }
+ hir::AssocItemConstraintKind::Bound { bounds }
}
}
};
- hir::TypeBinding {
+ hir::AssocItemConstraint {
hir_id: self.lower_node_id(constraint.id),
ident: self.lower_ident(constraint.ident),
gen_args,
@@ -2014,7 +2005,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let bound_args = self.arena.alloc(hir::GenericArgs {
args: &[],
- bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
+ constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
parenthesized: hir::GenericArgsParentheses::No,
span_ext: DUMMY_SP,
});
@@ -2587,10 +2578,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}
}
-/// Helper struct for delayed construction of GenericArgs.
+/// Helper struct for the delayed construction of [`hir::GenericArgs`].
struct GenericArgsCtor<'hir> {
args: SmallVec<[hir::GenericArg<'hir>; 4]>,
- bindings: &'hir [hir::TypeBinding<'hir>],
+ constraints: &'hir [hir::AssocItemConstraint<'hir>],
parenthesized: hir::GenericArgsParentheses,
span: Span,
}
@@ -2670,14 +2661,14 @@ impl<'hir> GenericArgsCtor<'hir> {
fn is_empty(&self) -> bool {
self.args.is_empty()
- && self.bindings.is_empty()
+ && self.constraints.is_empty()
&& self.parenthesized == hir::GenericArgsParentheses::No
}
fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
let ga = hir::GenericArgs {
args: this.arena.alloc_from_iter(self.args),
- bindings: self.bindings,
+ constraints: self.constraints,
parenthesized: self.parenthesized,
span_ext: this.lower_span(self.span),
};
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 7679424dceb9..9d38e1e67847 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -281,7 +281,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
(
GenericArgsCtor {
args: Default::default(),
- bindings: &[],
+ constraints: &[],
parenthesized: hir::GenericArgsParentheses::No,
span: path_span.shrink_to_hi(),
},
@@ -390,13 +390,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
AngleBracketedArg::Constraint(_) => None,
})
.collect();
- let bindings = self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg {
- AngleBracketedArg::Constraint(c) => Some(self.lower_assoc_ty_constraint(c, itctx)),
- AngleBracketedArg::Arg(_) => None,
- }));
+ let constraints =
+ self.arena.alloc_from_iter(data.args.iter().filter_map(|arg| match arg {
+ AngleBracketedArg::Constraint(c) => {
+ Some(self.lower_assoc_item_constraint(c, itctx))
+ }
+ AngleBracketedArg::Arg(_) => None,
+ }));
let ctor = GenericArgsCtor {
args,
- bindings,
+ constraints,
parenthesized: hir::GenericArgsParentheses::No,
span: data.span,
};
@@ -454,12 +457,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
Some(bound_modifier_allowed_features),
);
}
- let binding = self.assoc_ty_binding(sym::Output, output_span, output_ty);
+ let constraint = self.assoc_ty_binding(sym::Output, output_span, output_ty);
(
GenericArgsCtor {
args,
- bindings: arena_vec![self; binding],
+ constraints: arena_vec![self; constraint],
parenthesized: hir::GenericArgsParentheses::ParenSugar,
span: data.inputs_span,
},
@@ -467,24 +470,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
}
- /// An associated type binding `$assoc_ty_name = $ty`.
+ /// An associated type binding (i.e., associated type equality constraint).
pub(crate) fn assoc_ty_binding(
&mut self,
assoc_ty_name: rustc_span::Symbol,
span: Span,
ty: &'hir hir::Ty<'hir>,
- ) -> hir::TypeBinding<'hir> {
+ ) -> hir::AssocItemConstraint<'hir> {
let ident = Ident::with_dummy_span(assoc_ty_name);
- let kind = hir::TypeBindingKind::Equality { term: ty.into() };
+ let kind = hir::AssocItemConstraintKind::Equality { term: ty.into() };
let args = arena_vec![self;];
- let bindings = arena_vec![self;];
+ let constraints = arena_vec![self;];
let gen_args = self.arena.alloc(hir::GenericArgs {
args,
- bindings,
+ constraints,
parenthesized: hir::GenericArgsParentheses::No,
span_ext: DUMMY_SP,
});
- hir::TypeBinding {
+ hir::AssocItemConstraint {
hir_id: self.next_id(),
gen_args,
span: self.lower_span(span),
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 598a3ec2d3c3..435b0b6a9565 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -671,7 +671,7 @@ impl<'a> AstValidator<'a> {
let constraint_sugg = data.args.iter().filter_map(|a| match a {
AngleBracketedArg::Arg(_) => None,
AngleBracketedArg::Constraint(c) => {
- Some(pprust::to_string(|s| s.print_assoc_constraint(c)))
+ Some(pprust::to_string(|s| s.print_assoc_item_constraint(c)))
}
});
format!(
@@ -1199,11 +1199,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
for arg in &data.args {
match arg {
AngleBracketedArg::Arg(arg) => self.visit_generic_arg(arg),
- // Type bindings such as `Item = impl Debug` in `Iterator
- `
- // are allowed to contain nested `impl Trait`.
+ // Associated type bindings such as `Item = impl Debug` in
+ // `Iterator
- ` are allowed to contain nested `impl Trait`.
AngleBracketedArg::Constraint(constraint) => {
self.with_impl_trait(None, |this| {
- this.visit_assoc_constraint(constraint);
+ this.visit_assoc_item_constraint(constraint);
});
}
}
@@ -1363,7 +1363,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}
}
- // The lowered form of parenthesized generic args contains a type binding.
+ // The lowered form of parenthesized generic args contains an associated type binding.
Some(ast::GenericArgs::Parenthesized(args)) => {
self.dcx().emit_err(errors::NegativeBoundWithParentheticalNotation {
span: args.span,
@@ -1589,11 +1589,13 @@ fn deny_equality_constraints(
let len = assoc_path.segments.len() - 1;
let gen_args = args.as_deref().cloned();
// Build ``.
- let arg = AngleBracketedArg::Constraint(AssocConstraint {
+ let arg = AngleBracketedArg::Constraint(AssocItemConstraint {
id: rustc_ast::node_id::DUMMY_NODE_ID,
ident: *ident,
gen_args,
- kind: AssocConstraintKind::Equality { term: predicate.rhs_ty.clone().into() },
+ kind: AssocItemConstraintKind::Equality {
+ term: predicate.rhs_ty.clone().into(),
+ },
span: ident.span,
});
// Add `` to `Foo`.
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index a522f04b21db..a9dca9b6a293 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -1,6 +1,6 @@
use rustc_ast as ast;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
-use rustc_ast::{attr, AssocConstraint, AssocConstraintKind, NodeId};
+use rustc_ast::{attr, AssocItemConstraint, AssocItemConstraintKind, NodeId};
use rustc_ast::{token, PatKind};
use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP};
use rustc_session::parse::{feature_err, feature_err_issue, feature_warn};
@@ -344,7 +344,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
for predicate in &g.where_clause.predicates {
match predicate {
ast::WherePredicate::BoundPredicate(bound_pred) => {
- // A type binding, eg `for<'c> Foo: Send+Clone+'c`
+ // A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
self.check_late_bound_lifetime_defs(&bound_pred.bound_generic_params);
}
_ => {}
@@ -445,21 +445,21 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
visit::walk_fn(self, fn_kind)
}
- fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) {
- if let AssocConstraintKind::Bound { .. } = constraint.kind {
- if let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref()
- && args.inputs.is_empty()
- && matches!(args.output, ast::FnRetTy::Default(..))
- {
- gate!(
- &self,
- return_type_notation,
- constraint.span,
- "return type notation is experimental"
- );
- }
+ fn visit_assoc_item_constraint(&mut self, constraint: &'a AssocItemConstraint) {
+ if let AssocItemConstraintKind::Bound { .. } = constraint.kind
+ && let Some(ast::GenericArgs::Parenthesized(args)) = constraint.gen_args.as_ref()
+ && args.inputs.is_empty()
+ && let ast::FnRetTy::Default(..) = args.output
+ {
+ gate!(
+ &self,
+ return_type_notation,
+ constraint.span,
+ "return type notation is experimental"
+ );
}
- visit::walk_assoc_constraint(self, constraint)
+
+ visit::walk_assoc_item_constraint(self, constraint)
}
fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs
index 2128acba0bab..c61640de6f79 100644
--- a/compiler/rustc_ast_passes/src/node_count.rs
+++ b/compiler/rustc_ast_passes/src/node_count.rs
@@ -119,9 +119,9 @@ impl<'ast> Visitor<'ast> for NodeCounter {
self.count += 1;
walk_generic_args(self, generic_args)
}
- fn visit_assoc_constraint(&mut self, constraint: &AssocConstraint) {
+ fn visit_assoc_item_constraint(&mut self, constraint: &AssocItemConstraint) {
self.count += 1;
- walk_assoc_constraint(self, constraint)
+ walk_assoc_item_constraint(self, constraint)
}
fn visit_attribute(&mut self, _attr: &Attribute) {
self.count += 1;
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index f02fe4cf0a72..4c29ca0ca465 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -1045,7 +1045,7 @@ impl<'a> PrintState<'a> for State<'a> {
self.word("<");
self.commasep(Inconsistent, &data.args, |s, arg| match arg {
ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a),
- ast::AngleBracketedArg::Constraint(c) => s.print_assoc_constraint(c),
+ ast::AngleBracketedArg::Constraint(c) => s.print_assoc_item_constraint(c),
});
self.word(">")
}
@@ -1097,21 +1097,21 @@ impl<'a> State<'a> {
}
}
- pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocConstraint) {
+ pub fn print_assoc_item_constraint(&mut self, constraint: &ast::AssocItemConstraint) {
self.print_ident(constraint.ident);
if let Some(args) = constraint.gen_args.as_ref() {
self.print_generic_args(args, false)
}
self.space();
match &constraint.kind {
- ast::AssocConstraintKind::Equality { term } => {
+ ast::AssocItemConstraintKind::Equality { term } => {
self.word_space("=");
match term {
Term::Ty(ty) => self.print_type(ty),
Term::Const(c) => self.print_expr_anon_const(c, &[]),
}
}
- ast::AssocConstraintKind::Bound { bounds } => {
+ ast::AssocItemConstraintKind::Bound { bounds } => {
if !bounds.is_empty() {
self.word_nbsp(":");
self.print_type_bounds(bounds);
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 2f1b2ce9c4c7..821a90366547 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -399,8 +399,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
let hir = self.infcx.tcx.hir();
- if let Some(body_id) = hir.maybe_body_owned_by(self.mir_def_id()) {
- let expr = hir.body(body_id).value;
+ if let Some(body) = hir.maybe_body_owned_by(self.mir_def_id()) {
+ let expr = body.value;
let place = &self.move_data.move_paths[mpi].place;
let span = place.as_local().map(|local| self.body.local_decls[local].source_info.span);
let mut finder = ExpressionFinder {
@@ -556,11 +556,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// We use the statements were the binding was initialized, and inspect the HIR to look
// for the branching codepaths that aren't covered, to point at them.
let map = self.infcx.tcx.hir();
- let body_id = map.body_owned_by(self.mir_def_id());
- let body = map.body(body_id);
+ let body = map.body_owned_by(self.mir_def_id());
let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] };
- visitor.visit_body(body);
+ visitor.visit_body(&body);
let mut show_assign_sugg = false;
let isnt_initialized = if let InitializationRequiringAction::PartialAssignment
@@ -665,7 +664,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
let mut visitor = LetVisitor { decl_span, sugg_span: None };
- visitor.visit_body(body);
+ visitor.visit_body(&body);
if let Some(span) = visitor.sugg_span {
self.suggest_assign_value(&mut err, moved_place, span);
}
@@ -1348,7 +1347,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
return;
};
// Try to find predicates on *generic params* that would allow copying `ty`
- let ocx = ObligationCtxt::new(self.infcx);
+ let ocx = ObligationCtxt::new_with_diagnostics(self.infcx);
let cause = ObligationCause::misc(span, self.mir_def_id());
ocx.register_bound(cause, self.param_env, ty, def_id);
@@ -1362,7 +1361,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
match *predicate.self_ty().kind() {
ty::Param(param_ty) => Ok((
generics.type_param(param_ty, tcx),
- predicate.trait_ref.print_only_trait_path().to_string(),
+ predicate.trait_ref.print_trait_sugared().to_string(),
)),
_ => Err(()),
}
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 88172c62a3b2..1eb67ea367c2 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -11,7 +11,7 @@ use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::CoroutineKind;
use rustc_index::IndexSlice;
use rustc_infer::infer::BoundRegionConversionTime;
-use rustc_infer::traits::{FulfillmentErrorCode, SelectionError};
+use rustc_infer::traits::SelectionError;
use rustc_middle::bug;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::{
@@ -29,7 +29,9 @@ use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP};
use rustc_target::abi::{FieldIdx, VariantIdx};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _;
-use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
+use rustc_trait_selection::traits::{
+ type_known_to_meet_bound_modulo_regions, FulfillmentErrorCode,
+};
use crate::fluent_generated as fluent;
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 79b485085852..df1a1411cf5f 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -6,7 +6,6 @@ use hir::{ExprKind, Param};
use rustc_errors::{Applicability, Diag};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, BindingMode, ByRef, Node};
-use rustc_infer::traits;
use rustc_middle::bug;
use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt, Upcast};
@@ -18,6 +17,7 @@ use rustc_span::symbol::{kw, Symbol};
use rustc_span::{sym, BytePos, DesugaringKind, Span};
use rustc_target::abi::FieldIdx;
use rustc_trait_selection::infer::InferCtxtExt;
+use rustc_trait_selection::traits;
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
use crate::diagnostics::BorrowedContentSource;
@@ -647,8 +647,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let hir_map = self.infcx.tcx.hir();
let def_id = self.body.source.def_id();
let Some(local_def_id) = def_id.as_local() else { return };
- let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) else { return };
- let body = self.infcx.tcx.hir().body(body_id);
+ let Some(body) = hir_map.maybe_body_owned_by(local_def_id) else { return };
let mut v = SuggestIndexOperatorAlternativeVisitor {
assign_span: span,
@@ -656,7 +655,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
ty,
suggested: false,
};
- v.visit_body(body);
+ v.visit_body(&body);
if !v.suggested {
err.help(format!(
"to modify a `{ty}`, use `.get_mut()`, `.insert()` or the entry API",
@@ -746,9 +745,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// `fn foo(&x: &i32)` -> `fn foo(&(mut x): &i32)`
let def_id = self.body.source.def_id();
if let Some(local_def_id) = def_id.as_local()
- && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
- && let body = self.infcx.tcx.hir().body(body_id)
- && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(body).break_value()
+ && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
+ && let Some(hir_id) = (BindingFinder { span: pat_span }).visit_body(&body).break_value()
&& let node = self.infcx.tcx.hir_node(hir_id)
&& let hir::Node::LetStmt(hir::LetStmt {
pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
@@ -867,8 +865,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
}
}
- if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id())
- && let Block(block, _) = hir_map.body(body_id).value.kind
+ if let Some(body) = hir_map.maybe_body_owned_by(self.mir_def_id())
+ && let Block(block, _) = body.value.kind
{
// `span` corresponds to the expression being iterated, find the `for`-loop desugared
// expression with that span in order to identify potential fixes when encountering a
@@ -1189,10 +1187,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
Some((false, err_label_span, message, _)) => {
let def_id = self.body.source.def_id();
let hir_id = if let Some(local_def_id) = def_id.as_local()
- && let Some(body_id) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
+ && let Some(body) = self.infcx.tcx.hir().maybe_body_owned_by(local_def_id)
{
- let body = self.infcx.tcx.hir().body(body_id);
- BindingFinder { span: err_label_span }.visit_body(body).break_value()
+ BindingFinder { span: err_label_span }.visit_body(&body).break_value()
} else {
None
};
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index e11e4a7247c2..15a8764aab3c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -1183,8 +1183,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn suggest_move_on_borrowing_closure(&self, diag: &mut Diag<'_>) {
let map = self.infcx.tcx.hir();
- let body_id = map.body_owned_by(self.mir_def_id());
- let expr = &map.body(body_id).value.peel_blocks();
+ let body = map.body_owned_by(self.mir_def_id());
+ let expr = &body.value.peel_blocks();
let mut closure_span = None::;
match expr.kind {
hir::ExprKind::MethodCall(.., args, _) => {
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index c2db64e77025..2cf548e28b18 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -12,7 +12,7 @@ use rustc_middle::ty::print::RegionHighlightMode;
use rustc_middle::ty::{self, RegionVid, Ty};
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
use rustc_middle::{bug, span_bug};
-use rustc_span::symbol::{kw, sym, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
use crate::{universal_regions::DefiningTy, MirBorrowckCtxt};
@@ -843,13 +843,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
}) = opaque_ty.kind
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
&& let Some(args) = segment.args
- && let [
- hir::TypeBinding {
- ident: Ident { name: sym::Output, .. },
- kind: hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
- ..
- },
- ] = args.bindings
+ && let [constraint] = args.constraints
+ && constraint.ident.name == sym::Output
+ && let Some(ty) = constraint.ty()
{
ty
} else {
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 49f50babdcb9..5d7ce548469f 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -125,8 +125,8 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
placeholder_indices,
placeholder_index_to_region: _,
liveness_constraints,
- outlives_constraints,
- member_constraints,
+ mut outlives_constraints,
+ mut member_constraints,
universe_causes,
type_tests,
} = constraints;
@@ -144,6 +144,16 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
&universal_region_relations,
);
+ if let Some(guar) = universal_regions.tainted_by_errors() {
+ // Suppress unhelpful extra errors in `infer_opaque_types` by clearing out all
+ // outlives bounds that we may end up checking.
+ outlives_constraints = Default::default();
+ member_constraints = Default::default();
+
+ // Also taint the entire scope.
+ infcx.set_tainted_by_errors(guar);
+ }
+
let mut regioncx = RegionInferenceContext::new(
infcx,
var_origins,
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index f601a9d70739..06adb686ed48 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -340,7 +340,7 @@ fn check_opaque_type_well_formed<'tcx>(
.with_next_trait_solver(next_trait_solver)
.with_opaque_type_inference(parent_def_id)
.build();
- let ocx = ObligationCtxt::new(&infcx);
+ let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let identity_args = GenericArgs::identity_for_item(tcx, def_id);
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index b23ad2e15842..0cb4b15b1271 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -10,9 +10,9 @@ use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_span::Span;
-use rustc_trait_selection::solve::deeply_normalize;
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
+use rustc_trait_selection::traits::ScrubbedTraitError;
use crate::{
constraints::OutlivesConstraint,
@@ -282,11 +282,12 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
) -> Ty<'tcx> {
let result = CustomTypeOp::new(
|ocx| {
- deeply_normalize(
- ocx.infcx.at(&ObligationCause::dummy_with_span(self.span), self.param_env),
+ ocx.deeply_normalize(
+ &ObligationCause::dummy_with_span(self.span),
+ self.param_env,
ty,
)
- .map_err(|_| NoSolution)
+ .map_err(|_: Vec>| NoSolution)
},
"normalize type outlives obligation",
)
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
index 38ec9f7678eb..8b863efad6ca 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs
@@ -14,7 +14,6 @@ use std::rc::Rc;
use crate::{
constraints::OutlivesConstraintSet,
facts::{AllFacts, AllFactsExt},
- location::LocationTable,
region_infer::values::LivenessValues,
universal_regions::UniversalRegions,
};
@@ -39,7 +38,6 @@ pub(super) fn generate<'mir, 'tcx>(
elements: &Rc,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
move_data: &MoveData<'tcx>,
- location_table: &LocationTable,
use_polonius: bool,
) {
debug!("liveness::generate");
@@ -53,11 +51,9 @@ pub(super) fn generate<'mir, 'tcx>(
compute_relevant_live_locals(typeck.tcx(), &free_regions, body);
let facts_enabled = use_polonius || AllFacts::enabled(typeck.tcx());
- let polonius_drop_used = facts_enabled.then(|| {
- let mut drop_used = Vec::new();
- polonius::populate_access_facts(typeck, body, location_table, move_data, &mut drop_used);
- drop_used
- });
+ if facts_enabled {
+ polonius::populate_access_facts(typeck, body, move_data);
+ };
trace::trace(
typeck,
@@ -67,7 +63,6 @@ pub(super) fn generate<'mir, 'tcx>(
move_data,
relevant_live_locals,
boring_locals,
- polonius_drop_used,
);
// Mark regions that should be live where they appear within rvalues or within a call: like
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs
index ccfa9f12ef45..d8f03a07a63c 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/polonius.rs
@@ -85,13 +85,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UseFactsExtractor<'a, 'tcx> {
pub(super) fn populate_access_facts<'a, 'tcx>(
typeck: &mut TypeChecker<'a, 'tcx>,
body: &Body<'tcx>,
- location_table: &LocationTable,
move_data: &MoveData<'tcx>,
- //FIXME: this is not mutated, but expected to be modified as
- // out param, bug?
- dropped_at: &mut Vec<(Local, Location)>,
) {
debug!("populate_access_facts()");
+ let location_table = typeck.borrowck_context.location_table;
if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
let mut extractor = UseFactsExtractor {
@@ -104,10 +101,6 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
};
extractor.visit_body(body);
- facts.var_dropped_at.extend(
- dropped_at.iter().map(|&(local, location)| (local, location_table.mid_index(location))),
- );
-
for (local, local_decl) in body.local_decls.iter_enumerated() {
debug!(
"add use_of_var_derefs_origin facts - local={:?}, type={:?}",
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index 6cc0e67c0f80..50843c602cc8 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -16,6 +16,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
use rustc_mir_dataflow::move_paths::{HasMoveData, MoveData, MovePathIndex};
use rustc_mir_dataflow::ResultsCursor;
+use crate::location::RichLocation;
use crate::{
region_infer::values::{self, LiveLoans},
type_check::liveness::local_use_map::LocalUseMap,
@@ -46,7 +47,6 @@ pub(super) fn trace<'mir, 'tcx>(
move_data: &MoveData<'tcx>,
relevant_live_locals: Vec,
boring_locals: Vec,
- polonius_drop_used: Option>,
) {
let local_use_map = &LocalUseMap::build(&relevant_live_locals, elements, body);
@@ -93,9 +93,7 @@ pub(super) fn trace<'mir, 'tcx>(
let mut results = LivenessResults::new(cx);
- if let Some(drop_used) = polonius_drop_used {
- results.add_extra_drop_facts(drop_used, relevant_live_locals.iter().copied().collect())
- }
+ results.add_extra_drop_facts(&relevant_live_locals);
results.compute_for_all_locals(relevant_live_locals);
@@ -218,21 +216,38 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
///
/// Add facts for all locals with free regions, since regions may outlive
/// the function body only at certain nodes in the CFG.
- fn add_extra_drop_facts(
- &mut self,
- drop_used: Vec<(Local, Location)>,
- relevant_live_locals: FxIndexSet,
- ) {
+ fn add_extra_drop_facts(&mut self, relevant_live_locals: &[Local]) -> Option<()> {
+ let drop_used = self
+ .cx
+ .typeck
+ .borrowck_context
+ .all_facts
+ .as_ref()
+ .map(|facts| facts.var_dropped_at.clone())?;
+
+ let relevant_live_locals: FxIndexSet<_> = relevant_live_locals.iter().copied().collect();
+
let locations = IntervalSet::new(self.cx.elements.num_points());
- for (local, location) in drop_used {
+ for (local, location_index) in drop_used {
if !relevant_live_locals.contains(&local) {
let local_ty = self.cx.body.local_decls[local].ty;
if local_ty.has_free_regions() {
+ let location = match self
+ .cx
+ .typeck
+ .borrowck_context
+ .location_table
+ .to_location(location_index)
+ {
+ RichLocation::Start(l) => l,
+ RichLocation::Mid(l) => l,
+ };
self.cx.add_drop_live_facts_for(local, local_ty, &[location], &locations);
}
}
}
+ Some(())
}
/// Clear the value of fields that are "per local variable".
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 4e46a0c62c7c..291d2782c32c 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -27,8 +27,9 @@ use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::cast::CastTy;
use rustc_middle::ty::visit::TypeVisitableExt;
use rustc_middle::ty::{
- self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
- OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
+ self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, CoroutineArgsExt,
+ Dynamic, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType,
+ UserTypeAnnotationIndex,
};
use rustc_middle::ty::{GenericArgsRef, UserArgs};
use rustc_middle::{bug, span_bug};
@@ -188,15 +189,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
checker.equate_inputs_and_outputs(body, universal_regions, &normalized_inputs_and_output);
checker.check_signature_annotation(body);
- liveness::generate(
- &mut checker,
- body,
- elements,
- flow_inits,
- move_data,
- location_table,
- use_polonius,
- );
+ liveness::generate(&mut checker, body, elements, flow_inits, move_data, use_polonius);
translate_outlives_facts(&mut checker);
let opaque_type_values = infcx.take_opaque_types();
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index f8123535e2d0..9f5fb59e46c5 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -29,7 +29,8 @@ use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, T
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
use rustc_middle::{bug, span_bug};
use rustc_span::symbol::{kw, sym};
-use rustc_span::Symbol;
+use rustc_span::{ErrorGuaranteed, Symbol};
+use std::cell::Cell;
use std::iter;
use crate::renumber::RegionCtxt;
@@ -186,6 +187,10 @@ struct UniversalRegionIndices<'tcx> {
/// The vid assigned to `'static`. Used only for diagnostics.
pub fr_static: RegionVid,
+
+ /// Whether we've encountered an error region. If we have, cancel all
+ /// outlives errors, as they are likely bogus.
+ pub tainted_by_errors: Cell