Auto merge of #113120 - Dylan-DPC:rollup-cz4qr3o, r=Dylan-DPC

Rollup of 6 pull requests

Successful merges:

 - #111571 (Implement proposed API for `proc_macro_span`)
 - #112236 (Simplify computation of killed borrows)
 - #112867 (More `ImplSource` nits)
 - #113019 (add note for non-exhaustive matches with guards)
 - #113094 (Fix invalid HTML DIV tag used in HEAD)
 - #113111 (add myself to review for t-types stuff)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2023-06-28 13:25:41 +00:00
commit eb76764ea4
41 changed files with 236 additions and 315 deletions

View file

@ -2580,9 +2580,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.56" version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]

View file

@ -125,15 +125,9 @@ pub struct Borrows<'a, 'tcx> {
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>, borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
} }
struct StackEntry {
bb: mir::BasicBlock,
lo: usize,
hi: usize,
}
struct OutOfScopePrecomputer<'a, 'tcx> { struct OutOfScopePrecomputer<'a, 'tcx> {
visited: BitSet<mir::BasicBlock>, visited: BitSet<mir::BasicBlock>,
visit_stack: Vec<StackEntry>, visit_stack: Vec<mir::BasicBlock>,
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
regioncx: &'a RegionInferenceContext<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>,
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>, borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
@ -158,29 +152,50 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
borrow_region: RegionVid, borrow_region: RegionVid,
first_location: Location, first_location: Location,
) { ) {
// We visit one BB at a time. The complication is that we may start in the
// middle of the first BB visited (the one containing `first_location`), in which
// case we may have to later on process the first part of that BB if there
// is a path back to its start.
// For visited BBs, we record the index of the first statement processed.
// (In fully processed BBs this index is 0.) Note also that we add BBs to
// `visited` once they are added to `stack`, before they are actually
// processed, because this avoids the need to look them up again on
// completion.
self.visited.insert(first_location.block);
let first_block = first_location.block; let first_block = first_location.block;
let mut first_lo = first_location.statement_index; let first_bb_data = &self.body.basic_blocks[first_block];
let first_hi = self.body[first_block].statements.len();
self.visit_stack.push(StackEntry { bb: first_block, lo: first_lo, hi: first_hi }); // This is the first block, we only want to visit it from the creation of the borrow at
// `first_location`.
let first_lo = first_location.statement_index;
let first_hi = first_bb_data.statements.len();
'preorder: while let Some(StackEntry { bb, lo, hi }) = self.visit_stack.pop() { if let Some(kill_stmt) = self.regioncx.first_non_contained_inclusive(
borrow_region,
first_block,
first_lo,
first_hi,
) {
let kill_location = Location { block: first_block, statement_index: kill_stmt };
// If region does not contain a point at the location, then add to list and skip
// successor locations.
debug!("borrow {:?} gets killed at {:?}", borrow_index, kill_location);
self.borrows_out_of_scope_at_location
.entry(kill_location)
.or_default()
.push(borrow_index);
// The borrow is already dead, there is no need to visit other blocks.
return;
}
// The borrow is not dead. Add successor BBs to the work list, if necessary.
for succ_bb in first_bb_data.terminator().successors() {
if self.visited.insert(succ_bb) {
self.visit_stack.push(succ_bb);
}
}
// We may end up visiting `first_block` again. This is not an issue: we know at this point
// that it does not kill the borrow in the `first_lo..=first_hi` range, so checking the
// `0..first_lo` range and the `0..first_hi` range give the same result.
while let Some(block) = self.visit_stack.pop() {
let bb_data = &self.body[block];
let num_stmts = bb_data.statements.len();
if let Some(kill_stmt) = if let Some(kill_stmt) =
self.regioncx.first_non_contained_inclusive(borrow_region, bb, lo, hi) self.regioncx.first_non_contained_inclusive(borrow_region, block, 0, num_stmts)
{ {
let kill_location = Location { block: bb, statement_index: kill_stmt }; let kill_location = Location { block, statement_index: kill_stmt };
// If region does not contain a point at the location, then add to list and skip // If region does not contain a point at the location, then add to list and skip
// successor locations. // successor locations.
debug!("borrow {:?} gets killed at {:?}", borrow_index, kill_location); debug!("borrow {:?} gets killed at {:?}", borrow_index, kill_location);
@ -188,38 +203,15 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
.entry(kill_location) .entry(kill_location)
.or_default() .or_default()
.push(borrow_index); .push(borrow_index);
continue 'preorder;
}
// If we process the first part of the first basic block (i.e. we encounter that block // We killed the borrow, so we do not visit this block's successors.
// for the second time), we no longer have to visit its successors again.
if bb == first_block && hi != first_hi {
continue; continue;
} }
// Add successor BBs to the work list, if necessary. // Add successor BBs to the work list, if necessary.
let bb_data = &self.body[bb];
debug_assert!(hi == bb_data.statements.len());
for succ_bb in bb_data.terminator().successors() { for succ_bb in bb_data.terminator().successors() {
if !self.visited.insert(succ_bb) { if self.visited.insert(succ_bb) {
if succ_bb == first_block && first_lo > 0 { self.visit_stack.push(succ_bb);
// `succ_bb` has been seen before. If it wasn't
// fully processed, add its first part to `stack`
// for processing.
self.visit_stack.push(StackEntry { bb: succ_bb, lo: 0, hi: first_lo - 1 });
// And update this entry with 0, to represent the
// whole BB being processed.
first_lo = 0;
}
} else {
// succ_bb hasn't been seen before. Add it to
// `stack` for processing.
self.visit_stack.push(StackEntry {
bb: succ_bb,
lo: 0,
hi: self.body[succ_bb].statements.len(),
});
} }
} }
} }

View file

@ -2,7 +2,7 @@ use crate::base::ExtCtxt;
use pm::bridge::{ use pm::bridge::{
server, DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree, server, DelimSpan, Diagnostic, ExpnGlobals, Group, Ident, LitKind, Literal, Punct, TokenTree,
}; };
use pm::{Delimiter, Level, LineColumn}; use pm::{Delimiter, Level};
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::token; use rustc_ast::token;
use rustc_ast::tokenstream::{self, Spacing::*, TokenStream}; use rustc_ast::tokenstream::{self, Spacing::*, TokenStream};
@ -648,25 +648,24 @@ impl server::Span for Rustc<'_, '_> {
Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize } Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize }
} }
fn start(&mut self, span: Self::Span) -> Self::Span {
fn start(&mut self, span: Self::Span) -> LineColumn {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
LineColumn { line: loc.line, column: loc.col.to_usize() }
}
fn end(&mut self, span: Self::Span) -> LineColumn {
let loc = self.sess().source_map().lookup_char_pos(span.hi());
LineColumn { line: loc.line, column: loc.col.to_usize() }
}
fn before(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_lo() span.shrink_to_lo()
} }
fn after(&mut self, span: Self::Span) -> Self::Span { fn end(&mut self, span: Self::Span) -> Self::Span {
span.shrink_to_hi() span.shrink_to_hi()
} }
fn line(&mut self, span: Self::Span) -> usize {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
loc.line
}
fn column(&mut self, span: Self::Span) -> usize {
let loc = self.sess().source_map().lookup_char_pos(span.lo());
loc.col.to_usize() + 1
}
fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> { fn join(&mut self, first: Self::Span, second: Self::Span) -> Option<Self::Span> {
let self_loc = self.sess().source_map().lookup_char_pos(first.lo()); let self_loc = self.sess().source_map().lookup_char_pos(first.lo());
let other_loc = self.sess().source_map().lookup_char_pos(second.lo()); let other_loc = self.sess().source_map().lookup_char_pos(second.lo());

View file

@ -660,9 +660,6 @@ pub enum ImplSource<'tcx, N> {
/// ImplSource for trait upcasting coercion /// ImplSource for trait upcasting coercion
TraitUpcasting(ImplSourceTraitUpcastingData<N>), TraitUpcasting(ImplSourceTraitUpcastingData<N>),
/// ImplSource for a trait alias.
TraitAlias(ImplSourceTraitAliasData<'tcx, N>),
} }
impl<'tcx, N> ImplSource<'tcx, N> { impl<'tcx, N> ImplSource<'tcx, N> {
@ -671,7 +668,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::UserDefined(i) => i.nested, ImplSource::UserDefined(i) => i.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) => n, ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
ImplSource::Object(d) => d.nested, ImplSource::Object(d) => d.nested,
ImplSource::TraitAlias(d) => d.nested,
ImplSource::TraitUpcasting(d) => d.nested, ImplSource::TraitUpcasting(d) => d.nested,
} }
} }
@ -681,7 +677,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::UserDefined(i) => &i.nested, ImplSource::UserDefined(i) => &i.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n, ImplSource::Param(n, _) | ImplSource::Builtin(n) => &n,
ImplSource::Object(d) => &d.nested, ImplSource::Object(d) => &d.nested,
ImplSource::TraitAlias(d) => &d.nested,
ImplSource::TraitUpcasting(d) => &d.nested, ImplSource::TraitUpcasting(d) => &d.nested,
} }
} }
@ -691,7 +686,6 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::UserDefined(i) => &mut i.nested, ImplSource::UserDefined(i) => &mut i.nested,
ImplSource::Param(n, _) | ImplSource::Builtin(n) => n, ImplSource::Param(n, _) | ImplSource::Builtin(n) => n,
ImplSource::Object(d) => &mut d.nested, ImplSource::Object(d) => &mut d.nested,
ImplSource::TraitAlias(d) => &mut d.nested,
ImplSource::TraitUpcasting(d) => &mut d.nested, ImplSource::TraitUpcasting(d) => &mut d.nested,
} }
} }
@ -709,15 +703,9 @@ impl<'tcx, N> ImplSource<'tcx, N> {
ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct), ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()), ImplSource::Builtin(n) => ImplSource::Builtin(n.into_iter().map(f).collect()),
ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData { ImplSource::Object(o) => ImplSource::Object(ImplSourceObjectData {
upcast_trait_def_id: o.upcast_trait_def_id,
vtable_base: o.vtable_base, vtable_base: o.vtable_base,
nested: o.nested.into_iter().map(f).collect(), nested: o.nested.into_iter().map(f).collect(),
}), }),
ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData {
alias_def_id: d.alias_def_id,
substs: d.substs,
nested: d.nested.into_iter().map(f).collect(),
}),
ImplSource::TraitUpcasting(d) => { ImplSource::TraitUpcasting(d) => {
ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData { ImplSource::TraitUpcasting(ImplSourceTraitUpcastingData {
vtable_vptr_slot: d.vtable_vptr_slot, vtable_vptr_slot: d.vtable_vptr_slot,
@ -761,9 +749,6 @@ pub struct ImplSourceTraitUpcastingData<N> {
#[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)] #[derive(PartialEq, Eq, Clone, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)] #[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceObjectData<N> { pub struct ImplSourceObjectData<N> {
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
pub upcast_trait_def_id: DefId,
/// The vtable is formed by concatenating together the method lists of /// The vtable is formed by concatenating together the method lists of
/// the base object trait and all supertraits, pointers to supertrait vtable will /// the base object trait and all supertraits, pointers to supertrait vtable will
/// be provided when necessary; this is the start of `upcast_trait_ref`'s methods /// be provided when necessary; this is the start of `upcast_trait_ref`'s methods
@ -773,14 +758,6 @@ pub struct ImplSourceObjectData<N> {
pub nested: Vec<N>, pub nested: Vec<N>,
} }
#[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)]
#[derive(TypeFoldable, TypeVisitable)]
pub struct ImplSourceTraitAliasData<'tcx, N> {
pub alias_def_id: DefId,
pub substs: SubstsRef<'tcx>,
pub nested: Vec<N>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)] #[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
pub enum ObjectSafetyViolation { pub enum ObjectSafetyViolation {
/// `Self: Sized` declared on the trait. /// `Self: Sized` declared on the trait.

View file

@ -17,8 +17,6 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
write!(f, "ImplSourceParamData({:?}, {:?})", n, ct) write!(f, "ImplSourceParamData({:?}, {:?})", n, ct)
} }
super::ImplSource::TraitAlias(ref d) => write!(f, "{:?}", d),
super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d), super::ImplSource::TraitUpcasting(ref d) => write!(f, "{:?}", d),
} }
} }
@ -48,18 +46,8 @@ impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceObjectData<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
"ImplSourceObjectData(upcast={:?}, vtable_base={}, nested={:?})", "ImplSourceObjectData(vtable_base={}, nested={:?})",
self.upcast_trait_def_id, self.vtable_base, self.nested self.vtable_base, self.nested
)
}
}
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSourceTraitAliasData<'tcx, N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"ImplSourceTraitAliasData(alias_def_id={:?}, substs={:?}, nested={:?})",
self.alias_def_id, self.substs, self.nested
) )
} }
} }

View file

@ -214,6 +214,9 @@ mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsa
mir_build_non_const_path = runtime values cannot be referenced in patterns mir_build_non_const_path = runtime values cannot be referenced in patterns
mir_build_non_exhaustive_match_all_arms_guarded =
match arms with guards don't count towards exhaustivity
mir_build_non_exhaustive_omitted_pattern = some variants are not matched explicitly mir_build_non_exhaustive_omitted_pattern = some variants are not matched explicitly
.help = ensure that all variants are matched explicitly by adding the suggested match arms .help = ensure that all variants are matched explicitly by adding the suggested match arms
.note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found .note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found

View file

@ -432,6 +432,10 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
} }
} }
#[derive(Subdiagnostic)]
#[note(mir_build_non_exhaustive_match_all_arms_guarded)]
pub struct NonExhaustiveMatchAllArmsGuarded;
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(mir_build_static_in_pattern, code = "E0158")] #[diag(mir_build_static_in_pattern, code = "E0158")]
pub struct StaticInPattern { pub struct StaticInPattern {

View file

@ -830,6 +830,11 @@ fn non_exhaustive_match<'p, 'tcx>(
_ => " or multiple match arms", _ => " or multiple match arms",
}, },
); );
let all_arms_have_guards = arms.iter().all(|arm_id| thir[*arm_id].guard.is_some());
if !is_empty_match && all_arms_have_guards {
err.subdiagnostic(NonExhaustiveMatchAllArmsGuarded);
}
if let Some((span, sugg)) = suggestion { if let Some((span, sugg)) = suggestion {
err.span_suggestion_verbose(span, msg, sugg, Applicability::HasPlaceholders); err.span_suggestion_verbose(span, msg, sugg, Applicability::HasPlaceholders);
} else { } else {

View file

@ -5,7 +5,7 @@ pub mod suggestions;
use super::{ use super::{
FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause,
ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow, ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow,
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe, PredicateObligation, SelectionError, TraitNotObjectSafe,
}; };
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@ -2272,55 +2272,40 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
) )
}; };
let obligation = obligation.with(self.tcx, trait_ref); let ambiguities = ambiguity::recompute_applicable_impls(
let mut selcx = SelectionContext::new(&self); self.infcx,
match selcx.select_from_obligation(&obligation) { &obligation.with(self.tcx, trait_ref),
Ok(None) => { );
let ambiguities = let has_non_region_infer =
ambiguity::recompute_applicable_impls(self.infcx, &obligation); trait_ref.skip_binder().substs.types().any(|t| !t.is_ty_or_numeric_infer());
let has_non_region_infer = trait_ref // It doesn't make sense to talk about applicable impls if there are more
.skip_binder() // than a handful of them.
.substs if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
.types() if self.tainted_by_errors().is_some() && subst.is_none() {
.any(|t| !t.is_ty_or_numeric_infer()); // If `subst.is_none()`, then this is probably two param-env
// It doesn't make sense to talk about applicable impls if there are more // candidates or impl candidates that are equal modulo lifetimes.
// than a handful of them. // Therefore, if we've already emitted an error, just skip this
if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer { // one, since it's not particularly actionable.
if self.tainted_by_errors().is_some() && subst.is_none() { err.cancel();
// If `subst.is_none()`, then this is probably two param-env return;
// candidates or impl candidates that are equal modulo lifetimes.
// Therefore, if we've already emitted an error, just skip this
// one, since it's not particularly actionable.
err.cancel();
return;
}
self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
} else {
if self.tainted_by_errors().is_some() {
err.cancel();
return;
}
err.note(format!("cannot satisfy `{}`", predicate));
let impl_candidates = self.find_similar_impl_candidates(
predicate.to_opt_poly_trait_pred().unwrap(),
);
if impl_candidates.len() < 10 {
self.report_similar_impl_candidates(
impl_candidates.as_slice(),
trait_ref,
obligation.cause.body_id,
&mut err,
false,
);
}
}
} }
_ => { self.annotate_source_of_ambiguity(&mut err, &ambiguities, predicate);
if self.tainted_by_errors().is_some() { } else {
err.cancel(); if self.tainted_by_errors().is_some() {
return; err.cancel();
} return;
err.note(format!("cannot satisfy `{}`", predicate)); }
err.note(format!("cannot satisfy `{}`", predicate));
let impl_candidates = self
.find_similar_impl_candidates(predicate.to_opt_poly_trait_pred().unwrap());
if impl_candidates.len() < 10 {
self.report_similar_impl_candidates(
impl_candidates.as_slice(),
trait_ref,
obligation.cause.body_id,
&mut err,
false,
);
} }
} }

View file

@ -1720,7 +1720,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
}; };
let eligible = match &impl_source { let eligible = match &impl_source {
super::ImplSource::TraitAlias(_) => true,
super::ImplSource::UserDefined(impl_data) => { super::ImplSource::UserDefined(impl_data) => {
// We have to be careful when projecting out of an // We have to be careful when projecting out of an
// impl because of specialization. If we are not in // impl because of specialization. If we are not in
@ -2012,8 +2011,7 @@ fn confirm_select_candidate<'cx, 'tcx>(
} }
super::ImplSource::Object(_) super::ImplSource::Object(_)
| super::ImplSource::Param(..) | super::ImplSource::Param(..)
| super::ImplSource::TraitUpcasting(_) | super::ImplSource::TraitUpcasting(_) => {
| super::ImplSource::TraitAlias(..) => {
// we don't create Select candidates with this kind of resolution // we don't create Select candidates with this kind of resolution
span_bug!( span_bug!(
obligation.cause.span, obligation.cause.span,

View file

@ -27,10 +27,9 @@ use crate::traits::vtable::{
}; };
use crate::traits::{ use crate::traits::{
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource, BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
ImplSourceObjectData, ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceObjectData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause, Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError, SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented,
TraitNotObjectSafe, TraitObligation, Unimplemented,
}; };
use super::BuiltinImplConditions; use super::BuiltinImplConditions;
@ -105,7 +104,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
TraitAliasCandidate => { TraitAliasCandidate => {
let data = self.confirm_trait_alias_candidate(obligation); let data = self.confirm_trait_alias_candidate(obligation);
ImplSource::TraitAlias(data) ImplSource::Builtin(data)
} }
BuiltinObjectCandidate => { BuiltinObjectCandidate => {
@ -652,11 +651,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
(unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)), (unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)),
); );
Ok(ImplSourceObjectData { Ok(ImplSourceObjectData { vtable_base, nested })
upcast_trait_def_id: upcast_trait_ref.def_id(),
vtable_base,
nested,
})
} }
fn confirm_fn_pointer_candidate( fn confirm_fn_pointer_candidate(
@ -721,10 +716,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn confirm_trait_alias_candidate( fn confirm_trait_alias_candidate(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &TraitObligation<'tcx>,
) -> ImplSourceTraitAliasData<'tcx, PredicateObligation<'tcx>> { ) -> Vec<PredicateObligation<'tcx>> {
debug!(?obligation, "confirm_trait_alias_candidate"); debug!(?obligation, "confirm_trait_alias_candidate");
let alias_def_id = obligation.predicate.def_id();
let predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate); let predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
let trait_ref = predicate.trait_ref; let trait_ref = predicate.trait_ref;
let trait_def_id = trait_ref.def_id; let trait_def_id = trait_ref.def_id;
@ -741,7 +735,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
debug!(?trait_def_id, ?trait_obligations, "trait alias obligations"); debug!(?trait_def_id, ?trait_obligations, "trait alias obligations");
ImplSourceTraitAliasData { alias_def_id, substs, nested: trait_obligations } trait_obligations
} }
fn confirm_generator_candidate( fn confirm_generator_candidate(

View file

@ -248,7 +248,7 @@ pub fn get_vtable_index_of_object_method<'tcx, N>(
) -> Option<usize> { ) -> Option<usize> {
// Count number of methods preceding the one we are selecting and // Count number of methods preceding the one we are selecting and
// add them to the total offset. // add them to the total offset.
tcx.own_existential_vtable_entries(object.upcast_trait_def_id) tcx.own_existential_vtable_entries(tcx.parent(method_def_id))
.iter() .iter()
.copied() .copied()
.position(|def_id| def_id == method_def_id) .position(|def_id| def_id == method_def_id)

View file

@ -293,9 +293,7 @@ fn resolve_associated_item<'tcx>(
None None
} }
} }
traits::ImplSource::Param(..) traits::ImplSource::Param(..) | traits::ImplSource::TraitUpcasting(_) => None,
| traits::ImplSource::TraitAlias(..)
| traits::ImplSource::TraitUpcasting(_) => None,
}) })
} }

View file

@ -8,7 +8,7 @@
#![deny(unsafe_code)] #![deny(unsafe_code)]
use crate::{Delimiter, Level, LineColumn, Spacing}; use crate::{Delimiter, Level, Spacing};
use std::fmt; use std::fmt;
use std::hash::Hash; use std::hash::Hash;
use std::marker; use std::marker;
@ -95,10 +95,10 @@ macro_rules! with_api {
fn parent($self: $S::Span) -> Option<$S::Span>; fn parent($self: $S::Span) -> Option<$S::Span>;
fn source($self: $S::Span) -> $S::Span; fn source($self: $S::Span) -> $S::Span;
fn byte_range($self: $S::Span) -> Range<usize>; fn byte_range($self: $S::Span) -> Range<usize>;
fn start($self: $S::Span) -> LineColumn; fn start($self: $S::Span) -> $S::Span;
fn end($self: $S::Span) -> LineColumn; fn end($self: $S::Span) -> $S::Span;
fn before($self: $S::Span) -> $S::Span; fn line($self: $S::Span) -> usize;
fn after($self: $S::Span) -> $S::Span; fn column($self: $S::Span) -> usize;
fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>; fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>; fn subspan($self: $S::Span, start: Bound<usize>, end: Bound<usize>) -> Option<$S::Span>;
fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span; fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
@ -299,7 +299,6 @@ mark_noop! {
Delimiter, Delimiter,
LitKind, LitKind,
Level, Level,
LineColumn,
Spacing, Spacing,
} }
@ -319,7 +318,6 @@ rpc_encode_decode!(
Help, Help,
} }
); );
rpc_encode_decode!(struct LineColumn { line, column });
rpc_encode_decode!( rpc_encode_decode!(
enum Spacing { enum Spacing {
Alone, Alone,

View file

@ -43,7 +43,6 @@ mod diagnostic;
#[unstable(feature = "proc_macro_diagnostic", issue = "54140")] #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
pub use diagnostic::{Diagnostic, Level, MultiSpan}; pub use diagnostic::{Diagnostic, Level, MultiSpan};
use std::cmp::Ordering;
use std::ops::{Range, RangeBounds}; use std::ops::{Range, RangeBounds};
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
@ -494,28 +493,32 @@ impl Span {
self.0.byte_range() self.0.byte_range()
} }
/// Gets the starting line/column in the source file for this span.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn start(&self) -> LineColumn {
self.0.start().add_1_to_column()
}
/// Gets the ending line/column in the source file for this span.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn end(&self) -> LineColumn {
self.0.end().add_1_to_column()
}
/// Creates an empty span pointing to directly before this span. /// Creates an empty span pointing to directly before this span.
#[unstable(feature = "proc_macro_span_shrink", issue = "87552")] #[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn before(&self) -> Span { pub fn start(&self) -> Span {
Span(self.0.before()) Span(self.0.start())
} }
/// Creates an empty span pointing to directly after this span. /// Creates an empty span pointing to directly after this span.
#[unstable(feature = "proc_macro_span_shrink", issue = "87552")] #[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn after(&self) -> Span { pub fn end(&self) -> Span {
Span(self.0.after()) Span(self.0.end())
}
/// The one-indexed line of the source file where the span starts.
///
/// To obtain the line of the span's end, use `span.end().line()`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn line(&self) -> usize {
self.0.line()
}
/// The one-indexed column of the source file where the span starts.
///
/// To obtain the column of the span's end, use `span.end().column()`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub fn column(&self) -> usize {
self.0.column()
} }
/// Creates a new span encompassing `self` and `other`. /// Creates a new span encompassing `self` and `other`.
@ -586,44 +589,6 @@ impl fmt::Debug for Span {
} }
} }
/// A line-column pair representing the start or end of a `Span`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct LineColumn {
/// The 1-indexed line in the source file on which the span starts or ends (inclusive).
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub line: usize,
/// The 1-indexed column (number of bytes in UTF-8 encoding) in the source
/// file on which the span starts or ends (inclusive).
#[unstable(feature = "proc_macro_span", issue = "54725")]
pub column: usize,
}
impl LineColumn {
fn add_1_to_column(self) -> Self {
LineColumn { line: self.line, column: self.column + 1 }
}
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl !Send for LineColumn {}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl !Sync for LineColumn {}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl Ord for LineColumn {
fn cmp(&self, other: &Self) -> Ordering {
self.line.cmp(&other.line).then(self.column.cmp(&other.column))
}
}
#[unstable(feature = "proc_macro_span", issue = "54725")]
impl PartialOrd for LineColumn {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
/// The source file of a given `Span`. /// The source file of a given `Span`.
#[unstable(feature = "proc_macro_span", issue = "54725")] #[unstable(feature = "proc_macro_span", issue = "54725")]
#[derive(Clone)] #[derive(Clone)]

View file

@ -527,9 +527,9 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.56" version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]

View file

@ -1525,7 +1525,6 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
map.insert("toggle-all-docs".into(), 1); map.insert("toggle-all-docs".into(), 1);
map.insert("all-types".into(), 1); map.insert("all-types".into(), 1);
map.insert("default-settings".into(), 1); map.insert("default-settings".into(), 1);
map.insert("rustdoc-vars".into(), 1);
map.insert("sidebar-vars".into(), 1); map.insert("sidebar-vars".into(), 1);
map.insert("copy-path".into(), 1); map.insert("copy-path".into(), 1);
map.insert("TOC".into(), 1); map.insert("TOC".into(), 1);

View file

@ -3,13 +3,13 @@
// Local js definitions: // Local js definitions:
/* global addClass, getCurrentValue, onEachLazy, removeClass, browserSupportsHistoryApi */ /* global addClass, getCurrentValue, onEachLazy, removeClass, browserSupportsHistoryApi */
/* global updateLocalStorage */ /* global updateLocalStorage, getVar */
"use strict"; "use strict";
(function() { (function() {
const rootPath = document.getElementById("rustdoc-vars").attributes["data-root-path"].value; const rootPath = getVar("root-path");
const NAME_OFFSET = 0; const NAME_OFFSET = 0;
const DIRS_OFFSET = 1; const DIRS_OFFSET = 1;

View file

@ -108,7 +108,7 @@ function getCurrentValue(name) {
// Get a value from the rustdoc-vars div, which is used to convey data from // Get a value from the rustdoc-vars div, which is used to convey data from
// Rust to the JS. If there is no such element, return null. // Rust to the JS. If there is no such element, return null.
const getVar = (function getVar(name) { const getVar = (function getVar(name) {
const el = document.getElementById("rustdoc-vars"); const el = document.querySelector("head > meta[name='rustdoc-vars']");
return el ? el.attributes["data-" + name].value : null; return el ? el.attributes["data-" + name].value : null;
}); });

View file

@ -24,7 +24,7 @@
{% endfor %} {% endfor %}
></script> {# #} ></script> {# #}
{% endif %} {% endif %}
<div id="rustdoc-vars" {#+ #} <meta name="rustdoc-vars" {#+ #}
data-root-path="{{page.root_path|safe}}" {#+ #} data-root-path="{{page.root_path|safe}}" {#+ #}
data-static-root-path="{{static_root_path|safe}}" {#+ #} data-static-root-path="{{static_root_path|safe}}" {#+ #}
data-current-crate="{{layout.krate}}" {#+ #} data-current-crate="{{layout.krate}}" {#+ #}
@ -39,7 +39,6 @@
data-theme-dark-css="{{files.theme_dark_css}}" {#+ #} data-theme-dark-css="{{files.theme_dark_css}}" {#+ #}
data-theme-ayu-css="{{files.theme_ayu_css}}" {#+ #} data-theme-ayu-css="{{files.theme_ayu_css}}" {#+ #}
> {# #} > {# #}
</div> {# #}
<script src="{{static_root_path|safe}}{{files.storage_js}}"></script> {# #} <script src="{{static_root_path|safe}}{{files.storage_js}}"></script> {# #}
{% if page.css_class.contains("crate") %} {% if page.css_class.contains("crate") %}
<script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {# #} <script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {# #}

View file

@ -529,9 +529,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.56" version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]

View file

@ -179,9 +179,9 @@ checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.56" version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]

View file

@ -83,9 +83,9 @@ version = "0.1.0"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.49" version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]

View file

@ -193,9 +193,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.49" version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]

View file

@ -1304,9 +1304,9 @@ version = "0.0.0"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.56" version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]

View file

@ -8,10 +8,7 @@
//! //!
//! FIXME: No span and source file information is implemented yet //! FIXME: No span and source file information is implemented yet
use proc_macro::{ use proc_macro::bridge::{self, server};
bridge::{self, server},
LineColumn,
};
mod token_stream; mod token_stream;
pub use token_stream::TokenStream; pub use token_stream::TokenStream;
@ -304,14 +301,6 @@ impl server::Span for RustAnalyzer {
// FIXME handle span // FIXME handle span
Range { start: 0, end: 0 } Range { start: 0, end: 0 }
} }
fn start(&mut self, _span: Self::Span) -> LineColumn {
// FIXME handle span
LineColumn { line: 0, column: 0 }
}
fn end(&mut self, _span: Self::Span) -> LineColumn {
// FIXME handle span
LineColumn { line: 0, column: 0 }
}
fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> { fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> {
// Just return the first span again, because some macros will unwrap the result. // Just return the first span again, because some macros will unwrap the result.
Some(first) Some(first)
@ -330,13 +319,23 @@ impl server::Span for RustAnalyzer {
tt::TokenId::unspecified() tt::TokenId::unspecified()
} }
fn after(&mut self, _self_: Self::Span) -> Self::Span { fn end(&mut self, _self_: Self::Span) -> Self::Span {
tt::TokenId::unspecified() tt::TokenId::unspecified()
} }
fn before(&mut self, _self_: Self::Span) -> Self::Span { fn start(&mut self, _self_: Self::Span) -> Self::Span {
tt::TokenId::unspecified() tt::TokenId::unspecified()
} }
fn line(&mut self, _span: Self::Span) -> usize {
// FIXME handle line
0
}
fn column(&mut self, _span: Self::Span) -> usize {
// FIXME handle column
0
}
} }
impl server::Symbol for RustAnalyzer { impl server::Symbol for RustAnalyzer {

View file

@ -1,4 +1,4 @@
// @has test.css // @has test.css
// @has foo/struct.Foo.html // @has foo/struct.Foo.html
// @has - '//*[@id="rustdoc-vars"]/@data-themes' 'test' // @has - '//*[@name="rustdoc-vars"]/@data-themes' 'test'
pub struct Foo; pub struct Foo;

View file

@ -8,11 +8,6 @@ extern crate proc_macro;
use proc_macro::{quote, Span, TokenStream, TokenTree}; use proc_macro::{quote, Span, TokenStream, TokenTree};
fn assert_same_span(a: Span, b: Span) {
assert_eq!(a.start(), b.start());
assert_eq!(a.end(), b.end());
}
// This macro generates a macro with the same macro definition as `manual_foo` in // This macro generates a macro with the same macro definition as `manual_foo` in
// `same-sequence-span.rs` but with the same span for all sequences. // `same-sequence-span.rs` but with the same span for all sequences.
#[proc_macro] #[proc_macro]

View file

@ -17,15 +17,14 @@ LL | $(= $z:tt)*
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
--> $DIR/same-sequence-span.rs:19:1 --> $DIR/same-sequence-span.rs:19:1
| |
LL | | }
| |_________________________________^ not allowed after `expr` fragments
LL |
LL | proc_macro_sequence::make_foo!(); LL | proc_macro_sequence::make_foo!();
| ^------------------------------- | ^-------------------------------
| | | |
| _in this macro invocation | _in this macro invocation
| | | |
LL | |
LL | |
LL | | fn main() {}
| |_________________________________^ not allowed after `expr` fragments
| |
= note: allowed there are: `=>`, `,` or `;` = note: allowed there are: `=>`, `,` or `;`
= note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -176,6 +176,7 @@ LL | match_guarded_arm!(0u8);
| ^^^ pattern `_` not covered | ^^^ pattern `_` not covered
| |
= note: the matched value is of type `u8` = note: the matched value is of type `u8`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -183,7 +184,7 @@ LL + _ => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
--> $DIR/empty-match.rs:133:24 --> $DIR/empty-match.rs:134:24
| |
LL | match_guarded_arm!(NonEmptyStruct1); LL | match_guarded_arm!(NonEmptyStruct1);
| ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered | ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
@ -194,6 +195,7 @@ note: `NonEmptyStruct1` defined here
LL | struct NonEmptyStruct1; LL | struct NonEmptyStruct1;
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyStruct1` = note: the matched value is of type `NonEmptyStruct1`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -201,7 +203,7 @@ LL + NonEmptyStruct1 => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
--> $DIR/empty-match.rs:137:24 --> $DIR/empty-match.rs:139:24
| |
LL | match_guarded_arm!(NonEmptyStruct2(true)); LL | match_guarded_arm!(NonEmptyStruct2(true));
| ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered | ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
@ -212,6 +214,7 @@ note: `NonEmptyStruct2` defined here
LL | struct NonEmptyStruct2(bool); LL | struct NonEmptyStruct2(bool);
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyStruct2` = note: the matched value is of type `NonEmptyStruct2`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -219,7 +222,7 @@ LL + NonEmptyStruct2(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
--> $DIR/empty-match.rs:141:24 --> $DIR/empty-match.rs:144:24
| |
LL | match_guarded_arm!((NonEmptyUnion1 { foo: () })); LL | match_guarded_arm!((NonEmptyUnion1 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
@ -230,6 +233,7 @@ note: `NonEmptyUnion1` defined here
LL | union NonEmptyUnion1 { LL | union NonEmptyUnion1 {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyUnion1` = note: the matched value is of type `NonEmptyUnion1`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -237,7 +241,7 @@ LL + NonEmptyUnion1 { .. } => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
--> $DIR/empty-match.rs:145:24 --> $DIR/empty-match.rs:149:24
| |
LL | match_guarded_arm!((NonEmptyUnion2 { foo: () })); LL | match_guarded_arm!((NonEmptyUnion2 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
@ -248,6 +252,7 @@ note: `NonEmptyUnion2` defined here
LL | union NonEmptyUnion2 { LL | union NonEmptyUnion2 {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyUnion2` = note: the matched value is of type `NonEmptyUnion2`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -255,7 +260,7 @@ LL + NonEmptyUnion2 { .. } => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
--> $DIR/empty-match.rs:149:24 --> $DIR/empty-match.rs:154:24
| |
LL | match_guarded_arm!(NonEmptyEnum1::Foo(true)); LL | match_guarded_arm!(NonEmptyEnum1::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
@ -268,6 +273,7 @@ LL | enum NonEmptyEnum1 {
LL | Foo(bool), LL | Foo(bool),
| ^^^ not covered | ^^^ not covered
= note: the matched value is of type `NonEmptyEnum1` = note: the matched value is of type `NonEmptyEnum1`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -275,7 +281,7 @@ LL + NonEmptyEnum1::Foo(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
--> $DIR/empty-match.rs:153:24 --> $DIR/empty-match.rs:159:24
| |
LL | match_guarded_arm!(NonEmptyEnum2::Foo(true)); LL | match_guarded_arm!(NonEmptyEnum2::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
@ -291,6 +297,7 @@ LL | Foo(bool),
LL | Bar, LL | Bar,
| ^^^ not covered | ^^^ not covered
= note: the matched value is of type `NonEmptyEnum2` = note: the matched value is of type `NonEmptyEnum2`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -298,7 +305,7 @@ LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
--> $DIR/empty-match.rs:157:24 --> $DIR/empty-match.rs:164:24
| |
LL | match_guarded_arm!(NonEmptyEnum5::V1); LL | match_guarded_arm!(NonEmptyEnum5::V1);
| ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
@ -309,6 +316,7 @@ note: `NonEmptyEnum5` defined here
LL | enum NonEmptyEnum5 { LL | enum NonEmptyEnum5 {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyEnum5` = note: the matched value is of type `NonEmptyEnum5`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
| |
LL ~ _ if false => {}, LL ~ _ if false => {},

View file

@ -175,6 +175,7 @@ LL | match_guarded_arm!(0u8);
| ^^^ pattern `_` not covered | ^^^ pattern `_` not covered
| |
= note: the matched value is of type `u8` = note: the matched value is of type `u8`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -182,7 +183,7 @@ LL + _ => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
--> $DIR/empty-match.rs:133:24 --> $DIR/empty-match.rs:134:24
| |
LL | match_guarded_arm!(NonEmptyStruct1); LL | match_guarded_arm!(NonEmptyStruct1);
| ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered | ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
@ -193,6 +194,7 @@ note: `NonEmptyStruct1` defined here
LL | struct NonEmptyStruct1; LL | struct NonEmptyStruct1;
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyStruct1` = note: the matched value is of type `NonEmptyStruct1`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -200,7 +202,7 @@ LL + NonEmptyStruct1 => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
--> $DIR/empty-match.rs:137:24 --> $DIR/empty-match.rs:139:24
| |
LL | match_guarded_arm!(NonEmptyStruct2(true)); LL | match_guarded_arm!(NonEmptyStruct2(true));
| ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered | ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
@ -211,6 +213,7 @@ note: `NonEmptyStruct2` defined here
LL | struct NonEmptyStruct2(bool); LL | struct NonEmptyStruct2(bool);
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyStruct2` = note: the matched value is of type `NonEmptyStruct2`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -218,7 +221,7 @@ LL + NonEmptyStruct2(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
--> $DIR/empty-match.rs:141:24 --> $DIR/empty-match.rs:144:24
| |
LL | match_guarded_arm!((NonEmptyUnion1 { foo: () })); LL | match_guarded_arm!((NonEmptyUnion1 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
@ -229,6 +232,7 @@ note: `NonEmptyUnion1` defined here
LL | union NonEmptyUnion1 { LL | union NonEmptyUnion1 {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyUnion1` = note: the matched value is of type `NonEmptyUnion1`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -236,7 +240,7 @@ LL + NonEmptyUnion1 { .. } => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
--> $DIR/empty-match.rs:145:24 --> $DIR/empty-match.rs:149:24
| |
LL | match_guarded_arm!((NonEmptyUnion2 { foo: () })); LL | match_guarded_arm!((NonEmptyUnion2 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
@ -247,6 +251,7 @@ note: `NonEmptyUnion2` defined here
LL | union NonEmptyUnion2 { LL | union NonEmptyUnion2 {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyUnion2` = note: the matched value is of type `NonEmptyUnion2`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -254,7 +259,7 @@ LL + NonEmptyUnion2 { .. } => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
--> $DIR/empty-match.rs:149:24 --> $DIR/empty-match.rs:154:24
| |
LL | match_guarded_arm!(NonEmptyEnum1::Foo(true)); LL | match_guarded_arm!(NonEmptyEnum1::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
@ -267,6 +272,7 @@ LL | enum NonEmptyEnum1 {
LL | Foo(bool), LL | Foo(bool),
| ^^^ not covered | ^^^ not covered
= note: the matched value is of type `NonEmptyEnum1` = note: the matched value is of type `NonEmptyEnum1`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -274,7 +280,7 @@ LL + NonEmptyEnum1::Foo(_) => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
--> $DIR/empty-match.rs:153:24 --> $DIR/empty-match.rs:159:24
| |
LL | match_guarded_arm!(NonEmptyEnum2::Foo(true)); LL | match_guarded_arm!(NonEmptyEnum2::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered | ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
@ -290,6 +296,7 @@ LL | Foo(bool),
LL | Bar, LL | Bar,
| ^^^ not covered | ^^^ not covered
= note: the matched value is of type `NonEmptyEnum2` = note: the matched value is of type `NonEmptyEnum2`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
| |
LL ~ _ if false => {}, LL ~ _ if false => {},
@ -297,7 +304,7 @@ LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
| |
error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
--> $DIR/empty-match.rs:157:24 --> $DIR/empty-match.rs:164:24
| |
LL | match_guarded_arm!(NonEmptyEnum5::V1); LL | match_guarded_arm!(NonEmptyEnum5::V1);
| ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
@ -308,6 +315,7 @@ note: `NonEmptyEnum5` defined here
LL | enum NonEmptyEnum5 { LL | enum NonEmptyEnum5 {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyEnum5` = note: the matched value is of type `NonEmptyEnum5`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
| |
LL ~ _ if false => {}, LL ~ _ if false => {},

View file

@ -128,34 +128,42 @@ fn main() {
match_guarded_arm!(0u8); //~ ERROR `_` not covered match_guarded_arm!(0u8); //~ ERROR `_` not covered
//~| NOTE the matched value is of type //~| NOTE the matched value is of type
//~| NOTE match arms with guards don't count towards exhaustivity
//~| NOTE pattern `_` not covered //~| NOTE pattern `_` not covered
//~| NOTE in this expansion of match_guarded_arm! //~| NOTE in this expansion of match_guarded_arm!
match_guarded_arm!(NonEmptyStruct1); //~ ERROR `NonEmptyStruct1` not covered match_guarded_arm!(NonEmptyStruct1); //~ ERROR `NonEmptyStruct1` not covered
//~| NOTE pattern `NonEmptyStruct1` not covered //~| NOTE pattern `NonEmptyStruct1` not covered
//~| NOTE the matched value is of type //~| NOTE the matched value is of type
//~| NOTE match arms with guards don't count towards exhaustivity
//~| NOTE in this expansion of match_guarded_arm! //~| NOTE in this expansion of match_guarded_arm!
match_guarded_arm!(NonEmptyStruct2(true)); //~ ERROR `NonEmptyStruct2(_)` not covered match_guarded_arm!(NonEmptyStruct2(true)); //~ ERROR `NonEmptyStruct2(_)` not covered
//~| NOTE the matched value is of type //~| NOTE the matched value is of type
//~| NOTE pattern `NonEmptyStruct2(_)` not covered //~| NOTE pattern `NonEmptyStruct2(_)` not covered
//~| NOTE match arms with guards don't count towards exhaustivity
//~| NOTE in this expansion of match_guarded_arm! //~| NOTE in this expansion of match_guarded_arm!
match_guarded_arm!((NonEmptyUnion1 { foo: () })); //~ ERROR `NonEmptyUnion1 { .. }` not covered match_guarded_arm!((NonEmptyUnion1 { foo: () })); //~ ERROR `NonEmptyUnion1 { .. }` not covered
//~| NOTE the matched value is of type //~| NOTE the matched value is of type
//~| NOTE pattern `NonEmptyUnion1 { .. }` not covered //~| NOTE pattern `NonEmptyUnion1 { .. }` not covered
//~| NOTE match arms with guards don't count towards exhaustivity
//~| NOTE in this expansion of match_guarded_arm! //~| NOTE in this expansion of match_guarded_arm!
match_guarded_arm!((NonEmptyUnion2 { foo: () })); //~ ERROR `NonEmptyUnion2 { .. }` not covered match_guarded_arm!((NonEmptyUnion2 { foo: () })); //~ ERROR `NonEmptyUnion2 { .. }` not covered
//~| NOTE the matched value is of type //~| NOTE the matched value is of type
//~| NOTE pattern `NonEmptyUnion2 { .. }` not covered //~| NOTE pattern `NonEmptyUnion2 { .. }` not covered
//~| NOTE match arms with guards don't count towards exhaustivity
//~| NOTE in this expansion of match_guarded_arm! //~| NOTE in this expansion of match_guarded_arm!
match_guarded_arm!(NonEmptyEnum1::Foo(true)); //~ ERROR `NonEmptyEnum1::Foo(_)` not covered match_guarded_arm!(NonEmptyEnum1::Foo(true)); //~ ERROR `NonEmptyEnum1::Foo(_)` not covered
//~| NOTE the matched value is of type //~| NOTE the matched value is of type
//~| NOTE pattern `NonEmptyEnum1::Foo(_)` not covered //~| NOTE pattern `NonEmptyEnum1::Foo(_)` not covered
//~| NOTE match arms with guards don't count towards exhaustivity
//~| NOTE in this expansion of match_guarded_arm! //~| NOTE in this expansion of match_guarded_arm!
match_guarded_arm!(NonEmptyEnum2::Foo(true)); //~ ERROR `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered match_guarded_arm!(NonEmptyEnum2::Foo(true)); //~ ERROR `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
//~| NOTE the matched value is of type //~| NOTE the matched value is of type
//~| NOTE patterns `NonEmptyEnum2::Foo(_)` and //~| NOTE patterns `NonEmptyEnum2::Foo(_)` and
//~| NOTE match arms with guards don't count towards exhaustivity
//~| NOTE in this expansion of match_guarded_arm! //~| NOTE in this expansion of match_guarded_arm!
match_guarded_arm!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered match_guarded_arm!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
//~| NOTE the matched value is of type //~| NOTE the matched value is of type
//~| NOTE patterns `NonEmptyEnum5::V1`, //~| NOTE patterns `NonEmptyEnum5::V1`,
//~| NOTE match arms with guards don't count towards exhaustivity
//~| NOTE in this expansion of match_guarded_arm! //~| NOTE in this expansion of match_guarded_arm!
} }

View file

@ -1,19 +1,19 @@
#![feature(box_patterns)] #![feature(box_patterns)]
struct HTMLImageData { struct HTMLImageData {
image: Option<String> image: Option<String>,
} }
struct ElementData { struct ElementData {
kind: Box<ElementKind> kind: Box<ElementKind>,
} }
enum ElementKind { enum ElementKind {
HTMLImageElement(HTMLImageData) HTMLImageElement(HTMLImageData),
} }
enum NodeKind { enum NodeKind {
Element(ElementData) Element(ElementData),
} }
struct NodeData { struct NodeData {
@ -27,8 +27,13 @@ fn main() {
// n.b. span could be better // n.b. span could be better
match n.kind { match n.kind {
box NodeKind::Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns box NodeKind::Element(ed) => match ed.kind {
box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true } //~^ ERROR non-exhaustive patterns
//~| NOTE the matched value is of type
//~| NOTE match arms with guards don't count towards exhaustivity
//~| NOTE pattern `box _` not covered
//~| NOTE `Box<ElementKind>` defined here
box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => true,
}, },
}; };
} }

View file

@ -7,10 +7,11 @@ LL | box NodeKind::Element(ed) => match ed.kind {
note: `Box<ElementKind>` defined here note: `Box<ElementKind>` defined here
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
= note: the matched value is of type `Box<ElementKind>` = note: the matched value is of type `Box<ElementKind>`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL ~ box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true }, LL ~ box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => true,
LL + box _ => todo!() LL ~ box _ => todo!(),
| |
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,4 +1,5 @@
fn main() { fn main() {
match 0 { 1 => () } //~ ERROR non-exhaustive patterns match 0 { 1 => () } //~ ERROR non-exhaustive patterns
match 0 { 0 if false => () } //~ ERROR non-exhaustive patterns match 0 { 0 if false => () } //~ ERROR non-exhaustive patterns
//-| NOTE match arms with guards don't count towards exhaustivity
} }

View file

@ -17,6 +17,7 @@ LL | match 0 { 0 if false => () }
| ^ pattern `_` not covered | ^ pattern `_` not covered
| |
= note: the matched value is of type `i32` = note: the matched value is of type `i32`
= note: match arms with guards don't count towards exhaustivity
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
| |
LL | match 0 { 0 if false => (), _ => todo!() } LL | match 0 { 0 if false => (), _ => todo!() }

View file

@ -1,18 +1,9 @@
use proc_macro::{LineColumn, Punct, Spacing}; use proc_macro::{Punct, Spacing};
pub fn test() { pub fn test() {
test_line_column_ord();
test_punct_eq(); test_punct_eq();
} }
fn test_line_column_ord() {
let line0_column0 = LineColumn { line: 0, column: 0 };
let line0_column1 = LineColumn { line: 0, column: 1 };
let line1_column0 = LineColumn { line: 1, column: 0 };
assert!(line0_column0 < line0_column1);
assert!(line0_column1 < line1_column0);
}
fn test_punct_eq() { fn test_punct_eq() {
let colon_alone = Punct::new(':', Spacing::Alone); let colon_alone = Punct::new(':', Spacing::Alone);
assert_eq!(colon_alone, ':'); assert_eq!(colon_alone, ':');

View file

@ -26,10 +26,9 @@ pub fn assert_span_pos(input: TokenStream) -> TokenStream {
let line: usize = str1.parse().unwrap(); let line: usize = str1.parse().unwrap();
let col: usize = str2.parse().unwrap(); let col: usize = str2.parse().unwrap();
let sp1s = sp1.start(); if (line, col) != (sp1.line(), sp1.column()) {
if (line, col) != (sp1s.line, sp1s.column) {
let msg = format!("line/column mismatch: ({}, {}) != ({}, {})", line, col, let msg = format!("line/column mismatch: ({}, {}) != ({}, {})", line, col,
sp1s.line, sp1s.column); sp1.line(), sp1.column());
sp1.error(msg).emit(); sp1.error(msg).emit();
} }

View file

@ -81,7 +81,7 @@ fn expect_brace(tokens: &mut token_stream::IntoIter) -> token_stream::IntoIter {
fn check_useful_span(token: TokenTree, expected_filename: &str) { fn check_useful_span(token: TokenTree, expected_filename: &str) {
let span = token.span(); let span = token.span();
assert!(span.start().column < span.end().column); assert!(span.column() < span.end().column());
let source_path = span.source_file().path(); let source_path = span.source_file().path();
let filename = source_path.components().last().unwrap(); let filename = source_path.components().last().unwrap();

View file

@ -5,6 +5,7 @@ LL | needs_bar::<T>();
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
| |
= note: cannot satisfy `T: Bar` = note: cannot satisfy `T: Bar`
= help: the trait `Bar` is implemented for `T`
note: required by a bound in `needs_bar` note: required by a bound in `needs_bar`
--> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17 --> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17
| |

View file

@ -581,6 +581,7 @@ types = [
"@lcnr", "@lcnr",
"@oli-obk", "@oli-obk",
"@spastorino", "@spastorino",
"@BoxyUwU",
] ]
borrowck = [ borrowck = [
"@davidtwco", "@davidtwco",