Skip to content
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

Rollup of 9 pull requests #126642

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
012a458
Suggest removing unused tuple fields if they are the last fields
May 13, 2024
586821e
tip for inaccessible traits
bvanjoi Jun 1, 2024
2752a37
rewrite intrinsic-unreachable to rmake
Oneirical Jun 11, 2024
76c7a67
rewrite sepcomp-separate to rmake
Oneirical Jun 12, 2024
348c183
rewrite sepcomp-inlining and -separate to rmake.rs
Oneirical Jun 13, 2024
df1d616
safe transmute: support non-ZST, variantful, uninhabited enums
jswrenn Jun 14, 2024
ab0e727
Suggest standalone doctest for non-local impl defs
Urgau Jun 13, 2024
94c2821
Also simplify macro_rules doctest code
Urgau Jun 13, 2024
207c5bc
override user defined channel when using precompiled rustc
onur-ozkan Jun 17, 2024
5ae2446
simplify `Builder::doc_rust_lang_org_channel`
onur-ozkan Jun 17, 2024
ea30a9d
Rework count function without glob
Oneirical Jun 17, 2024
475b63f
Add `/rustc-ice*/ to `.gitignore`
tgross35 Jun 18, 2024
7321e79
Replace `move||` with `move ||` in `compiler/` and `library/`
Vonr Jun 18, 2024
de473a5
Test that opaque types can't have themselves as a hidden type with in…
oli-obk Apr 11, 2024
3b7bb08
Rollup merge of #123782 - oli-obk:equal_tait_args, r=compiler-errors
GuillaumeGomez Jun 18, 2024
b0237bd
Rollup merge of #124580 - gurry:124556-suggest-remove-tuple-field, r=…
GuillaumeGomez Jun 18, 2024
9429124
Rollup merge of #125852 - bvanjoi:improve-tip-for-invisible-trait, r=…
GuillaumeGomez Jun 18, 2024
328d55a
Rollup merge of #126422 - Urgau:doctest-impl-non-local-def, r=fmease
GuillaumeGomez Jun 18, 2024
8a21f48
Rollup merge of #126427 - Oneirical:oktobertest, r=jieyouxu
GuillaumeGomez Jun 18, 2024
2f006d6
Rollup merge of #126493 - jswrenn:fix-126460, r=compiler-errors
GuillaumeGomez Jun 18, 2024
bc4c936
Rollup merge of #126572 - onur-ozkan:channel-problem, r=clubby789
GuillaumeGomez Jun 18, 2024
6ea41de
Rollup merge of #126615 - tgross35:gitignore-ice, r=compiler-errors
GuillaumeGomez Jun 18, 2024
ef8c24a
Rollup merge of #126632 - Vonr:fix/moving-closure-formatting-v2, r=Ni…
GuillaumeGomez Jun 18, 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ build/
/src/tools/x/target
# Created by default with `src/ci/docker/run.sh`
/obj/
/rustc-ice*

## Temporary files
*~
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3476,6 +3476,7 @@ dependencies = [
"object 0.34.0",
"regex",
"similar",
"walkdir",
"wasmparser",
]

Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_const_eval/src/interpret/discriminant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
variant_index: VariantIdx,
) -> InterpResult<'tcx, Option<(ScalarInt, usize)>> {
match self.layout_of(ty)?.variants {
abi::Variants::Single { .. } => Ok(None),
abi::Variants::Single { .. } => {
// The tag of a `Single` enum is like the tag of the niched
// variant: there's no tag as the discriminant is encoded
// entirely implicitly. If `write_discriminant` ever hits this
// case, we do a "validation read" to ensure the the right
// discriminant is encoded implicitly, so any attempt to write
// the wrong discriminant for a `Single` enum will reliably
// result in UB.
Ok(None)
}

abi::Variants::Multiple {
tag_encoding: TagEncoding::Direct,
Expand Down
185 changes: 140 additions & 45 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,14 +303,57 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
if !candidates.is_empty() {
let help = format!(
"{an}other candidate{s} {were} found in the following trait{s}, perhaps \
add a `use` for {one_of_them}:",
"{an}other candidate{s} {were} found in the following trait{s}",
an = if candidates.len() == 1 { "an" } else { "" },
s = pluralize!(candidates.len()),
were = pluralize!("was", candidates.len()),
one_of_them = if candidates.len() == 1 { "it" } else { "one_of_them" },
);
self.suggest_use_candidates(&mut err, help, candidates);
self.suggest_use_candidates(
candidates,
|accessible_sugg, inaccessible_sugg, span| {
let suggest_for_access =
|err: &mut Diag<'_>, mut msg: String, sugg: Vec<_>| {
msg += &format!(
", perhaps add a `use` for {one_of_them}:",
one_of_them =
if sugg.len() == 1 { "it" } else { "one_of_them" },
);
err.span_suggestions(
span,
msg,
sugg,
Applicability::MaybeIncorrect,
);
};
let suggest_for_privacy =
|err: &mut Diag<'_>, mut msg: String, sugg: Vec<String>| {
if sugg.len() == 1 {
let msg = format!("\
trait `{}` provides `{item_name}` is implemented but not reachable",
sugg[0].trim()
);
err.help(msg);
} else {
msg += &format!(" but {} not reachable", pluralize!("is", sugg.len()));
err.span_suggestions(
span,
msg,
sugg,
Applicability::MaybeIncorrect,
);
}
};
if accessible_sugg.is_empty() {
// `inaccessible_sugg` must not be empty
suggest_for_privacy(&mut err, help, inaccessible_sugg);
} else if inaccessible_sugg.is_empty() {
suggest_for_access(&mut err, help, accessible_sugg);
} else {
suggest_for_access(&mut err, help.clone(), accessible_sugg);
suggest_for_privacy(&mut err, help, inaccessible_sugg);
}
},
);
}
if let ty::Ref(region, t_type, mutability) = rcvr_ty.kind() {
if needs_mut {
Expand Down Expand Up @@ -3089,49 +3132,69 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

fn suggest_use_candidates(&self, err: &mut Diag<'_>, msg: String, candidates: Vec<DefId>) {
fn suggest_use_candidates<F>(&self, candidates: Vec<DefId>, handle_candidates: F)
where
F: FnOnce(Vec<String>, Vec<String>, Span),
{
let parent_map = self.tcx.visible_parent_map(());

// Separate out candidates that must be imported with a glob, because they are named `_`
// and cannot be referred with their identifier.
let (candidates, globs): (Vec<_>, Vec<_>) = candidates.into_iter().partition(|trait_did| {
if let Some(parent_did) = parent_map.get(trait_did) {
// If the item is re-exported as `_`, we should suggest a glob-import instead.
if *parent_did != self.tcx.parent(*trait_did)
&& self
.tcx
.module_children(*parent_did)
.iter()
.filter(|child| child.res.opt_def_id() == Some(*trait_did))
.all(|child| child.ident.name == kw::Underscore)
{
return false;
}
}
let scope = self.tcx.parent_module_from_def_id(self.body_id);
let (accessible_candidates, inaccessible_candidates): (Vec<_>, Vec<_>) =
candidates.into_iter().partition(|id| {
let vis = self.tcx.visibility(*id);
vis.is_accessible_from(scope, self.tcx)
});

true
});
let sugg = |candidates: Vec<_>, visible| {
// Separate out candidates that must be imported with a glob, because they are named `_`
// and cannot be referred with their identifier.
let (candidates, globs): (Vec<_>, Vec<_>) =
candidates.into_iter().partition(|trait_did| {
if let Some(parent_did) = parent_map.get(trait_did) {
// If the item is re-exported as `_`, we should suggest a glob-import instead.
if *parent_did != self.tcx.parent(*trait_did)
&& self
.tcx
.module_children(*parent_did)
.iter()
.filter(|child| child.res.opt_def_id() == Some(*trait_did))
.all(|child| child.ident.name == kw::Underscore)
{
return false;
}
}

let module_did = self.tcx.parent_module_from_def_id(self.body_id);
let (module, _, _) = self.tcx.hir().get_module(module_did);
let span = module.spans.inject_use_span;
true
});

let path_strings = candidates.iter().map(|trait_did| {
format!("use {};\n", with_crate_prefix!(self.tcx.def_path_str(*trait_did)),)
});
let prefix = if visible { "use " } else { "" };
let postfix = if visible { ";" } else { "" };
let path_strings = candidates.iter().map(|trait_did| {
format!(
"{prefix}{}{postfix}\n",
with_crate_prefix!(self.tcx.def_path_str(*trait_did)),
)
});

let glob_path_strings = globs.iter().map(|trait_did| {
let parent_did = parent_map.get(trait_did).unwrap();
format!(
"use {}::*; // trait {}\n",
with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
self.tcx.item_name(*trait_did),
)
});
let mut sugg: Vec<_> = path_strings.chain(glob_path_strings).collect();
sugg.sort();
let glob_path_strings = globs.iter().map(|trait_did| {
let parent_did = parent_map.get(trait_did).unwrap();
format!(
"{prefix}{}::*{postfix} // trait {}\n",
with_crate_prefix!(self.tcx.def_path_str(*parent_did)),
self.tcx.item_name(*trait_did),
)
});
let mut sugg: Vec<_> = path_strings.chain(glob_path_strings).collect();
sugg.sort();
sugg
};

err.span_suggestions(span, msg, sugg, Applicability::MaybeIncorrect);
let accessible_sugg = sugg(accessible_candidates, true);
let inaccessible_sugg = sugg(inaccessible_candidates, false);

let (module, _, _) = self.tcx.hir().get_module(scope);
let span = module.spans.inject_use_span;
handle_candidates(accessible_sugg, inaccessible_sugg, span);
}

fn suggest_valid_traits(
Expand All @@ -3155,21 +3218,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if explain {
err.help("items from traits can only be used if the trait is in scope");
}

let msg = format!(
"{this_trait_is} implemented but not in scope; perhaps you want to import \
{one_of_them}",
"{this_trait_is} implemented but not in scope",
this_trait_is = if candidates.len() == 1 {
format!(
"trait `{}` which provides `{item_name}` is",
self.tcx.item_name(candidates[0]),
)
} else {
format!("the following traits which provide `{item_name}` are")
},
one_of_them = if candidates.len() == 1 { "it" } else { "one of them" },
}
);

self.suggest_use_candidates(err, msg, candidates);
self.suggest_use_candidates(candidates, |accessible_sugg, inaccessible_sugg, span| {
let suggest_for_access = |err: &mut Diag<'_>, mut msg: String, sugg: Vec<_>| {
msg += &format!(
"; perhaps you want to import {one_of}",
one_of = if sugg.len() == 1 { "it" } else { "one of them" },
);
err.span_suggestions(span, msg, sugg, Applicability::MaybeIncorrect);
};
let suggest_for_privacy = |err: &mut Diag<'_>, sugg: Vec<String>| {
let msg = format!(
"{this_trait_is} implemented but not reachable",
this_trait_is = if sugg.len() == 1 {
format!("trait `{}` which provides `{item_name}` is", sugg[0].trim())
} else {
format!("the following traits which provide `{item_name}` are")
}
);
if sugg.len() == 1 {
err.help(msg);
} else {
err.span_suggestions(span, msg, sugg, Applicability::MaybeIncorrect);
}
};
if accessible_sugg.is_empty() {
// `inaccessible_sugg` must not be empty
suggest_for_privacy(err, inaccessible_sugg);
} else if inaccessible_sugg.is_empty() {
suggest_for_access(err, msg, accessible_sugg);
} else {
suggest_for_access(err, msg, accessible_sugg);
suggest_for_privacy(err, inaccessible_sugg);
}
});

if let Some(did) = edition_fix {
err.note(format!(
"'{}' is included in the prelude starting in Edition 2021",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use std::ops::Deref;
/// e.g. closures defined within the function. For example:
/// ```ignore (illustrative)
/// fn foo() {
/// bar(move|| { ... })
/// bar(move || { ... })
/// }
/// ```
/// Here, the function `foo()` and the closure passed to
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho
.without_trait = methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl`
.with_trait = an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
.bounds = `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type
.doctest = make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}`
.exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration
.const_anon = use a const-anon item to suppress this lint
.macro_to_change = the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed
Expand Down
18 changes: 10 additions & 8 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,7 @@ pub enum NonLocalDefinitionsDiag {
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
const_anon: Option<Option<Span>>,
move_to: Option<(Span, Vec<Span>)>,
doctest: bool,
may_remove: Option<(Span, String)>,
has_trait: bool,
self_ty_str: String,
Expand All @@ -1368,8 +1369,7 @@ pub enum NonLocalDefinitionsDiag {
depth: u32,
body_kind_descr: &'static str,
body_name: String,
help: Option<()>,
doctest_help: Option<()>,
doctest: bool,
cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
},
}
Expand All @@ -1384,6 +1384,7 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
cargo_update,
const_anon,
move_to,
doctest,
may_remove,
has_trait,
self_ty_str,
Expand Down Expand Up @@ -1422,6 +1423,9 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
}
diag.span_help(ms, fluent::lint_non_local_definitions_impl_move_help);
}
if doctest {
diag.help(fluent::lint_doctest);
}

if let Some((span, part)) = may_remove {
diag.arg("may_remove_part", part);
Expand Down Expand Up @@ -1451,20 +1455,18 @@ impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
depth,
body_kind_descr,
body_name,
help,
doctest_help,
doctest,
cargo_update,
} => {
diag.primary_message(fluent::lint_non_local_definitions_macro_rules);
diag.arg("depth", depth);
diag.arg("body_kind_descr", body_kind_descr);
diag.arg("body_name", body_name);

if let Some(()) = help {
diag.help(fluent::lint_help);
}
if let Some(()) = doctest_help {
if doctest {
diag.help(fluent::lint_help_doctest);
} else {
diag.help(fluent::lint_help);
}

diag.note(fluent::lint_non_local);
Expand Down
Loading
Loading