From ce6adccdade1ec29bff031c296c5ae0d80ab0446 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sun, 12 Mar 2023 00:23:28 -0800 Subject: [PATCH 01/16] Prevent stable `libtest` from supporting `-Zunstable-options` --- src/bootstrap/compile.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8b80dfc0f9b..54971af644c 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -339,6 +339,12 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car "" }; + // `libtest` uses this to know whether or not to support + // `-Zunstable-options`. + if !builder.unstable_features() { + cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1"); + } + let mut features = String::new(); // Cranelift doesn't support `asm`. From 9afffc5b61d34d09e8f677dbfca8f283fc7fa697 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Tue, 14 Mar 2023 17:18:26 +0000 Subject: [PATCH 02/16] Remove box expressions from HIR --- compiler/rustc_ast/src/util/parser.rs | 4 +--- compiler/rustc_hir/src/hir.rs | 8 +------- compiler/rustc_hir/src/intravisit.rs | 1 - compiler/rustc_hir_pretty/src/lib.rs | 4 ---- compiler/rustc_hir_typeck/src/expr.rs | 11 ----------- compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 4 ---- .../src/generator_interior/drop_ranges/cfg_build.rs | 2 -- compiler/rustc_hir_typeck/src/mem_categorization.rs | 1 - compiler/rustc_middle/src/traits/mod.rs | 2 -- compiler/rustc_mir_build/src/thir/cx/expr.rs | 1 - compiler/rustc_passes/src/hir_stats.rs | 2 +- compiler/rustc_passes/src/liveness.rs | 5 +---- compiler/rustc_passes/src/naked_functions.rs | 3 +-- .../src/traits/error_reporting/suggestions.rs | 3 --- src/tools/clippy/clippy_lints/src/infinite_iter.rs | 2 +- src/tools/clippy/clippy_lints/src/loops/never_loop.rs | 3 +-- .../src/matches/significant_drop_in_scrutinee.rs | 1 - .../clippy_lints/src/methods/unnecessary_sort_by.rs | 4 ---- src/tools/clippy/clippy_lints/src/no_effect.rs | 6 ++---- src/tools/clippy/clippy_lints/src/shadow.rs | 3 +-- .../clippy_lints/src/significant_drop_tightening.rs | 1 - src/tools/clippy/clippy_lints/src/utils/author.rs | 5 ----- src/tools/clippy/clippy_utils/src/check_proc_macro.rs | 1 - src/tools/clippy/clippy_utils/src/eager_or_lazy.rs | 3 +-- src/tools/clippy/clippy_utils/src/hir_utils.rs | 3 +-- src/tools/clippy/clippy_utils/src/sugg.rs | 1 - src/tools/clippy/clippy_utils/src/visitors.rs | 1 - 27 files changed, 12 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 3a0af04f9eb..3893875e9a4 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -259,7 +259,6 @@ pub enum ExprPrecedence { Assign, AssignOp, - Box, AddrOf, Let, Unary, @@ -319,8 +318,7 @@ impl ExprPrecedence { ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8, // Unary, prefix - ExprPrecedence::Box - | ExprPrecedence::AddrOf + ExprPrecedence::AddrOf // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`. // However, this is not exactly right. When `let _ = a` is the LHS of a binop we // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b` diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f00a5f24e45..f4b46b9a131 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1673,7 +1673,6 @@ pub struct Expr<'hir> { impl Expr<'_> { pub fn precedence(&self) -> ExprPrecedence { match self.kind { - ExprKind::Box(_) => ExprPrecedence::Box, ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock, ExprKind::Array(_) => ExprPrecedence::Array, ExprKind::Call(..) => ExprPrecedence::Call, @@ -1763,7 +1762,6 @@ impl Expr<'_> { | ExprKind::Lit(_) | ExprKind::ConstBlock(..) | ExprKind::Unary(..) - | ExprKind::Box(..) | ExprKind::AddrOf(..) | ExprKind::Binary(..) | ExprKind::Yield(..) @@ -1851,7 +1849,6 @@ impl Expr<'_> { | ExprKind::InlineAsm(..) | ExprKind::AssignOp(..) | ExprKind::ConstBlock(..) - | ExprKind::Box(..) | ExprKind::Binary(..) | ExprKind::Yield(..) | ExprKind::DropTemps(..) @@ -1862,8 +1859,7 @@ impl Expr<'_> { /// To a first-order approximation, is this a pattern? pub fn is_approximately_pattern(&self) -> bool { match &self.kind { - ExprKind::Box(_) - | ExprKind::Array(_) + ExprKind::Array(_) | ExprKind::Call(..) | ExprKind::Tup(_) | ExprKind::Lit(_) @@ -1910,8 +1906,6 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool { #[derive(Debug, HashStable_Generic)] pub enum ExprKind<'hir> { - /// A `box x` expression. - Box(&'hir Expr<'hir>), /// Allow anonymous constants from an inline `const` block ConstBlock(AnonConst), /// An array (e.g., `[a, b, c, d]`). diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index cc0f64017e4..234256ab553 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -682,7 +682,6 @@ pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonCo pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) { visitor.visit_id(expression.hir_id); match expression.kind { - ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression), ExprKind::Array(subexpressions) => { walk_list!(visitor, visit_expr, subexpressions); } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index d715b03e40e..63ea6c90477 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1366,10 +1366,6 @@ impl<'a> State<'a> { self.ibox(INDENT_UNIT); self.ann.pre(self, AnnNode::Expr(expr)); match expr.kind { - hir::ExprKind::Box(expr) => { - self.word_space("Box::new"); - self.print_call_post(std::slice::from_ref(expr)); - } hir::ExprKind::Array(exprs) => { self.print_expr_vec(exprs); } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 7fc4ccb04ee..b3998446cd5 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -283,7 +283,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; match expr.kind { - ExprKind::Box(subexpr) => self.check_expr_box(subexpr, expected), ExprKind::Lit(ref lit) => self.check_lit(&lit, expected), ExprKind::Binary(op, lhs, rhs) => self.check_binop(expr, op, lhs, rhs, expected), ExprKind::Assign(lhs, rhs, span) => { @@ -358,16 +357,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn check_expr_box(&self, expr: &'tcx hir::Expr<'tcx>, expected: Expectation<'tcx>) -> Ty<'tcx> { - let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| match ty.kind() { - ty::Adt(def, _) if def.is_box() => Expectation::rvalue_hint(self, ty.boxed_ty()), - _ => NoExpectation, - }); - let referent_ty = self.check_expr_with_expectation(expr, expected_inner); - self.require_type_is_sized(referent_ty, expr.span, traits::SizedBoxType); - self.tcx.mk_box(referent_ty) - } - fn check_expr_unary( &self, unop: hir::UnOp, diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index b9a058d6bba..9aa6c7f103f 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -356,10 +356,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { self.walk_captures(closure); } - hir::ExprKind::Box(ref base) => { - self.consume_expr(base); - } - hir::ExprKind::Yield(value, _) => { self.consume_expr(value); } diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs index 7c0402b1c7f..1eeb7d984ee 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs @@ -190,7 +190,6 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> { // // Some of these may be interesting in the future ExprKind::Path(..) - | ExprKind::Box(..) | ExprKind::ConstBlock(..) | ExprKind::Array(..) | ExprKind::Call(..) @@ -478,7 +477,6 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { | ExprKind::AssignOp(..) | ExprKind::Binary(..) | ExprKind::Block(..) - | ExprKind::Box(..) | ExprKind::Cast(..) | ExprKind::Closure { .. } | ExprKind::ConstBlock(..) diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 4d3969d28aa..9a8d7ca9e33 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -382,7 +382,6 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::InlineAsm(..) - | hir::ExprKind::Box(..) | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)), } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 6231dd9b6f5..fb3e9cb1263 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -305,8 +305,6 @@ pub enum ObligationCauseCode<'tcx> { SizedReturnType, /// Yield type must be `Sized`. SizedYieldType, - /// Box expression result type must be `Sized`. - SizedBoxType, /// Inline asm operand type must be `Sized`. InlineAsmSized, /// `[expr; N]` requires `type_of(expr): Copy`. diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 9086412c09a..cecb8a61aa2 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -780,7 +780,6 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::DropTemps(ref source) => { ExprKind::Use { source: self.mirror_expr(source) } } - hir::ExprKind::Box(ref value) => ExprKind::Box { value: self.mirror_expr(value) }, hir::ExprKind::Array(ref fields) => { ExprKind::Array { fields: self.mirror_exprs(fields) } } diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 3e0d53029ef..47e032758f2 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -300,7 +300,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { record_variants!( (self, e, e.kind, Id::Node(e.hir_id), hir, Expr, ExprKind), [ - Box, ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, + ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, DropTemps, Let, If, Loop, Match, Closure, Block, Assign, AssignOp, Field, Index, Path, AddrOf, Break, Continue, Ret, InlineAsm, Struct, Repeat, Yield, Err ] diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index db9d0dcc300..36324e6f8da 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -473,7 +473,6 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::InlineAsm(..) - | hir::ExprKind::Box(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err(_) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) @@ -1059,8 +1058,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_expr(&l, r_succ) } - hir::ExprKind::Box(ref e) - | hir::ExprKind::AddrOf(_, _, ref e) + hir::ExprKind::AddrOf(_, _, ref e) | hir::ExprKind::Cast(ref e, _) | hir::ExprKind::Type(ref e, _) | hir::ExprKind::DropTemps(ref e) @@ -1425,7 +1423,6 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) { | hir::ExprKind::Closure { .. } | hir::ExprKind::Path(_) | hir::ExprKind::Yield(..) - | hir::ExprKind::Box(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err(_) => {} } diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index c5b5cf7f5a9..f07a64c7c3c 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -179,8 +179,7 @@ enum ItemKind { impl<'tcx> CheckInlineAssembly<'tcx> { fn check_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, span: Span) { match expr.kind { - ExprKind::Box(..) - | ExprKind::ConstBlock(..) + ExprKind::ConstBlock(..) | ExprKind::Array(..) | ExprKind::Call(..) | ExprKind::MethodCall(..) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 5541c085075..186bfc701bc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2944,9 +2944,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ObligationCauseCode::SizedYieldType => { err.note("the yield type of a generator must have a statically known size"); } - ObligationCauseCode::SizedBoxType => { - err.note("the type of a box expression must have a statically known size"); - } ObligationCauseCode::AssignmentLhsSized => { err.note("the left-hand-side of an assignment must have a statically known size"); } diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs index d1d2db27c6f..fe28c526be3 100644 --- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs +++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs @@ -167,7 +167,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { Finite }, ExprKind::Block(block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)), - ExprKind::Box(e) | ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e), + ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e), ExprKind::Call(path, _) => { if let ExprKind::Path(ref qpath) = path.kind { cx.qpath_res(qpath, path.hir_id) diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs index b1bc10802e1..f0a1b1dfe56 100644 --- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs @@ -124,8 +124,7 @@ fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'t #[allow(clippy::too_many_lines)] fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec, main_loop_id: HirId) -> NeverLoopResult { match expr.kind { - ExprKind::Box(e) - | ExprKind::Unary(_, e) + ExprKind::Unary(_, e) | ExprKind::Cast(e, _) | ExprKind::Type(e, _) | ExprKind::Field(e, _) diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index b33a2478172..04225beeb70 100644 --- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -321,7 +321,6 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { self.has_significant_drop = true; } } - ExprKind::Box(..) | ExprKind::Array(..) | ExprKind::Call(..) | ExprKind::Unary(..) | diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs index 5201da52bbf..67618f7038a 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -33,10 +33,6 @@ struct SortByKeyDetection { /// contains a and the other replaces it with b) fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: &Ident, b_expr: &Expr<'_>, b_ident: &Ident) -> bool { match (&a_expr.kind, &b_expr.kind) { - // Two boxes with mirrored contents - (ExprKind::Box(left_expr), ExprKind::Box(right_expr)) => { - mirrored_exprs(left_expr, a_ident, right_expr, b_ident) - }, // Two arrays with mirrored contents (ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => { iter::zip(*left_exprs, *right_exprs).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs index 79c1ae4861e..e3712190e67 100644 --- a/src/tools/clippy/clippy_lints/src/no_effect.rs +++ b/src/tools/clippy/clippy_lints/src/no_effect.rs @@ -127,8 +127,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { | ExprKind::Type(inner, _) | ExprKind::Unary(_, inner) | ExprKind::Field(inner, _) - | ExprKind::AddrOf(_, _, inner) - | ExprKind::Box(inner) => has_no_effect(cx, inner), + | ExprKind::AddrOf(_, _, inner) => has_no_effect(cx, inner), ExprKind::Struct(_, fields, ref base) => { !has_drop(cx, cx.typeck_results().expr_ty(expr)) && fields.iter().all(|field| has_no_effect(cx, field.expr)) @@ -234,8 +233,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option reduce_expression(cx, inner).or_else(|| Some(vec![inner])), + | ExprKind::AddrOf(_, _, inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])), ExprKind::Struct(_, fields, ref base) => { if has_drop(cx, cx.typeck_results().expr_ty(expr)) { None diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index 87f966ced0d..ae7d19624ba 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -213,8 +213,7 @@ fn is_self_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, mut expr: &Expr<'_>, hir_ } loop { expr = match expr.kind { - ExprKind::Box(e) - | ExprKind::AddrOf(_, _, e) + ExprKind::AddrOf(_, _, e) | ExprKind::Block( &Block { stmts: [], diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs index e2d90edec5a..e12681c0a0c 100644 --- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs +++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs @@ -380,7 +380,6 @@ impl<'cx, 'sdt, 'tcx> Visitor<'tcx> for SigDropFinder<'cx, 'sdt, 'tcx> { | hir::ExprKind::Assign(..) | hir::ExprKind::AssignOp(..) | hir::ExprKind::Binary(..) - | hir::ExprKind::Box(..) | hir::ExprKind::Call(..) | hir::ExprKind::Field(..) | hir::ExprKind::If(..) diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index f31c3fdb095..bc4adf1596d 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -395,11 +395,6 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { } self.expr(field!(let_expr.init)); }, - ExprKind::Box(inner) => { - bind!(self, inner); - kind!("Box({inner})"); - self.expr(inner); - }, ExprKind::Array(elements) => { bind!(self, elements); kind!("Array({elements})"); diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 43f0df145f0..d3a6929f67e 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -112,7 +112,6 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) { /// Get the search patterns to use for the given expression fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) { match e.kind { - ExprKind::Box(e) => (Pat::Str("box"), expr_search_pat(tcx, e).1), ExprKind::ConstBlock(_) => (Pat::Str("const"), Pat::Str("}")), ExprKind::Tup([]) => (Pat::Str(")"), Pat::Str("(")), ExprKind::Unary(UnOp::Deref, e) => (Pat::Str("*"), expr_search_pat(tcx, e).1), diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index ee2f816f181..babbc7294a1 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -199,8 +199,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS }, // Memory allocation, custom operator, loop, or call to an unknown function - ExprKind::Box(_) - | ExprKind::Unary(..) + ExprKind::Unary(..) | ExprKind::Binary(..) | ExprKind::Loop(..) | ExprKind::Call(..) => self.eagerness = Lazy, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 0603755f8a9..3a6d23ca5c1 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -249,7 +249,6 @@ impl HirEqInterExpr<'_, '_, '_> { both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name) && both(le, re, |l, r| self.eq_expr(l, r)) }, - (&ExprKind::Box(l), &ExprKind::Box(r)) => self.eq_expr(l, r), (&ExprKind::Call(l_fun, l_args), &ExprKind::Call(r_fun, r_args)) => { self.inner.allow_side_effects && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args) }, @@ -628,7 +627,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(j); } }, - ExprKind::Box(e) | ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => { + ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => { self.hash_expr(e); }, ExprKind::Call(fun, args) => { diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 85bf28b708b..44cb5d5756a 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -133,7 +133,6 @@ impl<'a> Sugg<'a> { match expr.kind { hir::ExprKind::AddrOf(..) - | hir::ExprKind::Box(..) | hir::ExprKind::If(..) | hir::ExprKind::Let(..) | hir::ExprKind::Closure { .. } diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index d27a20bd4df..86a93f64fb7 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -600,7 +600,6 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( helper(typeck, false, e, f)?; }, ExprKind::Block(&Block { expr: Some(e), .. }, _) - | ExprKind::Box(e) | ExprKind::Cast(e, _) | ExprKind::Unary(_, e) => { helper(typeck, true, e, f)?; From fb916a0132e7d476255a66d80a5ae6633a11d775 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 15 Mar 2023 12:55:37 +0900 Subject: [PATCH 03/16] Fix riscv64 fuchsia LLVM target name --- compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs index ab7c08958fa..0585ed76fe8 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_fuchsia.rs @@ -2,7 +2,7 @@ use crate::spec::{CodeModel, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { Target { - llvm_target: "riscv64gc-unknown-fuchsia".into(), + llvm_target: "riscv64-unknown-fuchsia".into(), pointer_width: 64, data_layout: "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128".into(), arch: "riscv64".into(), From 86a5e3632c77d1c77d58ddb750a147998b5e4dbd Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 15 Mar 2023 13:30:45 +0900 Subject: [PATCH 04/16] Fix linker detection for clang with prefix --- compiler/rustc_codegen_ssa/src/back/link.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 8aa744ce935..8bb143ed3da 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1199,7 +1199,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { .and_then(|(lhs, rhs)| rhs.chars().all(char::is_numeric).then_some(lhs)) .unwrap_or(stem); - // GCC can have an optional target prefix. + // GCC/Clang can have an optional target prefix. let flavor = if stem == "emcc" { LinkerFlavor::EmCc } else if stem == "gcc" @@ -1207,7 +1207,9 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { || stem == "g++" || stem.ends_with("-g++") || stem == "clang" + || stem.ends_with("-clang") || stem == "clang++" + || stem.ends_with("-clang++") { LinkerFlavor::from_cli(LinkerFlavorCli::Gcc, &sess.target) } else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") { From 26c4c1ea97d16863dbbaf2688d5dc7ce1ca3680b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 10 Mar 2023 17:48:11 -0300 Subject: [PATCH 05/16] Rename impl_trait_in_trait_parent to impl_trait_in_trait_parent_fn --- compiler/rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 2 +- compiler/rustc_trait_selection/src/traits/project.rs | 4 ++-- compiler/rustc_ty_utils/src/assoc.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 14dc9d89180..872fec3954b 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -557,7 +557,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { check_opaque(tcx, id); } DefKind::ImplTraitPlaceholder => { - let parent = tcx.impl_trait_in_trait_parent(id.owner_id.to_def_id()); + let parent = tcx.impl_trait_in_trait_parent_fn(id.owner_id.to_def_id()); // Only check the validity of this opaque type if the function has a default body if let hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(_)), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 28f0924d1d6..eab5cae9f26 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1550,7 +1550,7 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>( if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Alias(ty::Opaque, proj) = ty.kind() && tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder - && tcx.impl_trait_in_trait_parent(proj.def_id) == fn_def_id.to_def_id() + && tcx.impl_trait_in_trait_parent_fn(proj.def_id) == fn_def_id.to_def_id() { let span = tcx.def_span(proj.def_id); let bounds = wfcx.tcx().explicit_item_bounds(proj.def_id); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 9649ce2c5a7..c778574b2c5 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1028,7 +1028,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> | DefKind::InlineConst => true, DefKind::ImplTraitPlaceholder => { - let parent_def_id = tcx.impl_trait_in_trait_parent(def_id.to_def_id()); + let parent_def_id = tcx.impl_trait_in_trait_parent_fn(def_id.to_def_id()); let assoc_item = tcx.associated_item(parent_def_id); match assoc_item.container { // Always encode an RPIT in an impl fn, since it always has a body diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 04d7de531c2..71bd4be6650 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2552,7 +2552,7 @@ impl<'tcx> TyCtxt<'tcx> { matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait)) } - pub fn impl_trait_in_trait_parent(self, mut def_id: DefId) -> DefId { + pub fn impl_trait_in_trait_parent_fn(self, mut def_id: DefId) -> DefId { while let def_kind = self.def_kind(def_id) && def_kind != DefKind::AssocFn { debug_assert_eq!(def_kind, DefKind::ImplTraitPlaceholder); def_id = self.parent(def_id); diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 52d114bae30..4c606b939b2 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1288,7 +1288,7 @@ impl<'tcx> AliasTy<'tcx> { match tcx.def_kind(self.def_id) { DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id), DefKind::ImplTraitPlaceholder => { - tcx.parent(tcx.impl_trait_in_trait_parent(self.def_id)) + tcx.parent(tcx.impl_trait_in_trait_parent_fn(self.def_id)) } kind => bug!("expected a projection AliasTy; found {kind:?}"), } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index ef7c68c1a33..cd676445898 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -132,7 +132,7 @@ where projection.trait_ref_and_own_substs(tcx) } else { // HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys - let def_id = tcx.impl_trait_in_trait_parent(projection.def_id); + let def_id = tcx.impl_trait_in_trait_parent_fn(projection.def_id); let trait_generics = tcx.generics_of(def_id); ( tcx.mk_trait_ref(def_id, projection.substs.truncate_to(tcx, trait_generics)), diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 01075d7c55a..4a439134d8a 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1295,7 +1295,7 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>( ) { let tcx = selcx.tcx(); if tcx.def_kind(obligation.predicate.def_id) == DefKind::ImplTraitPlaceholder { - let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id); + let trait_fn_def_id = tcx.impl_trait_in_trait_parent_fn(obligation.predicate.def_id); let trait_def_id = tcx.parent(trait_fn_def_id); let trait_substs = @@ -2193,7 +2193,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( let tcx = selcx.tcx(); let mut obligations = data.nested; - let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id); + let trait_fn_def_id = tcx.impl_trait_in_trait_parent_fn(obligation.predicate.def_id); let leaf_def = match specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) { Ok(assoc_ty) => assoc_ty, Err(guar) => return Progress::error(tcx, guar), diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index a2816124538..aba8f49b691 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -244,7 +244,7 @@ fn associated_item_for_impl_trait_in_trait( tcx: TyCtxt<'_>, opaque_ty_def_id: LocalDefId, ) -> LocalDefId { - let fn_def_id = tcx.impl_trait_in_trait_parent(opaque_ty_def_id.to_def_id()); + let fn_def_id = tcx.impl_trait_in_trait_parent_fn(opaque_ty_def_id.to_def_id()); let trait_def_id = tcx.parent(fn_def_id); assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index d41bf603983..7512663a9fb 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -269,7 +269,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow { if let ty::Alias(ty::Projection, alias_ty) = *ty.kind() && self.tcx.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder - && self.tcx.impl_trait_in_trait_parent(alias_ty.def_id) == self.fn_def_id + && self.tcx.impl_trait_in_trait_parent_fn(alias_ty.def_id) == self.fn_def_id && self.seen.insert(alias_ty.def_id) { // We have entered some binders as we've walked into the From 39ffe9699a2b24c72bebd1c952daf31707b68106 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 Mar 2023 14:29:06 -0300 Subject: [PATCH 06/16] Properly implement generics_of for traits --- compiler/rustc_ty_utils/src/assoc.rs | 33 ++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index aba8f49b691..fae5997e394 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -289,8 +289,37 @@ fn associated_item_for_impl_trait_in_trait( InternalSubsts::identity_for_item(tcx, opaque_ty_def_id.to_def_id()), ))); - // Copy generics_of of the opaque. - trait_assoc_ty.generics_of(tcx.generics_of(opaque_ty_def_id).clone()); + // Copy generics_of of the opaque type item but the trait is the parent. + trait_assoc_ty.generics_of({ + let opaque_ty_generics = tcx.generics_of(opaque_ty_def_id); + let opaque_ty_parent_count = opaque_ty_generics.parent_count; + let mut params = opaque_ty_generics.params.clone(); + + let parent_generics = tcx.generics_of(trait_def_id); + let parent_count = parent_generics.parent_count + parent_generics.params.len(); + + let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone(); + + for param in &mut params { + param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32 + - opaque_ty_parent_count as u32; + } + + trait_fn_params.extend(params); + params = trait_fn_params; + + let param_def_id_to_index = + params.iter().map(|param| (param.def_id, param.index)).collect(); + + ty::Generics { + parent: Some(trait_def_id), + parent_count, + params, + param_def_id_to_index, + has_self: false, + has_late_bound_regions: opaque_ty_generics.has_late_bound_regions, + } + }); // There are no predicates for the synthesized associated type. trait_assoc_ty.explicit_predicates_of(ty::GenericPredicates { From 39d19ca9f22901a9460b5dcd9897bed969809fc4 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 13 Mar 2023 18:21:00 -0300 Subject: [PATCH 07/16] Make impl_trait_in_trait_container consider newly generated RPITITs --- compiler/rustc_middle/src/ty/mod.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 71bd4be6650..c6db65e7437 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2553,11 +2553,17 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn impl_trait_in_trait_parent_fn(self, mut def_id: DefId) -> DefId { - while let def_kind = self.def_kind(def_id) && def_kind != DefKind::AssocFn { - debug_assert_eq!(def_kind, DefKind::ImplTraitPlaceholder); - def_id = self.parent(def_id); + match self.opt_rpitit_info(def_id) { + Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) + | Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) => fn_def_id, + None => { + while let def_kind = self.def_kind(def_id) && def_kind != DefKind::AssocFn { + debug_assert_eq!(def_kind, DefKind::ImplTraitPlaceholder); + def_id = self.parent(def_id); + } + def_id + } } - def_id } pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool { From 0b9b7dd5c6771ab26dd7cab4cf96f8f5c2059b1a Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Wed, 15 Mar 2023 14:22:26 -0400 Subject: [PATCH 08/16] inherit_overflow: adapt pattern to also work with v0 mangling This test was failing under new-symbol-mangling = true. Adapt pattern to work in both cases. Related to #106002 from December. --- tests/codegen/inherit_overflow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/codegen/inherit_overflow.rs b/tests/codegen/inherit_overflow.rs index 0b0b890b2c9..39909d7abfd 100644 --- a/tests/codegen/inherit_overflow.rs +++ b/tests/codegen/inherit_overflow.rs @@ -4,7 +4,7 @@ //[NOASSERT] compile-flags: -Coverflow-checks=off // CHECK-LABEL: define{{.*}} @assertion -// ASSERT: call void @_ZN4core9panicking5panic17h +// ASSERT: call void @{{.*4core9panicking5panic}} // NOASSERT: ret i8 0 #[no_mangle] pub fn assertion() -> u8 { From e41491fe05a6a11a89b7c494ea0d95d3b32a6b0f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 Mar 2023 18:28:48 -0300 Subject: [PATCH 09/16] ImplTraitPlaceholder -> is_impl_trait_in_trait --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 8 ++++++-- compiler/rustc_hir_analysis/src/variance/mod.rs | 12 ++++++++---- compiler/rustc_hir_typeck/src/closure.rs | 14 +++++--------- .../rustc_infer/src/infer/error_reporting/mod.rs | 13 +++++++------ .../src/infer/error_reporting/note_and_explain.rs | 8 ++++---- compiler/rustc_infer/src/infer/opaque_types.rs | 8 ++------ compiler/rustc_middle/src/ty/mod.rs | 4 ++++ compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_ty_utils/src/ty.rs | 4 +++- src/librustdoc/clean/mod.rs | 2 +- 10 files changed, 41 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index eab5cae9f26..1687aff56d6 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1,7 +1,6 @@ use crate::autoderef::Autoderef; use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; -use hir::def::DefKind; use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; @@ -1549,7 +1548,12 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>( for arg in fn_output.walk() { if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Alias(ty::Opaque, proj) = ty.kind() - && tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder + // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) we should just check + // `tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder`. Right now + // `check_associated_type_bounds` is not called for RPITITs synthesized as + // associated types. See `check_mod_type_wf` to see how synthesized associated + // types are missed due to iterating over HIR. + && tcx.is_impl_trait_in_trait(proj.def_id) && tcx.impl_trait_in_trait_parent_fn(proj.def_id) == fn_def_id.to_def_id() { let span = tcx.def_span(proj.def_id); diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index a8b7699b667..361e8948e85 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -112,10 +112,14 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { match t.kind() { ty::Alias(_, ty::AliasTy { def_id, substs, .. }) - if matches!( - self.tcx.def_kind(*def_id), - DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder - ) => + if matches!(self.tcx.def_kind(*def_id), DefKind::OpaqueTy) => + { + self.visit_opaque(*def_id, substs) + } + // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) check whether this is necessary + // at all for RPITITs. + ty::Alias(_, ty::AliasTy { def_id, substs, .. }) + if self.tcx.is_impl_trait_in_trait(*def_id) => { self.visit_opaque(*def_id, substs) } diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 773ac0e40c5..c47a00139bb 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -2,7 +2,6 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}; -use hir::def::DefKind; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; @@ -713,14 +712,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .subst_iter_copied(self.tcx, substs) .find_map(|(p, s)| get_future_output(p, s))?, ty::Error(_) => return None, - ty::Alias(ty::Projection, proj) - if self.tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder => - { - self.tcx - .bound_explicit_item_bounds(proj.def_id) - .subst_iter_copied(self.tcx, proj.substs) - .find_map(|(p, s)| get_future_output(p, s))? - } + ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => self + .tcx + .bound_explicit_item_bounds(proj.def_id) + .subst_iter_copied(self.tcx, proj.substs) + .find_map(|(p, s)| get_future_output(p, s))?, _ => span_bug!( self.tcx.def_span(expr_def_id), "async fn generator return type not an inference variable: {ret_ty}" diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 8a2b800af0e..c89a45dbb00 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -359,10 +359,12 @@ impl<'tcx> InferCtxt<'tcx> { pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option> { let (def_id, substs) = match *ty.kind() { ty::Alias(_, ty::AliasTy { def_id, substs, .. }) - if matches!( - self.tcx.def_kind(def_id), - DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder - ) => + if matches!(self.tcx.def_kind(def_id), DefKind::OpaqueTy) => + { + (def_id, substs) + } + ty::Alias(_, ty::AliasTy { def_id, substs, .. }) + if self.tcx.is_impl_trait_in_trait(def_id) => { (def_id, substs) } @@ -1754,8 +1756,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) } (true, ty::Alias(ty::Projection, proj)) - if self.tcx.def_kind(proj.def_id) - == DefKind::ImplTraitPlaceholder => + if self.tcx.is_impl_trait_in_trait(proj.def_id) => { let sm = self.tcx.sess.source_map(); let pos = sm.lookup_char_pos(self.tcx.def_span(proj.def_id).lo()); 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 b33729d0be5..b38bbdfe7bb 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 @@ -1,7 +1,7 @@ use super::TypeErrCtxt; use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect}; use rustc_errors::{pluralize, Diagnostic, MultiSpan}; -use rustc_hir::{self as hir, def::DefKind}; +use rustc_hir as hir; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::Printer; @@ -75,7 +75,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag.note("an associated type was expected, but a different one was found"); } (ty::Param(p), ty::Alias(ty::Projection, proj)) | (ty::Alias(ty::Projection, proj), ty::Param(p)) - if tcx.def_kind(proj.def_id) != DefKind::ImplTraitPlaceholder => + if !tcx.is_impl_trait_in_trait(proj.def_id) => { let p_def_id = tcx .generics_of(body_owner_def_id) @@ -222,7 +222,7 @@ impl Trait for X { diag.span_label(p_span, "this type parameter"); } } - (ty::Alias(ty::Projection, proj_ty), _) if tcx.def_kind(proj_ty.def_id) != DefKind::ImplTraitPlaceholder => { + (ty::Alias(ty::Projection, proj_ty), _) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => { self.expected_projection( diag, proj_ty, @@ -231,7 +231,7 @@ impl Trait for X { cause.code(), ); } - (_, ty::Alias(ty::Projection, proj_ty)) if tcx.def_kind(proj_ty.def_id) != DefKind::ImplTraitPlaceholder => { + (_, ty::Alias(ty::Projection, proj_ty)) if !tcx.is_impl_trait_in_trait(proj_ty.def_id) => { let msg = format!( "consider constraining the associated type `{}` to `{}`", values.found, values.expected, diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index d5c824d4c41..cf7b364c678 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -1,7 +1,6 @@ use crate::errors::OpaqueHiddenTypeDiag; use crate::infer::{DefiningAnchor, InferCtxt, InferOk}; use crate::traits; -use hir::def::DefKind; use hir::def_id::{DefId, LocalDefId}; use hir::OpaqueTyOrigin; use rustc_data_structures::sync::Lrc; @@ -481,9 +480,7 @@ where } } - ty::Alias(ty::Projection, proj) - if self.tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder => - { + ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => { // Skip lifetime parameters that are not captures. let variances = self.tcx.variances_of(proj.def_id); @@ -563,8 +560,7 @@ impl<'tcx> InferCtxt<'tcx> { // FIXME(RPITIT): Don't replace RPITITs with inference vars. ty::Alias(ty::Projection, projection_ty) if !projection_ty.has_escaping_bound_vars() - && tcx.def_kind(projection_ty.def_id) - != DefKind::ImplTraitPlaceholder => + && !tcx.is_impl_trait_in_trait(projection_ty.def_id) => { self.infer_projection( param_env, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c6db65e7437..6ef8384d010 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2578,6 +2578,10 @@ impl<'tcx> TyCtxt<'tcx> { let Some(trait_item_def_id) = item.trait_item_def_id else { return false; }; + if self.lower_impl_trait_in_trait_to_assoc_ty() { + return !self.associated_items_for_impl_trait_in_trait(trait_item_def_id).is_empty(); + } + // FIXME(RPITIT): This does a somewhat manual walk through the signature // of the trait fn to look for any RPITITs, but that's kinda doing a lot // of work. We can probably remove this when we refactor RPITITs to be diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index b3139d23d36..fffdbfc9660 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -728,7 +728,7 @@ pub trait PrettyPrinter<'tcx>: } ty::Alias(ty::Projection, ref data) => { if !(self.should_print_verbose() || NO_QUERIES.with(|q| q.get())) - && self.tcx().def_kind(data.def_id) == DefKind::ImplTraitPlaceholder + && self.tcx().is_impl_trait_in_trait(data.def_id) { return self.pretty_print_opaque_impl_type(data.def_id, data.substs); } else { diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 7512663a9fb..ad05b68f1b4 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -268,7 +268,9 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow { if let ty::Alias(ty::Projection, alias_ty) = *ty.kind() - && self.tcx.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder + // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) need to project to the opaque, could + // get it via type_of + subst. + && self.tcx.is_impl_trait_in_trait(alias_ty.def_id) && self.tcx.impl_trait_in_trait_parent_fn(alias_ty.def_id) == self.fn_def_id && self.seen.insert(alias_ty.def_id) { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 29c3afe0d95..989e091a0d2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -426,7 +426,7 @@ fn clean_projection<'tcx>( cx: &mut DocContext<'tcx>, def_id: Option, ) -> Type { - if cx.tcx.def_kind(ty.skip_binder().def_id) == DefKind::ImplTraitPlaceholder { + if cx.tcx.is_impl_trait_in_trait(ty.skip_binder().def_id) { let bounds = cx .tcx .explicit_item_bounds(ty.skip_binder().def_id) From 11f181083136f1a91feb4061c640d8c753e3c5f0 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 13 Mar 2023 19:02:28 -0300 Subject: [PATCH 10/16] Feed is_type_alias_impl_trait for RPITITs on the trait side --- compiler/rustc_middle/src/query/mod.rs | 1 + compiler/rustc_ty_utils/src/assoc.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 75f05c4af23..690a0b8b04d 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -191,6 +191,7 @@ rustc_queries! { { desc { "determine whether the opaque is a type-alias impl trait" } separate_provide_extern + feedable } query unsizing_params_for_adt(key: DefId) -> &'tcx rustc_index::bit_set::BitSet diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index fae5997e394..68b1086e8e3 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -289,6 +289,8 @@ fn associated_item_for_impl_trait_in_trait( InternalSubsts::identity_for_item(tcx, opaque_ty_def_id.to_def_id()), ))); + trait_assoc_ty.is_type_alias_impl_trait(false); + // Copy generics_of of the opaque type item but the trait is the parent. trait_assoc_ty.generics_of({ let opaque_ty_generics = tcx.generics_of(opaque_ty_def_id); From c5c43407603599f4ff2b217cc09be2cc5f39967d Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 14 Mar 2023 19:23:16 -0300 Subject: [PATCH 11/16] Add revisions to fixed tests in -Zlower-impl-trait-in-trait-to-assoc-ty --- ... async-generics-and-bounds.current.stderr} | 12 +++--- .../async-generics-and-bounds.next.stderr | 37 +++++++++++++++++++ .../in-trait/async-generics-and-bounds.rs | 2 + ...s.stderr => async-generics.current.stderr} | 12 +++--- .../in-trait/async-generics.next.stderr | 37 +++++++++++++++++++ .../ui/async-await/in-trait/async-generics.rs | 2 + ...571.stderr => issue-102571.current.stderr} | 2 +- .../in-trait/issue-102571.next.stderr | 14 +++++++ tests/ui/impl-trait/in-trait/issue-102571.rs | 3 ++ ...r => specialization-broken.current.stderr} | 6 +-- .../specialization-broken.next.stderr | 31 ++++++++++++++++ .../in-trait/specialization-broken.rs | 3 ++ ...bounds.stderr => wf-bounds.current.stderr} | 6 +-- .../impl-trait/in-trait/wf-bounds.next.stderr | 30 +++++++++++++++ tests/ui/impl-trait/in-trait/wf-bounds.rs | 2 + 15 files changed, 180 insertions(+), 19 deletions(-) rename tests/ui/async-await/in-trait/{async-generics-and-bounds.stderr => async-generics-and-bounds.current.stderr} (82%) create mode 100644 tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr rename tests/ui/async-await/in-trait/{async-generics.stderr => async-generics.current.stderr} (83%) create mode 100644 tests/ui/async-await/in-trait/async-generics.next.stderr rename tests/ui/impl-trait/in-trait/{issue-102571.stderr => issue-102571.current.stderr} (93%) create mode 100644 tests/ui/impl-trait/in-trait/issue-102571.next.stderr rename tests/ui/impl-trait/in-trait/{specialization-broken.stderr => specialization-broken.current.stderr} (88%) create mode 100644 tests/ui/impl-trait/in-trait/specialization-broken.next.stderr rename tests/ui/impl-trait/in-trait/{wf-bounds.stderr => wf-bounds.current.stderr} (91%) create mode 100644 tests/ui/impl-trait/in-trait/wf-bounds.next.stderr diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr similarity index 82% rename from tests/ui/async-await/in-trait/async-generics-and-bounds.stderr rename to tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr index f1f0d7e5907..780da068962 100644 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.stderr +++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.current.stderr @@ -1,33 +1,33 @@ error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics-and-bounds.rs:12:28 + --> $DIR/async-generics-and-bounds.rs:14:28 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^^^ | note: the parameter type `U` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics-and-bounds.rs:12:18 + --> $DIR/async-generics-and-bounds.rs:14:18 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics-and-bounds.rs:12:28 + --> $DIR/async-generics-and-bounds.rs:14:28 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^^^ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics-and-bounds.rs:12:28 + --> $DIR/async-generics-and-bounds.rs:14:28 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^^^ | note: the parameter type `T` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics-and-bounds.rs:12:18 + --> $DIR/async-generics-and-bounds.rs:14:18 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics-and-bounds.rs:12:28 + --> $DIR/async-generics-and-bounds.rs:14:28 | LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; | ^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr b/tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr new file mode 100644 index 00000000000..780da068962 --- /dev/null +++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.next.stderr @@ -0,0 +1,37 @@ +error[E0311]: the parameter type `U` may not live long enough + --> $DIR/async-generics-and-bounds.rs:14:28 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^^^^^^^ + | +note: the parameter type `U` must be valid for the anonymous lifetime defined here... + --> $DIR/async-generics-and-bounds.rs:14:18 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^^^^^ +note: ...so that the reference type `&(T, U)` does not outlive the data it points at + --> $DIR/async-generics-and-bounds.rs:14:28 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^^^^^^^ + +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/async-generics-and-bounds.rs:14:28 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^^^^^^^ + | +note: the parameter type `T` must be valid for the anonymous lifetime defined here... + --> $DIR/async-generics-and-bounds.rs:14:18 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^^^^^ +note: ...so that the reference type `&(T, U)` does not outlive the data it points at + --> $DIR/async-generics-and-bounds.rs:14:28 + | +LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash; + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0311`. diff --git a/tests/ui/async-await/in-trait/async-generics-and-bounds.rs b/tests/ui/async-await/in-trait/async-generics-and-bounds.rs index a73d55adfec..146e74ec2d0 100644 --- a/tests/ui/async-await/in-trait/async-generics-and-bounds.rs +++ b/tests/ui/async-await/in-trait/async-generics-and-bounds.rs @@ -1,6 +1,8 @@ // check-fail // known-bug: #102682 // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/async-await/in-trait/async-generics.stderr b/tests/ui/async-await/in-trait/async-generics.current.stderr similarity index 83% rename from tests/ui/async-await/in-trait/async-generics.stderr rename to tests/ui/async-await/in-trait/async-generics.current.stderr index 2f05564564c..04e1ab6d769 100644 --- a/tests/ui/async-await/in-trait/async-generics.stderr +++ b/tests/ui/async-await/in-trait/async-generics.current.stderr @@ -1,33 +1,33 @@ error[E0311]: the parameter type `U` may not live long enough - --> $DIR/async-generics.rs:9:28 + --> $DIR/async-generics.rs:11:28 | LL | async fn foo(&self) -> &(T, U); | ^^^^^^^ | note: the parameter type `U` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics.rs:9:18 + --> $DIR/async-generics.rs:11:18 | LL | async fn foo(&self) -> &(T, U); | ^^^^^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics.rs:9:28 + --> $DIR/async-generics.rs:11:28 | LL | async fn foo(&self) -> &(T, U); | ^^^^^^^ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/async-generics.rs:9:28 + --> $DIR/async-generics.rs:11:28 | LL | async fn foo(&self) -> &(T, U); | ^^^^^^^ | note: the parameter type `T` must be valid for the anonymous lifetime defined here... - --> $DIR/async-generics.rs:9:18 + --> $DIR/async-generics.rs:11:18 | LL | async fn foo(&self) -> &(T, U); | ^^^^^ note: ...so that the reference type `&(T, U)` does not outlive the data it points at - --> $DIR/async-generics.rs:9:28 + --> $DIR/async-generics.rs:11:28 | LL | async fn foo(&self) -> &(T, U); | ^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-generics.next.stderr b/tests/ui/async-await/in-trait/async-generics.next.stderr new file mode 100644 index 00000000000..04e1ab6d769 --- /dev/null +++ b/tests/ui/async-await/in-trait/async-generics.next.stderr @@ -0,0 +1,37 @@ +error[E0311]: the parameter type `U` may not live long enough + --> $DIR/async-generics.rs:11:28 + | +LL | async fn foo(&self) -> &(T, U); + | ^^^^^^^ + | +note: the parameter type `U` must be valid for the anonymous lifetime defined here... + --> $DIR/async-generics.rs:11:18 + | +LL | async fn foo(&self) -> &(T, U); + | ^^^^^ +note: ...so that the reference type `&(T, U)` does not outlive the data it points at + --> $DIR/async-generics.rs:11:28 + | +LL | async fn foo(&self) -> &(T, U); + | ^^^^^^^ + +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/async-generics.rs:11:28 + | +LL | async fn foo(&self) -> &(T, U); + | ^^^^^^^ + | +note: the parameter type `T` must be valid for the anonymous lifetime defined here... + --> $DIR/async-generics.rs:11:18 + | +LL | async fn foo(&self) -> &(T, U); + | ^^^^^ +note: ...so that the reference type `&(T, U)` does not outlive the data it points at + --> $DIR/async-generics.rs:11:28 + | +LL | async fn foo(&self) -> &(T, U); + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0311`. diff --git a/tests/ui/async-await/in-trait/async-generics.rs b/tests/ui/async-await/in-trait/async-generics.rs index 67000e5770e..507500abf4e 100644 --- a/tests/ui/async-await/in-trait/async-generics.rs +++ b/tests/ui/async-await/in-trait/async-generics.rs @@ -1,6 +1,8 @@ // check-fail // known-bug: #102682 // edition: 2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/impl-trait/in-trait/issue-102571.stderr b/tests/ui/impl-trait/in-trait/issue-102571.current.stderr similarity index 93% rename from tests/ui/impl-trait/in-trait/issue-102571.stderr rename to tests/ui/impl-trait/in-trait/issue-102571.current.stderr index 87219941d91..cac9a29f644 100644 --- a/tests/ui/impl-trait/in-trait/issue-102571.stderr +++ b/tests/ui/impl-trait/in-trait/issue-102571.current.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-102571.rs:20:9 + --> $DIR/issue-102571.rs:23:9 | LL | let () = t.bar(); | ^^ ------- this expression has type `impl Deref` diff --git a/tests/ui/impl-trait/in-trait/issue-102571.next.stderr b/tests/ui/impl-trait/in-trait/issue-102571.next.stderr new file mode 100644 index 00000000000..cac9a29f644 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/issue-102571.next.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/issue-102571.rs:23:9 + | +LL | let () = t.bar(); + | ^^ ------- this expression has type `impl Deref` + | | + | expected associated type, found `()` + | + = note: expected associated type `impl Deref` + found unit type `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/issue-102571.rs b/tests/ui/impl-trait/in-trait/issue-102571.rs index 61c91e64417..f0ddab5e7f2 100644 --- a/tests/ui/impl-trait/in-trait/issue-102571.rs +++ b/tests/ui/impl-trait/in-trait/issue-102571.rs @@ -1,3 +1,6 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.current.stderr similarity index 88% rename from tests/ui/impl-trait/in-trait/specialization-broken.stderr rename to tests/ui/impl-trait/in-trait/specialization-broken.current.stderr index dc621d6b8a8..f48e7a1ed14 100644 --- a/tests/ui/impl-trait/in-trait/specialization-broken.stderr +++ b/tests/ui/impl-trait/in-trait/specialization-broken.current.stderr @@ -1,5 +1,5 @@ error[E0053]: method `bar` has an incompatible type for trait - --> $DIR/specialization-broken.rs:16:22 + --> $DIR/specialization-broken.rs:19:22 | LL | default impl Foo for U | - this type parameter @@ -11,7 +11,7 @@ LL | fn bar(&self) -> U { | help: change the output type to match the trait: `impl Sized` | note: type in trait - --> $DIR/specialization-broken.rs:9:22 + --> $DIR/specialization-broken.rs:12:22 | LL | fn bar(&self) -> impl Sized; | ^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | fn bar(&self) -> impl Sized; found signature `fn(&U) -> U` error: method with return-position `impl Trait` in trait cannot be specialized - --> $DIR/specialization-broken.rs:16:5 + --> $DIR/specialization-broken.rs:19:5 | LL | fn bar(&self) -> U { | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.next.stderr b/tests/ui/impl-trait/in-trait/specialization-broken.next.stderr new file mode 100644 index 00000000000..f48e7a1ed14 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/specialization-broken.next.stderr @@ -0,0 +1,31 @@ +error[E0053]: method `bar` has an incompatible type for trait + --> $DIR/specialization-broken.rs:19:22 + | +LL | default impl Foo for U + | - this type parameter +... +LL | fn bar(&self) -> U { + | ^ + | | + | expected associated type, found type parameter `U` + | help: change the output type to match the trait: `impl Sized` + | +note: type in trait + --> $DIR/specialization-broken.rs:12:22 + | +LL | fn bar(&self) -> impl Sized; + | ^^^^^^^^^^ + = note: expected signature `fn(&U) -> impl Sized` + found signature `fn(&U) -> U` + +error: method with return-position `impl Trait` in trait cannot be specialized + --> $DIR/specialization-broken.rs:19:5 + | +LL | fn bar(&self) -> U { + | ^^^^^^^^^^^^^^^^^^ + | + = note: specialization behaves in inconsistent and surprising ways with `#![feature(return_position_impl_trait_in_trait)]`, and for now is disallowed + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/impl-trait/in-trait/specialization-broken.rs b/tests/ui/impl-trait/in-trait/specialization-broken.rs index 2fcffdf3f9a..658d0709717 100644 --- a/tests/ui/impl-trait/in-trait/specialization-broken.rs +++ b/tests/ui/impl-trait/in-trait/specialization-broken.rs @@ -1,3 +1,6 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + // FIXME(compiler-errors): I'm not exactly sure if this is expected to pass or not. // But we fixed an ICE anyways. diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr similarity index 91% rename from tests/ui/impl-trait/in-trait/wf-bounds.stderr rename to tests/ui/impl-trait/in-trait/wf-bounds.current.stderr index 03cc4c2b93b..8392f26e7c8 100644 --- a/tests/ui/impl-trait/in-trait/wf-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:9:22 + --> $DIR/wf-bounds.rs:11:22 | LL | fn nya() -> impl Wf>; | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -9,14 +9,14 @@ note: required by a bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:12:23 + --> $DIR/wf-bounds.rs:14:23 | LL | fn nya2() -> impl Wf<[u8]>; | ^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `[u8]` note: required by a bound in `Wf` - --> $DIR/wf-bounds.rs:6:10 + --> $DIR/wf-bounds.rs:8:10 | LL | trait Wf {} | ^ required by this bound in `Wf` diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr new file mode 100644 index 00000000000..8392f26e7c8 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr @@ -0,0 +1,30 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/wf-bounds.rs:11:22 + | +LL | fn nya() -> impl Wf>; + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/wf-bounds.rs:14:23 + | +LL | fn nya2() -> impl Wf<[u8]>; + | ^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `Wf` + --> $DIR/wf-bounds.rs:8:10 + | +LL | trait Wf {} + | ^ required by this bound in `Wf` +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Wf {} + | ++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.rs b/tests/ui/impl-trait/in-trait/wf-bounds.rs index 2c71583b312..39f41275315 100644 --- a/tests/ui/impl-trait/in-trait/wf-bounds.rs +++ b/tests/ui/impl-trait/in-trait/wf-bounds.rs @@ -1,4 +1,6 @@ // issue #101663 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] From 0949da8f4e309ac5e5035250bd662dfdbd5c32b4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 15 Mar 2023 22:55:00 +0000 Subject: [PATCH 12/16] Install projection from RPITIT to default trait method opaque correctly --- .../src/collect/item_bounds.rs | 36 +++++++++++-------- compiler/rustc_ty_utils/src/ty.rs | 17 +++++++-- ...sync-default-fn-overridden.current.stderr} | 2 +- .../async-default-fn-overridden.next.stderr | 11 ++++++ .../in-trait/async-default-fn-overridden.rs | 2 ++ ... default-method-constraint.current.stderr} | 2 +- .../default-method-constraint.next.stderr | 11 ++++++ .../in-trait/default-method-constraint.rs | 2 ++ 8 files changed, 64 insertions(+), 19 deletions(-) rename tests/ui/async-await/in-trait/{async-default-fn-overridden.stderr => async-default-fn-overridden.current.stderr} (88%) create mode 100644 tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr rename tests/ui/impl-trait/in-trait/{default-method-constraint.stderr => default-method-constraint.current.stderr} (90%) create mode 100644 tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 7dce29cc0bb..df0258ff7a3 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -3,7 +3,7 @@ use crate::astconv::AstConv; use rustc_hir as hir; use rustc_infer::traits::util; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{self, ImplTraitInTraitData, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::Span; @@ -76,18 +76,26 @@ pub(super) fn explicit_item_bounds( tcx: TyCtxt<'_>, def_id: DefId, ) -> &'_ [(ty::Predicate<'_>, Span)] { - // If the def_id is about an RPITIT, delegate explicit_item_bounds to the opaque_def_id that - // generated the synthesized associate type. - let rpitit_info = if let Some(ImplTraitInTraitData::Trait { opaque_def_id, .. }) = - tcx.opt_rpitit_info(def_id) - { - Some(opaque_def_id) - } else { - None - }; + match tcx.opt_rpitit_info(def_id) { + // RPITIT's bounds are the same as opaque type bounds, but with + // a projection self type. + Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => { + let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item(); + let opaque_ty = item.expect_opaque_ty(); + return opaque_type_bounds( + tcx, + opaque_def_id, + opaque_ty.bounds, + tcx.mk_projection(def_id, ty::InternalSubsts::identity_for_item(tcx, def_id)), + item.span, + ); + } + // These should have been fed! + Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(), + None => {} + } - let bounds_def_id = rpitit_info.unwrap_or(def_id); - let hir_id = tcx.hir().local_def_id_to_hir_id(bounds_def_id.expect_local()); + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); match tcx.hir().get(hir_id) { hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(bounds, _), @@ -100,12 +108,12 @@ pub(super) fn explicit_item_bounds( .. }) => { let substs = InternalSubsts::identity_for_item(tcx, def_id); - let item_ty = if *in_trait || rpitit_info.is_some() { + let item_ty = if *in_trait && !tcx.lower_impl_trait_in_trait_to_assoc_ty() { tcx.mk_projection(def_id, substs) } else { tcx.mk_opaque(def_id, substs) }; - opaque_type_bounds(tcx, bounds_def_id, bounds, item_ty, *span) + opaque_type_bounds(tcx, def_id, bounds, item_ty, *span) } _ => bug!("item_bounds called on {:?}", def_id), } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index ad05b68f1b4..df4b8543ba6 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -268,8 +268,6 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow { if let ty::Alias(ty::Projection, alias_ty) = *ty.kind() - // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) need to project to the opaque, could - // get it via type_of + subst. && self.tcx.is_impl_trait_in_trait(alias_ty.def_id) && self.tcx.impl_trait_in_trait_parent_fn(alias_ty.def_id) == self.fn_def_id && self.seen.insert(alias_ty.def_id) @@ -284,11 +282,24 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { re } }); + + // If we're lowering to associated item, install the opaque type which is just + // the `type_of` of the trait's associated item. If we're using the old lowering + // strategy, then just reinterpret the associated type like an opaque :^) + let default_ty = if self.tcx.lower_impl_trait_in_trait_to_assoc_ty() { + self + .tcx + .type_of(alias_ty.def_id) + .subst(self.tcx, alias_ty.substs) + } else { + self.tcx.mk_alias(ty::Opaque, alias_ty) + }; + self.predicates.push( ty::Binder::bind_with_vars( ty::ProjectionPredicate { projection_ty: alias_ty, - term: self.tcx.mk_alias(ty::Opaque, alias_ty).into(), + term: default_ty.into(), }, self.bound_vars, ) diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.stderr b/tests/ui/async-await/in-trait/async-default-fn-overridden.current.stderr similarity index 88% rename from tests/ui/async-await/in-trait/async-default-fn-overridden.stderr rename to tests/ui/async-await/in-trait/async-default-fn-overridden.current.stderr index 61a826258d0..2142ee232ca 100644 --- a/tests/ui/async-await/in-trait/async-default-fn-overridden.stderr +++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.current.stderr @@ -1,5 +1,5 @@ warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/async-default-fn-overridden.rs:4:12 + --> $DIR/async-default-fn-overridden.rs:6:12 | LL | #![feature(async_fn_in_trait)] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr b/tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr new file mode 100644 index 00000000000..2142ee232ca --- /dev/null +++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.next.stderr @@ -0,0 +1,11 @@ +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/async-default-fn-overridden.rs:6:12 + | +LL | #![feature(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs index 0fd1a2703db..dd1af93d706 100644 --- a/tests/ui/async-await/in-trait/async-default-fn-overridden.rs +++ b/tests/ui/async-await/in-trait/async-default-fn-overridden.rs @@ -1,5 +1,7 @@ // run-pass // edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] //~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.stderr b/tests/ui/impl-trait/in-trait/default-method-constraint.current.stderr similarity index 90% rename from tests/ui/impl-trait/in-trait/default-method-constraint.stderr rename to tests/ui/impl-trait/in-trait/default-method-constraint.current.stderr index 5e18605aa4c..7bb79911f56 100644 --- a/tests/ui/impl-trait/in-trait/default-method-constraint.stderr +++ b/tests/ui/impl-trait/in-trait/default-method-constraint.current.stderr @@ -1,5 +1,5 @@ warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/default-method-constraint.rs:5:12 + --> $DIR/default-method-constraint.rs:7:12 | LL | #![feature(return_position_impl_trait_in_trait)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr b/tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr new file mode 100644 index 00000000000..7bb79911f56 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/default-method-constraint.next.stderr @@ -0,0 +1,11 @@ +warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/default-method-constraint.rs:7:12 + | +LL | #![feature(return_position_impl_trait_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.rs b/tests/ui/impl-trait/in-trait/default-method-constraint.rs index 8c50cc29586..e85fe3c8626 100644 --- a/tests/ui/impl-trait/in-trait/default-method-constraint.rs +++ b/tests/ui/impl-trait/in-trait/default-method-constraint.rs @@ -1,4 +1,6 @@ // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next // This didn't work in the previous default RPITIT method hack attempt From ff7c3b854df3f61380261fa2d32cd4c0843ebc83 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 16 Mar 2023 01:11:04 +0000 Subject: [PATCH 13/16] Don't install default opaque projection predicates in RPITIT associated type's param-env --- .../rustc_hir_analysis/src/check/wfcheck.rs | 28 +++++++++++-------- compiler/rustc_ty_utils/src/ty.rs | 22 ++++++++++----- ...box-coerce-span-in-default.current.stderr} | 2 +- .../box-coerce-span-in-default.next.stderr | 11 ++++++++ .../in-trait/box-coerce-span-in-default.rs | 2 ++ ...=> default-body-type-err-2.current.stderr} | 2 +- .../default-body-type-err-2.next.stderr | 11 ++++++++ .../in-trait/default-body-type-err-2.rs | 2 ++ ...r => default-body-type-err.current.stderr} | 2 +- .../default-body-type-err.next.stderr | 12 ++++++++ .../in-trait/default-body-type-err.rs | 3 ++ tests/ui/impl-trait/in-trait/default-body.rs | 2 ++ 12 files changed, 78 insertions(+), 21 deletions(-) rename tests/ui/impl-trait/in-trait/{box-coerce-span-in-default.stderr => box-coerce-span-in-default.current.stderr} (90%) create mode 100644 tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr rename tests/ui/impl-trait/in-trait/{default-body-type-err-2.stderr => default-body-type-err-2.current.stderr} (87%) create mode 100644 tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr rename tests/ui/impl-trait/in-trait/{default-body-type-err.stderr => default-body-type-err.current.stderr} (90%) create mode 100644 tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 1687aff56d6..c063b766227 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1545,21 +1545,27 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>( if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id()) && assoc_item.container == ty::AssocItemContainer::TraitContainer { + // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): Even with the new lowering + // strategy, we can't just call `check_associated_item` on the new RPITITs, + // because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail. + // That's because we need to check that the bounds of the RPITIT hold using + // the special substs that we create during opaque type lowering, otherwise we're + // getting a bunch of early bound and free regions mixed up... Haven't looked too + // deep into this, though. for arg in fn_output.walk() { if let ty::GenericArgKind::Type(ty) = arg.unpack() - && let ty::Alias(ty::Opaque, proj) = ty.kind() - // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) we should just check - // `tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder`. Right now - // `check_associated_type_bounds` is not called for RPITITs synthesized as - // associated types. See `check_mod_type_wf` to see how synthesized associated - // types are missed due to iterating over HIR. - && tcx.is_impl_trait_in_trait(proj.def_id) - && tcx.impl_trait_in_trait_parent_fn(proj.def_id) == fn_def_id.to_def_id() + // RPITITs are always eagerly normalized into opaques, so always look for an + // opaque here. + && let ty::Alias(ty::Opaque, opaque_ty) = ty.kind() + && let Some(opaque_def_id) = opaque_ty.def_id.as_local() + && let opaque = tcx.hir().expect_item(opaque_def_id).expect_opaque_ty() + && let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = opaque.origin + && source == fn_def_id { - let span = tcx.def_span(proj.def_id); - let bounds = wfcx.tcx().explicit_item_bounds(proj.def_id); + let span = tcx.def_span(opaque_ty.def_id); + let bounds = wfcx.tcx().explicit_item_bounds(opaque_ty.def_id); let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { - let bound = ty::EarlyBinder(bound).subst(tcx, proj.substs); + let bound = ty::EarlyBinder(bound).subst(tcx, opaque_ty.substs); let normalized_bound = wfcx.normalize(span, None, bound); traits::wf::predicate_obligations( wfcx.infcx, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index df4b8543ba6..9fed1e57c92 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -117,16 +117,22 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] { /// See `ParamEnv` struct definition for details. fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { - // When computing the param_env of an RPITIT, copy param_env of the containing function. The - // synthesized associated type doesn't have extra predicates to assume. - if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) { - return tcx.param_env(fn_def_id); - } - // Compute the bounds on Self and the type parameters. let ty::InstantiatedPredicates { mut predicates, .. } = tcx.predicates_of(def_id).instantiate_identity(tcx); + // When computing the param_env of an RPITIT, use predicates of the containing function, + // *except* for the additional assumption that the RPITIT normalizes to the trait method's + // default opaque type. This is needed to properly check the item bounds of the assoc + // type hold (`check_type_bounds`), since that method already installs a similar projection + // bound, so they will conflict. + // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): I don't like this, we should + // at least be making sure that the generics in RPITITs and their parent fn don't + // get out of alignment, or else we do actually need to substitute these predicates. + if let Some(ImplTraitInTraitData::Trait { fn_def_id, .. }) = tcx.opt_rpitit_info(def_id) { + predicates = tcx.predicates_of(fn_def_id).instantiate_identity(tcx).predicates; + } + // Finally, we have to normalize the bounds in the environment, in // case they contain any associated type projections. This process // can yield errors if the put in illegal associated types, like @@ -160,7 +166,9 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { } let local_did = def_id.as_local(); - let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)); + // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): This isn't correct for + // RPITITs in const trait fn. + let hir_id = local_did.and_then(|def_id| tcx.opt_local_def_id_to_hir_id(def_id)); // FIXME(consts): This is not exactly in line with the constness query. let constness = match hir_id { diff --git a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.current.stderr similarity index 90% rename from tests/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr rename to tests/ui/impl-trait/in-trait/box-coerce-span-in-default.current.stderr index d681ecf25e8..05c025cc169 100644 --- a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.stderr +++ b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.current.stderr @@ -1,5 +1,5 @@ warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/box-coerce-span-in-default.rs:3:12 + --> $DIR/box-coerce-span-in-default.rs:5:12 | LL | #![feature(return_position_impl_trait_in_trait)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr new file mode 100644 index 00000000000..05c025cc169 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.next.stderr @@ -0,0 +1,11 @@ +warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/box-coerce-span-in-default.rs:5:12 + | +LL | #![feature(return_position_impl_trait_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs index a4d483dee7a..163bb4fcf77 100644 --- a/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs +++ b/tests/ui/impl-trait/in-trait/box-coerce-span-in-default.rs @@ -1,4 +1,6 @@ // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(return_position_impl_trait_in_trait)] //~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr similarity index 87% rename from tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr rename to tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr index cc3bdf0e571..85450e3b0a0 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.stderr +++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.current.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/default-body-type-err-2.rs:8:9 + --> $DIR/default-body-type-err-2.rs:10:9 | LL | 42 | ^^- help: try using a conversion method: `.to_string()` diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr new file mode 100644 index 00000000000..85450e3b0a0 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.next.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/default-body-type-err-2.rs:10:9 + | +LL | 42 + | ^^- help: try using a conversion method: `.to_string()` + | | + | expected `String`, found integer + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs b/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs index 45ae2b8ad3a..62323776310 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs +++ b/tests/ui/impl-trait/in-trait/default-body-type-err-2.rs @@ -1,4 +1,6 @@ // edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![allow(incomplete_features)] #![feature(async_fn_in_trait)] diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr similarity index 90% rename from tests/ui/impl-trait/in-trait/default-body-type-err.stderr rename to tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr index 4742eb37d3e..c949168a377 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err.stderr +++ b/tests/ui/impl-trait/in-trait/default-body-type-err.current.stderr @@ -1,5 +1,5 @@ error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String` - --> $DIR/default-body-type-err.rs:7:22 + --> $DIR/default-body-type-err.rs:10:22 | LL | fn lol(&self) -> impl Deref { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String` diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr b/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr new file mode 100644 index 00000000000..c949168a377 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/default-body-type-err.next.stderr @@ -0,0 +1,12 @@ +error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String` + --> $DIR/default-body-type-err.rs:10:22 + | +LL | fn lol(&self) -> impl Deref { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String` +LL | +LL | &1i32 + | ----- return type was inferred to be `&i32` here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/in-trait/default-body-type-err.rs b/tests/ui/impl-trait/in-trait/default-body-type-err.rs index ac9baf91cae..9bd5b777989 100644 --- a/tests/ui/impl-trait/in-trait/default-body-type-err.rs +++ b/tests/ui/impl-trait/in-trait/default-body-type-err.rs @@ -1,3 +1,6 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + #![allow(incomplete_features)] #![feature(return_position_impl_trait_in_trait)] diff --git a/tests/ui/impl-trait/in-trait/default-body.rs b/tests/ui/impl-trait/in-trait/default-body.rs index b0baf5bb10d..ab6a51c6bcb 100644 --- a/tests/ui/impl-trait/in-trait/default-body.rs +++ b/tests/ui/impl-trait/in-trait/default-body.rs @@ -1,5 +1,7 @@ // check-pass // edition:2021 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait, return_position_impl_trait_in_trait)] #![allow(incomplete_features)] From 8d922eba796a236dbfdd032d5e4c279519e02b60 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 16 Mar 2023 01:22:56 +0000 Subject: [PATCH 14/16] Fix on_unimplemented_note for RPITITs --- .../traits/error_reporting/on_unimplemented.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 277926688e2..a9c4e126816 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -144,18 +144,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { trait_ref: ty::PolyTraitRef<'tcx>, obligation: &PredicateObligation<'tcx>, ) -> OnUnimplementedNote { - if self.tcx.opt_rpitit_info(obligation.cause.body_id.to_def_id()).is_some() { - return OnUnimplementedNote::default(); - } - let (def_id, substs) = self .impl_similar_to(trait_ref, obligation) .unwrap_or_else(|| (trait_ref.def_id(), trait_ref.skip_binder().substs)); let trait_ref = trait_ref.skip_binder(); - let body_hir = self.tcx.hir().local_def_id_to_hir_id(obligation.cause.body_id); - let mut flags = - vec![(sym::ItemContext, self.describe_enclosure(body_hir).map(|s| s.to_owned()))]; + let mut flags = vec![]; + // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): HIR is not present for RPITITs, + // but I guess we could synthesize one here. We don't see any errors that rely on + // that yet, though. + let enclosure = + if let Some(body_hir) = self.tcx.opt_local_def_id_to_hir_id(obligation.cause.body_id) { + self.describe_enclosure(body_hir).map(|s| s.to_owned()) + } else { + None + }; + flags.push((sym::ItemContext, enclosure)); match obligation.cause.code() { ObligationCauseCode::BuiltinDerivedObligation(..) From a8839c3de79740ad76bad4439a5cc5169bf68d53 Mon Sep 17 00:00:00 2001 From: est31 Date: Thu, 16 Mar 2023 13:00:49 +0100 Subject: [PATCH 15/16] Use sort_by_key instead of sort_by I went over the cases where sort_by is used and in these two, one can use sort_by_key instead. --- compiler/rustc_borrowck/src/region_infer/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 905d8c42b28..dbf15a3e05f 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -255,7 +255,7 @@ fn sccs_info<'cx, 'tcx>( let var_to_origin = infcx.reg_var_to_origin.borrow(); let mut var_to_origin_sorted = var_to_origin.clone().into_iter().collect::>(); - var_to_origin_sorted.sort_by(|a, b| a.0.cmp(&b.0)); + var_to_origin_sorted.sort_by_key(|vto| vto.0); let mut debug_str = "region variables to origins:\n".to_string(); for (reg_var, origin) in var_to_origin_sorted.into_iter() { debug_str.push_str(&format!("{:?}: {:?}\n", reg_var, origin)); @@ -2216,7 +2216,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // is in the same SCC or something. In that case, find what // appears to be the most interesting point to report to the // user via an even more ad-hoc guess. - categorized_path.sort_by(|p0, p1| p0.category.cmp(&p1.category)); + categorized_path.sort_by_key(|p| p.category); debug!("sorted_path={:#?}", categorized_path); (categorized_path.remove(0), extra_info) From 7a1a02ec9b0224f8ed51e6d259b9516a72a424fd Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 16 Mar 2023 20:55:50 +0100 Subject: [PATCH 16/16] Fix invalid markdown link references --- src/librustdoc/html/templates/STYLE.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/templates/STYLE.md b/src/librustdoc/html/templates/STYLE.md index 72c516c93eb..0281b1c47f8 100644 --- a/src/librustdoc/html/templates/STYLE.md +++ b/src/librustdoc/html/templates/STYLE.md @@ -1,12 +1,12 @@ # Style for Templates -This directory has templates in the [Tera templating language](teradoc), which is very -similar to [Jinja2](jinjadoc) and [Django](djangodoc) templates, and also to [Askama](askamadoc). +This directory has templates in the [Tera templating language][teradoc], which is very +similar to [Jinja2][jinjadoc] and [Django][djangodoc] templates, and also to [Askama][askamadoc]. [teradoc]: https://tera.netlify.app/docs/#templates -[jinjadoc]: https://jinja.palletsprojects.com/en/3.0.x/templates/ -[djangodoc]: https://docs.djangoproject.com/en/3.2/topics/templates/ -[askamadoc]: https://docs.rs/askama/0.10.5/askama/ +[jinjadoc]: https://jinja.palletsprojects.com/en/3.1.x/templates/ +[djangodoc]: https://docs.djangoproject.com/en/4.1/topics/templates/ +[askamadoc]: https://docs.rs/askama/latest/askama/ We want our rendered output to have as little unnecessary whitespace as possible, so that pages load quickly. To achieve that we use Tera's @@ -30,8 +30,8 @@ contents don't necessarily need a new line. Askama templates support quite sophisticated control flow. To keep our templates simple and understandable, we use only a subset: `if` and `for`. In particular -we avoid [assignments in the template logic](assignments) and [Askama -macros](macros). This also may make things easier if we switch to a different +we avoid [assignments in the template logic][assignments] and [Askama +macros][macros]. This also may make things easier if we switch to a different Jinja-style template system, like Askama, in the future. [assignments]: https://djc.github.io/askama/template_syntax.html#assignments