diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 521f8ef0f5ae5..4cf0e5fba5378 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -95,8 +95,6 @@ jobs: path-type: inherit install: > make - dos2unix - diffutils - name: disable git crlf conversion run: git config --global core.autocrlf false diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index f32ff57fe88b9..8200a58f31fff 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2888,7 +2888,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .. } = 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 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - Some(err) + Err(err) } #[instrument(level = "debug", skip(self))] diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index bdb808b1d4fff..412d8b93512a6 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1561,17 +1561,13 @@ fn print_native_static_libs( match out { OutFileName::Real(path) => { out.overwrite(&lib_args.join(" "), sess); - if !lib_args.is_empty() { - sess.dcx().emit_note(errors::StaticLibraryNativeArtifactsToFile { path }); - } + sess.dcx().emit_note(errors::StaticLibraryNativeArtifactsToFile { path }); } OutFileName::Stdout => { - if !lib_args.is_empty() { - sess.dcx().emit_note(errors::StaticLibraryNativeArtifacts); - // Prefix for greppability - // Note: This must not be translated as tools are allowed to depend on this exact string. - sess.dcx().note(format!("native-static-libs: {}", &lib_args.join(" "))); - } + sess.dcx().emit_note(errors::StaticLibraryNativeArtifacts); + // Prefix for greppability + // Note: This must not be translated as tools are allowed to depend on this exact string. + sess.dcx().note(format!("native-static-libs: {}", &lib_args.join(" "))); } } } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 9736c8b89204e..93222c1868651 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -628,7 +628,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; }; - let pick = self.confirm_method( + let pick = self.confirm_method_for_diagnostic( call_expr.span, callee_expr, call_expr, diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index d2a5924c8bbb9..f9720c9c30795 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -4,7 +4,7 @@ use rustc_errors::{Applicability, Diag}; 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 7fd081593854d..c4e55d564a019 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -87,7 +87,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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); @@ -1738,10 +1738,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 94e879ae9c3ed..9531c002829ea 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 172d874d4eed7..10d9e07db6f1f 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> FnCtxt<'a, '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/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 3c9a49e91a3f9..120e3239d1f1b 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -497,7 +497,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { 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 e842bba34bf82..3986374a343f0 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -634,8 +634,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + #[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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + #[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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + #[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 @@ impl<'a, 'tcx> ProbeContext<'a, '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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + #[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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + #[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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + #[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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /////////////////////////////////////////////////////////////////////////// // THE ACTUAL SEARCH + #[instrument(level = "debug", skip(self))] fn pick(mut self) -> PickResult<'tcx> { assert!(self.method_name.is_some()); @@ -1386,6 +1387,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } + #[instrument(level = "trace", skip(self, possibly_unsatisfied_predicates), ret)] fn consider_probe( &self, self_ty: Ty<'tcx>, @@ -1415,15 +1417,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { (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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { (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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { (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 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// 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_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 9476dc704831d..220556fe2568b 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -105,15 +105,16 @@ impl<'tcx> FnCtxt<'_, 'tcx> { 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 @@ impl<'tcx> FnCtxt<'_, 'tcx> { 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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,13 +987,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // 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) { - 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), } } @@ -1050,7 +1050,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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,12 +1223,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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_err(|diag| diag.emit()); // Type-check subpatterns. if subpats.len() == variant.fields.len() @@ -1249,6 +1244,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None, ); } + if let Err(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, @@ -1273,7 +1272,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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()); @@ -1330,7 +1329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // #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(), @@ -1445,8 +1444,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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)); @@ -1470,7 +1468,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 { @@ -1486,7 +1484,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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. @@ -1495,8 +1493,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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) => { @@ -1511,7 +1509,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) .unwrap_or_else(|| { inexistent_fields.push(field); - no_field_errors = false; Ty::new_misc_error(tcx) }) } @@ -1585,37 +1582,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } 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(); - e.emit(); + Err(e) } 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) { + if let Err(e) = self.error_tuple_variant_as_struct_pat(pat, fields, variant) { u.delay_as_bug(); - e.emit(); + Err(e) } else { - u.emit(); + Err(u.emit()) } } - (Some(err), None) => { - err.emit(); - } - (None, None) - if let Some(err) = - self.error_tuple_variant_index_shorthand(variant, pat, fields) => - { - err.emit(); + (Some(err), None) => Err(err.emit()), + (None, None) => { + self.error_tuple_variant_index_shorthand(variant, pat, fields)?; + result } - (None, None) => {} } - no_field_errors } fn error_tuple_variant_index_shorthand( @@ -1623,7 +1614,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 }). @@ -1645,10 +1636,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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) { @@ -1804,14 +1795,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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); @@ -1839,9 +1830,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("({sugg})"), appl, ); - return Some(err); + return Err(err.emit()); } - None + Ok(()) } fn get_suggested_tuple_struct_pattern( @@ -2065,20 +2056,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 } @@ -2222,7 +2213,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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(); } @@ -2327,7 +2318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 50b6c77e1b29d..4fad721ce9847 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/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 56a0f8e39c4aa..035c92bc84bfe 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -22,16 +22,12 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; #[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))] use crate::sys::weak::syscall; -#[cfg(any(target_os = "android", target_os = "macos", target_os = "solaris"))] +#[cfg(target_os = "android")] use crate::sys::weak::weak; use libc::{c_int, mode_t}; -#[cfg(any( - target_os = "solaris", - all(target_os = "linux", target_env = "gnu"), - target_vendor = "apple", -))] +#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))] use libc::c_char; #[cfg(any( all(target_os = "linux", not(target_env = "musl")), @@ -1753,19 +1749,6 @@ pub fn link(original: &Path, link: &Path) -> io::Result<()> { // Android has `linkat` on newer versions, but we happen to know `link` // always has the correct behavior, so it's here as well. cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?; - } else if #[cfg(any(target_os = "macos", target_os = "solaris"))] { - // MacOS (<=10.9) and Solaris 10 lack support for linkat while newer - // versions have it. We want to use linkat if it is available, so we use weak! - // to check. `linkat` is preferable to `link` because it gives us a flag to - // specify how symlinks should be handled. We pass 0 as the flags argument, - // meaning it shouldn't follow symlinks. - weak!(fn linkat(c_int, *const c_char, c_int, *const c_char, c_int) -> c_int); - - if let Some(f) = linkat.get() { - cvt(unsafe { f(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?; - } else { - cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?; - }; } else { // Where we can, use `linkat` instead of `link`; see the comment above // this one for details on why. diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index b5f17b9f54edc..da80f10b7dddd 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -137,19 +137,20 @@ pub fn check(build: &mut Build) { } // We need cmake, but only if we're actually building LLVM or sanitizers. - let building_llvm = build - .hosts - .iter() - .map(|host| { - build.config.llvm_enabled(*host) - && build - .config - .target_config - .get(host) - .map(|config| config.llvm_config.is_none()) - .unwrap_or(true) - }) - .any(|build_llvm_ourselves| build_llvm_ourselves); + let building_llvm = !build.config.llvm_from_ci + && build + .hosts + .iter() + .map(|host| { + build.config.llvm_enabled(*host) + && build + .config + .target_config + .get(host) + .map(|config| config.llvm_config.is_none()) + .unwrap_or(true) + }) + .any(|build_llvm_ourselves| build_llvm_ourselves); let need_cmake = building_llvm || build.config.any_sanitizers_to_build(); if need_cmake && cmd_finder.maybe_have("cmake").is_none() { diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 010e1b8fd51fd..4366a92fbcdf6 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -390,9 +390,7 @@ auto: - image: x86_64-mingw env: SCRIPT: make ci-mingw - RUST_CONFIGURE_ARGS: >- - --build=x86_64-pc-windows-gnu - --enable-profiler + RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu # We are intentionally allowing an old toolchain on this builder (and that's # incompatible with LLVM downloads today). NO_DOWNLOAD_CI_LLVM: 1 @@ -440,7 +438,6 @@ auto: RUST_CONFIGURE_ARGS: >- --build=i686-pc-windows-gnu --enable-full-tools - --enable-profiler # We are intentionally allowing an old toolchain on this builder (and that's # incompatible with LLVM downloads today). NO_DOWNLOAD_CI_LLVM: 1 @@ -454,7 +451,6 @@ auto: RUST_CONFIGURE_ARGS: >- --build=x86_64-pc-windows-gnu --enable-full-tools - --enable-profiler # We are intentionally allowing an old toolchain on this builder (and that's # incompatible with LLVM downloads today). NO_DOWNLOAD_CI_LLVM: 1 diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index cc972223f6dfb..65436a8a4401a 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1023,9 +1023,6 @@ fn iter_header( if mode == Mode::CoverageRun { let extra_directives: &[&str] = &[ "needs-profiler-support", - // FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works - // properly. Since we only have GCC on the CI ignore the test for now. - "ignore-windows-gnu", // FIXME(pietroalbini): this test currently does not work on cross-compiled // targets because remote-test is not capable of sending back the *.profraw // files generated by the LLVM instrumentation. diff --git a/tests/codegen/instrument-coverage/instrument-coverage-off.rs b/tests/codegen/instrument-coverage/instrument-coverage-off.rs index 616e3295e5b1a..e44d6c6587480 100644 --- a/tests/codegen/instrument-coverage/instrument-coverage-off.rs +++ b/tests/codegen/instrument-coverage/instrument-coverage-off.rs @@ -1,5 +1,6 @@ // Test that `-Cinstrument-coverage=off` does not add coverage instrumentation to LLVM IR. +//@ compile-flags: -Zno-profiler-runtime //@ revisions: n no off false_ zero //@ [n] compile-flags: -Cinstrument-coverage=n //@ [no] compile-flags: -Cinstrument-coverage=no diff --git a/tests/codegen/instrument-coverage/instrument-coverage.rs b/tests/codegen/instrument-coverage/instrument-coverage.rs index 65fa437d25066..3c16208d40e78 100644 --- a/tests/codegen/instrument-coverage/instrument-coverage.rs +++ b/tests/codegen/instrument-coverage/instrument-coverage.rs @@ -1,6 +1,6 @@ // Test that `-Cinstrument-coverage` creates expected __llvm_profile_filename symbol in LLVM IR. -//@ needs-profiler-support +//@ compile-flags: -Zno-profiler-runtime //@ revisions: default y yes on true_ all //@ [default] compile-flags: -Cinstrument-coverage //@ [y] compile-flags: -Cinstrument-coverage=y diff --git a/tests/codegen/instrument-coverage/testprog.rs b/tests/codegen/instrument-coverage/testprog.rs index acc4f35d90543..eea4d9cb3cf05 100644 --- a/tests/codegen/instrument-coverage/testprog.rs +++ b/tests/codegen/instrument-coverage/testprog.rs @@ -1,5 +1,5 @@ //@ edition: 2021 -//@ needs-profiler-support +//@ compile-flags: -Zno-profiler-runtime //@ compile-flags: -Cinstrument-coverage -Copt-level=0 //@ revisions: LINUX DARWIN WINDOWS diff --git a/tests/codegen/naked-fn/naked-nocoverage.rs b/tests/codegen/naked-fn/naked-nocoverage.rs index e8d3b5834fa3a..d73c5b7fd26d1 100644 --- a/tests/codegen/naked-fn/naked-nocoverage.rs +++ b/tests/codegen/naked-fn/naked-nocoverage.rs @@ -2,7 +2,7 @@ // Regression test for issue #105170. // //@ needs-asm-support -//@ needs-profiler-support +//@ compile-flags: -Zno-profiler-runtime //@ compile-flags: -Cinstrument-coverage #![crate_type = "lib"] #![feature(naked_functions)] diff --git a/tests/codegen/pgo-counter-bias.rs b/tests/codegen/pgo-counter-bias.rs index 87d31073d5ae1..48e815dda0483 100644 --- a/tests/codegen/pgo-counter-bias.rs +++ b/tests/codegen/pgo-counter-bias.rs @@ -2,7 +2,7 @@ //@ ignore-apple -runtime-counter-relocation not honored on Mach-O //@ compile-flags: -Cprofile-generate -Cllvm-args=-runtime-counter-relocation -Clto=fat -//@ needs-profiler-support +//@ compile-flags: -Zno-profiler-runtime //@ no-prefer-dynamic // CHECK: @__llvm_profile_counter_bias = {{.*}}global diff --git a/tests/codegen/pgo-instrumentation.rs b/tests/codegen/pgo-instrumentation.rs index b1906c145c6be..a8f12ccce1cb4 100644 --- a/tests/codegen/pgo-instrumentation.rs +++ b/tests/codegen/pgo-instrumentation.rs @@ -1,6 +1,6 @@ // Test that `-Cprofile-generate` creates expected instrumentation artifacts in LLVM IR. -//@ needs-profiler-support +//@ compile-flags: -Zno-profiler-runtime //@ compile-flags: -Cprofile-generate -Ccodegen-units=1 // CHECK: @__llvm_profile_raw_version = diff --git a/tests/crashes/109812.rs b/tests/crashes/109812.rs deleted file mode 100644 index c29b874652153..0000000000000 --- 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 77ccb9fb0978d..0000000000000 --- 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/run-make/optimization-remarks-dir-pgo/Makefile b/tests/run-make/optimization-remarks-dir-pgo/Makefile index 3bc3d7d142887..57ffd6e70f00b 100644 --- a/tests/run-make/optimization-remarks-dir-pgo/Makefile +++ b/tests/run-make/optimization-remarks-dir-pgo/Makefile @@ -1,10 +1,6 @@ # needs-profiler-support -# ignore-windows-gnu # ignore-cross-compile -# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works -# properly. Since we only have GCC on the CI ignore the test for now. - include ../tools.mk PROFILE_DIR=$(TMPDIR)/profiles diff --git a/tests/run-make/pgo-branch-weights/rmake.rs b/tests/run-make/pgo-branch-weights/rmake.rs index 55f6e7e56c5ae..d3cb79c39afa9 100644 --- a/tests/run-make/pgo-branch-weights/rmake.rs +++ b/tests/run-make/pgo-branch-weights/rmake.rs @@ -10,10 +10,6 @@ //@ needs-profiler-support //@ ignore-cross-compile -// FIXME(Oneirical): This test has problems generating profdata on mingw. -// For more information, see https://github.com/rust-lang/rust/pull/122613 -//@ ignore-windows-gnu - use run_make_support::{fs_wrapper, llvm_filecheck, llvm_profdata, run_with_args, rustc}; use std::path::Path; diff --git a/tests/run-make/pgo-gen-lto/Makefile b/tests/run-make/pgo-gen-lto/Makefile index 8b647846af3b3..54164c995222a 100644 --- a/tests/run-make/pgo-gen-lto/Makefile +++ b/tests/run-make/pgo-gen-lto/Makefile @@ -1,10 +1,6 @@ # needs-profiler-support -# ignore-windows-gnu # ignore-cross-compile -# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works -# properly. Since we only have GCC on the CI ignore the test for now. - include ../tools.mk COMPILE_FLAGS=-Copt-level=3 -Clto=fat -Cprofile-generate="$(TMPDIR)" diff --git a/tests/run-make/pgo-gen-no-imp-symbols/Makefile b/tests/run-make/pgo-gen-no-imp-symbols/Makefile index 7f72b11b611ed..d2baa145ba506 100644 --- a/tests/run-make/pgo-gen-no-imp-symbols/Makefile +++ b/tests/run-make/pgo-gen-no-imp-symbols/Makefile @@ -1,8 +1,6 @@ -# needs-profiler-support - include ../tools.mk -COMPILE_FLAGS=-O -Ccodegen-units=1 -Cprofile-generate="$(TMPDIR)" +COMPILE_FLAGS=-O -Ccodegen-units=1 -Cprofile-generate="$(TMPDIR)" -Zno-profiler-runtime all: $(RUSTC) $(COMPILE_FLAGS) --emit=llvm-ir test.rs diff --git a/tests/run-make/pgo-gen/Makefile b/tests/run-make/pgo-gen/Makefile index bf32cfdb802f5..c1d456986fb28 100644 --- a/tests/run-make/pgo-gen/Makefile +++ b/tests/run-make/pgo-gen/Makefile @@ -1,10 +1,6 @@ # needs-profiler-support -# ignore-windows-gnu # ignore-cross-compile -# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works -# properly. Since we only have GCC on the CI ignore the test for now. - include ../tools.mk COMPILE_FLAGS=-g -Cprofile-generate="$(TMPDIR)" diff --git a/tests/run-make/pgo-indirect-call-promotion/Makefile b/tests/run-make/pgo-indirect-call-promotion/Makefile index 542eb244d3959..8d1e69c4aba37 100644 --- a/tests/run-make/pgo-indirect-call-promotion/Makefile +++ b/tests/run-make/pgo-indirect-call-promotion/Makefile @@ -1,10 +1,6 @@ # needs-profiler-support -# ignore-windows-gnu # ignore-cross-compile -# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works -# properly. Since we only have GCC on the CI ignore the test for now. - include ../tools.mk all: diff --git a/tests/run-make/pgo-use/Makefile b/tests/run-make/pgo-use/Makefile index 9f440118daee3..92098a4019c47 100644 --- a/tests/run-make/pgo-use/Makefile +++ b/tests/run-make/pgo-use/Makefile @@ -1,10 +1,6 @@ # needs-profiler-support -# ignore-windows-gnu # ignore-cross-compile -# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works -# properly. Since we only have GCC on the CI ignore the test for now. - include ../tools.mk # This test makes sure that PGO profiling data leads to cold functions being diff --git a/tests/run-make/track-pgo-dep-info/Makefile b/tests/run-make/track-pgo-dep-info/Makefile index 6c7f67d0f0a9d..3afe3662fa753 100644 --- a/tests/run-make/track-pgo-dep-info/Makefile +++ b/tests/run-make/track-pgo-dep-info/Makefile @@ -1,5 +1,4 @@ # needs-profiler-support -# ignore-windows-gnu include ../tools.mk diff --git a/tests/ui/codegen/empty-static-libs-issue-108825.rs b/tests/ui/codegen/empty-static-libs-issue-108825.rs new file mode 100644 index 0000000000000..e25672a245f53 --- /dev/null +++ b/tests/ui/codegen/empty-static-libs-issue-108825.rs @@ -0,0 +1,14 @@ +// Test that linking a no_std application still outputs the +// `native-static-libs: ` note, even though it's empty. +//@ compile-flags: -Cpanic=abort --print=native-static-libs +//@ build-pass +//@ ignore-wasm +//@ ignore-cross-compile This doesn't produce any output on i686-unknown-linux-gnu for some reason? + +#![crate_type = "staticlib"] +#![no_std] + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} diff --git a/tests/ui/codegen/empty-static-libs-issue-108825.stderr b/tests/ui/codegen/empty-static-libs-issue-108825.stderr new file mode 100644 index 0000000000000..4f07d441fb6aa --- /dev/null +++ b/tests/ui/codegen/empty-static-libs-issue-108825.stderr @@ -0,0 +1,4 @@ +note: Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms. + +note: native-static-libs: + 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 0000000000000..cd222aa7ae9fc --- /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 0000000000000..c26c01e002d85 --- /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 0000000000000..271051f120abc --- /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 0000000000000..17f7cad660db1 --- /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 0000000000000..6ecb2b05fc56b --- /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 0000000000000..5fb0b8f1d14b2 --- /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 0000000000000..7fb2ff3b2bcc6 --- /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 0000000000000..fe6e166cb4fa1 --- /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 0000000000000..327f6ca3450f1 --- /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 0000000000000..40ad21532a4e2 --- /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 0000000000000..72982b695bbb0 --- /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 0000000000000..d62777ea2835d --- /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.rs b/tests/ui/impl-trait/method-resolution.rs new file mode 100644 index 0000000000000..60fbacd86462b --- /dev/null +++ b/tests/ui/impl-trait/method-resolution.rs @@ -0,0 +1,26 @@ +//! 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 +//@ check-pass + +trait Trait {} + +impl Trait for u32 {} + +struct Bar(T); + +impl Bar { + fn bar(self) {} +} + +fn foo(x: bool) -> Bar { + if x { + let x = foo(false); + x.bar(); + } + 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 0000000000000..223430e1658b4 --- /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 0000000000000..88d4f3d9896c7 --- /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 type 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 0000000000000..87dd862ef8f4f --- /dev/null +++ b/tests/ui/impl-trait/method-resolution3.current.stderr @@ -0,0 +1,20 @@ +error[E0034]: multiple applicable items in scope + --> $DIR/method-resolution3.rs:21: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.next.stderr b/tests/ui/impl-trait/method-resolution3.next.stderr new file mode 100644 index 0000000000000..87dd862ef8f4f --- /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:21: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 0000000000000..8c47ef4fc75c7 --- /dev/null +++ b/tests/ui/impl-trait/method-resolution3.rs @@ -0,0 +1,27 @@ +//! 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 { + if x { + let x = foo(false); + x.bar(); + //~^ 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 0000000000000..b48de0af3579d --- /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 0000000000000..91884eb59fd63 --- /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`. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[current] check-pass + +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 0000000000000..4da9a06a4659b --- /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/instrument-coverage/coverage-options.rs b/tests/ui/instrument-coverage/coverage-options.rs index 8f523a5fd11a0..7615a0fb2751c 100644 --- a/tests/ui/instrument-coverage/coverage-options.rs +++ b/tests/ui/instrument-coverage/coverage-options.rs @@ -1,6 +1,5 @@ -//@ needs-profiler-support //@ revisions: block branch condition mcdc bad -//@ compile-flags -Cinstrument-coverage +//@ compile-flags -Cinstrument-coverage -Zno-profiler-runtime //@ [block] check-pass //@ [block] compile-flags: -Zcoverage-options=block diff --git a/tests/ui/instrument-coverage/on-values.rs b/tests/ui/instrument-coverage/on-values.rs index a6793b2c304f2..53b149fd39cce 100644 --- a/tests/ui/instrument-coverage/on-values.rs +++ b/tests/ui/instrument-coverage/on-values.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ needs-profiler-support +//@ compile-flags: -Zno-profiler-runtime //@ revisions: default y yes on true_ all //@ [default] compile-flags: -Cinstrument-coverage //@ [y] compile-flags: -Cinstrument-coverage=y diff --git a/tests/ui/methods/opaque_param_in_ufc.rs b/tests/ui/methods/opaque_param_in_ufc.rs index a4b27a0131fd0..b170e6805f646 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 7e5bbbac8a9ab..0000000000000 --- 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/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 1fcf078594578..6c98050325638 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 0000000000000..14f7dbbd839c0 --- /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`. diff --git a/tests/ui/pattern/missing_lifetime.rs b/tests/ui/pattern/missing_lifetime.rs new file mode 100644 index 0000000000000..081f667d8f6a9 --- /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 0000000000000..ec4063fd289ad --- /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 0000000000000..408ff75884712 --- /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 0000000000000..b0441b1fadcfe --- /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`. 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 0000000000000..a9c05ad33424d --- /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 0000000000000..6b34358a56ea3 --- /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 0000000000000..f636aba15c0c4 --- /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.rs b/tests/ui/type-alias-impl-trait/method_resolution2.rs new file mode 100644 index 0000000000000..f69661db79922 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution2.rs @@ -0,0 +1,28 @@ +//! 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 +//@ check-pass + +#![feature(type_alias_impl_trait)] + +type Foo = impl Sized; + +struct Bar(T); + +impl Bar { + fn bar(self) { + self.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 0000000000000..e992d059daf7d --- /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 0000000000000..9272017cdf5d1 --- /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 0000000000000..447f3144b822c --- /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 0000000000000..3a2ca18f89097 --- /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 0000000000000..33ed2800ebe0c --- /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 0000000000000..42ed04b3c30f6 --- /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.rs b/tests/ui/type-alias-impl-trait/method_resolution5.rs new file mode 100644 index 0000000000000..64355e4560de2 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/method_resolution5.rs @@ -0,0 +1,33 @@ +//! 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 +//@ 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() + } +} + +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 0000000000000..f331da1af8793 --- /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 0000000000000..2617ce124c105 --- /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 0000000000000..b6adf08853f2f --- /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() {}