use let chains in mir, resolve, target
This commit is contained in:
parent
bae38bad78
commit
b8eb046e6e
28 changed files with 415 additions and 448 deletions
|
|
@ -997,12 +997,11 @@ fn promote_candidates<'tcx>(
|
|||
for candidate in candidates.into_iter().rev() {
|
||||
let Location { block, statement_index } = candidate.location;
|
||||
if let StatementKind::Assign(box (place, _)) = &body[block].statements[statement_index].kind
|
||||
&& let Some(local) = place.as_local()
|
||||
{
|
||||
if let Some(local) = place.as_local() {
|
||||
if temps[local] == TempState::PromotedOut {
|
||||
// Already promoted.
|
||||
continue;
|
||||
}
|
||||
if temps[local] == TempState::PromotedOut {
|
||||
// Already promoted.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1066,11 +1065,11 @@ fn promote_candidates<'tcx>(
|
|||
_ => true,
|
||||
});
|
||||
let terminator = block.terminator_mut();
|
||||
if let TerminatorKind::Drop { place, target, .. } = &terminator.kind {
|
||||
if let Some(index) = place.as_local() {
|
||||
if promoted(index) {
|
||||
terminator.kind = TerminatorKind::Goto { target: *target };
|
||||
}
|
||||
if let TerminatorKind::Drop { place, target, .. } = &terminator.kind
|
||||
&& let Some(index) = place.as_local()
|
||||
{
|
||||
if promoted(index) {
|
||||
terminator.kind = TerminatorKind::Goto { target: *target };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,14 +48,13 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
|
|||
let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect();
|
||||
for bb in postorder {
|
||||
debug!(" processing {:?}", bb);
|
||||
if let Some(unwind) = body[bb].terminator_mut().unwind_mut() {
|
||||
if let UnwindAction::Cleanup(unwind_bb) = *unwind {
|
||||
if nop_landing_pads.contains(unwind_bb) {
|
||||
debug!(" removing noop landing pad");
|
||||
landing_pads_removed += 1;
|
||||
*unwind = UnwindAction::Continue;
|
||||
}
|
||||
}
|
||||
if let Some(unwind) = body[bb].terminator_mut().unwind_mut()
|
||||
&& let UnwindAction::Cleanup(unwind_bb) = *unwind
|
||||
&& nop_landing_pads.contains(unwind_bb)
|
||||
{
|
||||
debug!(" removing noop landing pad");
|
||||
landing_pads_removed += 1;
|
||||
*unwind = UnwindAction::Continue;
|
||||
}
|
||||
|
||||
body[bb].terminator_mut().successors_mut(|target| {
|
||||
|
|
|
|||
|
|
@ -80,15 +80,14 @@ impl<'tcx> crate::MirPass<'tcx> for Validator {
|
|||
cfg_checker.fail(location, msg);
|
||||
}
|
||||
|
||||
if let MirPhase::Runtime(_) = body.phase {
|
||||
if let ty::InstanceKind::Item(_) = body.source.instance {
|
||||
if body.has_free_regions() {
|
||||
cfg_checker.fail(
|
||||
Location::START,
|
||||
format!("Free regions in optimized {} MIR", body.phase.name()),
|
||||
);
|
||||
}
|
||||
}
|
||||
if let MirPhase::Runtime(_) = body.phase
|
||||
&& let ty::InstanceKind::Item(_) = body.source.instance
|
||||
&& body.has_free_regions()
|
||||
{
|
||||
cfg_checker.fail(
|
||||
Location::START,
|
||||
format!("Free regions in optimized {} MIR", body.phase.name()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1178,12 +1178,11 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> MonoItemPartitio
|
|||
let autodiff_items = tcx.arena.alloc_from_iter(autodiff_items);
|
||||
|
||||
// Output monomorphization stats per def_id
|
||||
if let SwitchWithOptPath::Enabled(ref path) = tcx.sess.opts.unstable_opts.dump_mono_stats {
|
||||
if let Err(err) =
|
||||
if let SwitchWithOptPath::Enabled(ref path) = tcx.sess.opts.unstable_opts.dump_mono_stats
|
||||
&& let Err(err) =
|
||||
dump_mono_items_stats(tcx, codegen_units, path, tcx.crate_name(LOCAL_CRATE))
|
||||
{
|
||||
tcx.dcx().emit_fatal(CouldntDumpMonoStats { error: err.to_string() });
|
||||
}
|
||||
{
|
||||
tcx.dcx().emit_fatal(CouldntDumpMonoStats { error: err.to_string() });
|
||||
}
|
||||
|
||||
if tcx.sess.opts.unstable_opts.print_mono_items {
|
||||
|
|
|
|||
|
|
@ -1973,21 +1973,21 @@ impl<'a> Parser<'a> {
|
|||
format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token));
|
||||
|
||||
// Try to recover extra trailing angle brackets
|
||||
if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind {
|
||||
if let Some(last_segment) = segments.last() {
|
||||
let guar = self.check_trailing_angle_brackets(
|
||||
last_segment,
|
||||
&[exp!(Comma), exp!(CloseBrace)],
|
||||
);
|
||||
if let Some(_guar) = guar {
|
||||
// Handle a case like `Vec<u8>>,` where we can continue parsing fields
|
||||
// after the comma
|
||||
let _ = self.eat(exp!(Comma));
|
||||
if let TyKind::Path(_, Path { segments, .. }) = &a_var.ty.kind
|
||||
&& let Some(last_segment) = segments.last()
|
||||
{
|
||||
let guar = self.check_trailing_angle_brackets(
|
||||
last_segment,
|
||||
&[exp!(Comma), exp!(CloseBrace)],
|
||||
);
|
||||
if let Some(_guar) = guar {
|
||||
// Handle a case like `Vec<u8>>,` where we can continue parsing fields
|
||||
// after the comma
|
||||
let _ = self.eat(exp!(Comma));
|
||||
|
||||
// `check_trailing_angle_brackets` already emitted a nicer error, as
|
||||
// proven by the presence of `_guar`. We can continue parsing.
|
||||
return Ok(a_var);
|
||||
}
|
||||
// `check_trailing_angle_brackets` already emitted a nicer error, as
|
||||
// proven by the presence of `_guar`. We can continue parsing.
|
||||
return Ok(a_var);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3034,18 +3034,16 @@ impl<'a> Parser<'a> {
|
|||
|
||||
if let Ok(t) = &ty {
|
||||
// Check for trailing angle brackets
|
||||
if let TyKind::Path(_, Path { segments, .. }) = &t.kind {
|
||||
if let Some(segment) = segments.last() {
|
||||
if let Some(guar) =
|
||||
this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
|
||||
{
|
||||
return Ok((
|
||||
dummy_arg(segment.ident, guar),
|
||||
Trailing::No,
|
||||
UsePreAttrPos::No,
|
||||
));
|
||||
}
|
||||
}
|
||||
if let TyKind::Path(_, Path { segments, .. }) = &t.kind
|
||||
&& let Some(segment) = segments.last()
|
||||
&& let Some(guar) =
|
||||
this.check_trailing_angle_brackets(segment, &[exp!(CloseParen)])
|
||||
{
|
||||
return Ok((
|
||||
dummy_arg(segment.ident, guar),
|
||||
Trailing::No,
|
||||
UsePreAttrPos::No,
|
||||
));
|
||||
}
|
||||
|
||||
if this.token != token::Comma && this.token != token::CloseParen {
|
||||
|
|
|
|||
|
|
@ -104,10 +104,10 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
|
|||
|
||||
fn visit_inline_asm(&mut self, asm: &'tcx hir::InlineAsm<'tcx>, id: hir::HirId) {
|
||||
for (op, _) in asm.operands {
|
||||
if let hir::InlineAsmOperand::SymStatic { def_id, .. } = op {
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
self.reachable_symbols.insert(def_id);
|
||||
}
|
||||
if let hir::InlineAsmOperand::SymStatic { def_id, .. } = op
|
||||
&& let Some(def_id) = def_id.as_local()
|
||||
{
|
||||
self.reachable_symbols.insert(def_id);
|
||||
}
|
||||
}
|
||||
intravisit::walk_inline_asm(self, asm, id);
|
||||
|
|
|
|||
|
|
@ -929,10 +929,10 @@ struct CheckTraitImplStable<'tcx> {
|
|||
|
||||
impl<'tcx> Visitor<'tcx> for CheckTraitImplStable<'tcx> {
|
||||
fn visit_path(&mut self, path: &hir::Path<'tcx>, _id: hir::HirId) {
|
||||
if let Some(def_id) = path.res.opt_def_id() {
|
||||
if let Some(stab) = self.tcx.lookup_stability(def_id) {
|
||||
self.fully_stable &= stab.level.is_stable();
|
||||
}
|
||||
if let Some(def_id) = path.res.opt_def_id()
|
||||
&& let Some(stab) = self.tcx.lookup_stability(def_id)
|
||||
{
|
||||
self.fully_stable &= stab.level.is_stable();
|
||||
}
|
||||
intravisit::walk_path(self, path)
|
||||
}
|
||||
|
|
@ -1055,10 +1055,10 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
|
|||
// implications from this crate.
|
||||
remaining_implications.remove(&feature);
|
||||
|
||||
if let FeatureStability::Unstable { old_name: Some(alias) } = stability {
|
||||
if let Some(span) = remaining_lib_features.swap_remove(&alias) {
|
||||
tcx.dcx().emit_err(errors::RenamedFeature { span, feature, alias });
|
||||
}
|
||||
if let FeatureStability::Unstable { old_name: Some(alias) } = stability
|
||||
&& let Some(span) = remaining_lib_features.swap_remove(&alias)
|
||||
{
|
||||
tcx.dcx().emit_err(errors::RenamedFeature { span, feature, alias });
|
||||
}
|
||||
|
||||
if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
|
||||
|
|
|
|||
|
|
@ -75,19 +75,19 @@ impl<'tcx> Visitor<'tcx> for CaptureCollector<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
if let hir::ExprKind::Closure(closure) = expr.kind {
|
||||
if let Some(upvars) = self.tcx.upvars_mentioned(closure.def_id) {
|
||||
// Every capture of a closure expression is a local in scope,
|
||||
// that is moved/copied/borrowed into the closure value, and
|
||||
// for this analysis they are like any other access to a local.
|
||||
//
|
||||
// E.g. in `|b| |c| (a, b, c)`, the upvars of the inner closure
|
||||
// are `a` and `b`, and while `a` is not directly used in the
|
||||
// outer closure, it needs to be an upvar there too, so that
|
||||
// the inner closure can take it (from the outer closure's env).
|
||||
for (&var_id, upvar) in upvars {
|
||||
self.visit_local_use(var_id, upvar.span);
|
||||
}
|
||||
if let hir::ExprKind::Closure(closure) = expr.kind
|
||||
&& let Some(upvars) = self.tcx.upvars_mentioned(closure.def_id)
|
||||
{
|
||||
// Every capture of a closure expression is a local in scope,
|
||||
// that is moved/copied/borrowed into the closure value, and
|
||||
// for this analysis they are like any other access to a local.
|
||||
//
|
||||
// E.g. in `|b| |c| (a, b, c)`, the upvars of the inner closure
|
||||
// are `a` and `b`, and while `a` is not directly used in the
|
||||
// outer closure, it needs to be an upvar there too, so that
|
||||
// the inner closure can take it (from the outer closure's env).
|
||||
for (&var_id, upvar) in upvars {
|
||||
self.visit_local_use(var_id, upvar.span);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,12 +204,10 @@ where
|
|||
// Something like `fn() {my_method}` type of the method
|
||||
// `impl Pub<Priv> { pub fn my_method() {} }` is considered a private type,
|
||||
// so we need to visit the self type additionally.
|
||||
if let Some(assoc_item) = tcx.opt_associated_item(def_id) {
|
||||
if let Some(impl_def_id) = assoc_item.impl_container(tcx) {
|
||||
try_visit!(
|
||||
tcx.type_of(impl_def_id).instantiate_identity().visit_with(self)
|
||||
);
|
||||
}
|
||||
if let Some(assoc_item) = tcx.opt_associated_item(def_id)
|
||||
&& let Some(impl_def_id) = assoc_item.impl_container(tcx)
|
||||
{
|
||||
try_visit!(tcx.type_of(impl_def_id).instantiate_identity().visit_with(self));
|
||||
}
|
||||
}
|
||||
ty::Alias(kind @ (ty::Inherent | ty::Free | ty::Projection), data) => {
|
||||
|
|
@ -734,6 +732,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
|||
if let Some(ctor_def_id) = variant.data.ctor_def_id() {
|
||||
self.update(ctor_def_id, variant_ev, Level::Reachable);
|
||||
}
|
||||
|
||||
for field in variant.data.fields() {
|
||||
self.update(field.def_id, variant_ev, Level::Reachable);
|
||||
self.reach(field.def_id, variant_ev).ty();
|
||||
|
|
|
|||
|
|
@ -498,12 +498,12 @@ impl<D: Deps> DepGraph<D> {
|
|||
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
if let Some(target) = task_deps.node {
|
||||
if let Some(ref forbidden_edge) = data.current.forbidden_edge {
|
||||
let src = forbidden_edge.index_to_node.lock()[&dep_node_index];
|
||||
if forbidden_edge.test(&src, &target) {
|
||||
panic!("forbidden edge {:?} -> {:?} created", src, target)
|
||||
}
|
||||
if let Some(target) = task_deps.node
|
||||
&& let Some(ref forbidden_edge) = data.current.forbidden_edge
|
||||
{
|
||||
let src = forbidden_edge.index_to_node.lock()[&dep_node_index];
|
||||
if forbidden_edge.test(&src, &target) {
|
||||
panic!("forbidden edge {:?} -> {:?} created", src, target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,10 +289,10 @@ where
|
|||
F: FnMut(Span, QueryJobId) -> Option<Option<Waiter>>,
|
||||
{
|
||||
// Visit the parent query which is a non-resumable waiter since it's on the same stack
|
||||
if let Some(parent) = query.parent(query_map) {
|
||||
if let Some(cycle) = visit(query.span(query_map), parent) {
|
||||
return Some(cycle);
|
||||
}
|
||||
if let Some(parent) = query.parent(query_map)
|
||||
&& let Some(cycle) = visit(query.span(query_map), parent)
|
||||
{
|
||||
return Some(cycle);
|
||||
}
|
||||
|
||||
// Visit the explicit waiters which use condvars and are resumable
|
||||
|
|
|
|||
|
|
@ -818,10 +818,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
// If the first argument in call is `self` suggest calling a method.
|
||||
if let Some((call_span, args_span)) = self.call_has_self_arg(source) {
|
||||
let mut args_snippet = String::new();
|
||||
if let Some(args_span) = args_span {
|
||||
if let Ok(snippet) = self.r.tcx.sess.source_map().span_to_snippet(args_span) {
|
||||
args_snippet = snippet;
|
||||
}
|
||||
if let Some(args_span) = args_span
|
||||
&& let Ok(snippet) = self.r.tcx.sess.source_map().span_to_snippet(args_span)
|
||||
{
|
||||
args_snippet = snippet;
|
||||
}
|
||||
|
||||
err.span_suggestion(
|
||||
|
|
@ -955,59 +955,57 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)),
|
||||
false,
|
||||
) = (source, res, is_macro)
|
||||
{
|
||||
if let Some(bounds @ [first_bound, .., last_bound]) =
|
||||
&& let Some(bounds @ [first_bound, .., last_bound]) =
|
||||
self.diag_metadata.current_trait_object
|
||||
{
|
||||
fallback = true;
|
||||
let spans: Vec<Span> = bounds
|
||||
.iter()
|
||||
.map(|bound| bound.span())
|
||||
.filter(|&sp| sp != base_error.span)
|
||||
.collect();
|
||||
{
|
||||
fallback = true;
|
||||
let spans: Vec<Span> = bounds
|
||||
.iter()
|
||||
.map(|bound| bound.span())
|
||||
.filter(|&sp| sp != base_error.span)
|
||||
.collect();
|
||||
|
||||
let start_span = first_bound.span();
|
||||
// `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><)
|
||||
let end_span = last_bound.span();
|
||||
// `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar)
|
||||
let last_bound_span = spans.last().cloned().unwrap();
|
||||
let mut multi_span: MultiSpan = spans.clone().into();
|
||||
for sp in spans {
|
||||
let msg = if sp == last_bound_span {
|
||||
format!(
|
||||
"...because of {these} bound{s}",
|
||||
these = pluralize!("this", bounds.len() - 1),
|
||||
s = pluralize!(bounds.len() - 1),
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
multi_span.push_span_label(sp, msg);
|
||||
}
|
||||
multi_span.push_span_label(base_error.span, "expected this type to be a trait...");
|
||||
err.span_help(
|
||||
multi_span,
|
||||
"`+` is used to constrain a \"trait object\" type with lifetimes or \
|
||||
let start_span = first_bound.span();
|
||||
// `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><)
|
||||
let end_span = last_bound.span();
|
||||
// `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar)
|
||||
let last_bound_span = spans.last().cloned().unwrap();
|
||||
let mut multi_span: MultiSpan = spans.clone().into();
|
||||
for sp in spans {
|
||||
let msg = if sp == last_bound_span {
|
||||
format!(
|
||||
"...because of {these} bound{s}",
|
||||
these = pluralize!("this", bounds.len() - 1),
|
||||
s = pluralize!(bounds.len() - 1),
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
multi_span.push_span_label(sp, msg);
|
||||
}
|
||||
multi_span.push_span_label(base_error.span, "expected this type to be a trait...");
|
||||
err.span_help(
|
||||
multi_span,
|
||||
"`+` is used to constrain a \"trait object\" type with lifetimes or \
|
||||
auto-traits; structs and enums can't be bound in that way",
|
||||
);
|
||||
if bounds.iter().all(|bound| match bound {
|
||||
ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true,
|
||||
ast::GenericBound::Trait(tr) => tr.span == base_error.span,
|
||||
}) {
|
||||
let mut sugg = vec![];
|
||||
if base_error.span != start_span {
|
||||
sugg.push((start_span.until(base_error.span), String::new()));
|
||||
}
|
||||
if base_error.span != end_span {
|
||||
sugg.push((base_error.span.shrink_to_hi().to(end_span), String::new()));
|
||||
}
|
||||
|
||||
err.multipart_suggestion(
|
||||
"if you meant to use a type and not a trait here, remove the bounds",
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
);
|
||||
if bounds.iter().all(|bound| match bound {
|
||||
ast::GenericBound::Outlives(_) | ast::GenericBound::Use(..) => true,
|
||||
ast::GenericBound::Trait(tr) => tr.span == base_error.span,
|
||||
}) {
|
||||
let mut sugg = vec![];
|
||||
if base_error.span != start_span {
|
||||
sugg.push((start_span.until(base_error.span), String::new()));
|
||||
}
|
||||
if base_error.span != end_span {
|
||||
sugg.push((base_error.span.shrink_to_hi().to(end_span), String::new()));
|
||||
}
|
||||
|
||||
err.multipart_suggestion(
|
||||
"if you meant to use a type and not a trait here, remove the bounds",
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1151,13 +1149,13 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
}
|
||||
err.code(E0411);
|
||||
err.span_label(span, "`Self` is only available in impls, traits, and type definitions");
|
||||
if let Some(item) = self.diag_metadata.current_item {
|
||||
if let Some(ident) = item.kind.ident() {
|
||||
err.span_label(
|
||||
ident.span,
|
||||
format!("`Self` not allowed in {} {}", item.kind.article(), item.kind.descr()),
|
||||
);
|
||||
}
|
||||
if let Some(item) = self.diag_metadata.current_item
|
||||
&& let Some(ident) = item.kind.ident()
|
||||
{
|
||||
err.span_label(
|
||||
ident.span,
|
||||
format!("`Self` not allowed in {} {}", item.kind.article(), item.kind.descr()),
|
||||
);
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
@ -1932,11 +1930,11 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
};
|
||||
|
||||
let (ctor_def, ctor_vis, fields) = if let Some(struct_ctor) = struct_ctor {
|
||||
if let PathSource::Expr(Some(parent)) = source {
|
||||
if let ExprKind::Field(..) | ExprKind::MethodCall(..) = parent.kind {
|
||||
bad_struct_syntax_suggestion(self, err, def_id);
|
||||
return true;
|
||||
}
|
||||
if let PathSource::Expr(Some(parent)) = source
|
||||
&& let ExprKind::Field(..) | ExprKind::MethodCall(..) = parent.kind
|
||||
{
|
||||
bad_struct_syntax_suggestion(self, err, def_id);
|
||||
return true;
|
||||
}
|
||||
struct_ctor
|
||||
} else {
|
||||
|
|
@ -2344,19 +2342,13 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
if filter_fn(Res::Local(ast::DUMMY_NODE_ID)) {
|
||||
if let Some(node_id) =
|
||||
self.diag_metadata.current_self_type.as_ref().and_then(extract_node_id)
|
||||
&& let Some(resolution) = self.r.partial_res_map.get(&node_id)
|
||||
&& let Some(Res::Def(DefKind::Struct | DefKind::Union, did)) = resolution.full_res()
|
||||
&& let Some(fields) = self.r.field_idents(did)
|
||||
&& let Some(field) = fields.iter().find(|id| ident.name == id.name)
|
||||
{
|
||||
// Look for a field with the same name in the current self_type.
|
||||
if let Some(resolution) = self.r.partial_res_map.get(&node_id) {
|
||||
if let Some(Res::Def(DefKind::Struct | DefKind::Union, did)) =
|
||||
resolution.full_res()
|
||||
{
|
||||
if let Some(fields) = self.r.field_idents(did) {
|
||||
if let Some(field) = fields.iter().find(|id| ident.name == id.name) {
|
||||
return Some(AssocSuggestion::Field(field.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Some(AssocSuggestion::Field(field.span));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2391,44 +2383,44 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
|||
}
|
||||
|
||||
// Look for associated items in the current trait.
|
||||
if let Some((module, _)) = self.current_trait_ref {
|
||||
if let Ok(binding) = self.r.maybe_resolve_ident_in_module(
|
||||
if let Some((module, _)) = self.current_trait_ref
|
||||
&& let Ok(binding) = self.r.maybe_resolve_ident_in_module(
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
ns,
|
||||
&self.parent_scope,
|
||||
None,
|
||||
) {
|
||||
let res = binding.res();
|
||||
if filter_fn(res) {
|
||||
match res {
|
||||
Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => {
|
||||
let has_self = match def_id.as_local() {
|
||||
Some(def_id) => self
|
||||
.r
|
||||
.delegation_fn_sigs
|
||||
.get(&def_id)
|
||||
.is_some_and(|sig| sig.has_self),
|
||||
None => {
|
||||
self.r.tcx.fn_arg_idents(def_id).first().is_some_and(|&ident| {
|
||||
matches!(ident, Some(Ident { name: kw::SelfLower, .. }))
|
||||
})
|
||||
}
|
||||
};
|
||||
if has_self {
|
||||
return Some(AssocSuggestion::MethodWithSelf { called });
|
||||
} else {
|
||||
return Some(AssocSuggestion::AssocFn { called });
|
||||
)
|
||||
{
|
||||
let res = binding.res();
|
||||
if filter_fn(res) {
|
||||
match res {
|
||||
Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => {
|
||||
let has_self = match def_id.as_local() {
|
||||
Some(def_id) => self
|
||||
.r
|
||||
.delegation_fn_sigs
|
||||
.get(&def_id)
|
||||
.is_some_and(|sig| sig.has_self),
|
||||
None => {
|
||||
self.r.tcx.fn_arg_idents(def_id).first().is_some_and(|&ident| {
|
||||
matches!(ident, Some(Ident { name: kw::SelfLower, .. }))
|
||||
})
|
||||
}
|
||||
};
|
||||
if has_self {
|
||||
return Some(AssocSuggestion::MethodWithSelf { called });
|
||||
} else {
|
||||
return Some(AssocSuggestion::AssocFn { called });
|
||||
}
|
||||
Res::Def(DefKind::AssocConst, _) => {
|
||||
return Some(AssocSuggestion::AssocConst);
|
||||
}
|
||||
Res::Def(DefKind::AssocTy, _) => {
|
||||
return Some(AssocSuggestion::AssocType);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Res::Def(DefKind::AssocConst, _) => {
|
||||
return Some(AssocSuggestion::AssocConst);
|
||||
}
|
||||
Res::Def(DefKind::AssocTy, _) => {
|
||||
return Some(AssocSuggestion::AssocType);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1023,40 +1023,39 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
|||
node_id: NodeId,
|
||||
) {
|
||||
let span = path.span;
|
||||
if let Some(stability) = &ext.stability {
|
||||
if let StabilityLevel::Unstable { reason, issue, is_soft, implied_by, .. } =
|
||||
if let Some(stability) = &ext.stability
|
||||
&& let StabilityLevel::Unstable { reason, issue, is_soft, implied_by, .. } =
|
||||
stability.level
|
||||
{
|
||||
let feature = stability.feature;
|
||||
{
|
||||
let feature = stability.feature;
|
||||
|
||||
let is_allowed =
|
||||
|feature| self.tcx.features().enabled(feature) || span.allows_unstable(feature);
|
||||
let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
|
||||
if !is_allowed(feature) && !allowed_by_implication {
|
||||
let lint_buffer = &mut self.lint_buffer;
|
||||
let soft_handler = |lint, span, msg: String| {
|
||||
lint_buffer.buffer_lint(
|
||||
lint,
|
||||
node_id,
|
||||
span,
|
||||
BuiltinLintDiag::UnstableFeature(
|
||||
// FIXME make this translatable
|
||||
msg.into(),
|
||||
),
|
||||
)
|
||||
};
|
||||
stability::report_unstable(
|
||||
self.tcx.sess,
|
||||
feature,
|
||||
reason.to_opt_reason(),
|
||||
issue,
|
||||
None,
|
||||
is_soft,
|
||||
let is_allowed =
|
||||
|feature| self.tcx.features().enabled(feature) || span.allows_unstable(feature);
|
||||
let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature));
|
||||
if !is_allowed(feature) && !allowed_by_implication {
|
||||
let lint_buffer = &mut self.lint_buffer;
|
||||
let soft_handler = |lint, span, msg: String| {
|
||||
lint_buffer.buffer_lint(
|
||||
lint,
|
||||
node_id,
|
||||
span,
|
||||
soft_handler,
|
||||
stability::UnstableKind::Regular,
|
||||
);
|
||||
}
|
||||
BuiltinLintDiag::UnstableFeature(
|
||||
// FIXME make this translatable
|
||||
msg.into(),
|
||||
),
|
||||
)
|
||||
};
|
||||
stability::report_unstable(
|
||||
self.tcx.sess,
|
||||
feature,
|
||||
reason.to_opt_reason(),
|
||||
issue,
|
||||
None,
|
||||
is_soft,
|
||||
span,
|
||||
soft_handler,
|
||||
stability::UnstableKind::Regular,
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(depr) = &ext.deprecation {
|
||||
|
|
|
|||
|
|
@ -107,10 +107,10 @@ pub fn feature_err_issue(
|
|||
let span = span.into();
|
||||
|
||||
// Cancel an earlier warning for this same error, if it exists.
|
||||
if let Some(span) = span.primary_span() {
|
||||
if let Some(err) = sess.dcx().steal_non_err(span, StashKey::EarlySyntaxWarning) {
|
||||
err.cancel()
|
||||
}
|
||||
if let Some(span) = span.primary_span()
|
||||
&& let Some(err) = sess.dcx().steal_non_err(span, StashKey::EarlySyntaxWarning)
|
||||
{
|
||||
err.cancel()
|
||||
}
|
||||
|
||||
let mut err = sess.dcx().create_err(FeatureGateError { span, explain: explain.into() });
|
||||
|
|
|
|||
|
|
@ -1362,11 +1362,11 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
|
|||
sess.dcx().emit_err(errors::InstrumentationNotSupported { us: "XRay".to_string() });
|
||||
}
|
||||
|
||||
if let Some(flavor) = sess.opts.cg.linker_flavor {
|
||||
if let Some(compatible_list) = sess.target.linker_flavor.check_compatibility(flavor) {
|
||||
let flavor = flavor.desc();
|
||||
sess.dcx().emit_err(errors::IncompatibleLinkerFlavor { flavor, compatible_list });
|
||||
}
|
||||
if let Some(flavor) = sess.opts.cg.linker_flavor
|
||||
&& let Some(compatible_list) = sess.target.linker_flavor.check_compatibility(flavor)
|
||||
{
|
||||
let flavor = flavor.desc();
|
||||
sess.dcx().emit_err(errors::IncompatibleLinkerFlavor { flavor, compatible_list });
|
||||
}
|
||||
|
||||
if sess.opts.unstable_opts.function_return != FunctionReturn::default() {
|
||||
|
|
|
|||
|
|
@ -826,10 +826,10 @@ impl SourceMap {
|
|||
/// Given a `Span`, tries to get a shorter span ending just after the first occurrence of `char`
|
||||
/// `c`.
|
||||
pub fn span_through_char(&self, sp: Span, c: char) -> Span {
|
||||
if let Ok(snippet) = self.span_to_snippet(sp) {
|
||||
if let Some(offset) = snippet.find(c) {
|
||||
return sp.with_hi(BytePos(sp.lo().0 + (offset + c.len_utf8()) as u32));
|
||||
}
|
||||
if let Ok(snippet) = self.span_to_snippet(sp)
|
||||
&& let Some(offset) = snippet.find(c)
|
||||
{
|
||||
return sp.with_hi(BytePos(sp.lo().0 + (offset + c.len_utf8()) as u32));
|
||||
}
|
||||
sp
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,16 +314,15 @@ fn classify_arg<'a, Ty, C>(
|
|||
}
|
||||
|
||||
fn extend_integer_width<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64) {
|
||||
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
|
||||
if let Primitive::Int(i, _) = scalar.primitive() {
|
||||
// 32-bit integers are always sign-extended
|
||||
if i.size().bits() == 32 && xlen > 32 {
|
||||
if let PassMode::Direct(ref mut attrs) = arg.mode {
|
||||
attrs.ext(ArgExtension::Sext);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr
|
||||
&& let Primitive::Int(i, _) = scalar.primitive()
|
||||
&& i.size().bits() == 32
|
||||
&& xlen > 32
|
||||
&& let PassMode::Direct(ref mut attrs) = arg.mode
|
||||
{
|
||||
// 32-bit integers are always sign-extended
|
||||
attrs.ext(ArgExtension::Sext);
|
||||
return;
|
||||
}
|
||||
|
||||
arg.extend_integer_width_to(xlen);
|
||||
|
|
|
|||
|
|
@ -6,15 +6,14 @@ use crate::callconv::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform
|
|||
|
||||
fn extend_integer_width_mips<Ty>(arg: &mut ArgAbi<'_, Ty>, bits: u64) {
|
||||
// Always sign extend u32 values on 64-bit mips
|
||||
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
|
||||
if let Primitive::Int(i, signed) = scalar.primitive() {
|
||||
if !signed && i.size().bits() == 32 {
|
||||
if let PassMode::Direct(ref mut attrs) = arg.mode {
|
||||
attrs.ext(ArgExtension::Sext);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr
|
||||
&& let Primitive::Int(i, signed) = scalar.primitive()
|
||||
&& !signed
|
||||
&& i.size().bits() == 32
|
||||
&& let PassMode::Direct(ref mut attrs) = arg.mode
|
||||
{
|
||||
attrs.ext(ArgExtension::Sext);
|
||||
return;
|
||||
}
|
||||
|
||||
arg.extend_integer_width_to(bits);
|
||||
|
|
@ -58,13 +57,12 @@ where
|
|||
ret.cast_to(reg);
|
||||
return;
|
||||
}
|
||||
} else if ret.layout.fields.count() == 2 {
|
||||
if let Some(reg0) = float_reg(cx, ret, 0) {
|
||||
if let Some(reg1) = float_reg(cx, ret, 1) {
|
||||
ret.cast_to(CastTarget::pair(reg0, reg1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if ret.layout.fields.count() == 2
|
||||
&& let Some(reg0) = float_reg(cx, ret, 0)
|
||||
&& let Some(reg1) = float_reg(cx, ret, 1)
|
||||
{
|
||||
ret.cast_to(CastTarget::pair(reg0, reg1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -495,18 +495,16 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
|
|||
|
||||
pub fn extend_integer_width_to(&mut self, bits: u64) {
|
||||
// Only integers have signedness
|
||||
if let BackendRepr::Scalar(scalar) = self.layout.backend_repr {
|
||||
if let Primitive::Int(i, signed) = scalar.primitive() {
|
||||
if i.size().bits() < bits {
|
||||
if let PassMode::Direct(ref mut attrs) = self.mode {
|
||||
if signed {
|
||||
attrs.ext(ArgExtension::Sext)
|
||||
} else {
|
||||
attrs.ext(ArgExtension::Zext)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if let BackendRepr::Scalar(scalar) = self.layout.backend_repr
|
||||
&& let Primitive::Int(i, signed) = scalar.primitive()
|
||||
&& i.size().bits() < bits
|
||||
&& let PassMode::Direct(ref mut attrs) = self.mode
|
||||
{
|
||||
if signed {
|
||||
attrs.ext(ArgExtension::Sext)
|
||||
} else {
|
||||
attrs.ext(ArgExtension::Zext)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -393,16 +393,14 @@ fn classify_arg<'a, Ty, C>(
|
|||
}
|
||||
|
||||
fn extend_integer_width<Ty>(arg: &mut ArgAbi<'_, Ty>, xlen: u64) {
|
||||
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr {
|
||||
if let Primitive::Int(i, _) = scalar.primitive() {
|
||||
// 32-bit integers are always sign-extended
|
||||
if i.size().bits() == 32 && xlen > 32 {
|
||||
if let PassMode::Direct(ref mut attrs) = arg.mode {
|
||||
attrs.ext(ArgExtension::Sext);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let BackendRepr::Scalar(scalar) = arg.layout.backend_repr
|
||||
&& let Primitive::Int(i, _) = scalar.primitive()
|
||||
&& i.size().bits() == 32
|
||||
&& xlen > 32
|
||||
&& let PassMode::Direct(ref mut attrs) = arg.mode
|
||||
{
|
||||
attrs.ext(ArgExtension::Sext);
|
||||
return;
|
||||
}
|
||||
|
||||
arg.extend_integer_width_to(xlen);
|
||||
|
|
|
|||
|
|
@ -104,10 +104,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
ty::AssocKind::Fn { .. } => {
|
||||
if let Some(hir_id) =
|
||||
assoc_item.def_id.as_local().map(|id| self.tcx().local_def_id_to_hir_id(id))
|
||||
&& let Some(decl) = self.tcx().hir_fn_decl_by_hir_id(hir_id)
|
||||
{
|
||||
if let Some(decl) = self.tcx().hir_fn_decl_by_hir_id(hir_id) {
|
||||
visitor.visit_fn_decl(decl);
|
||||
}
|
||||
visitor.visit_fn_decl(decl);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -91,51 +91,51 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
) {
|
||||
// Heavily inspired by `FnCtxt::suggest_compatible_variants`, with
|
||||
// some modifications due to that being in typeck and this being in infer.
|
||||
if let ObligationCauseCode::Pattern { .. } = cause.code() {
|
||||
if let ty::Adt(expected_adt, args) = exp_found.expected.kind() {
|
||||
let compatible_variants: Vec<_> = expected_adt
|
||||
.variants()
|
||||
.iter()
|
||||
.filter(|variant| {
|
||||
variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn)
|
||||
})
|
||||
.filter_map(|variant| {
|
||||
let sole_field = &variant.single_field();
|
||||
let sole_field_ty = sole_field.ty(self.tcx, args);
|
||||
if self.same_type_modulo_infer(sole_field_ty, exp_found.found) {
|
||||
let variant_path =
|
||||
with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
|
||||
// FIXME #56861: DRYer prelude filtering
|
||||
if let Some(path) = variant_path.strip_prefix("std::prelude::") {
|
||||
if let Some((_, path)) = path.split_once("::") {
|
||||
return Some(path.to_string());
|
||||
}
|
||||
}
|
||||
Some(variant_path)
|
||||
} else {
|
||||
None
|
||||
if let ObligationCauseCode::Pattern { .. } = cause.code()
|
||||
&& let ty::Adt(expected_adt, args) = exp_found.expected.kind()
|
||||
{
|
||||
let compatible_variants: Vec<_> = expected_adt
|
||||
.variants()
|
||||
.iter()
|
||||
.filter(|variant| {
|
||||
variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn)
|
||||
})
|
||||
.filter_map(|variant| {
|
||||
let sole_field = &variant.single_field();
|
||||
let sole_field_ty = sole_field.ty(self.tcx, args);
|
||||
if self.same_type_modulo_infer(sole_field_ty, exp_found.found) {
|
||||
let variant_path =
|
||||
with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
|
||||
// FIXME #56861: DRYer prelude filtering
|
||||
if let Some(path) = variant_path.strip_prefix("std::prelude::")
|
||||
&& let Some((_, path)) = path.split_once("::")
|
||||
{
|
||||
return Some(path.to_string());
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
match &compatible_variants[..] {
|
||||
[] => {}
|
||||
[variant] => {
|
||||
let sugg = SuggestTuplePatternOne {
|
||||
variant: variant.to_owned(),
|
||||
span_low: cause.span.shrink_to_lo(),
|
||||
span_high: cause.span.shrink_to_hi(),
|
||||
};
|
||||
diag.subdiagnostic(sugg);
|
||||
}
|
||||
_ => {
|
||||
// More than one matching variant.
|
||||
let sugg = SuggestTuplePatternMany {
|
||||
path: self.tcx.def_path_str(expected_adt.did()),
|
||||
cause_span: cause.span,
|
||||
compatible_variants,
|
||||
};
|
||||
diag.subdiagnostic(sugg);
|
||||
Some(variant_path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
match &compatible_variants[..] {
|
||||
[] => {}
|
||||
[variant] => {
|
||||
let sugg = SuggestTuplePatternOne {
|
||||
variant: variant.to_owned(),
|
||||
span_low: cause.span.shrink_to_lo(),
|
||||
span_high: cause.span.shrink_to_hi(),
|
||||
};
|
||||
diag.subdiagnostic(sugg);
|
||||
}
|
||||
_ => {
|
||||
// More than one matching variant.
|
||||
let sugg = SuggestTuplePatternMany {
|
||||
path: self.tcx.def_path_str(expected_adt.did()),
|
||||
cause_span: cause.span,
|
||||
compatible_variants,
|
||||
};
|
||||
diag.subdiagnostic(sugg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -288,19 +288,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
.filter(|field| field.vis.is_accessible_from(field.did, self.tcx))
|
||||
.map(|field| (field.name, field.ty(self.tcx, expected_args)))
|
||||
.find(|(_, ty)| self.same_type_modulo_infer(*ty, exp_found.found))
|
||||
&& let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code()
|
||||
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
|
||||
{
|
||||
if let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code() {
|
||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||
let suggestion = if expected_def.is_struct() {
|
||||
SuggestAccessingField::Safe { span, snippet, name, ty }
|
||||
} else if expected_def.is_union() {
|
||||
SuggestAccessingField::Unsafe { span, snippet, name, ty }
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
diag.subdiagnostic(suggestion);
|
||||
}
|
||||
}
|
||||
let suggestion = if expected_def.is_struct() {
|
||||
SuggestAccessingField::Safe { span, snippet, name, ty }
|
||||
} else if expected_def.is_union() {
|
||||
SuggestAccessingField::Unsafe { span, snippet, name, ty }
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
diag.subdiagnostic(suggestion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -540,38 +538,35 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
) -> Option<SuggestAsRefKind> {
|
||||
if let (ty::Adt(exp_def, exp_args), ty::Ref(_, found_ty, _)) =
|
||||
(expected.kind(), found.kind())
|
||||
&& let ty::Adt(found_def, found_args) = *found_ty.kind()
|
||||
{
|
||||
if let ty::Adt(found_def, found_args) = *found_ty.kind() {
|
||||
if exp_def == &found_def {
|
||||
let have_as_ref = &[
|
||||
(sym::Option, SuggestAsRefKind::Option),
|
||||
(sym::Result, SuggestAsRefKind::Result),
|
||||
];
|
||||
if let Some(msg) = have_as_ref.iter().find_map(|(name, msg)| {
|
||||
self.tcx.is_diagnostic_item(*name, exp_def.did()).then_some(msg)
|
||||
}) {
|
||||
let mut show_suggestion = true;
|
||||
for (exp_ty, found_ty) in
|
||||
std::iter::zip(exp_args.types(), found_args.types())
|
||||
{
|
||||
match *exp_ty.kind() {
|
||||
ty::Ref(_, exp_ty, _) => {
|
||||
match (exp_ty.kind(), found_ty.kind()) {
|
||||
(_, ty::Param(_))
|
||||
| (_, ty::Infer(_))
|
||||
| (ty::Param(_), _)
|
||||
| (ty::Infer(_), _) => {}
|
||||
_ if self.same_type_modulo_infer(exp_ty, found_ty) => {}
|
||||
_ => show_suggestion = false,
|
||||
};
|
||||
}
|
||||
ty::Param(_) | ty::Infer(_) => {}
|
||||
_ => show_suggestion = false,
|
||||
if exp_def == &found_def {
|
||||
let have_as_ref = &[
|
||||
(sym::Option, SuggestAsRefKind::Option),
|
||||
(sym::Result, SuggestAsRefKind::Result),
|
||||
];
|
||||
if let Some(msg) = have_as_ref.iter().find_map(|(name, msg)| {
|
||||
self.tcx.is_diagnostic_item(*name, exp_def.did()).then_some(msg)
|
||||
}) {
|
||||
let mut show_suggestion = true;
|
||||
for (exp_ty, found_ty) in std::iter::zip(exp_args.types(), found_args.types()) {
|
||||
match *exp_ty.kind() {
|
||||
ty::Ref(_, exp_ty, _) => {
|
||||
match (exp_ty.kind(), found_ty.kind()) {
|
||||
(_, ty::Param(_))
|
||||
| (_, ty::Infer(_))
|
||||
| (ty::Param(_), _)
|
||||
| (ty::Infer(_), _) => {}
|
||||
_ if self.same_type_modulo_infer(exp_ty, found_ty) => {}
|
||||
_ => show_suggestion = false,
|
||||
};
|
||||
}
|
||||
ty::Param(_) | ty::Infer(_) => {}
|
||||
_ => show_suggestion = false,
|
||||
}
|
||||
if show_suggestion {
|
||||
return Some(*msg);
|
||||
}
|
||||
}
|
||||
if show_suggestion {
|
||||
return Some(*msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -381,15 +381,15 @@ impl IgnoredDiagnosticOption {
|
|||
old: Option<Span>,
|
||||
option_name: &'static str,
|
||||
) {
|
||||
if let (Some(new_item), Some(old_item)) = (new, old) {
|
||||
if let Some(item_def_id) = item_def_id.as_local() {
|
||||
tcx.emit_node_span_lint(
|
||||
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
|
||||
tcx.local_def_id_to_hir_id(item_def_id),
|
||||
new_item,
|
||||
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
|
||||
);
|
||||
}
|
||||
if let (Some(new_item), Some(old_item)) = (new, old)
|
||||
&& let Some(item_def_id) = item_def_id.as_local()
|
||||
{
|
||||
tcx.emit_node_span_lint(
|
||||
MALFORMED_DIAGNOSTIC_ATTRIBUTES,
|
||||
tcx.local_def_id_to_hir_id(item_def_id),
|
||||
new_item,
|
||||
IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2213,26 +2213,26 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
span: Span,
|
||||
trait_ref: DefId,
|
||||
) {
|
||||
if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id) {
|
||||
if let ty::AssocKind::Const { .. } | ty::AssocKind::Type { .. } = assoc_item.kind {
|
||||
err.note(format!(
|
||||
"{}s cannot be accessed directly on a `trait`, they can only be \
|
||||
if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id)
|
||||
&& let ty::AssocKind::Const { .. } | ty::AssocKind::Type { .. } = assoc_item.kind
|
||||
{
|
||||
err.note(format!(
|
||||
"{}s cannot be accessed directly on a `trait`, they can only be \
|
||||
accessed through a specific `impl`",
|
||||
self.tcx.def_kind_descr(assoc_item.as_def_kind(), item_def_id)
|
||||
));
|
||||
self.tcx.def_kind_descr(assoc_item.as_def_kind(), item_def_id)
|
||||
));
|
||||
|
||||
if !assoc_item.is_impl_trait_in_trait() {
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
"use the fully qualified path to an implementation",
|
||||
format!(
|
||||
"<Type as {}>::{}",
|
||||
self.tcx.def_path_str(trait_ref),
|
||||
assoc_item.name()
|
||||
),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
if !assoc_item.is_impl_trait_in_trait() {
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
"use the fully qualified path to an implementation",
|
||||
format!(
|
||||
"<Type as {}>::{}",
|
||||
self.tcx.def_path_str(trait_ref),
|
||||
assoc_item.name()
|
||||
),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -695,15 +695,14 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
|
|||
source: CandidateSource::Impl(def_id),
|
||||
result: Ok(_),
|
||||
} = cand.kind()
|
||||
&& let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id)
|
||||
{
|
||||
if let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id) {
|
||||
let message = infcx
|
||||
.tcx
|
||||
.get_attr(def_id, sym::rustc_reservation_impl)
|
||||
.and_then(|a| a.value_str());
|
||||
if let Some(message) = message {
|
||||
self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message });
|
||||
}
|
||||
let message = infcx
|
||||
.tcx
|
||||
.get_attr(def_id, sym::rustc_reservation_impl)
|
||||
.and_then(|a| a.value_str());
|
||||
if let Some(message) = message {
|
||||
self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -781,16 +781,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
self,
|
||||
&project_obligation,
|
||||
)
|
||||
{
|
||||
if let Some(cached_res) = self
|
||||
&& let Some(cached_res) = self
|
||||
.infcx
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.projection_cache()
|
||||
.is_complete(key)
|
||||
{
|
||||
break 'compute_res Ok(cached_res);
|
||||
}
|
||||
{
|
||||
break 'compute_res Ok(cached_res);
|
||||
}
|
||||
|
||||
// Need to explicitly set the depth of nested goals here as
|
||||
|
|
@ -1436,24 +1434,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
|
||||
let tcx = self.tcx();
|
||||
// Treat reservation impls as ambiguity.
|
||||
if let ImplCandidate(def_id) = candidate {
|
||||
if let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) {
|
||||
if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
|
||||
let message = tcx
|
||||
.get_attr(def_id, sym::rustc_reservation_impl)
|
||||
.and_then(|a| a.value_str());
|
||||
if let Some(message) = message {
|
||||
debug!(
|
||||
"filter_reservation_impls: \
|
||||
if let ImplCandidate(def_id) = candidate
|
||||
&& let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id)
|
||||
{
|
||||
if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
|
||||
let message =
|
||||
tcx.get_attr(def_id, sym::rustc_reservation_impl).and_then(|a| a.value_str());
|
||||
if let Some(message) = message {
|
||||
debug!(
|
||||
"filter_reservation_impls: \
|
||||
reservation impl ambiguity on {:?}",
|
||||
def_id
|
||||
);
|
||||
intercrate_ambiguity_clauses
|
||||
.insert(IntercrateAmbiguityCause::ReservationImpl { message });
|
||||
}
|
||||
def_id
|
||||
);
|
||||
intercrate_ambiguity_clauses
|
||||
.insert(IntercrateAmbiguityCause::ReservationImpl { message });
|
||||
}
|
||||
return Ok(None);
|
||||
}
|
||||
return Ok(None);
|
||||
}
|
||||
Ok(Some(candidate))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -642,11 +642,11 @@ fn fn_abi_adjust_for_abi<'tcx>(
|
|||
// The `deduced_param_attrs` list could be empty if this is a type of function
|
||||
// we can't deduce any parameters for, so make sure the argument index is in
|
||||
// bounds.
|
||||
if let Some(deduced_param_attrs) = deduced_param_attrs.get(arg_idx) {
|
||||
if deduced_param_attrs.read_only {
|
||||
attrs.regular.insert(ArgAttribute::ReadOnly);
|
||||
debug!("added deduced read-only attribute");
|
||||
}
|
||||
if let Some(deduced_param_attrs) = deduced_param_attrs.get(arg_idx)
|
||||
&& deduced_param_attrs.read_only
|
||||
{
|
||||
attrs.regular.insert(ArgAttribute::ReadOnly);
|
||||
debug!("added deduced read-only attribute");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,10 +106,10 @@ fn adt_sizedness_constraint<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
(def_id, sizedness): (DefId, SizedTraitKind),
|
||||
) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> {
|
||||
if let Some(def_id) = def_id.as_local() {
|
||||
if let ty::Representability::Infinite(_) = tcx.representability(def_id) {
|
||||
return None;
|
||||
}
|
||||
if let Some(def_id) = def_id.as_local()
|
||||
&& let ty::Representability::Infinite(_) = tcx.representability(def_id)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
let def = tcx.adt_def(def_id);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue