Skip to content

Rollup of 7 pull requests #126412

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 23 commits into from
Closed
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5cfe020
Always emit native-static-libs note, even if it is empty
madsmtm Feb 17, 2024
48d3425
Remove some msys2 utils
ChrisDenton Jun 12, 2024
c81ffab
std::unix::fs::link using direct linkat call for Solaris and macOs.
devnexen Jun 12, 2024
a84f754
Use `-Zno-profiler-runtime` instead of `//@ needs-profiler-support`
Zalathar Mar 16, 2024
0c67f32
Don't build a known-broken profiler runtime in `x86_64-mingw`
Zalathar Mar 17, 2024
d2ecfbb
Remove `//@ ignore-windows-gnu` from tests that need the profiler
Zalathar Mar 17, 2024
beb45a4
Remove broken/untested `--enable-profiler` from mingw dist builds
Zalathar Mar 17, 2024
2733b8a
Avoid follow-up errors on erroneous patterns
oli-obk Jun 11, 2024
a621701
Replace some `Option<Diag>` with `Result<(), Diag>`
oli-obk Jun 12, 2024
ece3e3e
Replace some `Option<Diag>` with `Result<(), Diag>`
oli-obk Jun 12, 2024
e8d6170
Replace some `Option<Diag>` with `Result<(), Diag>`
oli-obk Jun 12, 2024
7566307
Replace a `bool` with a `Result<(), ErrorGuaranteed>`
oli-obk Jun 12, 2024
b28221e
Use diagnostic method for diagnostics
oli-obk Apr 15, 2024
c75f728
Add some tests
oli-obk Apr 15, 2024
9cf60ee
Method resolution constrains hidden types instead of rejecting method…
oli-obk Apr 15, 2024
58e3ac0
extend the check for LLVM build
onur-ozkan Jun 13, 2024
32b7592
Rollup merge of #121216 - madsmtm:fix-108825, r=wesleywiser
matthiaskrgr Jun 13, 2024
7a1deaf
Rollup merge of #122613 - Zalathar:profiler, r=nnethercote
matthiaskrgr Jun 13, 2024
0650026
Rollup merge of #123962 - oli-obk:define_opaque_types5, r=lcnr
matthiaskrgr Jun 13, 2024
29cb7a9
Rollup merge of #126320 - oli-obk:pat_ice, r=lcnr
matthiaskrgr Jun 13, 2024
c9d783e
Rollup merge of #126343 - ChrisDenton:remove-utils, r=Kobzol
matthiaskrgr Jun 13, 2024
d78706b
Rollup merge of #126351 - devnexen:to_sol11_upd, r=ChrisDenton
matthiaskrgr Jun 13, 2024
1521dc8
Rollup merge of #126399 - onur-ozkan:126156, r=albertlarsan68
matthiaskrgr Jun 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -95,8 +95,6 @@ jobs:
path-type: inherit
install: >
make
dos2unix
diffutils
- name: disable git crlf conversion
run: git config --global core.autocrlf false
10 changes: 5 additions & 5 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
@@ -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<Diag<'tcx>> {
) -> 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))]
14 changes: 5 additions & 9 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
@@ -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(" ")));
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
@@ -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,
57 changes: 28 additions & 29 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
@@ -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<Diag<'tcx>> {
) -> 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<Diag<'tcx>> {
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<Diag<'tcx>> {
) -> 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<Diag<'tcx>> {
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<Diag<'tcx>>) {
) -> Result<Ty<'tcx>, 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
11 changes: 5 additions & 6 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
@@ -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,
) {
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
@@ -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();
}
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/method/confirm.rs
Original file line number Diff line number Diff line change
@@ -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);
}
65 changes: 29 additions & 36 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
@@ -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<Option<ty::AssocItem>, MethodError<'tcx>> {
131 changes: 61 additions & 70 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
@@ -105,15 +105,16 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
expected: Ty<'tcx>,
actual: Ty<'tcx>,
ti: &TopInfo<'tcx>,
) -> Option<Diag<'tcx>> {
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>(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,45 +1582,39 @@ 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(
&self,
variant: &VariantDef,
pat: &'_ Pat<'_>,
fields: &[hir::PatField<'_>],
) -> Option<Diag<'_>> {
) -> 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<Diag<'tcx>> {
) -> 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);
}
}

2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/traits/query.rs
Original file line number Diff line number Diff line change
@@ -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>>,
21 changes: 2 additions & 19 deletions library/std/src/sys/pal/unix/fs.rs
Original file line number Diff line number Diff line change
@@ -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.
27 changes: 14 additions & 13 deletions src/bootstrap/src/core/sanity.rs
Original file line number Diff line number Diff line change
@@ -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() {
6 changes: 1 addition & 5 deletions src/ci/github-actions/jobs.yml
Original file line number Diff line number Diff line change
@@ -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
3 changes: 0 additions & 3 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
@@ -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.
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion tests/codegen/instrument-coverage/instrument-coverage.rs
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion tests/codegen/instrument-coverage/testprog.rs
Original file line number Diff line number Diff line change
@@ -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

2 changes: 1 addition & 1 deletion tests/codegen/naked-fn/naked-nocoverage.rs
Original file line number Diff line number Diff line change
@@ -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)]
2 changes: 1 addition & 1 deletion tests/codegen/pgo-counter-bias.rs
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion tests/codegen/pgo-instrumentation.rs
Original file line number Diff line number Diff line change
@@ -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 =
22 changes: 0 additions & 22 deletions tests/crashes/109812.rs

This file was deleted.

20 changes: 0 additions & 20 deletions tests/crashes/125914.rs

This file was deleted.

4 changes: 0 additions & 4 deletions tests/run-make/optimization-remarks-dir-pgo/Makefile
Original file line number Diff line number Diff line change
@@ -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
4 changes: 0 additions & 4 deletions tests/run-make/pgo-branch-weights/rmake.rs
Original file line number Diff line number Diff line change
@@ -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;

4 changes: 0 additions & 4 deletions tests/run-make/pgo-gen-lto/Makefile
Original file line number Diff line number Diff line change
@@ -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)"
4 changes: 1 addition & 3 deletions tests/run-make/pgo-gen-no-imp-symbols/Makefile
Original file line number Diff line number Diff line change
@@ -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
4 changes: 0 additions & 4 deletions tests/run-make/pgo-gen/Makefile
Original file line number Diff line number Diff line change
@@ -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)"
4 changes: 0 additions & 4 deletions tests/run-make/pgo-indirect-call-promotion/Makefile
Original file line number Diff line number Diff line change
@@ -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:
4 changes: 0 additions & 4 deletions tests/run-make/pgo-use/Makefile
Original file line number Diff line number Diff line change
@@ -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
1 change: 0 additions & 1 deletion tests/run-make/track-pgo-dep-info/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# needs-profiler-support
# ignore-windows-gnu

include ../tools.mk

14 changes: 14 additions & 0 deletions tests/ui/codegen/empty-static-libs-issue-108825.rs
Original file line number Diff line number Diff line change
@@ -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 {}
}
4 changes: 4 additions & 0 deletions tests/ui/codegen/empty-static-libs-issue-108825.stderr
Original file line number Diff line number Diff line change
@@ -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:

17 changes: 17 additions & 0 deletions tests/ui/impl-trait/call_method_ambiguous.next.stderr
Original file line number Diff line number Diff line change
@@ -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`.
39 changes: 39 additions & 0 deletions tests/ui/impl-trait/call_method_ambiguous.rs
Original file line number Diff line number Diff line change
@@ -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<T> 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);
}
17 changes: 17 additions & 0 deletions tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr
Original file line number Diff line number Diff line change
@@ -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`.
25 changes: 25 additions & 0 deletions tests/ui/impl-trait/call_method_on_inherent_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver
//@[current] check-pass

trait MyDebug {
fn my_debug(&self);
}

impl<T> 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() {}
Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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`.
22 changes: 22 additions & 0 deletions tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.
31 changes: 31 additions & 0 deletions tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr
Original file line number Diff line number Diff line change
@@ -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`.
35 changes: 35 additions & 0 deletions tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//@ revisions: current next
//@[next] compile-flags: -Znext-solver

trait MyDebug {
fn my_debug(&self);
}

impl<T> 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() {}
37 changes: 37 additions & 0 deletions tests/ui/impl-trait/call_method_without_import.no_import.stderr
Original file line number Diff line number Diff line change
@@ -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`.
42 changes: 42 additions & 0 deletions tests/ui/impl-trait/call_method_without_import.rs
Original file line number Diff line number Diff line change
@@ -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>(t: impl std::fmt::Debug, f: &mut std::fmt::Formatter<'_>) {
t.fmt(f);
}

// and the desugared version, of course
fn baz<T: std::fmt::Debug>(t: T, f: &mut std::fmt::Formatter<'_>) {
t.fmt(f);
}

fn main() {}
26 changes: 26 additions & 0 deletions tests/ui/impl-trait/method-resolution.rs
Original file line number Diff line number Diff line change
@@ -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>(T);

impl Bar<u32> {
fn bar(self) {}
}

fn foo(x: bool) -> Bar<impl Sized> {
if x {
let x = foo(false);
x.bar();
}
todo!()
}

fn main() {}
20 changes: 20 additions & 0 deletions tests/ui/impl-trait/method-resolution2.next.stderr
Original file line number Diff line number Diff line change
@@ -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<T>`
--> $DIR/method-resolution2.rs:19:5
|
LL | fn bar(self) {}
| ^^^^^^^^^^^^
note: candidate #2 is defined in an impl for the type `Bar<u32>`
--> $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`.
31 changes: 31 additions & 0 deletions tests/ui/impl-trait/method-resolution2.rs
Original file line number Diff line number Diff line change
@@ -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>(T);

impl Bar<u32> {
fn bar(self) {}
}

impl<T: Trait> Bar<T> {
fn bar(self) {}
}

fn foo(x: bool) -> Bar<impl Trait> {
if x {
let x = foo(false);
x.bar();
//[next]~^ ERROR: multiple applicable items in scope
}
Bar(42_i32)
}

fn main() {}
20 changes: 20 additions & 0 deletions tests/ui/impl-trait/method-resolution3.current.stderr
Original file line number Diff line number Diff line change
@@ -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<i32>`
--> $DIR/method-resolution3.rs:15:5
|
LL | fn bar(self) {}
| ^^^^^^^^^^^^
note: candidate #2 is defined in an impl for the type `Bar<u32>`
--> $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`.
20 changes: 20 additions & 0 deletions tests/ui/impl-trait/method-resolution3.next.stderr
Original file line number Diff line number Diff line change
@@ -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<i32>`
--> $DIR/method-resolution3.rs:15:5
|
LL | fn bar(self) {}
| ^^^^^^^^^^^^
note: candidate #2 is defined in an impl for the type `Bar<u32>`
--> $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`.
27 changes: 27 additions & 0 deletions tests/ui/impl-trait/method-resolution3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Check that we consider `Bar<impl Sized>` to successfully unify
//! with both `Bar<u32>` and `Bar<i32>` (in isolation), so we bail
//! out with ambiguity.
//@ revisions: current next
//@[next] compile-flags: -Znext-solver

struct Bar<T>(T);

impl Bar<u32> {
fn bar(self) {}
}

impl Bar<i32> {
fn bar(self) {}
}

fn foo(x: bool) -> Bar<impl Sized> {
if x {
let x = foo(false);
x.bar();
//~^ ERROR: multiple applicable items in scope
}
todo!()
}

fn main() {}
22 changes: 22 additions & 0 deletions tests/ui/impl-trait/method-resolution4.next.stderr
Original file line number Diff line number Diff line change
@@ -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<Item = ()> {
| ------------------------ the expected opaque type
...
LL | std::iter::empty()
| ^^^^^^^^^^^^^^^^^^ types differ
|
= note: expected opaque type `impl Iterator<Item = ()>`
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`.
20 changes: 20 additions & 0 deletions tests/ui/impl-trait/method-resolution4.rs
Original file line number Diff line number Diff line change
@@ -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<Item = ()> {
if b {
foo(false).next().unwrap();
//[next]~^ type annotations needed
}
std::iter::empty()
//[next]~^ mismatched types
}

fn main() {}
42 changes: 42 additions & 0 deletions tests/ui/impl-trait/recursive-parent-trait-method-call.rs
Original file line number Diff line number Diff line change
@@ -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<Box<dyn Future<Output = Self::Output> + Send + 'static>> {
Box::pin(self)
}
}

trait StreamExt: Future + Sized + Send + 'static {
fn boxed(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'static>> {
Box::pin(self)
}
}

impl<T: Future + Sized + Send + 'static> FutureExt for T {}

fn go(i: usize) -> impl Future<Output = ()> + Send + 'static {
async move {
if i != 0 {
spawn(async move {
let fut = go(i - 1).boxed();
fut.await;
})
.await;
}
}
}

pub fn spawn<T: Send>(
_: impl Future<Output = T> + Send + 'static,
) -> impl Future<Output = ()> + Send + 'static {
async move { todo!() }
}

fn main() {}
3 changes: 1 addition & 2 deletions tests/ui/instrument-coverage/coverage-options.rs
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion tests/ui/instrument-coverage/on-values.rs
Original file line number Diff line number Diff line change
@@ -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
6 changes: 3 additions & 3 deletions tests/ui/methods/opaque_param_in_ufc.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#![feature(type_alias_impl_trait)]

//@ check-pass

struct Foo<T>(T);

impl Foo<u32> {
@@ -15,14 +18,11 @@ fn bar() -> Bar {
impl Foo<Bar> {
fn foo() -> Bar {
Self::method();
//~^ ERROR: no function or associated item named `method` found for struct `Foo<Bar>`
Foo::<Bar>::method();
//~^ ERROR: no function or associated item named `method` found for struct `Foo<Bar>`
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<Bar>`
todo!()
}
}
36 changes: 0 additions & 36 deletions tests/ui/methods/opaque_param_in_ufc.stderr

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//@ known-bug: #124004
//! This test used to ICE #124004
#![feature(box_patterns)]

use std::ops::{ Deref };

struct X(dyn Iterator<Item = &'a ()>);
//~^ ERROR: use of undeclared lifetime name `'a`

impl Deref for X {
type Target = isize;
19 changes: 19 additions & 0 deletions tests/ui/pattern/box-pattern-type-mismatch.stderr
Original file line number Diff line number Diff line change
@@ -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<Item = &'a ()>);
| ^^ 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<Item = &'a ()>);
| +++++++
help: consider introducing lifetime `'a` here
|
LL | struct X<'a>(dyn Iterator<Item = &'a ()>);
| ++++

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0261`.
25 changes: 25 additions & 0 deletions tests/ui/pattern/missing_lifetime.rs
Original file line number Diff line number Diff line change
@@ -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(..)) => {}
}
}
25 changes: 25 additions & 0 deletions tests/ui/pattern/missing_lifetime.stderr
Original file line number Diff line number Diff line change
@@ -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`.
30 changes: 30 additions & 0 deletions tests/ui/pattern/type_mismatch.rs
Original file line number Diff line number Diff line change
@@ -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() {}
11 changes: 11 additions & 0 deletions tests/ui/pattern/type_mismatch.stderr
Original file line number Diff line number Diff line change
@@ -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`.
15 changes: 15 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution.current.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
--> $DIR/method_resolution.rs:21:14
|
LL | struct Bar<T>(T);
| ------------- method `bar` not found for this struct
...
LL | self.bar()
| ^^^ method not found in `Bar<u32>`
|
= note: the method was found for
- `Bar<Foo>`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0599`.
12 changes: 12 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0599]: no method named `bar` found for struct `Bar<u32>` in the current scope
--> $DIR/method_resolution.rs:21:14
|
LL | struct Bar<T>(T);
| ------------- method `bar` not found for this struct
...
LL | self.bar()
| ^^^ method cannot be called on `Bar<u32>` due to unsatisfied trait bounds

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0599`.
30 changes: 30 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//! `Bar<u32>::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>(T);

impl Bar<Foo> {
fn bar(mut self) {
self.0 = 42_u32;
}
}

impl Bar<u32> {
fn foo(self) {
self.bar()
//~^ ERROR: no method named `bar`
}
}

fn foo() -> Foo {
42_u32
}

fn main() {}
28 changes: 28 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! Check that we do unify `Bar<Foo>` with `Bar<u32>`, 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>(T);

impl Bar<Foo> {
fn bar(self) {
self.foo()
}
}

impl Bar<u32> {
fn foo(self) {}
}

fn foo() -> Foo {
42_u32
}

fn main() {}
21 changes: 21 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution3.current.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0307]: invalid `self` parameter type: `Bar<u32>`
--> $DIR/method_resolution3.rs:16:18
|
LL | fn bar(self: Bar<u32>) {
| ^^^^^^^^
|
= 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>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)

error[E0307]: invalid `self` parameter type: `&Bar<u32>`
--> $DIR/method_resolution3.rs:21:18
|
LL | fn baz(self: &Bar<u32>) {
| ^^^^^^^^^
|
= 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>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (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`.
15 changes: 15 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution3.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0271]: type mismatch resolving `Foo == u32`
--> $DIR/method_resolution3.rs:16:18
|
LL | fn bar(self: Bar<u32>) {
| ^^^^^^^^ types differ

error[E0271]: type mismatch resolving `Foo == u32`
--> $DIR/method_resolution3.rs:21:18
|
LL | fn baz(self: &Bar<u32>) {
| ^^^^^^^^^ types differ

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0271`.
36 changes: 36 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution3.rs
Original file line number Diff line number Diff line change
@@ -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>(T);

impl Bar<Foo> {
fn bar(self: Bar<u32>) {
//[current]~^ ERROR: invalid `self` parameter
//[next]~^^ ERROR: type mismatch resolving `Foo == u32`
self.foo()
}
fn baz(self: &Bar<u32>) {
//[current]~^ ERROR: invalid `self` parameter
//[next]~^^ ERROR: type mismatch resolving `Foo == u32`
self.foo()
}
}

impl Bar<u32> {
fn foo(self) {}
}

fn foo() -> Foo {
42_u32
}

fn main() {}
21 changes: 21 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution4.current.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error[E0307]: invalid `self` parameter type: `Bar<Foo>`
--> $DIR/method_resolution4.rs:27:18
|
LL | fn foo(self: Bar<Foo>) {
| ^^^^^^^^
|
= 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>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)

error[E0307]: invalid `self` parameter type: `&Bar<Foo>`
--> $DIR/method_resolution4.rs:32:20
|
LL | fn foomp(self: &Bar<Foo>) {
| ^^^^^^^^^
|
= 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>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (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`.
15 changes: 15 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution4.next.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0271]: type mismatch resolving `u32 == Foo`
--> $DIR/method_resolution4.rs:27:18
|
LL | fn foo(self: Bar<Foo>) {
| ^^^^^^^^ types differ

error[E0271]: type mismatch resolving `u32 == Foo`
--> $DIR/method_resolution4.rs:32:20
|
LL | fn foomp(self: &Bar<Foo>) {
| ^^^^^^^^^ types differ

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0271`.
39 changes: 39 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution4.rs
Original file line number Diff line number Diff line change
@@ -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>(T);

impl Bar<Foo> {
fn bar(self) {}
}

impl Bar<u32> {
fn foo(self: Bar<Foo>) {
//[current]~^ ERROR: invalid `self` parameter
//[next]~^^ ERROR: type mismatch resolving `u32 == Foo`
self.bar()
}
fn foomp(self: &Bar<Foo>) {
//[current]~^ ERROR: invalid `self` parameter
//[next]~^^ ERROR: type mismatch resolving `u32 == Foo`
self.bar()
}
}

fn main() {}
33 changes: 33 additions & 0 deletions tests/ui/type-alias-impl-trait/method_resolution5.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! Even though `Bar<u32>::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>(T);

impl Bar<Foo> {
fn bar(mut self) {
self.0 = 42_u32;
}
}

impl Bar<u32> {
fn foo(self)
where
Foo:,
{
self.bar()
}
}

fn foo() -> Foo {
42_u32
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -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<Item = ()>;
| ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

Original file line number Diff line number Diff line change
@@ -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`.
Original file line number Diff line number Diff line change
@@ -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<Item = ()>;

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() {}