Skip to content

Commit 06460fe

Browse files
committed
Auto merge of rust-lang#94548 - matthiaskrgr:rollup-spa38z8, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#93562 (Update the documentation for `{As,Into,From}Raw{Fd,Handle,Socket}`.) - rust-lang#94101 (rustdoc: add test cases for hidden enum variants) - rust-lang#94484 (8 - Make more use of `let_chains`) - rust-lang#94522 (Remove out-of-context line at end of E0284 message) - rust-lang#94534 (Re-export (unstable) core::ffi types from std::ffi) - rust-lang#94536 (Move transmute_undefined_repr back to nursery again) - rust-lang#94537 (Use ? operator in one instance instead of manual match) - rust-lang#94544 (Add some examples to comments in mbe code) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 2f8d1a8 + 88aa75b commit 06460fe

File tree

25 files changed

+363
-313
lines changed

25 files changed

+363
-313
lines changed

compiler/rustc_error_codes/src/error_codes/E0284.md

-2
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,3 @@ fn main() {
3030
d = d + m;
3131
}
3232
```
33-
34-
Note that the type of `v` can now be inferred from the type of `temp`.

compiler/rustc_expand/src/mbe/macro_parser.rs

+32
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,38 @@ fn initial_matcher_pos<'root, 'tt>(ms: &'tt [TokenTree]) -> MatcherPos<'root, 't
345345
/// token tree. The depth of the `NamedMatch` structure will therefore depend
346346
/// only on the nesting depth of `ast::TTSeq`s in the originating
347347
/// token tree it was derived from.
348+
///
349+
/// In layman's terms: `NamedMatch` will form a tree representing nested matches of a particular
350+
/// meta variable. For example, if we are matching the following macro against the following
351+
/// invocation...
352+
///
353+
/// ```rust
354+
/// macro_rules! foo {
355+
/// ($($($x:ident),+);+) => {}
356+
/// }
357+
///
358+
/// foo!(a, b, c, d; a, b, c, d, e);
359+
/// ```
360+
///
361+
/// Then, the tree will have the following shape:
362+
///
363+
/// ```rust
364+
/// MatchedSeq([
365+
/// MatchedSeq([
366+
/// MatchedNonterminal(a),
367+
/// MatchedNonterminal(b),
368+
/// MatchedNonterminal(c),
369+
/// MatchedNonterminal(d),
370+
/// ]),
371+
/// MatchedSeq([
372+
/// MatchedNonterminal(a),
373+
/// MatchedNonterminal(b),
374+
/// MatchedNonterminal(c),
375+
/// MatchedNonterminal(d),
376+
/// MatchedNonterminal(e),
377+
/// ])
378+
/// ])
379+
/// ```
348380
#[derive(Debug, Clone)]
349381
crate enum NamedMatch {
350382
MatchedSeq(Lrc<NamedMatchVec>),

compiler/rustc_expand/src/mbe/transcribe.rs

+6
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,12 @@ impl LockstepIterSize {
358358
/// Note that if `repeats` does not match the exact correct depth of a meta-var,
359359
/// `lookup_cur_matched` will return `None`, which is why this still works even in the presence of
360360
/// multiple nested matcher sequences.
361+
///
362+
/// Example: `$($($x $y)+*);+` -- we need to make sure that `x` and `y` repeat the same amount as
363+
/// each other at the given depth when the macro was invoked. If they don't it might mean they were
364+
/// declared at unequal depths or there was a compile bug. For example, if we have 3 repetitions of
365+
/// the outer sequence and 4 repetitions of the inner sequence for `x`, we should have the same for
366+
/// `y`; otherwise, we can't transcribe them both at the given depth.
361367
fn lockstep_iter_size(
362368
tree: &mbe::TokenTree,
363369
interpolations: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+35-42
Original file line numberDiff line numberDiff line change
@@ -606,17 +606,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
606606
// don't show type `_`
607607
err.span_label(span, format!("this expression has type `{}`", ty));
608608
}
609-
if let Some(ty::error::ExpectedFound { found, .. }) = exp_found {
610-
if ty.is_box() && ty.boxed_ty() == found {
611-
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
612-
err.span_suggestion(
613-
span,
614-
"consider dereferencing the boxed value",
615-
format!("*{}", snippet),
616-
Applicability::MachineApplicable,
617-
);
618-
}
619-
}
609+
if let Some(ty::error::ExpectedFound { found, .. }) = exp_found
610+
&& ty.is_box() && ty.boxed_ty() == found
611+
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
612+
{
613+
err.span_suggestion(
614+
span,
615+
"consider dereferencing the boxed value",
616+
format!("*{}", snippet),
617+
Applicability::MachineApplicable,
618+
);
620619
}
621620
}
622621
ObligationCauseCode::Pattern { origin_expr: false, span: Some(span), .. } => {
@@ -1748,13 +1747,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
17481747
self.check_and_note_conflicting_crates(diag, terr);
17491748
self.tcx.note_and_explain_type_err(diag, terr, cause, span, body_owner_def_id.to_def_id());
17501749

1751-
if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values {
1752-
if let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind() {
1753-
if let Some(def_id) = def_id.as_local() {
1754-
let span = self.tcx.def_span(def_id);
1755-
diag.span_note(span, "this closure does not fulfill the lifetime requirements");
1756-
}
1757-
}
1750+
if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values
1751+
&& let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind()
1752+
&& let Some(def_id) = def_id.as_local()
1753+
{
1754+
let span = self.tcx.def_span(def_id);
1755+
diag.span_note(span, "this closure does not fulfill the lifetime requirements");
17581756
}
17591757

17601758
// It reads better to have the error origin as the final
@@ -2046,19 +2044,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
20462044
// containing a single character, perhaps the user meant to write `'c'` to
20472045
// specify a character literal (issue #92479)
20482046
(ty::Char, ty::Ref(_, r, _)) if r.is_str() => {
2049-
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
2050-
if let Some(code) =
2051-
code.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
2052-
{
2053-
if code.chars().count() == 1 {
2054-
err.span_suggestion(
2055-
span,
2056-
"if you meant to write a `char` literal, use single quotes",
2057-
format!("'{}'", code),
2058-
Applicability::MachineApplicable,
2059-
);
2060-
}
2061-
}
2047+
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
2048+
&& let Some(code) = code.strip_prefix('"').and_then(|s| s.strip_suffix('"'))
2049+
&& code.chars().count() == 1
2050+
{
2051+
err.span_suggestion(
2052+
span,
2053+
"if you meant to write a `char` literal, use single quotes",
2054+
format!("'{}'", code),
2055+
Applicability::MachineApplicable,
2056+
);
20622057
}
20632058
}
20642059
// If a string was expected and the found expression is a character literal,
@@ -2080,18 +2075,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
20802075
_ => {}
20812076
}
20822077
}
2083-
if let MatchExpressionArm(box MatchExpressionArmCause { source, .. }) =
2084-
*trace.cause.code()
2078+
let code = trace.cause.code();
2079+
if let &MatchExpressionArm(box MatchExpressionArmCause { source, .. }) = code
2080+
&& let hir::MatchSource::TryDesugar = source
2081+
&& let Some((expected_ty, found_ty)) = self.values_str(trace.values)
20852082
{
2086-
if let hir::MatchSource::TryDesugar = source {
2087-
if let Some((expected_ty, found_ty)) = self.values_str(trace.values) {
2088-
err.note(&format!(
2089-
"`?` operator cannot convert from `{}` to `{}`",
2090-
found_ty.content(),
2091-
expected_ty.content(),
2092-
));
2093-
}
2094-
}
2083+
err.note(&format!(
2084+
"`?` operator cannot convert from `{}` to `{}`",
2085+
found_ty.content(),
2086+
expected_ty.content(),
2087+
));
20952088
}
20962089
err
20972090
}

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+41-48
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,25 @@ impl<'a, 'tcx> Visitor<'tcx> for FindHirNodeVisitor<'a, 'tcx> {
114114
}
115115

116116
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
117-
if let ExprKind::Match(scrutinee, [_, arm], MatchSource::ForLoopDesugar) = expr.kind {
118-
if let Some(pat) = arm.pat.for_loop_some() {
119-
if let Some(ty) = self.node_ty_contains_target(pat.hir_id) {
120-
self.found_for_loop_iter = Some(scrutinee);
121-
self.found_node_ty = Some(ty);
122-
return;
123-
}
124-
}
117+
if let ExprKind::Match(scrutinee, [_, arm], MatchSource::ForLoopDesugar) = expr.kind
118+
&& let Some(pat) = arm.pat.for_loop_some()
119+
&& let Some(ty) = self.node_ty_contains_target(pat.hir_id)
120+
{
121+
self.found_for_loop_iter = Some(scrutinee);
122+
self.found_node_ty = Some(ty);
123+
return;
125124
}
126-
if let ExprKind::MethodCall(segment, exprs, _) = expr.kind {
127-
if segment.ident.span == self.target_span
128-
&& Some(self.target)
129-
== self.infcx.in_progress_typeck_results.and_then(|typeck_results| {
130-
typeck_results
131-
.borrow()
132-
.node_type_opt(exprs.first().unwrap().hir_id)
133-
.map(Into::into)
134-
})
135-
{
136-
self.found_exact_method_call = Some(&expr);
137-
return;
138-
}
125+
if let ExprKind::MethodCall(segment, exprs, _) = expr.kind
126+
&& segment.ident.span == self.target_span
127+
&& Some(self.target) == self.infcx.in_progress_typeck_results.and_then(|typeck_results| {
128+
typeck_results
129+
.borrow()
130+
.node_type_opt(exprs.first().unwrap().hir_id)
131+
.map(Into::into)
132+
})
133+
{
134+
self.found_exact_method_call = Some(&expr);
135+
return;
139136
}
140137

141138
// FIXME(const_generics): Currently, any uninferred `const` generics arguments
@@ -602,10 +599,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
602599
);
603600

604601
let use_diag = local_visitor.found_use_diagnostic.as_ref();
605-
if let Some(use_diag) = use_diag {
606-
if use_diag.applies_to(err_span) {
607-
use_diag.attach_note(&mut err);
608-
}
602+
if let Some(use_diag) = use_diag && use_diag.applies_to(err_span) {
603+
use_diag.attach_note(&mut err);
609604
}
610605

611606
let param_type = arg_data.kind.descr();
@@ -736,29 +731,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
736731
// | help: specify type like: `<Impl as Into<u32>>::into(foo_impl)`
737732
// |
738733
// = note: cannot satisfy `Impl: Into<_>`
739-
if !impl_candidates.is_empty() && e.span.contains(span) {
740-
if let Some(expr) = exprs.first() {
741-
if let ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind {
742-
if let [path_segment] = path.segments {
743-
let candidate_len = impl_candidates.len();
744-
let suggestions = impl_candidates.iter().map(|candidate| {
745-
format!(
746-
"{}::{}({})",
747-
candidate, segment.ident, path_segment.ident
748-
)
749-
});
750-
err.span_suggestions(
751-
e.span,
752-
&format!(
753-
"use the fully qualified path for the potential candidate{}",
754-
pluralize!(candidate_len),
755-
),
756-
suggestions,
757-
Applicability::MaybeIncorrect,
758-
);
759-
}
760-
}
761-
};
734+
if !impl_candidates.is_empty() && e.span.contains(span)
735+
&& let Some(expr) = exprs.first()
736+
&& let ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
737+
&& let [path_segment] = path.segments
738+
{
739+
let candidate_len = impl_candidates.len();
740+
let suggestions = impl_candidates.iter().map(|candidate| {
741+
format!(
742+
"{}::{}({})",
743+
candidate, segment.ident, path_segment.ident
744+
)
745+
});
746+
err.span_suggestions(
747+
e.span,
748+
&format!(
749+
"use the fully qualified path for the potential candidate{}",
750+
pluralize!(candidate_len),
751+
),
752+
suggestions,
753+
Applicability::MaybeIncorrect,
754+
);
762755
}
763756
// Suggest specifying type params or point out the return type of the call:
764757
//

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs

+22-25
Original file line numberDiff line numberDiff line change
@@ -223,35 +223,32 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
223223
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
224224

225225
let mut override_error_code = None;
226-
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sup_origin {
227-
if let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code() {
228-
// Handle case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a
229-
// `'static` lifetime when called as a method on a binding: `bar.qux()`.
230-
if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) {
231-
override_error_code = Some(ctxt.assoc_item.name);
232-
}
233-
}
226+
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sup_origin
227+
&& let ObligationCauseCode::UnifyReceiver(ctxt) = cause.code()
228+
// Handle case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a
229+
// `'static` lifetime when called as a method on a binding: `bar.qux()`.
230+
&& self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt)
231+
{
232+
override_error_code = Some(ctxt.assoc_item.name);
234233
}
235-
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sub_origin {
236-
let code = match cause.code() {
234+
235+
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sub_origin
236+
&& let code = match cause.code() {
237237
ObligationCauseCode::MatchImpl(parent, ..) => parent.code(),
238238
_ => cause.code(),
239-
};
240-
if let (ObligationCauseCode::ItemObligation(item_def_id), None) =
241-
(code, override_error_code)
239+
}
240+
&& let (ObligationCauseCode::ItemObligation(item_def_id), None) = (code, override_error_code)
241+
{
242+
// Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
243+
// lifetime as above, but called using a fully-qualified path to the method:
244+
// `Foo::qux(bar)`.
245+
let mut v = TraitObjectVisitor(FxHashSet::default());
246+
v.visit_ty(param.param_ty);
247+
if let Some((ident, self_ty)) =
248+
self.get_impl_ident_and_self_ty_from_trait(*item_def_id, &v.0)
249+
&& self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty)
242250
{
243-
// Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
244-
// lifetime as above, but called using a fully-qualified path to the method:
245-
// `Foo::qux(bar)`.
246-
let mut v = TraitObjectVisitor(FxHashSet::default());
247-
v.visit_ty(param.param_ty);
248-
if let Some((ident, self_ty)) =
249-
self.get_impl_ident_and_self_ty_from_trait(*item_def_id, &v.0)
250-
{
251-
if self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty) {
252-
override_error_code = Some(ident.name);
253-
}
254-
}
251+
override_error_code = Some(ident.name);
255252
}
256253
}
257254
if let (Some(ident), true) = (override_error_code, fn_returns.is_empty()) {

0 commit comments

Comments
 (0)