From 2733b8ab8d4407086eb41d615395a9a323a8fd77 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 11 Jun 2024 09:57:16 +0000 Subject: [PATCH 01/13] Avoid follow-up errors on erroneous patterns --- compiler/rustc_hir_typeck/src/pat.rs | 13 +++++----- tests/crashes/109812.rs | 22 ----------------- tests/crashes/125914.rs | 20 ---------------- tests/ui/pattern/missing_lifetime.rs | 25 ++++++++++++++++++++ tests/ui/pattern/missing_lifetime.stderr | 25 ++++++++++++++++++++ tests/ui/pattern/type_mismatch.rs | 30 ++++++++++++++++++++++++ tests/ui/pattern/type_mismatch.stderr | 11 +++++++++ 7 files changed, 97 insertions(+), 49 deletions(-) delete mode 100644 tests/crashes/109812.rs delete mode 100644 tests/crashes/125914.rs create mode 100644 tests/ui/pattern/missing_lifetime.rs create mode 100644 tests/ui/pattern/missing_lifetime.stderr create mode 100644 tests/ui/pattern/type_mismatch.rs create mode 100644 tests/ui/pattern/type_mismatch.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 9476dc70483..814bdc07637 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1223,12 +1223,7 @@ fn check_pat_tuple_struct( // Type-check the tuple struct pattern against the expected type. let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, pat_info.top_info); - let had_err = if let Some(err) = diag { - err.emit(); - true - } else { - false - }; + let had_err = diag.map(|diag| diag.emit()); // Type-check subpatterns. if subpats.len() == variant.fields.len() @@ -1249,6 +1244,10 @@ fn check_pat_tuple_struct( None, ); } + if let Some(e) = had_err { + on_error(e); + return Ty::new_error(tcx, e); + } } else { let e = self.emit_err_pat_wrong_number_of_fields( pat.span, @@ -1257,7 +1256,7 @@ fn check_pat_tuple_struct( subpats, &variant.fields.raw, expected, - had_err, + had_err.is_some(), ); on_error(e); return Ty::new_error(tcx, e); diff --git a/tests/crashes/109812.rs b/tests/crashes/109812.rs deleted file mode 100644 index c29b8746521..00000000000 --- a/tests/crashes/109812.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #109812 - -#![warn(rust_2021_incompatible_closure_captures)] - -enum Either { - One(X), - Two(X), -} - -struct X(Y); - -struct Y; - -fn move_into_fnmut() { - let x = X(Y); - - consume_fnmut(|| { - let Either::Two(ref mut _t) = x; - - let X(mut _t) = x; - }); -} diff --git a/tests/crashes/125914.rs b/tests/crashes/125914.rs deleted file mode 100644 index 77ccb9fb097..00000000000 --- a/tests/crashes/125914.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ known-bug: rust-lang/rust#125914 -enum AstKind<'ast> { - ExprInt, -} - -enum Foo { - Bar(isize), - Baz, -} - -enum Other { - Other1(Foo), - Other2(AstKind), -} - -fn main() { - match Other::Other1(Foo::Baz) { - ::Other::Other2(::Foo::Bar(..)) => {} - } -} diff --git a/tests/ui/pattern/missing_lifetime.rs b/tests/ui/pattern/missing_lifetime.rs new file mode 100644 index 00000000000..081f667d8f6 --- /dev/null +++ b/tests/ui/pattern/missing_lifetime.rs @@ -0,0 +1,25 @@ +//! This test used to ICE: rust-lang/rust#125914 +//! Instead of actually analyzing the erroneous patterns, +//! we instead stop after typeck where errors are already +//! reported. + +enum AstKind<'ast> { + //~^ ERROR: `'ast` is never used + ExprInt, +} + +enum Foo { + Bar(isize), + Baz, +} + +enum Other { + Other1(Foo), + Other2(AstKind), //~ ERROR: missing lifetime specifier +} + +fn main() { + match Other::Other1(Foo::Baz) { + ::Other::Other2(::Foo::Bar(..)) => {} + } +} diff --git a/tests/ui/pattern/missing_lifetime.stderr b/tests/ui/pattern/missing_lifetime.stderr new file mode 100644 index 00000000000..ec4063fd289 --- /dev/null +++ b/tests/ui/pattern/missing_lifetime.stderr @@ -0,0 +1,25 @@ +error[E0106]: missing lifetime specifier + --> $DIR/missing_lifetime.rs:18:12 + | +LL | Other2(AstKind), + | ^^^^^^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL ~ enum Other<'a> { +LL | Other1(Foo), +LL ~ Other2(AstKind<'a>), + | + +error[E0392]: lifetime parameter `'ast` is never used + --> $DIR/missing_lifetime.rs:6:14 + | +LL | enum AstKind<'ast> { + | ^^^^ unused lifetime parameter + | + = help: consider removing `'ast`, referring to it in a field, or using a marker such as `PhantomData` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0106, E0392. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/pattern/type_mismatch.rs b/tests/ui/pattern/type_mismatch.rs new file mode 100644 index 00000000000..408ff758847 --- /dev/null +++ b/tests/ui/pattern/type_mismatch.rs @@ -0,0 +1,30 @@ +//! This test used to ICE: rust-lang/rust#109812 +//! Instead of actually analyzing the erroneous patterns, +//! we instead stop after typeck where errors are already +//! reported. + +#![warn(rust_2021_incompatible_closure_captures)] + +enum Either { + One(X), + Two(X), +} + +struct X(Y); + +struct Y; + +fn consume_fnmut(_: impl FnMut()) {} + +fn move_into_fnmut() { + let x = X(Y); + + consume_fnmut(|| { + let Either::Two(ref mut _t) = x; + //~^ ERROR: mismatched types + + let X(mut _t) = x; + }); +} + +fn main() {} diff --git a/tests/ui/pattern/type_mismatch.stderr b/tests/ui/pattern/type_mismatch.stderr new file mode 100644 index 00000000000..b0441b1fadc --- /dev/null +++ b/tests/ui/pattern/type_mismatch.stderr @@ -0,0 +1,11 @@ +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:23:13 + | +LL | let Either::Two(ref mut _t) = x; + | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `X` + | | + | expected `X`, found `Either` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From a6217011f6aefde02af1a19a7716a411dd7803ff Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 14:59:32 +0000 Subject: [PATCH 02/13] Replace some `Option` with `Result<(), Diag>` --- .../src/diagnostics/conflict_errors.rs | 10 +-- compiler/rustc_hir_typeck/src/demand.rs | 57 ++++++++-------- compiler/rustc_hir_typeck/src/expr.rs | 11 ++- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 4 +- compiler/rustc_hir_typeck/src/pat.rs | 68 +++++++++---------- .../pattern/box-pattern-type-mismatch.rs} | 3 +- .../pattern/box-pattern-type-mismatch.stderr | 19 ++++++ 7 files changed, 95 insertions(+), 77 deletions(-) rename tests/{crashes/124004.rs => ui/pattern/box-pattern-type-mismatch.rs} (74%) create mode 100644 tests/ui/pattern/box-pattern-type-mismatch.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 821a9036654..808d8b78d2d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2888,7 +2888,7 @@ fn report_local_value_does_not_live_long_enough( .. } = explanation { - if let Some(diag) = self.try_report_cannot_return_reference_to_local( + if let Err(diag) = self.try_report_cannot_return_reference_to_local( borrow, borrow_span, span, @@ -3075,7 +3075,7 @@ fn report_temporary_value_does_not_live_long_enough( if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = explanation { - if let Some(diag) = self.try_report_cannot_return_reference_to_local( + if let Err(diag) = self.try_report_cannot_return_reference_to_local( borrow, proper_span, span, @@ -3237,11 +3237,11 @@ fn try_report_cannot_return_reference_to_local( return_span: Span, category: ConstraintCategory<'tcx>, opt_place_desc: Option<&String>, - ) -> Option> { + ) -> Result<(), Diag<'tcx>> { let return_kind = match category { ConstraintCategory::Return(_) => "return", ConstraintCategory::Yield => "yield", - _ => return None, + _ => return Ok(()), }; // FIXME use a better heuristic than Spans @@ -3317,7 +3317,7 @@ fn try_report_cannot_return_reference_to_local( } } - Some(err) + Err(err) } #[instrument(level = "debug", skip(self))] diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index d2a5924c8bb..f9720c9c307 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -4,7 +4,7 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::intravisit::Visitor; -use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; +use rustc_infer::infer::DefineOpaqueTypes; use rustc_middle::bug; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -166,7 +166,7 @@ fn adjust_expr_for_assert_eq_macro( /// Requires that the two types unify, and prints an error message if /// they don't. pub fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { - if let Some(e) = self.demand_suptype_diag(sp, expected, actual) { + if let Err(e) = self.demand_suptype_diag(sp, expected, actual) { e.emit(); } } @@ -176,7 +176,7 @@ pub fn demand_suptype_diag( sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Option> { + ) -> Result<(), Diag<'tcx>> { self.demand_suptype_with_origin(&self.misc(sp), expected, actual) } @@ -186,18 +186,15 @@ pub fn demand_suptype_with_origin( cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Option> { - match self.at(cause, self.param_env).sup(DefineOpaqueTypes::Yes, expected, actual) { - Ok(InferOk { obligations, value: () }) => { - self.register_predicates(obligations); - None - } - Err(e) => Some(self.err_ctxt().report_mismatched_types(cause, expected, actual, e)), - } + ) -> Result<(), Diag<'tcx>> { + self.at(cause, self.param_env) + .sup(DefineOpaqueTypes::Yes, expected, actual) + .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) + .map_err(|e| self.err_ctxt().report_mismatched_types(cause, expected, actual, e)) } pub fn demand_eqtype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { - if let Some(err) = self.demand_eqtype_diag(sp, expected, actual) { + if let Err(err) = self.demand_eqtype_diag(sp, expected, actual) { err.emit(); } } @@ -207,7 +204,7 @@ pub fn demand_eqtype_diag( sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Option> { + ) -> Result<(), Diag<'tcx>> { self.demand_eqtype_with_origin(&self.misc(sp), expected, actual) } @@ -216,14 +213,11 @@ pub fn demand_eqtype_with_origin( cause: &ObligationCause<'tcx>, expected: Ty<'tcx>, actual: Ty<'tcx>, - ) -> Option> { - match self.at(cause, self.param_env).eq(DefineOpaqueTypes::Yes, expected, actual) { - Ok(InferOk { obligations, value: () }) => { - self.register_predicates(obligations); - None - } - Err(e) => Some(self.err_ctxt().report_mismatched_types(cause, expected, actual, e)), - } + ) -> Result<(), Diag<'tcx>> { + self.at(cause, self.param_env) + .eq(DefineOpaqueTypes::Yes, expected, actual) + .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) + .map_err(|e| self.err_ctxt().report_mismatched_types(cause, expected, actual, e)) } pub fn demand_coerce( @@ -234,12 +228,17 @@ pub fn demand_coerce( expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, allow_two_phase: AllowTwoPhase, ) -> Ty<'tcx> { - let (ty, err) = - self.demand_coerce_diag(expr, checked_ty, expected, expected_ty_expr, allow_two_phase); - if let Some(err) = err { - err.emit(); + match self.demand_coerce_diag(expr, checked_ty, expected, expected_ty_expr, allow_two_phase) + { + Ok(ty) => ty, + Err(err) => { + err.emit(); + // Return the original type instead of an error type here, otherwise the type of `x` in + // `let x: u32 = ();` will be a type error, causing all subsequent usages of `x` to not + // report errors, even though `x` is definitely `u32`. + expected + } } - ty } /// Checks that the type of `expr` can be coerced to `expected`. @@ -254,11 +253,11 @@ pub fn demand_coerce_diag( expected: Ty<'tcx>, mut expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, allow_two_phase: AllowTwoPhase, - ) -> (Ty<'tcx>, Option>) { + ) -> Result, Diag<'tcx>> { let expected = self.resolve_vars_with_obligations(expected); let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) { - Ok(ty) => return (ty, None), + Ok(ty) => return Ok(ty), Err(e) => e, }; @@ -275,7 +274,7 @@ pub fn demand_coerce_diag( self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr, Some(e)); - (expected, Some(err)) + Err(err) } /// Notes the point at which a variable is constrained to some type incompatible diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 5b27ebe3416..1f185a35000 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -87,7 +87,7 @@ pub fn check_expr_has_type_or_error( ty = adj_ty; } - if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) { + if let Err(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) { let _ = self.emit_type_mismatch_suggestions( &mut err, expr.peel_drop_temps(), @@ -1132,7 +1132,7 @@ fn check_expr_assign( // say that the user intended to write `lhs == rhs` instead of `lhs = rhs`. // The likely cause of this is `if foo = bar { .. }`. let actual_ty = self.tcx.types.unit; - let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap(); + let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap_err(); let lhs_ty = self.check_expr(lhs); let rhs_ty = self.check_expr(rhs); let refs_can_coerce = |lhs: Ty<'tcx>, rhs: Ty<'tcx>| { @@ -1236,7 +1236,7 @@ fn check_expr_assign( // This is (basically) inlined `check_expr_coercible_to_type`, but we want // to suggest an additional fixup here in `suggest_deref_binop`. let rhs_ty = self.check_expr_with_hint(rhs, lhs_ty); - if let (_, Some(mut diag)) = + if let Err(mut diag) = self.demand_coerce_diag(rhs, rhs_ty, lhs_ty, Some(lhs), AllowTwoPhase::No) { suggest_deref_binop(&mut diag, rhs_ty); @@ -1741,10 +1741,9 @@ fn check_expr_struct_fields( // Make sure to give a type to the field even if there's // an error, so we can continue type-checking. let ty = self.check_expr_with_hint(field.expr, field_type); - let (_, diag) = - self.demand_coerce_diag(field.expr, ty, field_type, None, AllowTwoPhase::No); + let diag = self.demand_coerce_diag(field.expr, ty, field_type, None, AllowTwoPhase::No); - if let Some(diag) = diag { + if let Err(diag) = diag { if idx == hir_fields.len() - 1 { if remaining_fields.is_empty() { self.suggest_fru_from_range_and_emit(field, variant, args, diag); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index b8333d47493..0428ec56c99 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1578,7 +1578,7 @@ pub fn check_decl_initializer( // type of the place it is referencing, and not some // supertype thereof. let init_ty = self.check_expr_with_needs(init, Needs::maybe_mut_place(m)); - if let Some(mut diag) = self.demand_eqtype_diag(init.span, local_ty, init_ty) { + if let Err(mut diag) = self.demand_eqtype_diag(init.span, local_ty, init_ty) { self.emit_type_mismatch_suggestions( &mut diag, init.peel_drop_temps(), @@ -1624,7 +1624,7 @@ pub(in super::super) fn check_decl(&self, decl: Declaration<'tcx>) { let previous_diverges = self.diverges.get(); let else_ty = self.check_block_with_expected(blk, NoExpectation); let cause = self.cause(blk.span, ObligationCauseCode::LetElse); - if let Some(err) = self.demand_eqtype_with_origin(&cause, self.tcx.types.never, else_ty) + if let Err(err) = self.demand_eqtype_with_origin(&cause, self.tcx.types.never, else_ty) { err.emit(); } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 814bdc07637..9d4ba1eb489 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -105,15 +105,16 @@ fn demand_eqtype_pat_diag( expected: Ty<'tcx>, actual: Ty<'tcx>, ti: &TopInfo<'tcx>, - ) -> Option> { - let mut diag = - self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?; - if let Some(expr) = ti.origin_expr { - self.suggest_fn_call(&mut diag, expr, expected, |output| { - self.can_eq(self.param_env, output, actual) - }); - } - Some(diag) + ) -> Result<(), Diag<'tcx>> { + self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual) + .map_err(|mut diag| { + if let Some(expr) = ti.origin_expr { + self.suggest_fn_call(&mut diag, expr, expected, |output| { + self.can_eq(self.param_env, output, actual) + }); + } + diag + }) } fn demand_eqtype_pat( @@ -122,10 +123,8 @@ fn demand_eqtype_pat( expected: Ty<'tcx>, actual: Ty<'tcx>, ti: &TopInfo<'tcx>, - ) { - if let Some(err) = self.demand_eqtype_pat_diag(cause_span, expected, actual, ti) { - err.emit(); - } + ) -> Result<(), ErrorGuaranteed> { + self.demand_eqtype_pat_diag(cause_span, expected, actual, ti).map_err(|err| err.emit()) } } @@ -509,7 +508,7 @@ fn check_pat_lit( // // then that's equivalent to there existing a LUB. let cause = self.pattern_cause(ti, span); - if let Some(err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) { + if let Err(err) = self.demand_suptype_with_origin(&cause, expected, pat_ty) { err.emit_unless( ti.span .filter(|&s| { @@ -562,7 +561,7 @@ fn check_pat_range( // Subtyping doesn't matter here, as the value is some kind of scalar. let demand_eqtype = |x: &mut _, y| { if let Some((ref mut fail, x_ty, x_span)) = *x - && let Some(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti) + && let Err(mut err) = self.demand_eqtype_pat_diag(x_span, expected, x_ty, ti) { if let Some((_, y_ty, y_span)) = y { self.endpoint_has_type(&mut err, y_span, y_ty); @@ -736,7 +735,9 @@ fn check_pat_ident( // Otherwise, the type of x is the expected type `T`. ByRef::No => expected, // As above, `T <: typeof(x)` is required, but we use equality, see (note_1). }; - self.demand_eqtype_pat(pat.span, eq_ty, local_ty, ti); + + // We have a concrete type for the local, so we do not need to taint it and hide follow up errors *using* the local. + let _ = self.demand_eqtype_pat(pat.span, eq_ty, local_ty, ti); // If there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be. @@ -763,7 +764,7 @@ fn check_binding_alt_eq_ty( ti: &TopInfo<'tcx>, ) { let var_ty = self.local_ty(span, var_id); - if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) { + if let Err(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) { let hir = self.tcx.hir(); let var_ty = self.resolve_vars_if_possible(var_ty); let msg = format!("first introduced with type `{var_ty}` here"); @@ -986,7 +987,7 @@ fn check_pat_struct( }; // Type-check the path. - self.demand_eqtype_pat(pat.span, expected, pat_ty, pat_info.top_info); + let _ = self.demand_eqtype_pat(pat.span, expected, pat_ty, pat_info.top_info); // Type-check subpatterns. if self.check_struct_pat_fields(pat_ty, pat, variant, fields, has_rest_pat, pat_info) { @@ -1050,7 +1051,7 @@ fn check_pat_path( // Type-check the path. let (pat_ty, pat_res) = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.span, pat.hir_id); - if let Some(err) = + if let Err(err) = self.demand_suptype_with_origin(&self.pattern_cause(ti, pat.span), expected, pat_ty) { self.emit_bad_pat_path(err, pat, res, pat_res, pat_ty, segments); @@ -1223,7 +1224,7 @@ fn check_pat_tuple_struct( // Type-check the tuple struct pattern against the expected type. let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, pat_info.top_info); - let had_err = diag.map(|diag| diag.emit()); + let had_err = diag.map_err(|diag| diag.emit()); // Type-check subpatterns. if subpats.len() == variant.fields.len() @@ -1244,7 +1245,7 @@ fn check_pat_tuple_struct( None, ); } - if let Some(e) = had_err { + if let Err(e) = had_err { on_error(e); return Ty::new_error(tcx, e); } @@ -1256,7 +1257,7 @@ fn check_pat_tuple_struct( subpats, &variant.fields.raw, expected, - had_err.is_some(), + had_err.is_err(), ); on_error(e); return Ty::new_error(tcx, e); @@ -1444,8 +1445,7 @@ fn check_pat_tuple( let element_tys_iter = (0..max_len).map(|_| self.next_ty_var(span)); let element_tys = tcx.mk_type_list_from_iter(element_tys_iter); let pat_ty = Ty::new_tup(tcx, element_tys); - if let Some(err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, pat_info.top_info) { - let reported = err.emit(); + if let Err(reported) = self.demand_eqtype_pat(span, expected, pat_ty, pat_info.top_info) { // Walk subpatterns with an expected type of `err` in this case to silence // further errors being emitted when using the bindings. #50333 let element_tys_iter = (0..max_len).map(|_| Ty::new_error(tcx, reported)); @@ -2064,20 +2064,20 @@ fn check_pat_box( pat_info: PatInfo<'tcx, '_>, ) -> Ty<'tcx> { let tcx = self.tcx; - let (box_ty, inner_ty) = match self.check_dereferenceable(span, expected, inner) { - Ok(()) => { + let (box_ty, inner_ty) = self + .check_dereferenceable(span, expected, inner) + .and_then(|()| { // Here, `demand::subtype` is good enough, but I don't // think any errors can be introduced by using `demand::eqtype`. let inner_ty = self.next_ty_var(inner.span); let box_ty = Ty::new_box(tcx, inner_ty); - self.demand_eqtype_pat(span, expected, box_ty, pat_info.top_info); - (box_ty, inner_ty) - } - Err(guar) => { + self.demand_eqtype_pat(span, expected, box_ty, pat_info.top_info)?; + Ok((box_ty, inner_ty)) + }) + .unwrap_or_else(|guar| { let err = Ty::new_error(tcx, guar); (err, err) - } - }; + }); self.check_pat(inner, inner_ty, pat_info); box_ty } @@ -2221,7 +2221,7 @@ fn check_pat_ref( // Look for a case like `fn foo(&foo: u32)` and suggest // `fn foo(foo: &u32)` - if let Some(mut err) = err { + if let Err(mut err) = err { self.borrow_pat_suggestion(&mut err, pat); err.emit(); } @@ -2326,7 +2326,7 @@ fn check_pat_slice( self.try_resolve_slice_ty_to_array_ty(before, slice, span) { debug!(?resolved_arr_ty); - self.demand_eqtype(span, expected, resolved_arr_ty); + let _ = self.demand_eqtype(span, expected, resolved_arr_ty); } } diff --git a/tests/crashes/124004.rs b/tests/ui/pattern/box-pattern-type-mismatch.rs similarity index 74% rename from tests/crashes/124004.rs rename to tests/ui/pattern/box-pattern-type-mismatch.rs index 1fcf0785945..6c980503256 100644 --- a/tests/crashes/124004.rs +++ b/tests/ui/pattern/box-pattern-type-mismatch.rs @@ -1,10 +1,11 @@ -//@ known-bug: #124004 +//! This test used to ICE #124004 #![feature(box_patterns)] use std::ops::{ Deref }; struct X(dyn Iterator); +//~^ ERROR: use of undeclared lifetime name `'a` impl Deref for X { type Target = isize; diff --git a/tests/ui/pattern/box-pattern-type-mismatch.stderr b/tests/ui/pattern/box-pattern-type-mismatch.stderr new file mode 100644 index 00000000000..14f7dbbd839 --- /dev/null +++ b/tests/ui/pattern/box-pattern-type-mismatch.stderr @@ -0,0 +1,19 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/box-pattern-type-mismatch.rs:7:31 + | +LL | struct X(dyn Iterator); + | ^^ undeclared lifetime + | + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the bound lifetime-generic with a new `'a` lifetime + | +LL | struct X(dyn for<'a> Iterator); + | +++++++ +help: consider introducing lifetime `'a` here + | +LL | struct X<'a>(dyn Iterator); + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0261`. From ece3e3e4c146a94996b4c0f6141caf0a0a877084 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 15:09:03 +0000 Subject: [PATCH 03/13] Replace some `Option` with `Result<(), Diag>` --- compiler/rustc_hir_typeck/src/pat.rs | 42 +++++++++++----------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 9d4ba1eb489..a6f05e9b406 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -990,10 +990,9 @@ fn check_pat_struct( let _ = self.demand_eqtype_pat(pat.span, expected, pat_ty, pat_info.top_info); // Type-check subpatterns. - if self.check_struct_pat_fields(pat_ty, pat, variant, fields, has_rest_pat, pat_info) { - pat_ty - } else { - Ty::new_misc_error(self.tcx) + match self.check_struct_pat_fields(pat_ty, pat, variant, fields, has_rest_pat, pat_info) { + Ok(()) => pat_ty, + Err(guar) => Ty::new_error(self.tcx, guar), } } @@ -1469,7 +1468,7 @@ fn check_struct_pat_fields( fields: &'tcx [hir::PatField<'tcx>], has_rest_pat: bool, pat_info: PatInfo<'tcx, '_>, - ) -> bool { + ) -> Result<(), ErrorGuaranteed> { let tcx = self.tcx; let ty::Adt(adt, args) = adt_ty.kind() else { @@ -1485,7 +1484,7 @@ fn check_struct_pat_fields( // Keep track of which fields have already appeared in the pattern. let mut used_fields = FxHashMap::default(); - let mut no_field_errors = true; + let mut result = Ok(()); let mut inexistent_fields = vec![]; // Typecheck each field. @@ -1494,8 +1493,8 @@ fn check_struct_pat_fields( let ident = tcx.adjust_ident(field.ident, variant.def_id); let field_ty = match used_fields.entry(ident) { Occupied(occupied) => { - no_field_errors = false; let guar = self.error_field_already_bound(span, field.ident, *occupied.get()); + result = Err(guar); Ty::new_error(tcx, guar) } Vacant(vacant) => { @@ -1510,7 +1509,6 @@ fn check_struct_pat_fields( }) .unwrap_or_else(|| { inexistent_fields.push(field); - no_field_errors = false; Ty::new_misc_error(tcx) }) } @@ -1589,32 +1587,26 @@ fn check_struct_pat_fields( // `Foo { a, b }` when it should have been `Foo(a, b)`. i.delay_as_bug(); u.delay_as_bug(); - e.emit(); + Err(e.emit()) } else { i.emit(); - u.emit(); + Err(u.emit()) } } (None, Some(u)) => { if let Some(e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) { u.delay_as_bug(); - e.emit(); + Err(e.emit()) } else { - u.emit(); + Err(u.emit()) } } - (Some(err), None) => { - err.emit(); + (Some(err), None) => Err(err.emit()), + (None, None) => { + self.error_tuple_variant_index_shorthand(variant, pat, fields)?; + result } - (None, None) - if let Some(err) = - self.error_tuple_variant_index_shorthand(variant, pat, fields) => - { - err.emit(); - } - (None, None) => {} } - no_field_errors } fn error_tuple_variant_index_shorthand( @@ -1622,7 +1614,7 @@ fn error_tuple_variant_index_shorthand( variant: &VariantDef, pat: &'_ Pat<'_>, fields: &[hir::PatField<'_>], - ) -> Option> { + ) -> Result<(), ErrorGuaranteed> { // if this is a tuple struct, then all field names will be numbers // so if any fields in a struct pattern use shorthand syntax, they will // be invalid identifiers (for example, Foo { 0, 1 }). @@ -1644,10 +1636,10 @@ fn error_tuple_variant_index_shorthand( format!("({})", self.get_suggested_tuple_struct_pattern(fields, variant)), Applicability::MaybeIncorrect, ); - return Some(err); + return Err(err.emit()); } } - None + Ok(()) } fn error_foreign_non_exhaustive_spat(&self, pat: &Pat<'_>, descr: &str, no_fields: bool) { From e8d6170b8a6e70901b63ec967e37595949ecb66c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 15:11:49 +0000 Subject: [PATCH 04/13] Replace some `Option` with `Result<(), Diag>` --- compiler/rustc_hir_typeck/src/pat.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index a6f05e9b406..898d90b9f45 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1582,21 +1582,21 @@ fn check_struct_pat_fields( } match (inexistent_fields_err, unmentioned_err) { (Some(i), Some(u)) => { - if let Some(e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) { + if let Err(e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) { // We don't want to show the nonexistent fields error when this was // `Foo { a, b }` when it should have been `Foo(a, b)`. i.delay_as_bug(); u.delay_as_bug(); - Err(e.emit()) + Err(e) } else { i.emit(); Err(u.emit()) } } (None, Some(u)) => { - if let Some(e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) { + if let Err(e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) { u.delay_as_bug(); - Err(e.emit()) + Err(e) } else { Err(u.emit()) } @@ -1795,14 +1795,14 @@ fn error_tuple_variant_as_struct_pat( pat: &Pat<'_>, fields: &'tcx [hir::PatField<'tcx>], variant: &ty::VariantDef, - ) -> Option> { + ) -> Result<(), ErrorGuaranteed> { if let (Some(CtorKind::Fn), PatKind::Struct(qpath, pattern_fields, ..)) = (variant.ctor_kind(), &pat.kind) { let is_tuple_struct_match = !pattern_fields.is_empty() && pattern_fields.iter().map(|field| field.ident.name.as_str()).all(is_number); if is_tuple_struct_match { - return None; + return Ok(()); } let path = rustc_hir_pretty::qpath_to_string(&self.tcx, qpath); @@ -1830,9 +1830,9 @@ fn error_tuple_variant_as_struct_pat( format!("({sugg})"), appl, ); - return Some(err); + return Err(err.emit()); } - None + Ok(()) } fn get_suggested_tuple_struct_pattern( From 7566307edc3b1e08b5bf08a664243fc4889e55c3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 12 Jun 2024 15:19:57 +0000 Subject: [PATCH 05/13] Replace a `bool` with a `Result<(), ErrorGuaranteed>` --- compiler/rustc_hir_typeck/src/pat.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 898d90b9f45..220556fe256 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1256,7 +1256,7 @@ fn check_pat_tuple_struct( subpats, &variant.fields.raw, expected, - had_err.is_err(), + had_err, ); on_error(e); return Ty::new_error(tcx, e); @@ -1272,7 +1272,7 @@ fn emit_err_pat_wrong_number_of_fields( subpats: &'tcx [Pat<'tcx>], fields: &'tcx [ty::FieldDef], expected: Ty<'tcx>, - had_err: bool, + had_err: Result<(), ErrorGuaranteed>, ) -> ErrorGuaranteed { let subpats_ending = pluralize!(subpats.len()); let fields_ending = pluralize!(fields.len()); @@ -1329,7 +1329,7 @@ fn emit_err_pat_wrong_number_of_fields( // #67037: only do this if we could successfully type-check the expected type against // the tuple struct pattern. Otherwise the args could get out of range on e.g., // `let P() = U;` where `P != U` with `struct P(T);`. - (ty::Adt(_, args), [field], false) => { + (ty::Adt(_, args), [field], Ok(())) => { let field_ty = self.field_ty(pat_span, field, args); match field_ty.kind() { ty::Tuple(fields) => fields.len() == subpats.len(), From b28221e74f5f05d0f7a6212f99c9d5af868c0ed3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Apr 2024 11:10:50 +0000 Subject: [PATCH 06/13] Use diagnostic method for diagnostics --- compiler/rustc_hir_typeck/src/callee.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 9736c8b8920..93222c18686 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -628,7 +628,7 @@ fn suggest_call_as_method( return; }; - let pick = self.confirm_method( + let pick = self.confirm_method_for_diagnostic( call_expr.span, callee_expr, call_expr, From c75f7283bf52c6e2ec6a178f2b7717a4daddacf4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Apr 2024 11:20:33 +0000 Subject: [PATCH 07/13] Add some tests --- .../call_method_ambiguous.next.stderr | 17 ++++++++ tests/ui/impl-trait/call_method_ambiguous.rs | 39 +++++++++++++++++ .../call_method_on_inherent_impl.next.stderr | 17 ++++++++ .../call_method_on_inherent_impl.rs | 25 +++++++++++ ...inherent_impl_on_rigid_type.current.stderr | 16 +++++++ ...on_inherent_impl_on_rigid_type.next.stderr | 17 ++++++++ ...l_method_on_inherent_impl_on_rigid_type.rs | 22 ++++++++++ ...method_on_inherent_impl_ref.current.stderr | 40 ++++++++++++++++++ ...ll_method_on_inherent_impl_ref.next.stderr | 31 ++++++++++++++ .../call_method_on_inherent_impl_ref.rs | 35 ++++++++++++++++ ...all_method_without_import.no_import.stderr | 37 ++++++++++++++++ .../impl-trait/call_method_without_import.rs | 42 +++++++++++++++++++ .../method-resolution.current.stderr | 36 ++++++++++++++++ tests/ui/impl-trait/method-resolution.rs | 29 +++++++++++++ .../impl-trait/method-resolution2.next.stderr | 20 +++++++++ tests/ui/impl-trait/method-resolution2.rs | 31 ++++++++++++++ .../method-resolution3.current.stderr | 37 ++++++++++++++++ .../impl-trait/method-resolution3.next.stderr | 20 +++++++++ tests/ui/impl-trait/method-resolution3.rs | 29 +++++++++++++ .../impl-trait/method-resolution4.next.stderr | 22 ++++++++++ tests/ui/impl-trait/method-resolution4.rs | 20 +++++++++ .../recursive-parent-trait-method-call.rs | 42 +++++++++++++++++++ .../method_resolution.current.stderr | 15 +++++++ .../method_resolution.next.stderr | 12 ++++++ .../method_resolution.rs | 30 +++++++++++++ .../method_resolution2.current.stderr | 36 ++++++++++++++++ .../method_resolution2.rs | 30 +++++++++++++ .../method_resolution3.current.stderr | 21 ++++++++++ .../method_resolution3.next.stderr | 15 +++++++ .../method_resolution3.rs | 36 ++++++++++++++++ .../method_resolution4.current.stderr | 21 ++++++++++ .../method_resolution4.next.stderr | 15 +++++++ .../method_resolution4.rs | 39 +++++++++++++++++ .../method_resolution5.current.stderr | 15 +++++++ .../method_resolution5.rs | 34 +++++++++++++++ ...on_trait_method_from_opaque.current.stderr | 15 +++++++ ...ution_trait_method_from_opaque.next.stderr | 9 ++++ ...hod_resolution_trait_method_from_opaque.rs | 31 ++++++++++++++ 38 files changed, 998 insertions(+) create mode 100644 tests/ui/impl-trait/call_method_ambiguous.next.stderr create mode 100644 tests/ui/impl-trait/call_method_ambiguous.rs create mode 100644 tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr create mode 100644 tests/ui/impl-trait/call_method_on_inherent_impl.rs create mode 100644 tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr create mode 100644 tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr create mode 100644 tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs create mode 100644 tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr create mode 100644 tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr create mode 100644 tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs create mode 100644 tests/ui/impl-trait/call_method_without_import.no_import.stderr create mode 100644 tests/ui/impl-trait/call_method_without_import.rs create mode 100644 tests/ui/impl-trait/method-resolution.current.stderr create mode 100644 tests/ui/impl-trait/method-resolution.rs create mode 100644 tests/ui/impl-trait/method-resolution2.next.stderr create mode 100644 tests/ui/impl-trait/method-resolution2.rs create mode 100644 tests/ui/impl-trait/method-resolution3.current.stderr create mode 100644 tests/ui/impl-trait/method-resolution3.next.stderr create mode 100644 tests/ui/impl-trait/method-resolution3.rs create mode 100644 tests/ui/impl-trait/method-resolution4.next.stderr create mode 100644 tests/ui/impl-trait/method-resolution4.rs create mode 100644 tests/ui/impl-trait/recursive-parent-trait-method-call.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution2.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution2.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution3.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution3.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution3.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution4.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution4.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution4.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution5.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution5.rs create mode 100644 tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr create mode 100644 tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs diff --git a/tests/ui/impl-trait/call_method_ambiguous.next.stderr b/tests/ui/impl-trait/call_method_ambiguous.next.stderr new file mode 100644 index 00000000000..cd222aa7ae9 --- /dev/null +++ b/tests/ui/impl-trait/call_method_ambiguous.next.stderr @@ -0,0 +1,17 @@ +error[E0282]: type annotations needed + --> $DIR/call_method_ambiguous.rs:29:13 + | +LL | let mut iter = foo(n - 1, m); + | ^^^^^^^^ +LL | +LL | assert_eq!(iter.get(), 1); + | ---- type must be known at this point + | +help: consider giving `iter` an explicit type + | +LL | let mut iter: /* Type */ = foo(n - 1, m); + | ++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/call_method_ambiguous.rs b/tests/ui/impl-trait/call_method_ambiguous.rs new file mode 100644 index 00000000000..c26c01e002d --- /dev/null +++ b/tests/ui/impl-trait/call_method_ambiguous.rs @@ -0,0 +1,39 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[current] run-pass + +#![feature(precise_capturing)] +#![allow(incomplete_features)] + +trait Get { + fn get(&mut self) -> u32; +} + +impl Get for () { + fn get(&mut self) -> u32 { + 0 + } +} + +impl Get for &mut T +where + T: Get, +{ + fn get(&mut self) -> u32 { + T::get(self) + 1 + } +} + +fn foo(n: usize, m: &mut ()) -> impl use<'_> Get { + if n > 0 { + let mut iter = foo(n - 1, m); + //[next]~^ type annotations needed + assert_eq!(iter.get(), 1); + } + m +} + +fn main() { + let g = foo(1, &mut ()).get(); + assert_eq!(g, 1); +} diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr new file mode 100644 index 00000000000..271051f120a --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr @@ -0,0 +1,17 @@ +error[E0282]: type annotations needed + --> $DIR/call_method_on_inherent_impl.rs:18:13 + | +LL | let x = my_foo(); + | ^ +LL | +LL | x.my_debug(); + | - type must be known at this point + | +help: consider giving `x` an explicit type + | +LL | let x: /* Type */ = my_foo(); + | ++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl.rs b/tests/ui/impl-trait/call_method_on_inherent_impl.rs new file mode 100644 index 00000000000..17f7cad660d --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl.rs @@ -0,0 +1,25 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[current] check-pass + +trait MyDebug { + fn my_debug(&self); +} + +impl MyDebug for T +where + T: std::fmt::Debug, +{ + fn my_debug(&self) {} +} + +fn my_foo() -> impl std::fmt::Debug { + if false { + let x = my_foo(); + //[next]~^ type annotations needed + x.my_debug(); + } + () +} + +fn main() {} diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr new file mode 100644 index 00000000000..6ecb2b05fc5 --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr @@ -0,0 +1,16 @@ +error[E0599]: no method named `my_debug` found for reference `&impl Debug` in the current scope + --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:16:11 + | +LL | x.my_debug(); + | ^^^^^^^^ method not found in `&impl Debug` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it + --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:4:1 + | +LL | trait MyDebug { + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr new file mode 100644 index 00000000000..5fb0b8f1d14 --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr @@ -0,0 +1,17 @@ +error[E0282]: type annotations needed for `&_` + --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:14:13 + | +LL | let x = &my_foo(); + | ^ +LL | +LL | x.my_debug(); + | -------- type must be known at this point + | +help: consider giving `x` an explicit type, where the placeholders `_` are specified + | +LL | let x: &_ = &my_foo(); + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs new file mode 100644 index 00000000000..7fb2ff3b2bc --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs @@ -0,0 +1,22 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +trait MyDebug { + fn my_debug(&self); +} + +impl MyDebug for &() { + fn my_debug(&self) {} +} + +fn my_foo() -> impl std::fmt::Debug { + if false { + let x = &my_foo(); + //[next]~^ ERROR: type annotations needed + x.my_debug(); + //[current]~^ ERROR: no method named `my_debug` + } + () +} + +fn main() {} diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr new file mode 100644 index 00000000000..fe6e166cb4f --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr @@ -0,0 +1,40 @@ +error[E0599]: no method named `my_debug` found for opaque type `impl Debug` in the current scope + --> $DIR/call_method_on_inherent_impl_ref.rs:20:11 + | +LL | fn my_debug(&self); + | -------- the method is available for `&impl Debug` here +... +LL | x.my_debug(); + | ^^^^^^^^ method not found in `impl Debug` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it + --> $DIR/call_method_on_inherent_impl_ref.rs:4:1 + | +LL | trait MyDebug { + | ^^^^^^^^^^^^^ + +error[E0391]: cycle detected when computing type of opaque `my_foo::{opaque#0}` + --> $DIR/call_method_on_inherent_impl_ref.rs:15:16 + | +LL | fn my_foo() -> impl std::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ + | +note: ...which requires type-checking `my_foo`... + --> $DIR/call_method_on_inherent_impl_ref.rs:20:9 + | +LL | x.my_debug(); + | ^ + = note: ...which requires evaluating trait selection obligation `my_foo::{opaque#0}: core::marker::Unpin`... + = note: ...which again requires computing type of opaque `my_foo::{opaque#0}`, completing the cycle +note: cycle used when computing type of `my_foo::{opaque#0}` + --> $DIR/call_method_on_inherent_impl_ref.rs:15:16 + | +LL | fn my_foo() -> impl std::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0391, E0599. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr new file mode 100644 index 00000000000..327f6ca3450 --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr @@ -0,0 +1,31 @@ +error[E0282]: type annotations needed + --> $DIR/call_method_on_inherent_impl_ref.rs:18:13 + | +LL | let x = my_foo(); + | ^ +LL | +LL | x.my_debug(); + | - type must be known at this point + | +help: consider giving `x` an explicit type + | +LL | let x: /* Type */ = my_foo(); + | ++++++++++++ + +error[E0282]: type annotations needed for `&_` + --> $DIR/call_method_on_inherent_impl_ref.rs:28:13 + | +LL | let x = &my_bar(); + | ^ +LL | +LL | x.my_debug(); + | -------- type must be known at this point + | +help: consider giving `x` an explicit type, where the placeholders `_` are specified + | +LL | let x: &_ = &my_bar(); + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs new file mode 100644 index 00000000000..40ad21532a4 --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs @@ -0,0 +1,35 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +trait MyDebug { + fn my_debug(&self); +} + +impl MyDebug for &T +where + T: std::fmt::Debug, +{ + fn my_debug(&self) {} +} + +fn my_foo() -> impl std::fmt::Debug { + //[current]~^ cycle + if false { + let x = my_foo(); + //[next]~^ type annotations needed + x.my_debug(); + //[current]~^ no method named `my_debug` found + } + () +} + +fn my_bar() -> impl std::fmt::Debug { + if false { + let x = &my_bar(); + //[next]~^ type annotations needed + x.my_debug(); + } + () +} + +fn main() {} diff --git a/tests/ui/impl-trait/call_method_without_import.no_import.stderr b/tests/ui/impl-trait/call_method_without_import.no_import.stderr new file mode 100644 index 00000000000..72982b695bb --- /dev/null +++ b/tests/ui/impl-trait/call_method_without_import.no_import.stderr @@ -0,0 +1,37 @@ +error[E0599]: no method named `fmt` found for opaque type `impl Debug` in the current scope + --> $DIR/call_method_without_import.rs:17:11 + | +LL | x.fmt(f); + | ^^^ method not found in `impl Debug` + --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL + | + = note: the method is available for `impl Debug` here + | + = help: items from traits can only be used if the trait is in scope +help: trait `Debug` which provides `fmt` is implemented but not in scope; perhaps you want to import it + | +LL + use std::fmt::Debug; + | + +error[E0599]: no method named `fmt` found for mutable reference `&mut impl Debug` in the current scope + --> $DIR/call_method_without_import.rs:26:11 + | +LL | x.fmt(f); + | ^^^ method not found in `&mut impl Debug` + | + = help: items from traits can only be used if the trait is in scope +help: the following traits which provide `fmt` are implemented but not in scope; perhaps you want to import one of them + | +LL + use std::fmt::Binary; + | +LL + use std::fmt::Debug; + | +LL + use std::fmt::Display; + | +LL + use std::fmt::LowerExp; + | + and 5 other candidates + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/call_method_without_import.rs b/tests/ui/impl-trait/call_method_without_import.rs new file mode 100644 index 00000000000..d62777ea283 --- /dev/null +++ b/tests/ui/impl-trait/call_method_without_import.rs @@ -0,0 +1,42 @@ +//! Test that opaque types only pick up methods from traits in their bounds +//! if the trait is imported. +//! +//! FIXME: always look through the bounds of an opaque type to see if there are +//! methods that could be called on any of the bound traits, irrespective of +//! imported traits. + +//@ revisions: import no_import +//@[import] check-pass + +#[cfg(import)] +use std::fmt::Debug as _; + +fn foo(f: &mut std::fmt::Formatter<'_>) -> impl std::fmt::Debug { + if false { + let x = foo(f); + x.fmt(f); + //[no_import]~^ ERROR: no method named `fmt` found + } + () +} + +fn foo1(f: &mut std::fmt::Formatter<'_>) -> impl std::fmt::Debug { + if false { + let x = &mut foo(f); + x.fmt(f); + //[no_import]~^ ERROR: no method named `fmt` found + } + () +} + +// inconsistent with this +fn bar(t: impl std::fmt::Debug, f: &mut std::fmt::Formatter<'_>) { + t.fmt(f); +} + +// and the desugared version, of course +fn baz(t: T, f: &mut std::fmt::Formatter<'_>) { + t.fmt(f); +} + +fn main() {} diff --git a/tests/ui/impl-trait/method-resolution.current.stderr b/tests/ui/impl-trait/method-resolution.current.stderr new file mode 100644 index 00000000000..6d10693c893 --- /dev/null +++ b/tests/ui/impl-trait/method-resolution.current.stderr @@ -0,0 +1,36 @@ +error[E0599]: no method named `bar` found for struct `Bar` in the current scope + --> $DIR/method-resolution.rs:23:11 + | +LL | struct Bar(T); + | ------------- method `bar` not found for this struct +... +LL | x.bar(); + | ^^^ method not found in `Bar` + | + = note: the method was found for + - `Bar` + +error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}` + --> $DIR/method-resolution.rs:19:24 + | +LL | fn foo(x: bool) -> Bar { + | ^^^^^^^^^^ + | +note: ...which requires type-checking `foo`... + --> $DIR/method-resolution.rs:23:9 + | +LL | x.bar(); + | ^ + = note: ...which requires evaluating trait selection obligation `Bar: core::marker::Unpin`... + = note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle +note: cycle used when computing type of `foo::{opaque#0}` + --> $DIR/method-resolution.rs:19:24 + | +LL | fn foo(x: bool) -> Bar { + | ^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0391, E0599. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/impl-trait/method-resolution.rs b/tests/ui/impl-trait/method-resolution.rs new file mode 100644 index 00000000000..07618aa6408 --- /dev/null +++ b/tests/ui/impl-trait/method-resolution.rs @@ -0,0 +1,29 @@ +//! Check that we do not constrain hidden types during method resolution. +//! Otherwise we'd pick up that calling `bar` can be satisfied iff `u32` +//! is the hidden type of the RPIT. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +trait Trait {} + +impl Trait for u32 {} + +struct Bar(T); + +impl Bar { + fn bar(self) {} +} + +fn foo(x: bool) -> Bar { + //[current]~^ ERROR: cycle detected + if x { + let x = foo(false); + x.bar(); + //[current]~^ ERROR: no method named `bar` found + } + todo!() +} + +fn main() {} diff --git a/tests/ui/impl-trait/method-resolution2.next.stderr b/tests/ui/impl-trait/method-resolution2.next.stderr new file mode 100644 index 00000000000..223430e1658 --- /dev/null +++ b/tests/ui/impl-trait/method-resolution2.next.stderr @@ -0,0 +1,20 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/method-resolution2.rs:25:11 + | +LL | x.bar(); + | ^^^ multiple `bar` found + | +note: candidate #1 is defined in an impl for the type `Bar` + --> $DIR/method-resolution2.rs:19:5 + | +LL | fn bar(self) {} + | ^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Bar` + --> $DIR/method-resolution2.rs:15:5 + | +LL | fn bar(self) {} + | ^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0034`. diff --git a/tests/ui/impl-trait/method-resolution2.rs b/tests/ui/impl-trait/method-resolution2.rs new file mode 100644 index 00000000000..2930b42b8bc --- /dev/null +++ b/tests/ui/impl-trait/method-resolution2.rs @@ -0,0 +1,31 @@ +//! Check that the method call does not constrain the RPIT to `i32`, even though +//! `i32` is the only trait that satisfies the RPIT's trait bounds. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[current] check-pass + +trait Trait {} + +impl Trait for i32 {} + +struct Bar(T); + +impl Bar { + fn bar(self) {} +} + +impl Bar { + fn bar(self) {} +} + +fn foo(x: bool) -> Bar { + if x { + let x = foo(false); + x.bar(); + //[next]~^ ERROR: multiple applicable items in scope + } + Bar(42_i32) +} + +fn main() {} diff --git a/tests/ui/impl-trait/method-resolution3.current.stderr b/tests/ui/impl-trait/method-resolution3.current.stderr new file mode 100644 index 00000000000..7407b489e32 --- /dev/null +++ b/tests/ui/impl-trait/method-resolution3.current.stderr @@ -0,0 +1,37 @@ +error[E0599]: no method named `bar` found for struct `Bar` in the current scope + --> $DIR/method-resolution3.rs:22:11 + | +LL | struct Bar(T); + | ------------- method `bar` not found for this struct +... +LL | x.bar(); + | ^^^ method not found in `Bar` + | + = note: the method was found for + - `Bar` + - `Bar` + +error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}` + --> $DIR/method-resolution3.rs:18:24 + | +LL | fn foo(x: bool) -> Bar { + | ^^^^^^^^^^ + | +note: ...which requires type-checking `foo`... + --> $DIR/method-resolution3.rs:22:9 + | +LL | x.bar(); + | ^ + = note: ...which requires evaluating trait selection obligation `Bar: core::marker::Unpin`... + = note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle +note: cycle used when computing type of `foo::{opaque#0}` + --> $DIR/method-resolution3.rs:18:24 + | +LL | fn foo(x: bool) -> Bar { + | ^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0391, E0599. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/impl-trait/method-resolution3.next.stderr b/tests/ui/impl-trait/method-resolution3.next.stderr new file mode 100644 index 00000000000..53b77c620ba --- /dev/null +++ b/tests/ui/impl-trait/method-resolution3.next.stderr @@ -0,0 +1,20 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/method-resolution3.rs:22:11 + | +LL | x.bar(); + | ^^^ multiple `bar` found + | +note: candidate #1 is defined in an impl for the type `Bar` + --> $DIR/method-resolution3.rs:15:5 + | +LL | fn bar(self) {} + | ^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Bar` + --> $DIR/method-resolution3.rs:11:5 + | +LL | fn bar(self) {} + | ^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0034`. diff --git a/tests/ui/impl-trait/method-resolution3.rs b/tests/ui/impl-trait/method-resolution3.rs new file mode 100644 index 00000000000..8474e2da7db --- /dev/null +++ b/tests/ui/impl-trait/method-resolution3.rs @@ -0,0 +1,29 @@ +//! Check that we consider `Bar` to successfully unify +//! with both `Bar` and `Bar` (in isolation), so we bail +//! out with ambiguity. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +struct Bar(T); + +impl Bar { + fn bar(self) {} +} + +impl Bar { + fn bar(self) {} +} + +fn foo(x: bool) -> Bar { + //[current]~^ ERROR: cycle + if x { + let x = foo(false); + x.bar(); + //[current]~^ ERROR: no method named `bar` + //[next]~^^ ERROR: multiple applicable items in scope + } + todo!() +} + +fn main() {} diff --git a/tests/ui/impl-trait/method-resolution4.next.stderr b/tests/ui/impl-trait/method-resolution4.next.stderr new file mode 100644 index 00000000000..b48de0af357 --- /dev/null +++ b/tests/ui/impl-trait/method-resolution4.next.stderr @@ -0,0 +1,22 @@ +error[E0282]: type annotations needed + --> $DIR/method-resolution4.rs:13:9 + | +LL | foo(false).next().unwrap(); + | ^^^^^^^^^^ cannot infer type + +error[E0308]: mismatched types + --> $DIR/method-resolution4.rs:16:5 + | +LL | fn foo(b: bool) -> impl Iterator { + | ------------------------ the expected opaque type +... +LL | std::iter::empty() + | ^^^^^^^^^^^^^^^^^^ types differ + | + = note: expected opaque type `impl Iterator` + found struct `std::iter::Empty<_>` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs new file mode 100644 index 00000000000..3578db7cb55 --- /dev/null +++ b/tests/ui/impl-trait/method-resolution4.rs @@ -0,0 +1,20 @@ +//! The recursive method call yields the opaque type. The +//! `next` method call then constrains the hidden type to `&mut _` +//! because `next` takes `&mut self`. We never resolve the inference +//! variable, but get a type mismatch when comparing `&mut _` with +//! `std::iter::Empty`. + +//@[current] check-pass +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +fn foo(b: bool) -> impl Iterator { + if b { + foo(false).next().unwrap(); + //[next]~^ type annotations needed + } + std::iter::empty() + //[next]~^ mismatched types +} + +fn main() {} diff --git a/tests/ui/impl-trait/recursive-parent-trait-method-call.rs b/tests/ui/impl-trait/recursive-parent-trait-method-call.rs new file mode 100644 index 00000000000..4da9a06a465 --- /dev/null +++ b/tests/ui/impl-trait/recursive-parent-trait-method-call.rs @@ -0,0 +1,42 @@ +//! This test checks that we can resolve the `boxed` method call to `FutureExt`, +//! because we know that the anonymous future does not implement `StreamExt`. + +//@ edition: 2021 +//@ check-pass + +use std::future::Future; +use std::pin::Pin; + +trait FutureExt: Future + Sized + Send + 'static { + fn boxed(self) -> Pin + Send + 'static>> { + Box::pin(self) + } +} + +trait StreamExt: Future + Sized + Send + 'static { + fn boxed(self) -> Pin + Send + 'static>> { + Box::pin(self) + } +} + +impl FutureExt for T {} + +fn go(i: usize) -> impl Future + Send + 'static { + async move { + if i != 0 { + spawn(async move { + let fut = go(i - 1).boxed(); + fut.await; + }) + .await; + } + } +} + +pub fn spawn( + _: impl Future + Send + 'static, +) -> impl Future + Send + 'static { + async move { todo!() } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/method_resolution.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution.current.stderr new file mode 100644 index 00000000000..a9c05ad3342 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution.current.stderr @@ -0,0 +1,15 @@ +error[E0599]: no method named `bar` found for struct `Bar` in the current scope + --> $DIR/method_resolution.rs:21:14 + | +LL | struct Bar(T); + | ------------- method `bar` not found for this struct +... +LL | self.bar() + | ^^^ method not found in `Bar` + | + = note: the method was found for + - `Bar` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution.next.stderr new file mode 100644 index 00000000000..6b34358a56e --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution.next.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `bar` found for struct `Bar` in the current scope + --> $DIR/method_resolution.rs:21:14 + | +LL | struct Bar(T); + | ------------- method `bar` not found for this struct +... +LL | self.bar() + | ^^^ method cannot be called on `Bar` due to unsatisfied trait bounds + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution.rs b/tests/ui/type-alias-impl-trait/method_resolution.rs new file mode 100644 index 00000000000..f636aba15c0 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution.rs @@ -0,0 +1,30 @@ +//! `Bar::foo` is not defining `Foo`, so it cannot rely on the fact that +//! `u32` is the hidden type of `Foo` to call `bar` + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +#![feature(type_alias_impl_trait)] + +type Foo = impl Sized; + +struct Bar(T); + +impl Bar { + fn bar(mut self) { + self.0 = 42_u32; + } +} + +impl Bar { + fn foo(self) { + self.bar() + //~^ ERROR: no method named `bar` + } +} + +fn foo() -> Foo { + 42_u32 +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr new file mode 100644 index 00000000000..e68ea70a8ef --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr @@ -0,0 +1,36 @@ +error[E0599]: no method named `foo` found for struct `Bar` in the current scope + --> $DIR/method_resolution2.rs:17:14 + | +LL | struct Bar(T); + | ------------- method `foo` not found for this struct +... +LL | self.foo() + | ^^^ method not found in `Bar` + | + = note: the method was found for + - `Bar` + +error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}` + --> $DIR/method_resolution2.rs:10:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + | +note: ...which requires type-checking `::bar`... + --> $DIR/method_resolution2.rs:17:9 + | +LL | self.foo() + | ^^^^ + = note: ...which requires evaluating trait selection obligation `Bar: core::marker::Unpin`... + = note: ...which again requires computing type of opaque `Foo::{opaque#0}`, completing the cycle +note: cycle used when computing type of `Foo::{opaque#0}` + --> $DIR/method_resolution2.rs:10:12 + | +LL | type Foo = impl Sized; + | ^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0391, E0599. +For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution2.rs b/tests/ui/type-alias-impl-trait/method_resolution2.rs new file mode 100644 index 00000000000..d252f8640d4 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution2.rs @@ -0,0 +1,30 @@ +//! Check that we do not unify `Bar` with `Bar`, even though the +//! `foo` method call can be resolved unambiguously by doing so. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +#![feature(type_alias_impl_trait)] + +type Foo = impl Sized; +//[current]~^ ERROR: cycle + +struct Bar(T); + +impl Bar { + fn bar(self) { + self.foo() + //[current]~^ ERROR: no method named `foo` + } +} + +impl Bar { + fn foo(self) {} +} + +fn foo() -> Foo { + 42_u32 +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr new file mode 100644 index 00000000000..e992d059daf --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution3.current.stderr @@ -0,0 +1,21 @@ +error[E0307]: invalid `self` parameter type: `Bar` + --> $DIR/method_resolution3.rs:16:18 + | +LL | fn bar(self: Bar) { + | ^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0307]: invalid `self` parameter type: `&Bar` + --> $DIR/method_resolution3.rs:21:18 + | +LL | fn baz(self: &Bar) { + | ^^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0307`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr new file mode 100644 index 00000000000..9272017cdf5 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution3.next.stderr @@ -0,0 +1,15 @@ +error[E0271]: type mismatch resolving `Foo == u32` + --> $DIR/method_resolution3.rs:16:18 + | +LL | fn bar(self: Bar) { + | ^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `Foo == u32` + --> $DIR/method_resolution3.rs:21:18 + | +LL | fn baz(self: &Bar) { + | ^^^^^^^^^ types differ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution3.rs b/tests/ui/type-alias-impl-trait/method_resolution3.rs new file mode 100644 index 00000000000..447f3144b82 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution3.rs @@ -0,0 +1,36 @@ +//! Check that one cannot use arbitrary self types where a generic parameter +//! mismatches with an opaque type. In theory this could unify with the opaque +//! type, registering the generic parameter as the hidden type of the opaque type. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +#![feature(type_alias_impl_trait, arbitrary_self_types)] + +type Foo = impl Copy; + +#[derive(Copy, Clone)] +struct Bar(T); + +impl Bar { + fn bar(self: Bar) { + //[current]~^ ERROR: invalid `self` parameter + //[next]~^^ ERROR: type mismatch resolving `Foo == u32` + self.foo() + } + fn baz(self: &Bar) { + //[current]~^ ERROR: invalid `self` parameter + //[next]~^^ ERROR: type mismatch resolving `Foo == u32` + self.foo() + } +} + +impl Bar { + fn foo(self) {} +} + +fn foo() -> Foo { + 42_u32 +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr new file mode 100644 index 00000000000..3a2ca18f890 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution4.current.stderr @@ -0,0 +1,21 @@ +error[E0307]: invalid `self` parameter type: `Bar` + --> $DIR/method_resolution4.rs:27:18 + | +LL | fn foo(self: Bar) { + | ^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error[E0307]: invalid `self` parameter type: `&Bar` + --> $DIR/method_resolution4.rs:32:20 + | +LL | fn foomp(self: &Bar) { + | ^^^^^^^^^ + | + = note: type of `self` must be `Self` or a type that dereferences to it + = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0307`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr new file mode 100644 index 00000000000..33ed2800ebe --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution4.next.stderr @@ -0,0 +1,15 @@ +error[E0271]: type mismatch resolving `u32 == Foo` + --> $DIR/method_resolution4.rs:27:18 + | +LL | fn foo(self: Bar) { + | ^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `u32 == Foo` + --> $DIR/method_resolution4.rs:32:20 + | +LL | fn foomp(self: &Bar) { + | ^^^^^^^^^ types differ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution4.rs b/tests/ui/type-alias-impl-trait/method_resolution4.rs new file mode 100644 index 00000000000..42ed04b3c30 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution4.rs @@ -0,0 +1,39 @@ +//! Check that one cannot use arbitrary self types where a generic parameter +//! mismatches with an opaque type. In theory this could unify with the opaque +//! type, registering the generic parameter as the hidden type of the opaque type. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +#![feature(type_alias_impl_trait, arbitrary_self_types)] + +mod foo { + pub type Foo = impl Copy; + + fn foo() -> Foo { + 42_u32 + } +} +use foo::Foo; + +#[derive(Copy, Clone)] +struct Bar(T); + +impl Bar { + fn bar(self) {} +} + +impl Bar { + fn foo(self: Bar) { + //[current]~^ ERROR: invalid `self` parameter + //[next]~^^ ERROR: type mismatch resolving `u32 == Foo` + self.bar() + } + fn foomp(self: &Bar) { + //[current]~^ ERROR: invalid `self` parameter + //[next]~^^ ERROR: type mismatch resolving `u32 == Foo` + self.bar() + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/method_resolution5.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution5.current.stderr new file mode 100644 index 00000000000..193e6e14709 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution5.current.stderr @@ -0,0 +1,15 @@ +error[E0599]: no method named `bar` found for struct `Bar` in the current scope + --> $DIR/method_resolution5.rs:25:14 + | +LL | struct Bar(T); + | ------------- method `bar` not found for this struct +... +LL | self.bar() + | ^^^ method not found in `Bar` + | + = note: the method was found for + - `Bar` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution5.rs b/tests/ui/type-alias-impl-trait/method_resolution5.rs new file mode 100644 index 00000000000..69335c9dede --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution5.rs @@ -0,0 +1,34 @@ +//! Even though `Bar::foo` is defining `Foo`, the old solver does +//! not figure out that `u32` is the hidden type of `Foo` to call `bar`. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +#![feature(type_alias_impl_trait)] + +type Foo = impl Sized; + +struct Bar(T); + +impl Bar { + fn bar(mut self) { + self.0 = 42_u32; + } +} + +impl Bar { + fn foo(self) + where + Foo:, + { + self.bar() + //[current]~^ ERROR: no method named `bar` + } +} + +fn foo() -> Foo { + 42_u32 +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr new file mode 100644 index 00000000000..f331da1af87 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.current.stderr @@ -0,0 +1,15 @@ +error: item does not constrain `Tait::{opaque#0}`, but has it in its signature + --> $DIR/method_resolution_trait_method_from_opaque.rs:24:8 + | +LL | fn foo(&mut self) { + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/method_resolution_trait_method_from_opaque.rs:17:13 + | +LL | type Tait = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr new file mode 100644 index 00000000000..2617ce124c1 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/method_resolution_trait_method_from_opaque.rs:26:9 + | +LL | self.bar.next().unwrap(); + | ^^^^^^^^ cannot infer type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs new file mode 100644 index 00000000000..b6adf08853f --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.rs @@ -0,0 +1,31 @@ +//! This test demonstrates how method calls will attempt to unify an opaque type with a reference +//! if the method takes `&self` as its argument. This is almost never what is desired, as the user +//! would like to have method resolution happen on the opaque type instead of inferring the hidden +//! type. Once type-alias-impl-trait requires annotating which functions should constrain the hidden +//! type, this won't be as much of a problem, as most functions that do method calls on opaque types +//! won't also be the ones defining the hidden type. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +#![feature(type_alias_impl_trait)] + +pub struct Foo { + bar: Tait, +} + +type Tait = impl Iterator; + +impl Foo { + pub fn new() -> Foo { + Foo { bar: std::iter::empty() } + } + + fn foo(&mut self) { + //[current]~^ ERROR: item does not constrain + self.bar.next().unwrap(); + //[next]~^ ERROR: type annotations needed + } +} + +fn main() {} From 9cf60ee9d33fadff387d83d09aef1ce43589e233 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Apr 2024 11:37:09 +0000 Subject: [PATCH 08/13] Method resolution constrains hidden types instead of rejecting method candidates --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- .../rustc_hir_typeck/src/method/confirm.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 65 +++++++++---------- compiler/rustc_middle/src/traits/query.rs | 2 +- .../method-resolution.current.stderr | 36 ---------- tests/ui/impl-trait/method-resolution.rs | 9 +-- tests/ui/impl-trait/method-resolution2.rs | 2 +- .../method-resolution3.current.stderr | 47 +++++--------- .../impl-trait/method-resolution3.next.stderr | 2 +- tests/ui/impl-trait/method-resolution3.rs | 4 +- tests/ui/impl-trait/method-resolution4.rs | 2 +- tests/ui/methods/opaque_param_in_ufc.rs | 6 +- tests/ui/methods/opaque_param_in_ufc.stderr | 36 ---------- .../method_resolution2.current.stderr | 36 ---------- .../method_resolution2.rs | 6 +- .../method_resolution5.current.stderr | 15 ----- .../method_resolution5.rs | 3 +- 17 files changed, 60 insertions(+), 215 deletions(-) delete mode 100644 tests/ui/impl-trait/method-resolution.current.stderr delete mode 100644 tests/ui/methods/opaque_param_in_ufc.stderr delete mode 100644 tests/ui/type-alias-impl-trait/method_resolution2.current.stderr delete mode 100644 tests/ui/type-alias-impl-trait/method_resolution5.current.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 94e879ae9c3..9531c002829 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1418,7 +1418,7 @@ fn inferred_kind( let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args)); let self_ty = self.normalize(span, self_ty); match self.at(&self.misc(span), self.param_env).eq( - DefineOpaqueTypes::No, + DefineOpaqueTypes::Yes, impl_ty, self_ty, ) { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 3c9a49e91a3..120e3239d1f 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -497,7 +497,7 @@ fn unify_receivers( args, })), ); - match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::No, method_self_ty, self_ty) { + match self.at(&cause, self.param_env).sup(DefineOpaqueTypes::Yes, method_self_ty, self_ty) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index e842bba34bf..3986374a343 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -634,8 +634,8 @@ fn assemble_inherent_candidates(&mut self) { } } + #[instrument(level = "debug", skip(self))] fn assemble_probe(&mut self, self_ty: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>) { - debug!("assemble_probe: self_ty={:?}", self_ty); let raw_self_ty = self_ty.value.value; match *raw_self_ty.kind() { ty::Dynamic(data, ..) if let Some(p) = data.principal() => { @@ -713,13 +713,12 @@ fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) { } } + #[instrument(level = "debug", skip(self))] fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) { if !self.impl_dups.insert(impl_def_id) { return; // already visited } - debug!("assemble_inherent_impl_probe {:?}", impl_def_id); - for item in self.impl_or_trait_item(impl_def_id) { if !self.has_applicable_self(&item) { // No receiver declared. Not a candidate. @@ -737,9 +736,8 @@ fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) { } } + #[instrument(level = "debug", skip(self))] fn assemble_inherent_candidates_from_object(&mut self, self_ty: Ty<'tcx>) { - debug!("assemble_inherent_candidates_from_object(self_ty={:?})", self_ty); - let principal = match self_ty.kind() { ty::Dynamic(ref data, ..) => Some(data), _ => None, @@ -768,9 +766,9 @@ fn assemble_inherent_candidates_from_object(&mut self, self_ty: Ty<'tcx>) { }); } + #[instrument(level = "debug", skip(self))] fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) { // FIXME: do we want to commit to this behavior for param bounds? - debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty); let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| { let bound_predicate = predicate.kind(); @@ -826,6 +824,7 @@ fn elaborate_bounds( } } + #[instrument(level = "debug", skip(self))] fn assemble_extension_candidates_for_traits_in_scope(&mut self) { let mut duplicates = FxHashSet::default(); let opt_applicable_traits = self.tcx.in_scope_traits(self.scope_expr_id); @@ -842,6 +841,7 @@ fn assemble_extension_candidates_for_traits_in_scope(&mut self) { } } + #[instrument(level = "debug", skip(self))] fn assemble_extension_candidates_for_all_traits(&mut self) { let mut duplicates = FxHashSet::default(); for trait_info in suggest::all_traits(self.tcx) { @@ -863,12 +863,12 @@ fn matches_return_type(&self, method: ty::AssocItem, expected: Ty<'tcx>) -> bool } } + #[instrument(level = "debug", skip(self))] fn assemble_extension_candidates_for_trait( &mut self, import_ids: &SmallVec<[LocalDefId; 1]>, trait_def_id: DefId, ) { - debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id); let trait_args = self.fresh_args_for_item(self.span, trait_def_id); let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, trait_args); @@ -958,6 +958,7 @@ fn candidate_method_names( /////////////////////////////////////////////////////////////////////////// // THE ACTUAL SEARCH + #[instrument(level = "debug", skip(self))] fn pick(mut self) -> PickResult<'tcx> { assert!(self.method_name.is_some()); @@ -1386,6 +1387,7 @@ fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> Ca } } + #[instrument(level = "trace", skip(self, possibly_unsatisfied_predicates), ret)] fn consider_probe( &self, self_ty: Ty<'tcx>, @@ -1415,15 +1417,8 @@ fn consider_probe( (xform_self_ty, xform_ret_ty) = self.xform_self_ty(probe.item, impl_ty, impl_args); xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); - // FIXME: Make this `ocx.sup` once we define opaques more eagerly. - match self.at(cause, self.param_env).sup( - DefineOpaqueTypes::No, - xform_self_ty, - self_ty, - ) { - Ok(infer_ok) => { - ocx.register_infer_ok_obligations(infer_ok); - } + match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) { + Ok(()) => {} Err(err) => { debug!("--> cannot relate self-types {:?}", err); return ProbeResult::NoMatch; @@ -1484,19 +1479,23 @@ fn consider_probe( (xform_self_ty, xform_ret_ty) = self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args); xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); - // FIXME: Make this `ocx.sup` once we define opaques more eagerly. - match self.at(cause, self.param_env).sup( - DefineOpaqueTypes::No, - xform_self_ty, - self_ty, - ) { - Ok(infer_ok) => { - ocx.register_infer_ok_obligations(infer_ok); - } - Err(err) => { - debug!("--> cannot relate self-types {:?}", err); + match self_ty.kind() { + // HACK: opaque types will match anything for which their bounds hold. + // Thus we need to prevent them from trying to match the `&_` autoref + // candidates that get created for `&self` trait methods. + ty::Alias(ty::Opaque, alias_ty) + if self.infcx.can_define_opaque_ty(alias_ty.def_id) + && !xform_self_ty.is_ty_var() => + { return ProbeResult::NoMatch; } + _ => match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) { + Ok(()) => {} + Err(err) => { + debug!("--> cannot relate self-types {:?}", err); + return ProbeResult::NoMatch; + } + }, } let obligation = traits::Obligation::new( self.tcx, @@ -1536,15 +1535,8 @@ fn consider_probe( (xform_self_ty, xform_ret_ty) = self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args); xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty); - // FIXME: Make this `ocx.sup` once we define opaques more eagerly. - match self.at(cause, self.param_env).sup( - DefineOpaqueTypes::No, - xform_self_ty, - self_ty, - ) { - Ok(infer_ok) => { - ocx.register_infer_ok_obligations(infer_ok); - } + match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) { + Ok(()) => {} Err(err) => { debug!("--> cannot relate self-types {:?}", err); return ProbeResult::NoMatch; @@ -1665,6 +1657,7 @@ fn collapse_candidates_to_trait_pick( /// Similarly to `probe_for_return_type`, this method attempts to find the best matching /// candidate method where the method name may have been misspelled. Similarly to other /// edit distance based suggestions, we provide at most one such suggestion. + #[instrument(level = "debug", skip(self))] pub(crate) fn probe_for_similar_candidate( &mut self, ) -> Result, MethodError<'tcx>> { diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 50b6c77e1b2..4fad721ce98 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -156,7 +156,7 @@ pub struct CandidateStep<'tcx> { #[derive(Copy, Clone, Debug, HashStable)] pub struct MethodAutoderefStepsResult<'tcx> { - /// The valid autoderef steps that could be find. + /// The valid autoderef steps that could be found. pub steps: &'tcx [CandidateStep<'tcx>], /// If Some(T), a type autoderef reported an error on. pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>, diff --git a/tests/ui/impl-trait/method-resolution.current.stderr b/tests/ui/impl-trait/method-resolution.current.stderr deleted file mode 100644 index 6d10693c893..00000000000 --- a/tests/ui/impl-trait/method-resolution.current.stderr +++ /dev/null @@ -1,36 +0,0 @@ -error[E0599]: no method named `bar` found for struct `Bar` in the current scope - --> $DIR/method-resolution.rs:23:11 - | -LL | struct Bar(T); - | ------------- method `bar` not found for this struct -... -LL | x.bar(); - | ^^^ method not found in `Bar` - | - = note: the method was found for - - `Bar` - -error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}` - --> $DIR/method-resolution.rs:19:24 - | -LL | fn foo(x: bool) -> Bar { - | ^^^^^^^^^^ - | -note: ...which requires type-checking `foo`... - --> $DIR/method-resolution.rs:23:9 - | -LL | x.bar(); - | ^ - = note: ...which requires evaluating trait selection obligation `Bar: core::marker::Unpin`... - = note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle -note: cycle used when computing type of `foo::{opaque#0}` - --> $DIR/method-resolution.rs:19:24 - | -LL | fn foo(x: bool) -> Bar { - | ^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0391, E0599. -For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/impl-trait/method-resolution.rs b/tests/ui/impl-trait/method-resolution.rs index 07618aa6408..60fbacd8646 100644 --- a/tests/ui/impl-trait/method-resolution.rs +++ b/tests/ui/impl-trait/method-resolution.rs @@ -1,10 +1,9 @@ -//! Check that we do not constrain hidden types during method resolution. -//! Otherwise we'd pick up that calling `bar` can be satisfied iff `u32` -//! is the hidden type of the RPIT. +//! Since there is only one possible `bar` method, we invoke it and subsequently +//! constrain `foo`'s RPIT to `u32`. //@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass trait Trait {} @@ -17,11 +16,9 @@ fn bar(self) {} } fn foo(x: bool) -> Bar { - //[current]~^ ERROR: cycle detected if x { let x = foo(false); x.bar(); - //[current]~^ ERROR: no method named `bar` found } todo!() } diff --git a/tests/ui/impl-trait/method-resolution2.rs b/tests/ui/impl-trait/method-resolution2.rs index 2930b42b8bc..88d4f3d9896 100644 --- a/tests/ui/impl-trait/method-resolution2.rs +++ b/tests/ui/impl-trait/method-resolution2.rs @@ -1,5 +1,5 @@ //! Check that the method call does not constrain the RPIT to `i32`, even though -//! `i32` is the only trait that satisfies the RPIT's trait bounds. +//! `i32` is the only type that satisfies the RPIT's trait bounds. //@ revisions: current next //@[next] compile-flags: -Znext-solver diff --git a/tests/ui/impl-trait/method-resolution3.current.stderr b/tests/ui/impl-trait/method-resolution3.current.stderr index 7407b489e32..87dd862ef8f 100644 --- a/tests/ui/impl-trait/method-resolution3.current.stderr +++ b/tests/ui/impl-trait/method-resolution3.current.stderr @@ -1,37 +1,20 @@ -error[E0599]: no method named `bar` found for struct `Bar` in the current scope - --> $DIR/method-resolution3.rs:22:11 - | -LL | struct Bar(T); - | ------------- method `bar` not found for this struct -... -LL | x.bar(); - | ^^^ method not found in `Bar` - | - = note: the method was found for - - `Bar` - - `Bar` - -error[E0391]: cycle detected when computing type of opaque `foo::{opaque#0}` - --> $DIR/method-resolution3.rs:18:24 - | -LL | fn foo(x: bool) -> Bar { - | ^^^^^^^^^^ - | -note: ...which requires type-checking `foo`... - --> $DIR/method-resolution3.rs:22:9 +error[E0034]: multiple applicable items in scope + --> $DIR/method-resolution3.rs:21:11 | LL | x.bar(); - | ^ - = note: ...which requires evaluating trait selection obligation `Bar: core::marker::Unpin`... - = note: ...which again requires computing type of opaque `foo::{opaque#0}`, completing the cycle -note: cycle used when computing type of `foo::{opaque#0}` - --> $DIR/method-resolution3.rs:18:24 + | ^^^ multiple `bar` found | -LL | fn foo(x: bool) -> Bar { - | ^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information +note: candidate #1 is defined in an impl for the type `Bar` + --> $DIR/method-resolution3.rs:15:5 + | +LL | fn bar(self) {} + | ^^^^^^^^^^^^ +note: candidate #2 is defined in an impl for the type `Bar` + --> $DIR/method-resolution3.rs:11:5 + | +LL | fn bar(self) {} + | ^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0391, E0599. -For more information about an error, try `rustc --explain E0391`. +For more information about this error, try `rustc --explain E0034`. diff --git a/tests/ui/impl-trait/method-resolution3.next.stderr b/tests/ui/impl-trait/method-resolution3.next.stderr index 53b77c620ba..87dd862ef8f 100644 --- a/tests/ui/impl-trait/method-resolution3.next.stderr +++ b/tests/ui/impl-trait/method-resolution3.next.stderr @@ -1,5 +1,5 @@ error[E0034]: multiple applicable items in scope - --> $DIR/method-resolution3.rs:22:11 + --> $DIR/method-resolution3.rs:21:11 | LL | x.bar(); | ^^^ multiple `bar` found diff --git a/tests/ui/impl-trait/method-resolution3.rs b/tests/ui/impl-trait/method-resolution3.rs index 8474e2da7db..8c47ef4fc75 100644 --- a/tests/ui/impl-trait/method-resolution3.rs +++ b/tests/ui/impl-trait/method-resolution3.rs @@ -16,12 +16,10 @@ fn bar(self) {} } fn foo(x: bool) -> Bar { - //[current]~^ ERROR: cycle if x { let x = foo(false); x.bar(); - //[current]~^ ERROR: no method named `bar` - //[next]~^^ ERROR: multiple applicable items in scope + //~^ ERROR: multiple applicable items in scope } todo!() } diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method-resolution4.rs index 3578db7cb55..91884eb59fd 100644 --- a/tests/ui/impl-trait/method-resolution4.rs +++ b/tests/ui/impl-trait/method-resolution4.rs @@ -4,9 +4,9 @@ //! variable, but get a type mismatch when comparing `&mut _` with //! `std::iter::Empty`. -//@[current] check-pass //@ revisions: current next //@[next] compile-flags: -Znext-solver +//@[current] check-pass fn foo(b: bool) -> impl Iterator { if b { diff --git a/tests/ui/methods/opaque_param_in_ufc.rs b/tests/ui/methods/opaque_param_in_ufc.rs index a4b27a0131f..b170e6805f6 100644 --- a/tests/ui/methods/opaque_param_in_ufc.rs +++ b/tests/ui/methods/opaque_param_in_ufc.rs @@ -1,4 +1,7 @@ #![feature(type_alias_impl_trait)] + +//@ check-pass + struct Foo(T); impl Foo { @@ -15,14 +18,11 @@ fn bar() -> Bar { impl Foo { fn foo() -> Bar { Self::method(); - //~^ ERROR: no function or associated item named `method` found for struct `Foo` Foo::::method(); - //~^ ERROR: no function or associated item named `method` found for struct `Foo` let x = Foo(bar()); Foo::method2(x); let x = Self(bar()); Self::method2(x); - //~^ ERROR: no function or associated item named `method2` found for struct `Foo` todo!() } } diff --git a/tests/ui/methods/opaque_param_in_ufc.stderr b/tests/ui/methods/opaque_param_in_ufc.stderr deleted file mode 100644 index 7e5bbbac8a9..00000000000 --- a/tests/ui/methods/opaque_param_in_ufc.stderr +++ /dev/null @@ -1,36 +0,0 @@ -error[E0599]: no function or associated item named `method` found for struct `Foo` in the current scope - --> $DIR/opaque_param_in_ufc.rs:17:15 - | -LL | struct Foo(T); - | ------------- function or associated item `method` not found for this struct -... -LL | Self::method(); - | ^^^^^^ function or associated item not found in `Foo` - | - = note: the function or associated item was found for - - `Foo` - -error[E0599]: no function or associated item named `method` found for struct `Foo` in the current scope - --> $DIR/opaque_param_in_ufc.rs:19:21 - | -LL | struct Foo(T); - | ------------- function or associated item `method` not found for this struct -... -LL | Foo::::method(); - | ^^^^^^ function or associated item not found in `Foo` - | - = note: the function or associated item was found for - - `Foo` - -error[E0599]: no function or associated item named `method2` found for struct `Foo` in the current scope - --> $DIR/opaque_param_in_ufc.rs:24:15 - | -LL | struct Foo(T); - | ------------- function or associated item `method2` not found for this struct -... -LL | Self::method2(x); - | ^^^^^^^ function or associated item not found in `Foo` - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr deleted file mode 100644 index e68ea70a8ef..00000000000 --- a/tests/ui/type-alias-impl-trait/method_resolution2.current.stderr +++ /dev/null @@ -1,36 +0,0 @@ -error[E0599]: no method named `foo` found for struct `Bar` in the current scope - --> $DIR/method_resolution2.rs:17:14 - | -LL | struct Bar(T); - | ------------- method `foo` not found for this struct -... -LL | self.foo() - | ^^^ method not found in `Bar` - | - = note: the method was found for - - `Bar` - -error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}` - --> $DIR/method_resolution2.rs:10:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - | -note: ...which requires type-checking `::bar`... - --> $DIR/method_resolution2.rs:17:9 - | -LL | self.foo() - | ^^^^ - = note: ...which requires evaluating trait selection obligation `Bar: core::marker::Unpin`... - = note: ...which again requires computing type of opaque `Foo::{opaque#0}`, completing the cycle -note: cycle used when computing type of `Foo::{opaque#0}` - --> $DIR/method_resolution2.rs:10:12 - | -LL | type Foo = impl Sized; - | ^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0391, E0599. -For more information about an error, try `rustc --explain E0391`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution2.rs b/tests/ui/type-alias-impl-trait/method_resolution2.rs index d252f8640d4..f69661db799 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution2.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution2.rs @@ -1,21 +1,19 @@ -//! Check that we do not unify `Bar` with `Bar`, even though the +//! Check that we do unify `Bar` with `Bar`, as the //! `foo` method call can be resolved unambiguously by doing so. //@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass #![feature(type_alias_impl_trait)] type Foo = impl Sized; -//[current]~^ ERROR: cycle struct Bar(T); impl Bar { fn bar(self) { self.foo() - //[current]~^ ERROR: no method named `foo` } } diff --git a/tests/ui/type-alias-impl-trait/method_resolution5.current.stderr b/tests/ui/type-alias-impl-trait/method_resolution5.current.stderr deleted file mode 100644 index 193e6e14709..00000000000 --- a/tests/ui/type-alias-impl-trait/method_resolution5.current.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0599]: no method named `bar` found for struct `Bar` in the current scope - --> $DIR/method_resolution5.rs:25:14 - | -LL | struct Bar(T); - | ------------- method `bar` not found for this struct -... -LL | self.bar() - | ^^^ method not found in `Bar` - | - = note: the method was found for - - `Bar` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/type-alias-impl-trait/method_resolution5.rs b/tests/ui/type-alias-impl-trait/method_resolution5.rs index 69335c9dede..64355e4560d 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution5.rs +++ b/tests/ui/type-alias-impl-trait/method_resolution5.rs @@ -3,7 +3,7 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[next] check-pass +//@ check-pass #![feature(type_alias_impl_trait)] @@ -23,7 +23,6 @@ fn foo(self) Foo:, { self.bar() - //[current]~^ ERROR: no method named `bar` } } From 9bff23005dc8cfca8fab4e5edaaf7d910b6c10f3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 11 Jun 2024 14:05:30 +0200 Subject: [PATCH 09/13] Allow to bless diff tests --- src/tools/run-make-support/src/diff/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs index 105cdbc7b32..d0be57ca9d7 100644 --- a/src/tools/run-make-support/src/diff/mod.rs +++ b/src/tools/run-make-support/src/diff/mod.rs @@ -1,6 +1,6 @@ use regex::Regex; use similar::TextDiff; -use std::path::Path; +use std::path::{Path, PathBuf}; use crate::drop_bomb::DropBomb; @@ -17,6 +17,7 @@ pub fn diff() -> Diff { pub struct Diff { expected: Option, expected_name: Option, + expected_file: Option, actual: Option, actual_name: Option, normalizers: Vec<(String, String)>, @@ -30,6 +31,7 @@ pub fn new() -> Self { Self { expected: None, expected_name: None, + expected_file: None, actual: None, actual_name: None, normalizers: Vec::new(), @@ -43,6 +45,7 @@ pub fn expected_file>(&mut self, path: P) -> &mut Self { let content = std::fs::read_to_string(path).expect("failed to read file"); let name = path.to_string_lossy().to_string(); + self.expected_file = Some(path.into()); self.expected = Some(content); self.expected_name = Some(name); self @@ -104,6 +107,15 @@ pub fn run(&mut self) { .to_string(); if !output.is_empty() { + // If we can bless (meaning we have a file to write into and the `RUSTC_BLESS_TEST` + // environment variable set), then we write into the file and return. + if let Some(ref expected_file) = self.expected_file { + if std::env::var("RUSTC_BLESS_TEST").is_ok() { + println!("Blessing `{}`", expected_file.display()); + std::fs::write(expected_file, actual).unwrap(); + return; + } + } panic!( "test failed: `{}` is different from `{}`\n\n{}", expected_name, actual_name, output From be7b587cd13af17bd23dd8e38182c454df23e278 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 11 Jun 2024 14:05:55 +0200 Subject: [PATCH 10/13] Migrate `run-make/const_fn_mir` to `rmake.rs` --- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/const_fn_mir/Makefile | 6 ------ tests/run-make/const_fn_mir/rmake.rs | 8 ++++++++ 3 files changed, 8 insertions(+), 7 deletions(-) delete mode 100644 tests/run-make/const_fn_mir/Makefile create mode 100644 tests/run-make/const_fn_mir/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 37da5d9c88d..14d7bfe9ad4 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -18,7 +18,6 @@ run-make/compiler-lookup-paths-2/Makefile run-make/compiler-lookup-paths/Makefile run-make/compiler-rt-works-on-mingw/Makefile run-make/compressed-debuginfo/Makefile -run-make/const_fn_mir/Makefile run-make/crate-hash-rustc-version/Makefile run-make/crate-name-priority/Makefile run-make/cross-lang-lto-clang/Makefile diff --git a/tests/run-make/const_fn_mir/Makefile b/tests/run-make/const_fn_mir/Makefile deleted file mode 100644 index 3399446130d..00000000000 --- a/tests/run-make/const_fn_mir/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# needs-unwind -Cpanic=abort gives different MIR output -include ../tools.mk - -all: - $(RUSTC) main.rs --emit=mir -o "$(TMPDIR)"/dump.mir - $(RUSTC_TEST_OP) "$(TMPDIR)"/dump.mir dump.mir diff --git a/tests/run-make/const_fn_mir/rmake.rs b/tests/run-make/const_fn_mir/rmake.rs new file mode 100644 index 00000000000..a4cc4299b1b --- /dev/null +++ b/tests/run-make/const_fn_mir/rmake.rs @@ -0,0 +1,8 @@ +// The `needs-unwind -Cpanic=abort` gives a different MIR output. + +use run_make_support::{cwd, diff, rustc}; + +fn main() { + rustc().input("main.rs").emit("mir").output("dump-actual.mir").run(); + diff().expected_file("dump.mir").actual_file("dump-actual.mir").run(); +} From 5f4111f781abcd8faca117e18e25c633f9effdcc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 13 Jun 2024 11:39:45 +0200 Subject: [PATCH 11/13] Update run-make-support/diff to new `fs_wrapper` API --- src/tools/run-make-support/src/diff/mod.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/tools/run-make-support/src/diff/mod.rs b/src/tools/run-make-support/src/diff/mod.rs index d0be57ca9d7..3e0bdc1c6f6 100644 --- a/src/tools/run-make-support/src/diff/mod.rs +++ b/src/tools/run-make-support/src/diff/mod.rs @@ -3,6 +3,7 @@ use std::path::{Path, PathBuf}; use crate::drop_bomb::DropBomb; +use crate::fs_wrapper; #[cfg(test)] mod tests; @@ -42,7 +43,7 @@ pub fn new() -> Self { /// Specify the expected output for the diff from a file. pub fn expected_file>(&mut self, path: P) -> &mut Self { let path = path.as_ref(); - let content = std::fs::read_to_string(path).expect("failed to read file"); + let content = fs_wrapper::read_to_string(path); let name = path.to_string_lossy().to_string(); self.expected_file = Some(path.into()); @@ -61,10 +62,7 @@ pub fn expected_text>(&mut self, name: &str, text: T) -> &mut Sel /// Specify the actual output for the diff from a file. pub fn actual_file>(&mut self, path: P) -> &mut Self { let path = path.as_ref(); - let content = match std::fs::read_to_string(path) { - Ok(c) => c, - Err(e) => panic!("failed to read `{}`: {:?}", path.display(), e), - }; + let content = fs_wrapper::read_to_string(path); let name = path.to_string_lossy().to_string(); self.actual = Some(content); @@ -112,7 +110,7 @@ pub fn run(&mut self) { if let Some(ref expected_file) = self.expected_file { if std::env::var("RUSTC_BLESS_TEST").is_ok() { println!("Blessing `{}`", expected_file.display()); - std::fs::write(expected_file, actual).unwrap(); + fs_wrapper::write(expected_file, actual); return; } } From 14014abf06712412b4e700b74c570148ac63de27 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Mon, 10 Jun 2024 18:32:31 +0000 Subject: [PATCH 12/13] Update fuchsia commit, and SDK to 21.20240610.2.1 This includes a fix to the race when publishing multiple packages at the same time. --- .../x86_64-gnu-integration/Dockerfile | 28 +++++++++---------- .../x86_64-gnu-integration/build-fuchsia.sh | 2 +- .../docker/scripts/build-fuchsia-toolchain.sh | 8 +++--- src/ci/docker/scripts/fuchsia-test-runner.py | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile index d228dfc87eb..a944f370c6b 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/Dockerfile @@ -26,27 +26,27 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ # Duplicated in dist-various-2 Dockerfile. # FIXME: Move to canonical triple ENV \ - AR_x86_64_fuchsia=x86_64-unknown-fuchsia-ar \ - CC_x86_64_fuchsia=x86_64-unknown-fuchsia-clang \ - CFLAGS_x86_64_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot -I/usr/local/core-linux-amd64-fuchsia-sdk/pkg/fdio/include" \ - CXX_x86_64_fuchsia=x86_64-unknown-fuchsia-clang++ \ - CXXFLAGS_x86_64_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot -I/usr/local/core-linux-amd64-fuchsia-sdk/pkg/fdio/include" \ - LDFLAGS_x86_64_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot -L/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/lib" + AR_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-ar \ + CC_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-clang \ + CFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot -I/usr/local/core-linux-amd64-fuchsia-sdk/pkg/fdio/include" \ + CXX_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-clang++ \ + CXXFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot -I/usr/local/core-linux-amd64-fuchsia-sdk/pkg/fdio/include" \ + LDFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot -L/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/lib" WORKDIR /tmp COPY scripts/shared.sh /tmp/ COPY scripts/build-fuchsia-toolchain.sh /tmp/ RUN /tmp/build-fuchsia-toolchain.sh -ENV CARGO_TARGET_X86_64_FUCHSIA_AR /usr/local/bin/llvm-ar -ENV CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS \ +ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_AR /usr/local/bin/llvm-ar +ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS \ -C panic=abort \ -C force-unwind-tables=yes \ -C link-arg=--sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot \ -Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot/lib \ -Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/lib -ENV TARGETS=x86_64-fuchsia +ENV TARGETS=x86_64-unknown-fuchsia ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnu ENV TARGETS=$TARGETS,wasm32-unknown-unknown @@ -69,11 +69,11 @@ ENV RUST_CONFIGURE_ARGS \ --llvm-libunwind=in-tree \ --enable-extended \ --disable-docs \ - --set target.x86_64-fuchsia.cc=/usr/local/bin/clang \ - --set target.x86_64-fuchsia.cxx=/usr/local/bin/clang++ \ - --set target.x86_64-fuchsia.ar=/usr/local/bin/llvm-ar \ - --set target.x86_64-fuchsia.ranlib=/usr/local/bin/llvm-ranlib \ - --set target.x86_64-fuchsia.linker=/usr/local/bin/ld.lld + --set target.x86_64-unknown-fuchsia.cc=/usr/local/bin/clang \ + --set target.x86_64-unknown-fuchsia.cxx=/usr/local/bin/clang++ \ + --set target.x86_64-unknown-fuchsia.ar=/usr/local/bin/llvm-ar \ + --set target.x86_64-unknown-fuchsia.ranlib=/usr/local/bin/llvm-ranlib \ + --set target.x86_64-unknown-fuchsia.linker=/usr/local/bin/ld.lld ENV SCRIPT \ python3 ../x.py install --target $TARGETS compiler/rustc library/std clippy && \ bash ../src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh index 913a0b0c09c..2bb1d0a6338 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh +++ b/src/ci/docker/host-x86_64/x86_64-gnu-integration/build-fuchsia.sh @@ -35,7 +35,7 @@ PICK_REFS=() # commit hash of fuchsia.git and some other repos in the "monorepo" checkout, in # addition to versions of prebuilts. It should be bumped regularly by the # Fuchsia team – we aim for every 1-2 months. -INTEGRATION_SHA=1011e3298775ee7cdf6f6dc73e808d6a86e33bd6 +INTEGRATION_SHA=737ebdd83afa47b742ca8325fad0176952fcefbd checkout=fuchsia jiri=.jiri_root/bin/jiri diff --git a/src/ci/docker/scripts/build-fuchsia-toolchain.sh b/src/ci/docker/scripts/build-fuchsia-toolchain.sh index 7a0d4fcffc1..027d412d250 100755 --- a/src/ci/docker/scripts/build-fuchsia-toolchain.sh +++ b/src/ci/docker/scripts/build-fuchsia-toolchain.sh @@ -4,13 +4,13 @@ set -ex source shared.sh FUCHSIA_SDK_URL=https://chrome-infra-packages.appspot.com/dl/fuchsia/sdk/core/linux-amd64 -FUCHSIA_SDK_ID=version:20.20240412.3.1 -FUCHSIA_SDK_SHA256=cc52f3497487dd813c89d9316e6967efcea89c7759edccf3e40fcf3662e53f19 +FUCHSIA_SDK_ID=version:21.20240610.2.1 +FUCHSIA_SDK_SHA256=2d2d057fc3f0404197cced2200f88cbcdaaf5fbf6475955045091f8676791ce7 FUCHSIA_SDK_USR_DIR=/usr/local/core-linux-amd64-fuchsia-sdk CLANG_DOWNLOAD_URL=\ https://chrome-infra-packages.appspot.com/dl/fuchsia/third_party/clang/linux-amd64 -CLANG_DOWNLOAD_ID=git_revision:c777c011a709dffd4fa5e79cad7947b7c3405d02 -CLANG_DOWNLOAD_SHA256=779167422ad73c292f049dcea5569f84577af9292189ed2749518b966a4d0844 +CLANG_DOWNLOAD_ID=git_revision:3809e20afc68d7d03821f0ec59b928dcf9befbf4 +CLANG_DOWNLOAD_SHA256=3c2c442b61cd9e8f1b567738f6d53cffe11b3fc820e7dae87a82a0859be8f204 install_clang() { mkdir -p clang_download diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py index 4f504341d52..d791550a8db 100755 --- a/src/ci/docker/scripts/fuchsia-test-runner.py +++ b/src/ci/docker/scripts/fuchsia-test-runner.py @@ -286,7 +286,7 @@ class TestEnvironment: # Look up the product bundle transfer manifest. self.log_info("Looking up the product bundle transfer manifest...") product_name = "minimal." + self.triple_to_arch(self.target) - fuchsia_version = "20.20240412.3.1" + fuchsia_version = "21.20240610.2.1" out = self.check_output( [ From efbfcdd220a9f7ccdee235e0839e1848a554c4a5 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Fri, 14 Jun 2024 00:18:21 +0000 Subject: [PATCH 13/13] Fill out missing Windows support information --- src/doc/rustc/src/platform-support.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c672cff7452..e55bb3bd155 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -259,7 +259,7 @@ target | std | host | notes [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD `aarch64-unknown-redox` | ? | | ARM64 Redox OS -`aarch64-uwp-windows-msvc` | ? | | +`aarch64-uwp-windows-msvc` | ✓ | | `aarch64-wrs-vxworks` | ? | | `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian) @@ -300,8 +300,8 @@ target | std | host | notes [`i686-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 32-bit GNU/Hurd [^x86_32-floats-return-ABI] [`i686-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD/i386 with SSE2 [^x86_32-floats-return-ABI] [`i686-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 32-bit OpenBSD [^x86_32-floats-return-ABI] -`i686-uwp-windows-gnu` | ? | | [^x86_32-floats-return-ABI] -`i686-uwp-windows-msvc` | ? | | [^x86_32-floats-return-ABI] +`i686-uwp-windows-gnu` | ✓ | | [^x86_32-floats-return-ABI] +`i686-uwp-windows-msvc` | ✓ | | [^x86_32-floats-return-ABI] [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] `i686-wrs-vxworks` | ? | | [^x86_32-floats-return-ABI] [`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | ? | | LoongArch64 Linux (LP64D ABI) with musl 1.2.3 @@ -362,7 +362,7 @@ target | std | host | notes [`sparc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/sparc64 [`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Thumb-mode Bare Armv4T [`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Thumb-mode Bare Armv5TE -`thumbv7a-pc-windows-msvc` | ? | | +`thumbv7a-pc-windows-msvc` | ✓ | | `thumbv7a-uwp-windows-msvc` | ✓ | | `thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.3 [`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ | | WebAssembly