Support `?Sized` in where clauses #37791

Merged
merged 1 commit into from Nov 29, 2016

Projects

None yet

9 participants

@petrochenkov
Contributor

Implemented as described in #20503 (comment) - ?Trait bounds are moved on type parameter definitions when possible, reported as errors otherwise.
(It'd be nice to unify bounds and where clauses in HIR, but this is mostly blocked by rustdoc now - it needs to render bounds in pleasant way and the best way to do it so far is to mirror what was written in source code.)

Fixes #20503
r? @nikomatsakis

@brson brson added the relnotes label Nov 16, 2016
src/librustc/hir/lowering.rs
+ if name == ty_param.ident.name {
+ add_bounds.entry(ty_param.id).or_insert(Vec::new())
+ .push(bound.clone());
+ break 'next_bound;
@petrochenkov
petrochenkov Nov 16, 2016 Contributor

s/break/continue/

src/librustc/hir/lowering.rs
+ bound_pred.bound_lifetimes.is_empty() => {
+ let name = path.segments[0].identifier.name;
+ for ty_param in &g.ty_params {
+ // Don't bother looking up the definition,
@arielb1
arielb1 Nov 16, 2016 Contributor

Can't macros make a mess of this in their evil macro-ey ways? Better look up the definition to avoid the question.

@petrochenkov
petrochenkov Nov 16, 2016 Contributor

Type parameters are not hygienic now, but it may make sense to lookup definitions for future proofing. Even if this is a loop it's probably not very performance critical.

@arielb1
arielb1 Nov 16, 2016 Contributor

Sure. Randomly implementing unhygienic lookup is a sure way to cause bugs in the future.

@nikomatsakis
Contributor

@petrochenkov do you have an alternate, more hygiene-friendly impl in mind?

@petrochenkov
Contributor

@nikomatsakis
Yes, sure, all definitions are recorded in def map when AST->HIR lowering happens and can be compared instead of names.

@nikomatsakis
Contributor

@petrochenkov ok seems better

@petrochenkov
Contributor

Updated.

@thepowersgang
Contributor

I am against this because I believe that being sized is such an important part of the type that the annotation removing it should be in a prominent location, not hidden among the where clauses.

@KalitaAlexey
Contributor

@thepowersgang I like to place all constraints after where.

@nikomatsakis

Code looks good, I just think we can tweak the error message.

src/librustc/hir/lowering.rs
+ if let TraitTyParamBound(_, TraitBoundModifier::Maybe) = *bound {
+ let report_error = |this: &mut Self| {
+ this.diagnostic().span_err(bound_pred.bounded_ty.span,
+ "`?Trait` bounds are permitted only on fresh type parameters");
@nikomatsakis
nikomatsakis Nov 22, 2016 Contributor

Nit: maybe "only permitted at the point where a type parameter is declared"?

@petrochenkov
petrochenkov Nov 24, 2016 Contributor

Updated the message.

+struct S4<T>(T) where for<'a> T: ?Trait<'a>;
+//~^ ERROR `?Trait` bounds are permitted only on fresh type parameters
+
+struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
@nikomatsakis
nikomatsakis Nov 22, 2016 Contributor

what on earth is ?Trait<'static>? we permit that??

@nikomatsakis
nikomatsakis Nov 22, 2016 Contributor

huh, apparently. I would have thought it'd be an error. Oh well, obviously pre-existing.

@nikomatsakis nikomatsakis added the T-lang label Nov 22, 2016
@nikomatsakis
Contributor

@rfcbot fcp merge

Strictly speaking, this is an "insta-stable" lang change. We could use a stability period, not sure if it is necessary in this case. I propose we merge, as this feels more like a bugfix to me, but am amenable to a stability period as well. But let's FCP it.

OK @rust-lang/lang, what do you think? The change is to permit fn foo<T>() where T: ?Sized and not require that it be declared like fn foo<T: ?Sized>() (i.e., allow T: ?Sized to be moved into a where-clause on the item where T is declared.

@rfcbot
rfcbot commented Nov 22, 2016 edited

Team member @nikomatsakis has proposed to merge this. The next step is review by the rest of the tagged teams:

No concerns currently listed.

Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@withoutboats
Contributor
withoutboats commented Nov 22, 2016 edited

@rfcbot reviewed

Seems like a bug fix to me. It should always be possible to transpose bounds from the parameter introduction clause to the where clause. "Special cases aren't special enough to break the rules." etc

@petrochenkov petrochenkov Support `?Sized` in where clauses
7d15250
@nikomatsakis
Contributor

@bors r+

@bors
Contributor
bors commented Nov 28, 2016

๐Ÿ“Œ Commit 7d15250 has been approved by nikomatsakis

@bors
Contributor
bors commented Nov 28, 2016

โŒ›๏ธ Testing commit 7d15250 with merge 1c44857...

@bors bors added a commit that referenced this pull request Nov 28, 2016
@bors bors Auto merge of #37791 - petrochenkov:where, r=nikomatsakis
Support `?Sized` in where clauses

Implemented as described in #20503 (comment) - `?Trait` bounds are moved on type parameter definitions when possible, reported as errors otherwise.
(It'd be nice to unify bounds and where clauses in HIR, but this is mostly blocked by rustdoc now - it needs to render bounds in pleasant way and the best way to do it so far is to mirror what was written in source code.)

Fixes #20503
r? @nikomatsakis
1c44857
@bors bors merged commit 7d15250 into rust-lang:master Nov 29, 2016

2 checks passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment