Skip to content

Track implicit Sized obligations in type params #98816

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
}

fn normalize(mut self) -> Vec<traits::PredicateObligation<'tcx>> {
let cause = self.cause(traits::MiscObligation);
let cause = self.cause(traits::WellFormed(None));
let infcx = &mut self.infcx;
let param_env = self.param_env;
let mut obligations = Vec::with_capacity(self.out.len());
Expand Down Expand Up @@ -385,7 +385,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
self.out.extend(obligations);

let tcx = self.tcx();
let cause = self.cause(traits::MiscObligation);
let cause = self.cause(traits::WellFormed(None));
let param_env = self.param_env;
let depth = self.recursion_depth;

Expand Down Expand Up @@ -445,7 +445,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
let predicate =
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv.shrink()))
.to_predicate(self.tcx());
let cause = self.cause(traits::MiscObligation);
let cause = self.cause(traits::WellFormed(None));
self.out.push(traits::Obligation::with_depth(
cause,
self.recursion_depth,
Expand All @@ -457,7 +457,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
let resolved = self.infcx.shallow_resolve(infer);
// the `InferConst` changed, meaning that we made progress.
if resolved != infer {
let cause = self.cause(traits::MiscObligation);
let cause = self.cause(traits::WellFormed(None));

let resolved_constant = self.infcx.tcx.mk_const(ty::ConstS {
kind: ty::ConstKind::Infer(resolved),
Expand Down Expand Up @@ -648,7 +648,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
let defer_to_coercion = self.tcx().features().object_safe_for_dispatch;

if !defer_to_coercion {
let cause = self.cause(traits::MiscObligation);
let cause = self.cause(traits::WellFormed(None));
let component_traits = data.auto_traits().chain(data.principal_def_id());
let tcx = self.tcx();
self.out.extend(component_traits.map(|did| {
Expand Down Expand Up @@ -679,7 +679,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
let ty = self.infcx.shallow_resolve(ty);
if let ty::Infer(ty::TyVar(_)) = ty.kind() {
// Not yet resolved, but we've made progress.
let cause = self.cause(traits::MiscObligation);
let cause = self.cause(traits::WellFormed(None));
self.out.push(traits::Obligation::with_depth(
cause,
self.recursion_depth,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};

// we must check that return type of called functions is WF:
self.register_wf_obligation(output.into(), call_expr.span, traits::MiscObligation);
self.register_wf_obligation(output.into(), call_expr.span, traits::WellFormed(None));

output
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
let t = <dyn AstConv<'_>>::ast_ty_to_ty(self, ast_t);
self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
self.register_wf_obligation(t.into(), ast_t.span, traits::WellFormed(None));
t
}

Expand Down Expand Up @@ -526,7 +526,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.register_wf_obligation(
c.into(),
self.tcx.hir().span(ast_c.hir_id),
ObligationCauseCode::MiscObligation,
ObligationCauseCode::WellFormed(None),
);
c
}
Expand All @@ -544,7 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.register_wf_obligation(
c.into(),
self.tcx.hir().span(ast_c.hir_id),
ObligationCauseCode::MiscObligation,
ObligationCauseCode::WellFormed(None),
);
c
}
Expand Down Expand Up @@ -607,7 +607,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for arg in substs.iter().filter(|arg| {
matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
}) {
self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
self.register_wf_obligation(arg, expr.span, traits::WellFormed(None));
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/method/confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// the function type must also be well-formed (this is not
// implied by the substs being well-formed because of inherent
// impls and late-bound regions - see issue #28609).
self.register_wf_obligation(fty.into(), self.span, traits::MiscObligation);
self.register_wf_obligation(fty.into(), self.span, traits::WellFormed(None));
}

///////////////////////////////////////////////////////////////////////////
Expand Down
51 changes: 39 additions & 12 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let type_param = generics.type_param(param_type, self.tcx);
Some(self.tcx.def_span(type_param.def_id))
}
ty::Adt(def, _) if def.did().is_local() => {
tcx.def_ident_span(def.did()).map(|span| span)
}
ty::Adt(def, _) if def.did().is_local() => Some(tcx.def_span(def.did())),
_ => None,
};

Expand Down Expand Up @@ -621,12 +619,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Find all the requirements that come from a local `impl` block.
let mut skip_list: FxHashSet<_> = Default::default();
let mut spanned_predicates: FxHashMap<MultiSpan, _> = Default::default();
for (data, p, parent_p, impl_def_id, cause_span) in unsatisfied_predicates
for (data, p, parent_p, impl_def_id, cause) in unsatisfied_predicates
.iter()
.filter_map(|(p, parent, c)| c.as_ref().map(|c| (p, parent, c)))
.filter_map(|(p, parent, c)| match c.code() {
ObligationCauseCode::ImplDerivedObligation(ref data) => {
Some((&data.derived, p, parent, data.impl_def_id, data.span))
Some((&data.derived, p, parent, data.impl_def_id, data))
}
_ => None,
})
Expand Down Expand Up @@ -695,9 +693,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let _ = format_pred(*pred);
}
skip_list.insert(p);
let mut spans = if cause_span != *item_span {
let mut spans: MultiSpan = cause_span.into();
spans.push_span_label(cause_span, unsatisfied_msg);
let mut spans = if cause.span != *item_span {
let mut spans: MultiSpan = cause.span.into();
spans.push_span_label(cause.span, unsatisfied_msg);
spans
} else {
ident.span.into()
Expand All @@ -709,7 +707,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Unmet obligation coming from an `impl`.
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { of_trait, self_ty, .. }),
kind:
hir::ItemKind::Impl(hir::Impl {
of_trait, self_ty, generics, ..
}),
span: item_span,
..
})) if !matches!(
Expand All @@ -725,14 +726,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Some(ExpnKind::Macro(MacroKind::Derive, _))
) =>
{
let sized_pred =
unsatisfied_predicates.iter().any(|(pred, _, _)| {
match pred.kind().skip_binder() {
ty::PredicateKind::Trait(pred) => {
Some(pred.def_id())
== self.tcx.lang_items().sized_trait()
&& pred.polarity == ty::ImplPolarity::Positive
}
_ => false,
}
});
for param in generics.params {
if param.span == cause.span && sized_pred {
let (sp, sugg) = match param.colon_span {
Some(sp) => (sp.shrink_to_hi(), " ?Sized +"),
None => (param.span.shrink_to_hi(), ": ?Sized"),
};
err.span_suggestion_verbose(
sp,
"consider relaxing the type parameter's implicit \
`Sized` bound",
sugg,
Applicability::MachineApplicable,
);
}
}
if let Some(pred) = parent_p {
// Done to add the "doesn't satisfy" `span_label`.
let _ = format_pred(*pred);
}
skip_list.insert(p);
let mut spans = if cause_span != *item_span {
let mut spans: MultiSpan = cause_span.into();
spans.push_span_label(cause_span, unsatisfied_msg);
let mut spans = if cause.span != *item_span {
let mut spans: MultiSpan = cause.span.into();
spans.push_span_label(cause.span, unsatisfied_msg);
spans
} else {
let mut spans = Vec::with_capacity(2);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1180,7 +1180,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: LocalDefId, ty_span: Span, allow_fo
fcx.register_bound(
item_ty,
tcx.require_lang_item(LangItem::Sized, None),
traits::ObligationCause::new(ty_span, fcx.body_id, traits::MiscObligation),
traits::ObligationCause::new(ty_span, fcx.body_id, traits::WellFormed(None)),
);
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_typeck/src/hir_wf_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fn diagnostic_hir_wf_check<'tcx>(
let cause = traits::ObligationCause::new(
ty.span,
self.hir_id,
traits::ObligationCauseCode::MiscObligation,
traits::ObligationCauseCode::WellFormed(None),
);
fulfill.register_predicate_obligation(
&infcx,
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/associated-item/associated-item-enum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0599]: no variant or associated item named `mispellable` found for enum `
--> $DIR/associated-item-enum.rs:17:11
|
LL | enum Enum { Variant }
| ---- variant or associated item `mispellable` not found for this enum
| --------- variant or associated item `mispellable` not found for this enum
...
LL | Enum::mispellable();
| ^^^^^^^^^^^
Expand All @@ -14,7 +14,7 @@ error[E0599]: no variant or associated item named `mispellable_trait` found for
--> $DIR/associated-item-enum.rs:18:11
|
LL | enum Enum { Variant }
| ---- variant or associated item `mispellable_trait` not found for this enum
| --------- variant or associated item `mispellable_trait` not found for this enum
...
LL | Enum::mispellable_trait();
| ^^^^^^^^^^^^^^^^^
Expand All @@ -26,7 +26,7 @@ error[E0599]: no variant or associated item named `MISPELLABLE` found for enum `
--> $DIR/associated-item-enum.rs:19:11
|
LL | enum Enum { Variant }
| ---- variant or associated item `MISPELLABLE` not found for this enum
| --------- variant or associated item `MISPELLABLE` not found for this enum
...
LL | Enum::MISPELLABLE;
| ^^^^^^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/async-await/pin-needed-to-poll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0599]: no method named `poll` found for struct `Sleep` in the current sco
--> $DIR/pin-needed-to-poll.rs:42:20
|
LL | struct Sleep;
| ----- method `poll` not found for this struct
| ------------ method `poll` not found for this struct
...
LL | self.sleep.poll(cx)
| ^^^^ method not found in `Sleep`
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/bogus-tag.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0599]: no variant or associated item named `Hsl` found for enum `Color` i
--> $DIR/bogus-tag.rs:7:16
|
LL | enum Color { Rgb(isize, isize, isize), Rgba(isize, isize, isize, isize), }
| ----- variant or associated item `Hsl` not found for this enum
| ---------- variant or associated item `Hsl` not found for this enum
...
LL | Color::Hsl(h, s, l) => { println!("hsl"); }
| ^^^ variant or associated item not found in `Color`
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/confuse-field-and-method/issue-18343.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0599]: no method named `closure` found for struct `Obj` in the current sc
--> $DIR/issue-18343.rs:7:7
|
LL | struct Obj<F> where F: FnMut() -> u32 {
| --- method `closure` not found for this struct
| ------------- method `closure` not found for this struct
...
LL | o.closure();
| ^^^^^^^ field, not a method
Expand Down
22 changes: 11 additions & 11 deletions src/test/ui/confuse-field-and-method/issue-2392.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0599]: no method named `closure` found for struct `Obj` in the current sc
--> $DIR/issue-2392.rs:36:15
|
LL | struct Obj<F> where F: FnOnce() -> u32 {
| --- method `closure` not found for this struct
| ------------- method `closure` not found for this struct
...
LL | o_closure.closure();
| ^^^^^^^ field, not a method
Expand All @@ -16,7 +16,7 @@ error[E0599]: no method named `not_closure` found for struct `Obj` in the curren
--> $DIR/issue-2392.rs:38:15
|
LL | struct Obj<F> where F: FnOnce() -> u32 {
| --- method `not_closure` not found for this struct
| ------------- method `not_closure` not found for this struct
...
LL | o_closure.not_closure();
| ^^^^^^^^^^^-- help: remove the arguments
Expand All @@ -27,7 +27,7 @@ error[E0599]: no method named `closure` found for struct `Obj` in the current sc
--> $DIR/issue-2392.rs:42:12
|
LL | struct Obj<F> where F: FnOnce() -> u32 {
| --- method `closure` not found for this struct
| ------------- method `closure` not found for this struct
...
LL | o_func.closure();
| ^^^^^^^ field, not a method
Expand All @@ -41,7 +41,7 @@ error[E0599]: no method named `boxed_closure` found for struct `BoxedObj` in the
--> $DIR/issue-2392.rs:45:14
|
LL | struct BoxedObj {
| -------- method `boxed_closure` not found for this struct
| --------------- method `boxed_closure` not found for this struct
...
LL | boxed_fn.boxed_closure();
| ^^^^^^^^^^^^^ field, not a method
Expand All @@ -55,7 +55,7 @@ error[E0599]: no method named `boxed_closure` found for struct `BoxedObj` in the
--> $DIR/issue-2392.rs:48:19
|
LL | struct BoxedObj {
| -------- method `boxed_closure` not found for this struct
| --------------- method `boxed_closure` not found for this struct
...
LL | boxed_closure.boxed_closure();
| ^^^^^^^^^^^^^ field, not a method
Expand All @@ -69,7 +69,7 @@ error[E0599]: no method named `closure` found for struct `Obj` in the current sc
--> $DIR/issue-2392.rs:53:12
|
LL | struct Obj<F> where F: FnOnce() -> u32 {
| --- method `closure` not found for this struct
| ------------- method `closure` not found for this struct
...
LL | w.wrap.closure();
| ^^^^^^^ field, not a method
Expand All @@ -83,7 +83,7 @@ error[E0599]: no method named `not_closure` found for struct `Obj` in the curren
--> $DIR/issue-2392.rs:55:12
|
LL | struct Obj<F> where F: FnOnce() -> u32 {
| --- method `not_closure` not found for this struct
| ------------- method `not_closure` not found for this struct
...
LL | w.wrap.not_closure();
| ^^^^^^^^^^^-- help: remove the arguments
Expand All @@ -94,7 +94,7 @@ error[E0599]: no method named `closure` found for struct `Obj` in the current sc
--> $DIR/issue-2392.rs:58:24
|
LL | struct Obj<F> where F: FnOnce() -> u32 {
| --- method `closure` not found for this struct
| ------------- method `closure` not found for this struct
...
LL | check_expression().closure();
| ^^^^^^^ field, not a method
Expand All @@ -108,7 +108,7 @@ error[E0599]: no method named `f1` found for struct `FuncContainer` in the curre
--> $DIR/issue-2392.rs:64:31
|
LL | struct FuncContainer {
| ------------- method `f1` not found for this struct
| -------------------- method `f1` not found for this struct
...
LL | (*self.container).f1(1);
| ^^ field, not a method
Expand All @@ -122,7 +122,7 @@ error[E0599]: no method named `f2` found for struct `FuncContainer` in the curre
--> $DIR/issue-2392.rs:65:31
|
LL | struct FuncContainer {
| ------------- method `f2` not found for this struct
| -------------------- method `f2` not found for this struct
...
LL | (*self.container).f2(1);
| ^^ field, not a method
Expand All @@ -136,7 +136,7 @@ error[E0599]: no method named `f3` found for struct `FuncContainer` in the curre
--> $DIR/issue-2392.rs:66:31
|
LL | struct FuncContainer {
| ------------- method `f3` not found for this struct
| -------------------- method `f3` not found for this struct
...
LL | (*self.container).f3(1);
| ^^ field, not a method
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/confuse-field-and-method/issue-32128.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0599]: no method named `example` found for struct `Example` in the curren
--> $DIR/issue-32128.rs:12:10
|
LL | struct Example {
| ------- method `example` not found for this struct
| -------------- method `example` not found for this struct
...
LL | demo.example(1);
| ^^^^^^^ field, not a method
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/confuse-field-and-method/private-field.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0599]: no method named `dog_age` found for struct `Dog` in the current sc
--> $DIR/private-field.rs:16:23
|
LL | pub struct Dog {
| --- method `dog_age` not found for this struct
| -------------- method `dog_age` not found for this struct
...
LL | let dog_age = dog.dog_age();
| ^^^^^^^ private field, not a method
Expand Down
Loading